PageSourceSearch

https://paulafreitas.pr.gov.br/bower_components/angular-sanitize/angular-sanitize.js

js paulafreitas.pr.gov.br collected 2026-10-02 21:21:03 UTC 20,772 bytes, 624 lines download raw bytes

1/**
2 * @license AngularJS v1.2.16
3 * (c) 2010-2014 Google, Inc. http://angularjs.org
4 * License: MIT
5 */
6(function(window, angular, undefined) {'use strict';
7
8var $sanitizeMinErr = angular.$$minErr('$sanitize');
9
10/**
11 * @ngdoc module
12 * @name ngSanitize
13 * @description
14 *
15 * # ngSanitize
16 *
17 * The `ngSanitize` module provides functionality to sanitize HTML.
18 *
19 *
20 * <div doc-module-components="ngSanitize"></div>
21 *
22 * See {@link ngSanitize.$sanitize `$sanitize`} for usage.
23 */
24
25/*
26 * HTML Parser By Misko Hevery ([email protected])
27 * based on:  HTML Parser By John Resig (ejohn.org)
28 * Original code by Erik Arvidsson, Mozilla Public License
29 * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
30 *
31 * // Use like so:
32 * htmlParser(htmlString, {
33 *     start: function(tag, attrs, unary) {},
34 *     end: function(tag) {},
35 *     chars: function(text) {},
36 *     comment: function(text) {}
37 * });
38 *
39 */
40
41
42/**
43 * @ngdoc service
44 * @name $sanitize
45 * @function
46 *
47 * @description
48 *   The input is sanitized by parsing the html into tokens. All safe tokens (from a whitelist) are
49 *   then serialized back to properly escaped html string. This means that no unsafe input can make
50 *   it into the returned string, however, since our parser is more strict than a typical browser
51 *   parser, it's possible that some obscure input, which would be recognized as valid HTML by a
52 *   browser, won't make it through the sanitizer.
53 *   The whitelist is configured using the functions `aHrefSanitizationWhitelist` and
54 *   `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider `$compileProvider`}.
55 *
56 * @param {string} html Html input.
57 * @returns {string} Sanitized html.
58 *
59 * @example
60   <example module="ngSanitize" deps="angular-sanitize.js">
61   <file name="index.html">
62     <script>
63       function Ctrl($scope, $sce) {
64         $scope.snippet =
65           '<p style="color:blue">an html\n' +
66           '<em onmouseover="this.textContent=\'PWN3D!\'">click here</em>\n' +
67           'snippet</p>';
68         $scope.deliberatelyTrustDangerousSnippet = function() {
69           return $sce.trustAsHtml($scope.snippet);
70         };
71       }
72     </script>
73     <div ng-controller="Ctrl">
74        Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
75       <table>
76         <tr>
77           <td>Directive</td>
78           <td>How</td>
79           <td>Source</td>
80           <td>Rendered</td>
81         </tr>
82         <tr id="bind-html-with-sanitize">
83           <td>ng-bind-html</td>
84           <td>Automatically uses $sanitize</td>
85           <td><pre>&lt;div ng-bind-html="snippet"&gt;<br/>&lt;/div&gt;</pre></td>
86           <td><div ng-bind-html="snippet"></div></td>
87         </tr>
88         <tr id="bind-html-with-trust">
89           <td>ng-bind-html</td>
90           <td>Bypass $sanitize by explicitly trusting the dangerous value</td>
91           <td>
92           <pre>&lt;div ng-bind-html="deliberatelyTrustDangerousSnippet()"&gt;
93&lt;/div&gt;</pre>
94           </td>
95           <td><div ng-bind-html="deliberatelyTrustDangerousSnippet()"></div></td>
96         </tr>
97         <tr id="bind-default">
98           <td>ng-bind</td>
99           <td>Automatically escapes</td>
100           <td><pre>&lt;div ng-bind="snippet"&gt;<br/>&lt;/div&gt;</pre></td>
101           <td><div ng-bind="snippet"></div></td>
102         </tr>
103       </table>
104       </div>
105   </file>
106   <file name="protractor.js" type="protractor">
107     it('should sanitize the html snippet by default', function() {
108       expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
109         toBe('<p>an html\n<em>click here</em>\nsnippet</p>');
110     });
111
112     it('should inline raw snippet if bound to a trusted value', function() {
113       expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).
114         toBe("<p style=\"color:blue\">an html\n" +
115              "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
116              "snippet</p>");
117     });
118
119     it('should escape snippet without any filter', function() {
120       expect(element(by.css('#bind-default div')).getInnerHtml()).
121         toBe("&lt;p style=\"color:blue\"&gt;an html\n" +
122              "&lt;em onmouseover=\"this.textContent='PWN3D!'\"&gt;click here&lt;/em&gt;\n" +
123              "snippet&lt;/p&gt;");
124     });
125
126     it('should update', function() {
127       element(by.model('snippet')).clear();
128       element(by.model('snippet')).sendKeys('new <b onclick="alert(1)">text</b>');
129       expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
130         toBe('new <b>text</b>');
131       expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).toBe(
132         'new <b onclick="alert(1)">text</b>');
133       expect(element(by.css('#bind-default div')).getInnerHtml()).toBe(
134         "new &lt;b onclick=\"alert(1)\"&gt;text&lt;/b&gt;");
135     });
136   </file>
137   </example>
138 */
139function $SanitizeProvider() {
140  this.$get = ['$$sanitizeUri', function($$sanitizeUri) {
141    return function(html) {
142      var buf = [];
143      htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) {
144        return !/^unsafe/.test($$sanitizeUri(uri, isImage));
145      }));
146      return buf.join('');
147    };
148  }];
149}
150
151function sanitizeText(chars) {
152  var buf = [];
153  var writer = htmlSanitizeWriter(buf, angular.noop);
154  writer.chars(chars);
155  return buf.join('');
156}
157
158
159// Regular Expressions for parsing tags and attributes
160var START_TAG_REGEXP =
161       /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,
162  END_TAG_REGEXP = /^<\s*\/\s*([\w:-]+)[^>]*>/,
163  ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,
164  BEGIN_TAG_REGEXP = /^</,
165  BEGING_END_TAGE_REGEXP = /^<\s*\//,
166  COMMENT_REGEXP = /<!--(.*?)-->/g,
167  DOCTYPE_REGEXP = /<!DOCTYPE([^>]*?)>/i,
168  CDATA_REGEXP = /<!\[CDATA\[(.*?)]]>/g,
169  // Match everything outside of normal chars and " (quote character)
170  NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;
171
172
173// Good source of info about elements and attributes
174// http://dev.w3.org/html5/spec/Overview.html#semantics
175// http://simon.html5.org/html-elements
176
177// Safe Void Elements - HTML5
178// http://dev.w3.org/html5/spec/Overview.html#void-elements
179var voidElements = makeMap("area,br,col,hr,img,wbr");
180
181// Elements that you can, intentionally, leave open (and which close themselves)
182// http://dev.w3.org/html5/spec/Overview.html#optional-tags
183var optionalEndTagBlockElements = makeMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),
184    optionalEndTagInlineElements = makeMap("rp,rt"),
185    optionalEndTagElements = angular.extend({},
186                                            optionalEndTagInlineElements,
187                                            optionalEndTagBlockElements);
188
189// Safe Block Elements - HTML5
190var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article," +
191        "aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," +
192        "h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul"));
193
194// Inline Elements - HTML5
195var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b," +
196        "bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," +
197        "samp,small,span,strike,strong,sub,sup,time,tt,u,var"));
198
199
200// Special Elements (can contain anything)
201var specialElements = makeMap("script,style");
202
203var validElements = angular.extend({},
204                                   voidElements,
205                                   blockElements,
206                                   inlineElements,
207                                   optionalEndTagElements);
208
209//Attributes that have href and hence need to be sanitized
210var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap");
211var validAttrs = angular.extend({}, uriAttrs, makeMap(
212    'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+
213    'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+
214    'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+
215    'scope,scrolling,shape,size,span,start,summary,target,title,type,'+
216    'valign,value,vspace,width'));
217
218function makeMap(str) {
219  var obj = {}, items = str.split(','), i;
220  for (i = 0; i < items.length; i++) obj[items[i]] = true;
221  return obj;
222}
223
224
225/**
226 * @example
227 * htmlParser(htmlString, {
228 *     start: function(tag, attrs, unary) {},
229 *     end: function(tag) {},
230 *     chars: function(text) {},
231 *     comment: function(text) {}
232 * });
233 *
234 * @param {string} html string
235 * @param {object} handler
236 */
237function htmlParser( html, handler ) {
238  var index, chars, match, stack = [], last = html;
239  stack.last = function() { return stack[ stack.length - 1 ]; };
240
241  while ( html ) {
242    chars = true;
243
244    // Make sure we're not in a script or style element
245    if ( !stack.last() || !specialElements[ stack.last() ] ) {
246
247      // Comment
248      if ( html.indexOf("<!--") === 0 ) {
249        // comments containing -- are not allowed unless they terminate the comment
250        index = html.indexOf("--", 4);
251
252        if ( index >= 0 && html.lastIndexOf("-->", index) === index) {
253          if (handler.comment) handler.comment( html.substring( 4, index ) );
254          html = html.substring( index + 3 );
255          chars = false;
vendor: 9,258 bytes, lines 256-556
256        }
257      // DOCTYPE
258      } else if ( DOCTYPE_REGEXP.test(html) ) {
259        match = html.match( DOCTYPE_REGEXP );
260
261        if ( match ) {
262          html = html.replace( match[0], '');
263          chars = false;
264        }
265      // end tag
266      } else if ( BEGING_END_TAGE_REGEXP.test(html) ) {
267        match = html.match( END_TAG_REGEXP );
268
269        if ( match ) {
270          html = html.substring( match[0].length );
271          match[0].replace( END_TAG_REGEXP, parseEndTag );
272          chars = false;
273        }
274
275      // start tag
276      } else if ( BEGIN_TAG_REGEXP.test(html) ) {
277        match = html.match( START_TAG_REGEXP );
278
279        if ( match ) {
280          html = html.substring( match[0].length );
281          match[0].replace( START_TAG_REGEXP, parseStartTag );
282          chars = false;
283        }
284      }
285
286      if ( chars ) {
287        index = html.indexOf("<");
288
289        var text = index < 0 ? html : html.substring( 0, index );
290        html = index < 0 ? "" : html.substring( index );
291
292        if (handler.chars) handler.chars( decodeEntities(text) );
293      }
294
295    } else {
296      html = html.replace(new RegExp("(.*)<\\s*\\/\\s*" + stack.last() + "[^>]*>", 'i'),
297        function(all, text){
298          text = text.replace(COMMENT_REGEXP, "$1").replace(CDATA_REGEXP, "$1");
299
300          if (handler.chars) handler.chars( decodeEntities(text) );
301
302          return "";
303      });
304
305      parseEndTag( "", stack.last() );
306    }
307
308    if ( html == last ) {
309      throw $sanitizeMinErr('badparse', "The sanitizer was unable to parse the following block " +
310                                        "of html: {0}", html);
311    }
312    last = html;
313  }
314
315  // Clean up any remaining tags
316  parseEndTag();
317
318  function parseStartTag( tag, tagName, rest, unary ) {
319    tagName = angular.lowercase(tagName);
320    if ( blockElements[ tagName ] ) {
321      while ( stack.last() && inlineElements[ stack.last() ] ) {
322        parseEndTag( "", stack.last() );
323      }
324    }
325
326    if ( optionalEndTagElements[ tagName ] && stack.last() == tagName ) {
327      parseEndTag( "", tagName );
328    }
329
330    unary = voidElements[ tagName ] || !!unary;
331
332    if ( !unary )
333      stack.push( tagName );
334
335    var attrs = {};
336
337    rest.replace(ATTR_REGEXP,
338      function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) {
339        var value = doubleQuotedValue
340          || singleQuotedValue
341          || unquotedValue
342          || '';
343
344        attrs[name] = decodeEntities(value);
345    });
346    if (handler.start) handler.start( tagName, attrs, unary );
347  }
348
349  function parseEndTag( tag, tagName ) {
350    var pos = 0, i;
351    tagName = angular.lowercase(tagName);
352    if ( tagName )
353      // Find the closest opened tag of the same type
354      for ( pos = stack.length - 1; pos >= 0; pos-- )
355        if ( stack[ pos ] == tagName )
356          break;
357
358    if ( pos >= 0 ) {
359      // Close all the open elements, up the stack
360      for ( i = stack.length - 1; i >= pos; i-- )
361        if (handler.end) handler.end( stack[ i ] );
362
363      // Remove the open elements from the stack
364      stack.length = pos;
365    }
366  }
367}
368
369var hiddenPre=document.createElement("pre");
370var spaceRe = /^(\s*)([\s\S]*?)(\s*)$/;
371/**
372 * decodes all entities into regular string
373 * @param value
374 * @returns {string} A string with decoded entities.
375 */
376function decodeEntities(value) {
377  if (!value) { return ''; }
378
379  // Note: IE8 does not preserve spaces at the start/end of innerHTML
380  // so we must capture them and reattach them afterward
381  var parts = spaceRe.exec(value);
382  var spaceBefore = parts[1];
383  var spaceAfter = parts[3];
384  var content = parts[2];
385  if (content) {
386    hiddenPre.innerHTML=content.replace(/</g,"&lt;");
387    // innerText depends on styling as it doesn't display hidden elements.
388    // Therefore, it's better to use textContent not to cause unnecessary
389    // reflows. However, IE<9 don't support textContent so the innerText
390    // fallback is necessary.
391    content = 'textContent' in hiddenPre ?
392      hiddenPre.textContent : hiddenPre.innerText;
393  }
394  return spaceBefore + content + spaceAfter;
395}
396
397/**
398 * Escapes all potentially dangerous characters, so that the
399 * resulting string can be safely inserted into attribute or
400 * element text.
401 * @param value
402 * @returns {string} escaped text
403 */
404function encodeEntities(value) {
405  return value.
406    replace(/&/g, '&amp;').
407    replace(NON_ALPHANUMERIC_REGEXP, function(value){
408      return '&#' + value.charCodeAt(0) + ';';
409    }).
410    replace(/</g, '&lt;').
411    replace(/>/g, '&gt;');
412}
413
414/**
415 * create an HTML/XML writer which writes to buffer
416 * @param {Array} buf use buf.jain('') to get out sanitized html string
417 * @returns {object} in the form of {
418 *     start: function(tag, attrs, unary) {},
419 *     end: function(tag) {},
420 *     chars: function(text) {},
421 *     comment: function(text) {}
422 * }
423 */
424function htmlSanitizeWriter(buf, uriValidator){
425  var ignore = false;
426  var out = angular.bind(buf, buf.push);
427  return {
428    start: function(tag, attrs, unary){
429      tag = angular.lowercase(tag);
430      if (!ignore && specialElements[tag]) {
431        ignore = tag;
432      }
433      if (!ignore && validElements[tag] === true) {
434        out('<');
435        out(tag);
436        angular.forEach(attrs, function(value, key){
437          var lkey=angular.lowercase(key);
438          var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background');
439          if (validAttrs[lkey] === true &&
440            (uriAttrs[lkey] !== true || uriValidator(value, isImage))) {
441            out(' ');
442            out(key);
443            out('="');
444            out(encodeEntities(value));
445            out('"');
446          }
447        });
448        out(unary ? '/>' : '>');
449      }
450    },
451    end: function(tag){
452        tag = angular.lowercase(tag);
453        if (!ignore && validElements[tag] === true) {
454          out('</');
455          out(tag);
456          out('>');
457        }
458        if (tag == ignore) {
459          ignore = false;
460        }
461      },
462    chars: function(chars){
463        if (!ignore) {
464          out(encodeEntities(chars));
465        }
466      }
467  };
468}
469
470
471// define ngSanitize module and register $sanitize service
472angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider);
473
474/* global sanitizeText: false */
475
476/**
477 * @ngdoc filter
478 * @name linky
479 * @function
480 *
481 * @description
482 * Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and
483 * plain email address links.
484 *
485 * Requires the {@link ngSanitize `ngSanitize`} module to be installed.
486 *
487 * @param {string} text Input text.
488 * @param {string} target Window (_blank|_self|_parent|_top) or named frame to open links in.
489 * @returns {string} Html-linkified text.
490 *
491 * @usage
492   <span ng-bind-html="linky_expression | linky"></span>
493 *
494 * @example
495   <example module="ngSanitize" deps="angular-sanitize.js">
496     <file name="index.html">
497       <script>
498         function Ctrl($scope) {
499           $scope.snippet =
500             'Pretty text with some links:\n'+
501             'http://angularjs.org/,\n'+
502             'mailto:[email protected],\n'+
503             '[email protected],\n'+
504             'and one more: ftp://127.0.0.1/.';
505           $scope.snippetWithTarget = 'http://angularjs.org/';
506         }
507       </script>
508       <div ng-controller="Ctrl">
509       Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
510       <table>
511         <tr>
512           <td>Filter</td>
513           <td>Source</td>
514           <td>Rendered</td>
515         </tr>
516         <tr id="linky-filter">
517           <td>linky filter</td>
518           <td>
519             <pre>&lt;div ng-bind-html="snippet | linky"&gt;<br>&lt;/div&gt;</pre>
520           </td>
521           <td>
522             <div ng-bind-html="snippet | linky"></div>
523           </td>
524         </tr>
525         <tr id="linky-target">
526          <td>linky target</td>
527          <td>
528            <pre>&lt;div ng-bind-html="snippetWithTarget | linky:'_blank'"&gt;<br>&lt;/div&gt;</pre>
529          </td>
530          <td>
531            <div ng-bind-html="snippetWithTarget | linky:'_blank'"></div>
532          </td>
533         </tr>
534         <tr id="escaped-html">
535           <td>no filter</td>
536           <td><pre>&lt;div ng-bind="snippet"&gt;<br>&lt;/div&gt;</pre></td>
537           <td><div ng-bind="snippet"></div></td>
538         </tr>
539       </table>
540     </file>
541     <file name="protractor.js" type="protractor">
542       it('should linkify the snippet with urls', function() {
543         expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
544             toBe('Pretty text with some links: http://angularjs.org/, [email protected], ' +
545                  '[email protected], and one more: ftp://127.0.0.1/.');
546         expect(element.all(by.css('#linky-filter a')).count()).toEqual(4);
547       });
548
549       it('should not linkify snippet without the linky filter', function() {
550         expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()).
551             toBe('Pretty text with some links: http://angularjs.org/, mailto:[email protected], ' +
552                  '[email protected], and one more: ftp://127.0.0.1/.');
553         expect(element.all(by.css('#escaped-html a')).count()).toEqual(0);
554       });
555
556       it('should update', function() {
557         element(by.model('snippet')).clear();
558         element(by.model('snippet')).sendKeys('new http://link.');
559         expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
560             toBe('new http://link.');
561         expect(element.all(by.css('#linky-filter a')).count()).toEqual(1);
562         expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText())
563             .toBe('new http://link.');
564       });
565
566       it('should work with the target property', function() {
567        expect(element(by.id('linky-target')).
568            element(by.binding("snippetWithTarget | linky:'_blank'")).getText()).
569            toBe('http://angularjs.org/');
570        expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank');
571       });
572     </file>
573   </example>
574 */
575angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
576  var LINKY_URL_REGEXP =
577        /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>]/,
578      MAILTO_REGEXP = /^mailto:/;
579
580  return function(text, target) {
581    if (!text) return text;
582    var match;
583    var raw = text;
584    var html = [];
585    var url;
586    var i;
587    while ((match = raw.match(LINKY_URL_REGEXP))) {
588      // We can not end in these as they are sometimes found at the end of the sentence
589      url = match[0];
590      // if we did not match ftp/http/mailto then assume mailto
591      if (match[2] == match[3]) url = 'mailto:' + url;
592      i = match.index;
593      addText(raw.substr(0, i));
594      addLink(url, match[0].replace(MAILTO_REGEXP, ''));
595      raw = raw.substring(i + match[0].length);
596    }
597    addText(raw);
598    return $sanitize(html.join(''));
599
600    function addText(text) {
601      if (!text) {
602        return;
603      }
604      html.push(sanitizeText(text));
605    }
606
607    function addLink(url, text) {
608      html.push('<a ');
609      if (angular.isDefined(target)) {
610        html.push('target="');
611        html.push(target);
612        html.push('" ');
613      }
614      html.push('href="');
615      html.push(url);
616      html.push('">');
617      addText(text);
618      html.push('</a>');
619    }
620  };
621}]);
622
623
624})(window, window.angular);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.