diff options
| author | Vojta Jina | 2012-04-10 16:50:31 -0700 |
|---|---|---|
| committer | Vojta Jina | 2012-04-11 15:50:47 -0700 |
| commit | 5bcd7198664dca2bf85ddf8b3a89f417cd4e4796 (patch) | |
| tree | 3c9bde1e97e94a4af986019dbaea1eaa50a209d9 /src | |
| parent | e1743cc837a51e3146f2e73e3083eee7f4a8f549 (diff) | |
| download | angular.js-5bcd7198664dca2bf85ddf8b3a89f417cd4e4796.tar.bz2 | |
chore(ngSanitize): extract $sanitize, ngBindHtml, linkyFilter into a module
Create build for other modules as well (ngResource, ngCookies):
- wrap into a function
- add license
- add version
Breaks `$sanitize` service, `ngBindHtml` directive and `linky` filter were moved to the `ngSanitize` module. Apps that depend on any of these will need to load `angular-sanitize.js` and include `ngSanitize` in their dependency list: `var myApp = angular.module('myApp', ['ngSanitize']);`
Diffstat (limited to 'src')
| -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 |
9 files changed, 200 insertions, 179 deletions
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); |
