diff options
| -rw-r--r-- | Rakefile | 24 | ||||
| -rw-r--r-- | angularFiles.js | 15 | ||||
| -rw-r--r-- | docs/content/cookbook/deeplinking.ngdoc | 2 | ||||
| -rw-r--r-- | docs/src/templates/docs.js | 3 | ||||
| -rw-r--r-- | docs/src/templates/index.html | 1 | ||||
| -rw-r--r-- | src/AngularPublic.js | 2 | ||||
| -rw-r--r-- | src/module.prefix | 6 | ||||
| -rw-r--r-- | src/module.suffix | 2 | ||||
| -rw-r--r-- | src/ng/directive/ngBind.js | 73 | ||||
| -rw-r--r-- | src/ng/filter.js | 1 | ||||
| -rw-r--r-- | src/ng/filter/filters.js | 107 | ||||
| -rw-r--r-- | src/ngSanitize/directive/ngBindHtml.js | 26 | ||||
| -rw-r--r-- | src/ngSanitize/filter/linky.js | 106 | ||||
| -rw-r--r-- | src/ngSanitize/sanitize.js (renamed from src/ng/sanitize.js) | 56 | ||||
| -rw-r--r-- | test/ng/directive/ngBindSpec.js | 28 | ||||
| -rw-r--r-- | test/ng/filter/filtersSpec.js | 26 | ||||
| -rw-r--r-- | test/ngSanitize/directive/ngBindHtmlSpec.js | 25 | ||||
| -rw-r--r-- | test/ngSanitize/filter/linkySpec.js | 27 | ||||
| -rw-r--r-- | test/ngSanitize/sanitizeSpec.js (renamed from test/ng/sanitizeSpec.js) | 13 | ||||
| -rw-r--r-- | test/ngScenario/dslSpec.js | 2 | 
20 files changed, 301 insertions, 244 deletions
| @@ -82,15 +82,23 @@ task :compile => [:init, :compile_scenario, :compile_jstd_scenario_adapter] do        'src/loader.js',        'src/loader.suffix']) -  FileUtils.cp 'src/ngMock/angular-mocks.js', path_to('angular-mocks.js') -  FileUtils.cp 'src/ngResource/resource.js', path_to('angular-resource.js') -  FileUtils.cp 'src/ngCookies/cookies.js', path_to('angular-cookies.js') +  concat_module('sanitize', [ +      'src/ngSanitize/sanitize.js', +      'src/ngSanitize/directive/ngBindHtml.js', +      'src/ngSanitize/filter/linky.js']) + +  concat_module('resource', ['src/ngResource/resource.js']) +  concat_module('cookies', ['src/ngCookies/cookies.js']) + + +  FileUtils.cp 'src/ngMock/angular-mocks.js', path_to('angular-mocks.js')    closure_compile('angular.js')    closure_compile('angular-cookies.js')    closure_compile('angular-loader.js')    closure_compile('angular-resource.js') +  closure_compile('angular-sanitize.js')  end @@ -121,6 +129,8 @@ task :package => [:clean, :compile, :docs] do      path_to('angular-cookies.min.js'),      path_to('angular-resource.js'),      path_to('angular-resource.min.js'), +    path_to('angular-sanitize.js'), +    path_to('angular-sanitize.min.js'),      path_to('angular-scenario.js'),      path_to('jstd-scenario-adapter.js'),      path_to('jstd-scenario-adapter-config.js'), @@ -147,7 +157,8 @@ task :package => [:clean, :compile, :docs] do      rewrite_file(src) do |content|        content.sub!('angular.js', "angular-#{NG_VERSION.full}.js").                sub!('angular-resource.js', "angular-resource-#{NG_VERSION.full}.js"). -              sub!('angular-cookies.js', "angular-cookies-#{NG_VERSION.full}.js") +              sub!('angular-cookies.js', "angular-cookies-#{NG_VERSION.full}.js"). +              sub!('angular-sanitize.js', "angular-sanitize-#{NG_VERSION.full}.js")      end    end @@ -290,6 +301,11 @@ def concat_file(filename, deps, footer='')  end +def concat_module(name, files) +  concat_file('angular-' + name + '.js', ['src/module.prefix'] + files + ['src/module.suffix']) +end + +  def rewrite_file(filename)    File.open(filename, File::RDWR) do |f|      content = f.read diff --git a/angularFiles.js b/angularFiles.js index c819b629..d8be657a 100644 --- a/angularFiles.js +++ b/angularFiles.js @@ -24,7 +24,6 @@ angularFiles = {      'src/ng/route.js',      'src/ng/routeParams.js',      'src/ng/rootScope.js', -    'src/ng/sanitize.js',      'src/ng/sniffer.js',      'src/ng/window.js',      'src/ng/http.js', @@ -65,6 +64,9 @@ angularFiles = {    'angularSrcModules': [      'src/ngCookies/cookies.js',      'src/ngResource/resource.js', +    'src/ngSanitize/sanitize.js', +    'src/ngSanitize/directive/ngBindHtml.js', +    'src/ngSanitize/filter/linky.js',      'src/ngMock/angular-mocks.js'    ], @@ -98,6 +100,9 @@ angularFiles = {      'test/ng/filter/*.js',      'test/ngCookies/*.js',      'test/ngResource/*.js', +    'test/ngSanitize/*.js', +    'test/ngSanitize/directive/*.js', +    'test/ngSanitize/filter/*.js',      'test/ngMock/*.js'    ], @@ -136,10 +141,16 @@ angularFiles = {      'src/ngMock/angular-mocks.js',      'src/ngCookies/cookies.js',      'src/ngResource/resource.js', +    'src/ngSanitize/sanitize.js', +    'src/ngSanitize/directive/ngBindHtml.js', +    'src/ngSanitize/filter/linky.js',      'test/matchers.js',      'test/ngMock/*.js',      'test/ngCookies/*.js', -    'test/ngResource/*.js' +    'test/ngResource/*.js', +    'test/ngSanitize/*.js', +    'test/ngSanitize/directive/*.js', +    'test/ngSanitize/filter/*.js'    ],    'jstdPerf': [ diff --git a/docs/content/cookbook/deeplinking.ngdoc b/docs/content/cookbook/deeplinking.ngdoc index 10af8a2d..4343ded2 100644 --- a/docs/content/cookbook/deeplinking.ngdoc +++ b/docs/content/cookbook/deeplinking.ngdoc @@ -39,7 +39,7 @@ The two partials are defined in the following URLs:  <doc:example module="deepLinking">   <doc:source jsfiddle="false">      <script> -     angular.module('deepLinking', []) +     angular.module('deepLinking', ['ngSanitize'])         .config(function($routeProvider) {            $routeProvider.when("/welcome",  {template:'./examples/welcome.html',  controller:WelcomeCntl});            $routeProvider.when("/settings", {template:'./examples/settings.html', controller:SettingsCntl}); diff --git a/docs/src/templates/docs.js b/docs/src/templates/docs.js index b82ba660..bd294ba9 100644 --- a/docs/src/templates/docs.js +++ b/docs/src/templates/docs.js @@ -146,7 +146,8 @@ function TutorialInstructionsCtrl($scope, $cookieStore) {    };  } -angular.module('ngdocs', ['ngdocs.directives', 'ngResource', 'ngCookies'], function($locationProvider, $filterProvider, $compileProvider) { +angular.module('ngdocs', ['ngdocs.directives', 'ngResource', 'ngCookies', 'ngSanitize'], +    function($locationProvider, $filterProvider, $compileProvider) {    $locationProvider.html5Mode(true).hashPrefix('!');    $filterProvider.register('title', function(){ diff --git a/docs/src/templates/index.html b/docs/src/templates/index.html index 26e95d62..45e1a63d 100644 --- a/docs/src/templates/index.html +++ b/docs/src/templates/index.html @@ -30,6 +30,7 @@        addTag('script', {src: path('angular.js')}, sync);        addTag('script', {src: path('angular-resource.js') }, sync);        addTag('script', {src: path('angular-cookies.js') }, sync); +      addTag('script', {src: path('angular-sanitize.js') }, sync);        addTag('script', {src: 'docs-combined.js'}, sync);        addTag('script', {src: 'docs-keywords.js'}, sync); diff --git a/src/AngularPublic.js b/src/AngularPublic.js index 352e14a8..834fd04a 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -71,7 +71,6 @@ function publishExternalAPI(angular){              style: styleDirective,              option: optionDirective,              ngBind: ngBindDirective, -            ngBindHtml: ngBindHtmlDirective,              ngBindHtmlUnsafe: ngBindHtmlUnsafeDirective,              ngBindTemplate: ngBindTemplateDirective,              ngClass: ngClassDirective, @@ -123,7 +122,6 @@ function publishExternalAPI(angular){          $routeParams: $RouteParamsProvider,          $rootScope: $RootScopeProvider,          $q: $QProvider, -        $sanitize: $SanitizeProvider,          $sniffer: $SnifferProvider,          $templateCache: $TemplateCacheProvider,          $window: $WindowProvider diff --git a/src/module.prefix b/src/module.prefix new file mode 100644 index 00000000..92367961 --- /dev/null +++ b/src/module.prefix @@ -0,0 +1,6 @@ +/** + * @license AngularJS v"NG_VERSION_FULL" + * (c) 2010-2012 AngularJS http://angularjs.org + * License: MIT + */ +(function(angular) { diff --git a/src/module.suffix b/src/module.suffix new file mode 100644 index 00000000..4c04d073 --- /dev/null +++ b/src/module.suffix @@ -0,0 +1,2 @@ + +})(window.angular); diff --git a/src/ng/directive/ngBind.js b/src/ng/directive/ngBind.js index 4f6d49aa..82402ae8 100644 --- a/src/ng/directive/ngBind.js +++ b/src/ng/directive/ngBind.js @@ -57,54 +57,6 @@ var ngBindDirective = ngDirective(function(scope, element, attr) {  /**   * @ngdoc directive - * @name angular.module.ng.$compileProvider.directive.ngBindHtmlUnsafe - * - * @description - * Creates a binding that will innerHTML the result of evaluating the `expression` into the current - * element. *The innerHTML-ed content will not be sanitized!* You should use this directive only if - * {@link angular.module.ng.$compileProvider.directive.ngBindHtml ngBindHtml} directive is too - * restrictive and when you absolutely trust the source of the content you are binding to. - * - * See {@link angular.module.ng.$sanitize $sanitize} docs for examples. - * - * @element ANY - * @param {expression} ngBindHtmlUnsafe {@link guide/dev_guide.expressions Expression} to evaluate. - */ -var ngBindHtmlUnsafeDirective = ngDirective(function(scope, element, attr) { -  element.addClass('ng-binding').data('$binding', attr.ngBindHtmlUnsafe); -  scope.$watch(attr.ngBindHtmlUnsafe, function(value) { -    element.html(value || ''); -  }); -}); - - -/** - * @ngdoc directive - * @name angular.module.ng.$compileProvider.directive.ngBindHtml - * - * @description - * Creates a binding that will sanitize the result of evaluating the `expression` with the - * {@link angular.module.ng.$sanitize $sanitize} service and innerHTML the result into the current - * element. - * - * See {@link angular.module.ng.$sanitize $sanitize} docs for examples. - * - * @element ANY - * @param {expression} ngBindHtml {@link guide/dev_guide.expressions Expression} to evaluate. - */ -var ngBindHtmlDirective = ['$sanitize', function($sanitize) { -  return function(scope, element, attr) { -    element.addClass('ng-binding').data('$binding', attr.ngBindHtml); -    scope.$watch(attr.ngBindHtml, function(value) { -      value = $sanitize(value); -      element.html(value || ''); -    }); -  } -}]; - - -/** - * @ngdoc directive   * @name angular.module.ng.$compileProvider.directive.ngBindTemplate   *   * @description @@ -160,3 +112,28 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) {      });    }  }]; + + +/** + * @ngdoc directive + * @name angular.module.ng.$compileProvider.directive.ngBindHtmlUnsafe + * + * @description + * Creates a binding that will innerHTML the result of evaluating the `expression` into the current + * element. *The innerHTML-ed content will not be sanitized!* You should use this directive only if + * {@link angular.module.ng.$compileProvider.directive.ngBindHtml ngBindHtml} directive is too + * restrictive and when you absolutely trust the source of the content you are binding to. + * + * See {@link angular.module.ng.$sanitize $sanitize} docs for examples. + * + * @element ANY + * @param {expression} ngBindHtmlUnsafe {@link guide/dev_guide.expressions Expression} to evaluate. + */ +var ngBindHtmlUnsafeDirective = [function() { +  return function(scope, element, attr) { +    element.addClass('ng-binding').data('$binding', attr.ngBindHtmlUnsafe); +    scope.$watch(attr.ngBindHtmlUnsafe, function(value) { +      element.html(value || ''); +    }); +  }; +}]; diff --git a/src/ng/filter.js b/src/ng/filter.js index 4ed3f620..24ba248c 100644 --- a/src/ng/filter.js +++ b/src/ng/filter.js @@ -96,7 +96,6 @@ function $FilterProvider($provide) {    register('filter', filterFilter);    register('json', jsonFilter);    register('limitTo', limitToFilter); -  register('linky', linkyFilter);    register('lowercase', lowercaseFilter);    register('number', numberFilter);    register('orderBy', orderByFilter); diff --git a/src/ng/filter/filters.js b/src/ng/filter/filters.js index faea82d4..841a0eaa 100644 --- a/src/ng/filter/filters.js +++ b/src/ng/filter/filters.js @@ -439,110 +439,3 @@ var lowercaseFilter = valueFn(lowercase);   * @see angular.uppercase   */  var uppercaseFilter = valueFn(uppercase); - - -/** - * @ngdoc filter - * @name angular.module.ng.$filter.linky - * @function - * - * @description - *   Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and - *   plain email address links. - * - * @param {string} text Input text. - * @returns {string} Html-linkified text. - * - * @example -   <doc:example> -     <doc:source> -       <script> -         function Ctrl($scope) { -           $scope.snippet = -             'Pretty text with some links:\n'+ -             'http://angularjs.org/,\n'+ -             'mailto:us@somewhere.org,\n'+ -             'another@somewhere.org,\n'+ -             'and one more: ftp://127.0.0.1/.'; -         } -       </script> -       <div ng-controller="Ctrl"> -       Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea> -       <table> -         <tr> -           <td>Filter</td> -           <td>Source</td> -           <td>Rendered</td> -         </tr> -         <tr id="linky-filter"> -           <td>linky filter</td> -           <td> -             <pre><div ng-bind-html="snippet | linky"><br></div></pre> -           </td> -           <td> -             <div ng-bind-html="snippet | linky"></div> -           </td> -         </tr> -         <tr id="escaped-html"> -           <td>no filter</td> -           <td><pre><div ng-bind="snippet"><br></div></pre></td> -           <td><div ng-bind="snippet"></div></td> -         </tr> -       </table> -     </doc:source> -     <doc:scenario> -       it('should linkify the snippet with urls', function() { -         expect(using('#linky-filter').binding('snippet | linky')). -           toBe('Pretty text with some links:
' + -                '<a href="http://angularjs.org/">http://angularjs.org/</a>,
' + -                '<a href="mailto:us@somewhere.org">us@somewhere.org</a>,
' + -                '<a href="mailto:another@somewhere.org">another@somewhere.org</a>,
' + -                'and one more: <a href="ftp://127.0.0.1/">ftp://127.0.0.1/</a>.'); -       }); - -       it ('should not linkify snippet without the linky filter', function() { -         expect(using('#escaped-html').binding('snippet')). -           toBe("Pretty text with some links:\n" + -                "http://angularjs.org/,\n" + -                "mailto:us@somewhere.org,\n" + -                "another@somewhere.org,\n" + -                "and one more: ftp://127.0.0.1/."); -       }); - -       it('should update', function() { -         input('snippet').enter('new http://link.'); -         expect(using('#linky-filter').binding('snippet | linky')). -           toBe('new <a href="http://link">http://link</a>.'); -         expect(using('#escaped-html').binding('snippet')).toBe('new http://link.'); -       }); -     </doc:scenario> -   </doc:example> - */ -function linkyFilter() { -  var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}\<\>]/, -      MAILTO_REGEXP = /^mailto:/; - -  return function(text) { -    if (!text) return text; -    var match; -    var raw = text; -    var html = []; -    var writer = htmlSanitizeWriter(html); -    var url; -    var i; -    while ((match = raw.match(LINKY_URL_REGEXP))) { -      // We can not end in these as they are sometimes found at the end of the sentence -      url = match[0]; -      // if we did not match ftp/http/mailto then assume mailto -      if (match[2] == match[3]) url = 'mailto:' + url; -      i = match.index; -      writer.chars(raw.substr(0, i)); -      writer.start('a', {href:url}); -      writer.chars(match[0].replace(MAILTO_REGEXP, '')); -      writer.end('a'); -      raw = raw.substring(i + match[0].length); -    } -    writer.chars(raw); -    return html.join(''); -  }; -} diff --git a/src/ngSanitize/directive/ngBindHtml.js b/src/ngSanitize/directive/ngBindHtml.js new file mode 100644 index 00000000..f8ccef18 --- /dev/null +++ b/src/ngSanitize/directive/ngBindHtml.js @@ -0,0 +1,26 @@ + + + +/** + * @ngdoc directive + * @name angular.module.ngSanitize.directive.ngBindHtml + * + * @description + * Creates a binding that will sanitize the result of evaluating the `expression` with the + * {@link angular.module.ng.$sanitize $sanitize} service and innerHTML the result into the current + * element. + * + * See {@link angular.module.ng.$sanitize $sanitize} docs for examples. + * + * @element ANY + * @param {expression} ngBindHtml {@link guide/dev_guide.expressions 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(value) { +      value = $sanitize(value); +      element.html(value || ''); +    }); +  }; +}]); diff --git a/src/ngSanitize/filter/linky.js b/src/ngSanitize/filter/linky.js new file mode 100644 index 00000000..c30665a2 --- /dev/null +++ b/src/ngSanitize/filter/linky.js @@ -0,0 +1,106 @@ +/** + * @ngdoc filter + * @name angular.module.ngSanitize.filter.linky + * @function + * + * @description + *   Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and + *   plain email address links. + * + * @param {string} text Input text. + * @returns {string} Html-linkified text. + * + * @example +   <doc:example module="ngSanitize"> +     <doc:source> +       <script> +         function Ctrl($scope) { +           $scope.snippet = +             'Pretty text with some links:\n'+ +             'http://angularjs.org/,\n'+ +             'mailto:us@somewhere.org,\n'+ +             'another@somewhere.org,\n'+ +             'and one more: ftp://127.0.0.1/.'; +         } +       </script> +       <div ng-controller="Ctrl"> +       Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea> +       <table> +         <tr> +           <td>Filter</td> +           <td>Source</td> +           <td>Rendered</td> +         </tr> +         <tr id="linky-filter"> +           <td>linky filter</td> +           <td> +             <pre><div ng-bind-html="snippet | linky"><br></div></pre> +           </td> +           <td> +             <div ng-bind-html="snippet | linky"></div> +           </td> +         </tr> +         <tr id="escaped-html"> +           <td>no filter</td> +           <td><pre><div ng-bind="snippet"><br></div></pre></td> +           <td><div ng-bind="snippet"></div></td> +         </tr> +       </table> +     </doc:source> +     <doc:scenario> +       it('should linkify the snippet with urls', function() { +         expect(using('#linky-filter').binding('snippet | linky')). +           toBe('Pretty text with some links:
' + +                '<a href="http://angularjs.org/">http://angularjs.org/</a>,
' + +                '<a href="mailto:us@somewhere.org">us@somewhere.org</a>,
' + +                '<a href="mailto:another@somewhere.org">another@somewhere.org</a>,
' + +                'and one more: <a href="ftp://127.0.0.1/">ftp://127.0.0.1/</a>.'); +       }); + +       it ('should not linkify snippet without the linky filter', function() { +         expect(using('#escaped-html').binding('snippet')). +           toBe("Pretty text with some links:\n" + +                "http://angularjs.org/,\n" + +                "mailto:us@somewhere.org,\n" + +                "another@somewhere.org,\n" + +                "and one more: ftp://127.0.0.1/."); +       }); + +       it('should update', function() { +         input('snippet').enter('new http://link.'); +         expect(using('#linky-filter').binding('snippet | linky')). +           toBe('new <a href="http://link">http://link</a>.'); +         expect(using('#escaped-html').binding('snippet')).toBe('new http://link.'); +       }); +     </doc:scenario> +   </doc:example> + */ +angular.module('ngSanitize').filter('linky', function() { +  var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}\<\>]/, +      MAILTO_REGEXP = /^mailto:/; + +  return function(text) { +    if (!text) return text; +    var match; +    var raw = text; +    var html = []; +    // TODO(vojta): use $sanitize instead +    var writer = htmlSanitizeWriter(html); +    var url; +    var i; +    while ((match = raw.match(LINKY_URL_REGEXP))) { +      // We can not end in these as they are sometimes found at the end of the sentence +      url = match[0]; +      // if we did not match ftp/http/mailto then assume mailto +      if (match[2] == match[3]) url = 'mailto:' + url; +      i = match.index; +      writer.chars(raw.substr(0, i)); +      writer.start('a', {href:url}); +      writer.chars(match[0].replace(MAILTO_REGEXP, '')); +      writer.end('a'); +      raw = raw.substring(i + match[0].length); +    } +    writer.chars(raw); +    return html.join(''); +  }; +}); diff --git a/src/ng/sanitize.js b/src/ngSanitize/sanitize.js index 6a7a2be4..c8d28315 100644 --- a/src/ng/sanitize.js +++ b/src/ngSanitize/sanitize.js @@ -1,5 +1,11 @@  'use strict'; +/** + * @ngdoc overview + * @name angular.module.ngSanitize + * @description + */ +  /*   * HTML Parser By Misko Hevery (misko@hevery.com)   * based on:  HTML Parser By John Resig (ejohn.org) @@ -17,10 +23,9 @@   */ -  /**   * @ngdoc service - * @name angular.module.ng.$sanitize + * @name angular.module.ngSanitize.$sanitize   * @function   *   * @description @@ -34,7 +39,7 @@   * @returns {string} Sanitized html.   *   * @example -   <doc:example> +   <doc:example module="ngSanitize">       <doc:source>         <script>           function Ctrl($scope) { @@ -103,14 +108,12 @@       </doc:scenario>     </doc:example>   */ - -function $SanitizeProvider() { -  this.$get = valueFn(function(html) { -    var buf = []; +var $sanitize = function(html) { +  var buf = [];      htmlParser(html, htmlSanitizeWriter(buf));      return buf.join(''); -  }); -} +}; +  // Regular Expressions for parsing tags and attributes  var START_TAG_REGEXP = /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/, @@ -136,15 +139,15 @@ var voidElements = makeMap("area,br,col,hr,img,wbr");  // http://dev.w3.org/html5/spec/Overview.html#optional-tags  var optionalEndTagBlockElements = makeMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),      optionalEndTagInlineElements = makeMap("rp,rt"), -    optionalEndTagElements = extend({}, optionalEndTagInlineElements, optionalEndTagBlockElements); +    optionalEndTagElements = angular.extend({}, optionalEndTagInlineElements, optionalEndTagBlockElements);  // Safe Block Elements - HTML5 -var blockElements = extend({}, optionalEndTagBlockElements, makeMap("address,article,aside," + +var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article,aside," +          "blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6," +          "header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul"));  // Inline Elements - HTML5 -var inlineElements = extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b,bdi,bdo," + +var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b,bdi,bdo," +          "big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,samp,small," +          "span,strike,strong,sub,sup,time,tt,u,var")); @@ -152,17 +155,24 @@ var inlineElements = extend({}, optionalEndTagInlineElements, makeMap("a,abbr,ac  // Special Elements (can contain anything)  var specialElements = makeMap("script,style"); -var validElements = extend({}, voidElements, blockElements, inlineElements, optionalEndTagElements); +var validElements = angular.extend({}, voidElements, blockElements, inlineElements, optionalEndTagElements);  //Attributes that have href and hence need to be sanitized  var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap"); -var validAttrs = extend({}, uriAttrs, makeMap( +var validAttrs = angular.extend({}, uriAttrs, makeMap(      'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+      'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+      'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+      'scope,scrolling,shape,span,start,summary,target,title,type,'+      'valign,value,vspace,width')); +function makeMap(str) { +  var obj = {}, items = str.split(','), i; +  for (i = 0; i < items.length; i++) obj[items[i]] = true; +  return obj; +} + +  /**   * @example   * htmlParser(htmlString, { @@ -249,7 +259,7 @@ function htmlParser( html, handler ) {    parseEndTag();    function parseStartTag( tag, tagName, rest, unary ) { -    tagName = lowercase(tagName); +    tagName = angular.lowercase(tagName);      if ( blockElements[ tagName ] ) {        while ( stack.last() && inlineElements[ stack.last() ] ) {          parseEndTag( "", stack.last() ); @@ -280,7 +290,7 @@ function htmlParser( html, handler ) {    function parseEndTag( tag, tagName ) {      var pos = 0, i; -    tagName = lowercase(tagName); +    tagName = angular.lowercase(tagName);      if ( tagName )        // Find the closest opened tag of the same type        for ( pos = stack.length - 1; pos >= 0; pos-- ) @@ -338,18 +348,18 @@ function encodeEntities(value) {   */  function htmlSanitizeWriter(buf){    var ignore = false; -  var out = bind(buf, buf.push); +  var out = angular.bind(buf, buf.push);    return {      start: function(tag, attrs, unary){ -      tag = lowercase(tag); +      tag = angular.lowercase(tag);        if (!ignore && specialElements[tag]) {          ignore = tag;        }        if (!ignore && validElements[tag] == true) {          out('<');          out(tag); -        forEach(attrs, function(value, key){ -          var lkey=lowercase(key); +        angular.forEach(attrs, function(value, key){ +          var lkey=angular.lowercase(key);            if (validAttrs[lkey]==true && (uriAttrs[lkey]!==true || value.match(URI_REGEXP))) {              out(' ');              out(key); @@ -362,7 +372,7 @@ function htmlSanitizeWriter(buf){        }      },      end: function(tag){ -        tag = lowercase(tag); +        tag = angular.lowercase(tag);          if (!ignore && validElements[tag] == true) {            out('</');            out(tag); @@ -379,3 +389,7 @@ function htmlSanitizeWriter(buf){        }    };  } + + +// define ngSanitize module and register $sanitize service +angular.module('ngSanitize', []).value('$sanitize', $sanitize); diff --git a/test/ng/directive/ngBindSpec.js b/test/ng/directive/ngBindSpec.js index b3c63b34..da291fa4 100644 --- a/test/ng/directive/ngBindSpec.js +++ b/test/ng/directive/ngBindSpec.js @@ -67,39 +67,13 @@ describe('ngBind*', function() {    }); -  describe('ngBindHtml', function() { - -    it('should set html', inject(function($rootScope, $compile) { -      element = $compile('<div ng-bind-html="html"></div>')($rootScope); -      $rootScope.html = '<div unknown>hello</div>'; -      $rootScope.$digest(); -      expect(lowercase(element.html())).toEqual('<div>hello</div>'); -    })); - - -    it('should reset html when value is null or undefined', inject(function($compile, $rootScope) { -      element = $compile('<div ng-bind-html="html"></div>')($rootScope); - -      forEach([null, undefined, ''], function(val) { -        $rootScope.html = 'some val'; -        $rootScope.$digest(); -        expect(lowercase(element.html())).toEqual('some val'); - -        $rootScope.html = val; -        $rootScope.$digest(); -        expect(lowercase(element.html())).toEqual(''); -      }); -    })); -  }); - -    describe('ngBindHtmlUnsafe', function() {      it('should set unsafe html', inject(function($rootScope, $compile) {        element = $compile('<div ng-bind-html-unsafe="html"></div>')($rootScope);        $rootScope.html = '<div onclick="">hello</div>';        $rootScope.$digest(); -      expect(lowercase(element.html())).toEqual('<div onclick="">hello</div>'); +      expect(angular.lowercase(element.html())).toEqual('<div onclick="">hello</div>');      }));    });  }); diff --git a/test/ng/filter/filtersSpec.js b/test/ng/filter/filtersSpec.js index 9ea200a3..55476882 100644 --- a/test/ng/filter/filtersSpec.js +++ b/test/ng/filter/filtersSpec.js @@ -153,32 +153,6 @@ describe('filters', function() {      });    }); -  describe('linky', function() { -    var linky; - -    beforeEach(inject(function($filter){ -      linky = $filter('linky') -    })); - -    it('should do basic filter', function() { -      expect(linky("http://ab/ (http://a/) <http://a/> http://1.2/v:~-123. c")). -        toEqual('<a href="http://ab/">http://ab/</a> ' + -                '(<a href="http://a/">http://a/</a>) ' + -                '<<a href="http://a/">http://a/</a>> ' + -                '<a href="http://1.2/v:~-123">http://1.2/v:~-123</a>. c'); -      expect(linky(undefined)).not.toBeDefined(); -    }); - -    it('should handle mailto:', function() { -      expect(linky("mailto:me@example.com")). -                      toEqual('<a href="mailto:me@example.com">me@example.com</a>'); -      expect(linky("me@example.com")). -                      toEqual('<a href="mailto:me@example.com">me@example.com</a>'); -      expect(linky("send email to me@example.com, but")). -        toEqual('send email to <a href="mailto:me@example.com">me@example.com</a>, but'); -    }); -  }); -    describe('date', function() {      var morning  = new angular.mock.TzDate(+5, '2010-09-03T12:05:08.000Z'); //7am diff --git a/test/ngSanitize/directive/ngBindHtmlSpec.js b/test/ngSanitize/directive/ngBindHtmlSpec.js new file mode 100644 index 00000000..be23e5a5 --- /dev/null +++ b/test/ngSanitize/directive/ngBindHtmlSpec.js @@ -0,0 +1,25 @@ +describe('ngBindHtml', function() { +  beforeEach(module('ngSanitize')); + +  it('should set html', inject(function($rootScope, $compile) { +    element = $compile('<div ng-bind-html="html"></div>')($rootScope); +    $rootScope.html = '<div unknown>hello</div>'; +    $rootScope.$digest(); +    expect(angular.lowercase(element.html())).toEqual('<div>hello</div>'); +  })); + + +  it('should reset html when value is null or undefined', inject(function($compile, $rootScope) { +    element = $compile('<div ng-bind-html="html"></div>')($rootScope); + +    angular.forEach([null, undefined, ''], function(val) { +      $rootScope.html = 'some val'; +      $rootScope.$digest(); +      expect(angular.lowercase(element.html())).toEqual('some val'); + +      $rootScope.html = val; +      $rootScope.$digest(); +      expect(angular.lowercase(element.html())).toEqual(''); +    }); +  })); +}); diff --git a/test/ngSanitize/filter/linkySpec.js b/test/ngSanitize/filter/linkySpec.js new file mode 100644 index 00000000..0448159a --- /dev/null +++ b/test/ngSanitize/filter/linkySpec.js @@ -0,0 +1,27 @@ +describe('linky', function() { +  var linky; + +  beforeEach(module('ngSanitize')); + +  beforeEach(inject(function($filter){ +    linky = $filter('linky'); +  })); + +  it('should do basic filter', function() { +    expect(linky("http://ab/ (http://a/) <http://a/> http://1.2/v:~-123. c")). +      toEqual('<a href="http://ab/">http://ab/</a> ' + +              '(<a href="http://a/">http://a/</a>) ' + +              '<<a href="http://a/">http://a/</a>> ' + +              '<a href="http://1.2/v:~-123">http://1.2/v:~-123</a>. c'); +    expect(linky(undefined)).not.toBeDefined(); +  }); + +  it('should handle mailto:', function() { +    expect(linky("mailto:me@example.com")). +                    toEqual('<a href="mailto:me@example.com">me@example.com</a>'); +    expect(linky("me@example.com")). +                    toEqual('<a href="mailto:me@example.com">me@example.com</a>'); +    expect(linky("send email to me@example.com, but")). +      toEqual('send email to <a href="mailto:me@example.com">me@example.com</a>, but'); +  }); +}); diff --git a/test/ng/sanitizeSpec.js b/test/ngSanitize/sanitizeSpec.js index a33d8992..b4fd8a2a 100644 --- a/test/ng/sanitizeSpec.js +++ b/test/ngSanitize/sanitizeSpec.js @@ -4,6 +4,8 @@ describe('HTML', function() {    var expectHTML; +  beforeEach(module('ngSanitize')); +    beforeEach(inject(function($sanitize) {      expectHTML = function(html){        return expect($sanitize(html)); @@ -11,6 +13,8 @@ describe('HTML', function() {    }));    describe('htmlParser', function() { +    if (angular.isUndefined(window.htmlParser)) return; +      var handler, start, text;      beforeEach(function() {        handler = { @@ -22,8 +26,8 @@ describe('HTML', function() {              };              // Since different browsers handle newlines differenttly we trim              // so that it is easier to write tests. -            forEach(attrs, function(value, key){ -              attrs[key] = trim(value); +            angular.forEach(attrs, function(value, key) { +              attrs[key] = value.replace(/^\s*/, '').replace(/\s*$/, '')              });            },            chars: function(text_){ @@ -64,9 +68,9 @@ describe('HTML', function() {        expect(start).toEqual({tag:'option', attrs:{selected:'', value:''}, unary:false});        expect(text).toEqual('abc');      }); -    }); +  // THESE TESTS ARE EXECUTED WITH COMPILED ANGULAR    it('should echo html', function() {      expectHTML('hello<b class="1\'23" align=\'""\'>world</b>.').         toEqual('hello<b class="1\'23" align="""">world</b>.'); @@ -141,6 +145,8 @@ describe('HTML', function() {    });    describe('htmlSanitizerWriter', function() { +    if (angular.isUndefined(window.htmlSanitizeWriter)) return; +      var writer, html;      beforeEach(function() {        html = ''; @@ -277,5 +283,4 @@ describe('HTML', function() {      });    }); -  }); diff --git a/test/ngScenario/dslSpec.js b/test/ngScenario/dslSpec.js index 0a8ab762..fee5c3b5 100644 --- a/test/ngScenario/dslSpec.js +++ b/test/ngScenario/dslSpec.js @@ -9,6 +9,8 @@ describe("angular.scenario.dsl", function() {      dealoc(element);    }); +  beforeEach(module('ngSanitize')); +    beforeEach(inject(function($injector) {      eventLog = [];      $window = { | 
