app/assets/javascripts/angular/angular-sanitize.js in angular-rails-engine-1.1.5.0 vs app/assets/javascripts/angular/angular-sanitize.js in angular-rails-engine-1.2.0.0

- old
+ new

@@ -1,17 +1,37 @@ /** - * @license AngularJS v1.1.5 + * @license AngularJS v1.2.0rc1 * (c) 2010-2012 Google, Inc. http://angularjs.org * License: MIT */ -(function(window, angular, undefined) { -'use strict'; +(function(window, angular, undefined) {'use strict'; +var $sanitizeMinErr = angular.$$minErr('$sanitize'); + /** * @ngdoc overview * @name ngSanitize * @description + * + * The `ngSanitize` module provides functionality to sanitize HTML. + * + * # Installation + * As a separate module, it must be loaded after Angular core is loaded; otherwise, an 'Uncaught Error: + * No module: ngSanitize' runtime error will occur. + * + * <pre> + * <script src="angular.js"></script> + * <script src="angular-sanitize.js"></script> + * </pre> + * + * # Usage + * To make sure the module is available to your application, declare it as a dependency of you application + * module. + * + * <pre> + * angular.module('app', ['ngSanitize']); + * </pre> */ /* * HTML Parser By Misko Hevery (misko@hevery.com) * based on: HTML Parser By John Resig (ejohn.org) @@ -46,72 +66,75 @@ * * @example <doc:example module="ngSanitize"> <doc:source> <script> - function Ctrl($scope) { + function Ctrl($scope, $sce) { $scope.snippet = '<p style="color:blue">an html\n' + '<em onmouseover="this.textContent=\'PWN3D!\'">click here</em>\n' + 'snippet</p>'; + $scope.deliberatelyTrustDangerousSnippet = function() { + return $sce.trustAsHtml($scope.snippet); + }; } </script> <div ng-controller="Ctrl"> Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea> <table> <tr> - <td>Filter</td> + <td>Directive</td> + <td>How</td> <td>Source</td> <td>Rendered</td> </tr> - <tr id="html-filter"> - <td>html filter</td> - <td> - <pre>&lt;div ng-bind-html="snippet"&gt;<br/>&lt;/div&gt;</pre> - </td> - <td> - <div ng-bind-html="snippet"></div> - </td> + <tr id="bind-html-with-sanitize"> + <td>ng-bind-html</td> + <td>Automatically uses $sanitize</td> + <td><pre>&lt;div ng-bind-html="snippet"&gt;<br/>&lt;/div&gt;</pre></td> + <td><div ng-bind-html="snippet"></div></td> </tr> - <tr id="escaped-html"> - <td>no filter</td> + <tr id="bind-html-with-trust"> + <td>ng-bind-html</td> + <td>Bypass $sanitize by explicitly trusting the dangerous value</td> + <td><pre>&lt;div ng-bind-html="deliberatelyTrustDangerousSnippet()"&gt;<br/>&lt;/div&gt;</pre></td> + <td><div ng-bind-html="deliberatelyTrustDangerousSnippet()"></div></td> + </tr> + <tr id="bind-default"> + <td>ng-bind</td> + <td>Automatically escapes</td> <td><pre>&lt;div ng-bind="snippet"&gt;<br/>&lt;/div&gt;</pre></td> <td><div ng-bind="snippet"></div></td> </tr> - <tr id="html-unsafe-filter"> - <td>unsafe html filter</td> - <td><pre>&lt;div ng-bind-html-unsafe="snippet"&gt;<br/>&lt;/div&gt;</pre></td> - <td><div ng-bind-html-unsafe="snippet"></div></td> - </tr> </table> </div> </doc:source> <doc:scenario> - it('should sanitize the html snippet ', function() { - expect(using('#html-filter').element('div').html()). + it('should sanitize the html snippet by default', function() { + expect(using('#bind-html-with-sanitize').element('div').html()). toBe('<p>an html\n<em>click here</em>\nsnippet</p>'); }); + it('should inline raw snippet if bound to a trusted value', function() { + expect(using('#bind-html-with-trust').element("div").html()). + toBe("<p style=\"color:blue\">an html\n" + + "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" + + "snippet</p>"); + }); + it('should escape snippet without any filter', function() { - expect(using('#escaped-html').element('div').html()). + expect(using('#bind-default').element('div').html()). toBe("&lt;p style=\"color:blue\"&gt;an html\n" + "&lt;em onmouseover=\"this.textContent='PWN3D!'\"&gt;click here&lt;/em&gt;\n" + "snippet&lt;/p&gt;"); }); - it('should inline raw snippet if filtered as unsafe', function() { - expect(using('#html-unsafe-filter').element("div").html()). - toBe("<p style=\"color:blue\">an html\n" + - "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" + - "snippet</p>"); - }); - it('should update', function() { - input('snippet').enter('new <b>text</b>'); - expect(using('#html-filter').binding('snippet')).toBe('new <b>text</b>'); - expect(using('#escaped-html').element('div').html()).toBe("new &lt;b&gt;text&lt;/b&gt;"); - expect(using('#html-unsafe-filter').binding("snippet")).toBe('new <b>text</b>'); + input('snippet').enter('new <b onclick="alert(1)">text</b>'); + expect(using('#bind-html-with-sanitize').element('div').html()).toBe('new <b>text</b>'); + expect(using('#bind-html-with-trust').element('div').html()).toBe('new <b onclick="alert(1)">text</b>'); + expect(using('#bind-default').element('div').html()).toBe("new &lt;b onclick=\"alert(1)\"&gt;text&lt;/b&gt;"); }); </doc:scenario> </doc:example> */ var $sanitize = function(html) { @@ -127,11 +150,11 @@ ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g, BEGIN_TAG_REGEXP = /^</, BEGING_END_TAGE_REGEXP = /^<\s*\//, COMMENT_REGEXP = /<!--(.*?)-->/g, CDATA_REGEXP = /<!\[CDATA\[(.*?)]]>/g, - URI_REGEXP = /^((ftp|https?):\/\/|mailto:|tel:|#)/, + URI_REGEXP = /^((ftp|https?):\/\/|mailto:|tel:|#)/i, NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g; // Match everything outside of normal chars and " (quote character) // Good source of info about elements and attributes // http://dev.w3.org/html5/spec/Overview.html#semantics @@ -254,11 +277,11 @@ parseEndTag( "", stack.last() ); } if ( html == last ) { - throw "Parse Error: " + html; + throw $sanitizeMinErr('badparse', "The sanitizer was unable to parse the following block of html: {0}", html); } last = html; } // Clean up any remaining tags @@ -281,14 +304,14 @@ if ( !unary ) stack.push( tagName ); var attrs = {}; - rest.replace(ATTR_REGEXP, function(match, name, doubleQuotedValue, singleQoutedValue, unqoutedValue) { + rest.replace(ATTR_REGEXP, function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) { var value = doubleQuotedValue - || singleQoutedValue - || unqoutedValue + || singleQuotedValue + || unquotedValue || ''; attrs[name] = decodeEntities(value); }); if (handler.start) handler.start( tagName, attrs, unary ); @@ -397,32 +420,9 @@ } // define ngSanitize module and register $sanitize service angular.module('ngSanitize', []).value('$sanitize', $sanitize); - -/** - * @ngdoc directive - * @name ngSanitize.directive:ngBindHtml - * - * @description - * Creates a binding that will sanitize the result of evaluating the `expression` with the - * {@link ngSanitize.$sanitize $sanitize} service and innerHTML the result into the current element. - * - * See {@link ngSanitize.$sanitize $sanitize} docs for examples. - * - * @element ANY - * @param {expression} ngBindHtml {@link guide/expression Expression} to evaluate. - */ -angular.module('ngSanitize').directive('ngBindHtml', ['$sanitize', function($sanitize) { - return function(scope, element, attr) { - element.addClass('ng-binding').data('$binding', attr.ngBindHtml); - scope.$watch(attr.ngBindHtml, function ngBindHtmlWatchAction(value) { - value = $sanitize(value); - element.html(value || ''); - }); - }; -}]); /** * @ngdoc filter * @name ngSanitize.filter:linky * @function