@angular-wave/angular.ts 0.0.31 → 0.0.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/angular-ts.esm.js +1 -1
  2. package/dist/angular-ts.umd.js +1 -1
  3. package/index.html +5 -14
  4. package/package.json +1 -1
  5. package/src/core/compile.js +5 -4
  6. package/src/core/location.js +1 -1
  7. package/src/core/parser/parse.js +1 -2
  8. package/src/core/root-scope.js +49 -99
  9. package/src/directive/events.js +2 -1
  10. package/src/directive/model.js +4 -2
  11. package/src/router/directives/state-directives.js +33 -18
  12. package/src/router/directives/view-directive.js +1 -2
  13. package/src/router/globals.js +2 -0
  14. package/src/router/index.js +23 -21
  15. package/src/router/services.js +6 -62
  16. package/src/router/state/state-queue-manager.js +2 -1
  17. package/src/router/state/state-registry.js +35 -18
  18. package/src/router/state/state-service.js +169 -1
  19. package/src/router/state/views.js +46 -2
  20. package/src/router/transition/reject-factory.js +0 -8
  21. package/src/router/transition/transition-service.js +43 -1
  22. package/src/router/url/url-config.js +7 -1
  23. package/src/router/url/url-rule.js +4 -4
  24. package/src/router/url/url-service.js +32 -15
  25. package/src/router/view/view.js +7 -51
  26. package/src/services/http.js +2 -1
  27. package/src/shared/strings.js +7 -2
  28. package/test/core/compile.spec.js +2 -2
  29. package/test/core/scope.spec.js +2 -37
  30. package/test/router/services.spec.js +7 -15
  31. package/test/router/state-directives.spec.js +2 -2
  32. package/test/router/state-filter.spec.js +0 -2
  33. package/test/router/state.spec.js +4 -4
  34. package/test/router/template-factory.spec.js +19 -10
  35. package/test/router/url-service.spec.js +4 -6
  36. package/test/router/view-directive.spec.js +9 -9
  37. package/test/router/view-hook.spec.js +10 -10
  38. package/legacy/angular-animate.js +0 -4272
  39. package/legacy/angular-aria.js +0 -426
  40. package/legacy/angular-message-format.js +0 -1072
  41. package/legacy/angular-messages.js +0 -829
  42. package/legacy/angular-route.js +0 -1266
  43. package/legacy/angular-sanitize.js +0 -891
  44. package/legacy/angular.js +0 -36600
  45. package/src/router/router.js +0 -103
  46. package/test/original-test.html +0 -33
@@ -1,891 +0,0 @@
1
- /**
2
- * @license AngularJS v1.8.4-local+sha.4e1bd4b90
3
- * (c) 2010-2020 Google LLC. http://angularjs.org
4
- * License: MIT
5
- */
6
- (function(window, angular) {'use strict';
7
-
8
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
9
- * Any commits to this file should be reviewed with security in mind. *
10
- * Changes to this file can potentially create security vulnerabilities. *
11
- * An approval from 2 Core members with history of modifying *
12
- * this file is required. *
13
- * *
14
- * Does the change somehow allow for arbitrary javascript to be executed? *
15
- * Or allows for someone to change the prototype of built-in objects? *
16
- * Or gives undesired access to variables likes document or window? *
17
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
18
-
19
- var $sanitizeMinErr = angular.$$minErr('$sanitize');
20
- var bind;
21
- var extend;
22
- var forEach;
23
- var isArray;
24
- var isDefined;
25
- var lowercase;
26
- var noop;
27
- var nodeContains;
28
- var htmlParser;
29
- var htmlSanitizeWriter;
30
-
31
- /**
32
- * @ngdoc module
33
- * @name ngSanitize
34
- * @description
35
- *
36
- * The `ngSanitize` module provides functionality to sanitize HTML.
37
- *
38
- * See {@link ngSanitize.$sanitize `$sanitize`} for usage.
39
- */
40
-
41
- /**
42
- * @ngdoc service
43
- * @name $sanitize
44
- * @kind function
45
- *
46
- * @description
47
- * Sanitizes an html string by stripping all potentially dangerous tokens.
48
- *
49
- * The input is sanitized by parsing the HTML into tokens. All safe tokens (from a trusted URI list) are
50
- * then serialized back to a properly escaped HTML string. This means that no unsafe input can make
51
- * it into the returned string.
52
- *
53
- * The trusted URIs for URL sanitization of attribute values is configured using the functions
54
- * `aHrefSanitizationTrustedUrlList` and `imgSrcSanitizationTrustedUrlList` of {@link $compileProvider}.
55
- *
56
- * The input may also contain SVG markup if this is enabled via {@link $sanitizeProvider}.
57
- *
58
- * @param {string} html HTML input.
59
- * @returns {string} Sanitized HTML.
60
- *
61
- * @example
62
- <example module="sanitizeExample" deps="angular-sanitize.js" name="sanitize-service">
63
- <file name="index.html">
64
- <script>
65
- angular.module('sanitizeExample', ['ngSanitize'])
66
- .controller('ExampleController', ['$scope', '$sce', function($scope, $sce) {
67
- $scope.snippet =
68
- '<p style="color:blue">an html\n' +
69
- '<em onmouseover="this.textContent=\'PWN3D!\'">click here</em>\n' +
70
- 'snippet</p>';
71
- $scope.deliberatelyTrustDangerousSnippet = function() {
72
- return $sce.trustAsHtml($scope.snippet);
73
- };
74
- }]);
75
- </script>
76
- <div ng-controller="ExampleController">
77
- Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
78
- <table>
79
- <tr>
80
- <td>Directive</td>
81
- <td>How</td>
82
- <td>Source</td>
83
- <td>Rendered</td>
84
- </tr>
85
- <tr id="bind-html-with-sanitize">
86
- <td>ng-bind-html</td>
87
- <td>Automatically uses $sanitize</td>
88
- <td><pre>&lt;div ng-bind-html="snippet"&gt;<br/>&lt;/div&gt;</pre></td>
89
- <td><div ng-bind-html="snippet"></div></td>
90
- </tr>
91
- <tr id="bind-html-with-trust">
92
- <td>ng-bind-html</td>
93
- <td>Bypass $sanitize by explicitly trusting the dangerous value</td>
94
- <td>
95
- <pre>&lt;div ng-bind-html="deliberatelyTrustDangerousSnippet()"&gt;
96
- &lt;/div&gt;</pre>
97
- </td>
98
- <td><div ng-bind-html="deliberatelyTrustDangerousSnippet()"></div></td>
99
- </tr>
100
- <tr id="bind-default">
101
- <td>ng-bind</td>
102
- <td>Automatically escapes</td>
103
- <td><pre>&lt;div ng-bind="snippet"&gt;<br/>&lt;/div&gt;</pre></td>
104
- <td><div ng-bind="snippet"></div></td>
105
- </tr>
106
- </table>
107
- </div>
108
- </file>
109
- <file name="protractor.js" type="protractor">
110
- it('should sanitize the html snippet by default', function() {
111
- expect(element(by.css('#bind-html-with-sanitize div')).getAttribute('innerHTML')).
112
- toBe('<p>an html\n<em>click here</em>\nsnippet</p>');
113
- });
114
-
115
- it('should inline raw snippet if bound to a trusted value', function() {
116
- expect(element(by.css('#bind-html-with-trust div')).getAttribute('innerHTML')).
117
- toBe("<p style=\"color:blue\">an html\n" +
118
- "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
119
- "snippet</p>");
120
- });
121
-
122
- it('should escape snippet without any filter', function() {
123
- expect(element(by.css('#bind-default div')).getAttribute('innerHTML')).
124
- toBe("&lt;p style=\"color:blue\"&gt;an html\n" +
125
- "&lt;em onmouseover=\"this.textContent='PWN3D!'\"&gt;click here&lt;/em&gt;\n" +
126
- "snippet&lt;/p&gt;");
127
- });
128
-
129
- it('should update', function() {
130
- element(by.model('snippet')).clear();
131
- element(by.model('snippet')).sendKeys('new <b onclick="alert(1)">text</b>');
132
- expect(element(by.css('#bind-html-with-sanitize div')).getAttribute('innerHTML')).
133
- toBe('new <b>text</b>');
134
- expect(element(by.css('#bind-html-with-trust div')).getAttribute('innerHTML')).toBe(
135
- 'new <b onclick="alert(1)">text</b>');
136
- expect(element(by.css('#bind-default div')).getAttribute('innerHTML')).toBe(
137
- "new &lt;b onclick=\"alert(1)\"&gt;text&lt;/b&gt;");
138
- });
139
- </file>
140
- </example>
141
- */
142
-
143
-
144
- /**
145
- * @ngdoc provider
146
- * @name $sanitizeProvider
147
- * @this
148
- *
149
- * @description
150
- * Creates and configures {@link $sanitize} instance.
151
- */
152
- function $SanitizeProvider() {
153
- var hasBeenInstantiated = false;
154
- var svgEnabled = false;
155
-
156
- this.$get = ['$$sanitizeUri', function($$sanitizeUri) {
157
- hasBeenInstantiated = true;
158
- if (svgEnabled) {
159
- extend(validElements, svgElements);
160
- }
161
- return function(html) {
162
- var buf = [];
163
- htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) {
164
- return !/^unsafe:/.test($$sanitizeUri(uri, isImage));
165
- }));
166
- return buf.join('');
167
- };
168
- }];
169
-
170
-
171
- /**
172
- * @ngdoc method
173
- * @name $sanitizeProvider#enableSvg
174
- * @kind function
175
- *
176
- * @description
177
- * Enables a subset of svg to be supported by the sanitizer.
178
- *
179
- * <div class="alert alert-warning">
180
- * <p>By enabling this setting without taking other precautions, you might expose your
181
- * application to click-hijacking attacks. In these attacks, sanitized svg elements could be positioned
182
- * outside of the containing element and be rendered over other elements on the page (e.g. a login
183
- * link). Such behavior can then result in phishing incidents.</p>
184
- *
185
- * <p>To protect against these, explicitly setup `overflow: hidden` css rule for all potential svg
186
- * tags within the sanitized content:</p>
187
- *
188
- * <br>
189
- *
190
- * <pre><code>
191
- * .rootOfTheIncludedContent svg {
192
- * overflow: hidden !important;
193
- * }
194
- * </code></pre>
195
- * </div>
196
- *
197
- * @param {boolean=} flag Enable or disable SVG support in the sanitizer.
198
- * @returns {boolean|$sanitizeProvider} Returns the currently configured value if called
199
- * without an argument or self for chaining otherwise.
200
- */
201
- this.enableSvg = function(enableSvg) {
202
- if (isDefined(enableSvg)) {
203
- svgEnabled = enableSvg;
204
- return this;
205
- } else {
206
- return svgEnabled;
207
- }
208
- };
209
-
210
-
211
- /**
212
- * @ngdoc method
213
- * @name $sanitizeProvider#addValidElements
214
- * @kind function
215
- *
216
- * @description
217
- * Extends the built-in lists of valid HTML/SVG elements, i.e. elements that are considered safe
218
- * and are not stripped off during sanitization. You can extend the following lists of elements:
219
- *
220
- * - `htmlElements`: A list of elements (tag names) to extend the current list of safe HTML
221
- * elements. HTML elements considered safe will not be removed during sanitization. All other
222
- * elements will be stripped off.
223
- *
224
- * - `htmlVoidElements`: This is similar to `htmlElements`, but marks the elements as
225
- * "void elements" (similar to HTML
226
- * [void elements](https://rawgit.com/w3c/html/html5.1-2/single-page.html#void-elements)). These
227
- * elements have no end tag and cannot have content.
228
- *
229
- * - `svgElements`: This is similar to `htmlElements`, but for SVG elements. This list is only
230
- * taken into account if SVG is {@link ngSanitize.$sanitizeProvider#enableSvg enabled} for
231
- * `$sanitize`.
232
- *
233
- * <div class="alert alert-info">
234
- * This method must be called during the {@link angular.Module#config config} phase. Once the
235
- * `$sanitize` service has been instantiated, this method has no effect.
236
- * </div>
237
- *
238
- * <div class="alert alert-warning">
239
- * Keep in mind that extending the built-in lists of elements may expose your app to XSS or
240
- * other vulnerabilities. Be very mindful of the elements you add.
241
- * </div>
242
- *
243
- * @param {Array<String>|Object} elements - A list of valid HTML elements or an object with one or
244
- * more of the following properties:
245
- * - **htmlElements** - `{Array<String>}` - A list of elements to extend the current list of
246
- * HTML elements.
247
- * - **htmlVoidElements** - `{Array<String>}` - A list of elements to extend the current list of
248
- * void HTML elements; i.e. elements that do not have an end tag.
249
- * - **svgElements** - `{Array<String>}` - A list of elements to extend the current list of SVG
250
- * elements. The list of SVG elements is only taken into account if SVG is
251
- * {@link ngSanitize.$sanitizeProvider#enableSvg enabled} for `$sanitize`.
252
- *
253
- * Passing an array (`[...]`) is equivalent to passing `{htmlElements: [...]}`.
254
- *
255
- * @return {$sanitizeProvider} Returns self for chaining.
256
- */
257
- this.addValidElements = function(elements) {
258
- if (!hasBeenInstantiated) {
259
- if (isArray(elements)) {
260
- elements = {htmlElements: elements};
261
- }
262
-
263
- addElementsTo(svgElements, elements.svgElements);
264
- addElementsTo(voidElements, elements.htmlVoidElements);
265
- addElementsTo(validElements, elements.htmlVoidElements);
266
- addElementsTo(validElements, elements.htmlElements);
267
- }
268
-
269
- return this;
270
- };
271
-
272
-
273
- /**
274
- * @ngdoc method
275
- * @name $sanitizeProvider#addValidAttrs
276
- * @kind function
277
- *
278
- * @description
279
- * Extends the built-in list of valid attributes, i.e. attributes that are considered safe and are
280
- * not stripped off during sanitization.
281
- *
282
- * **Note**:
283
- * The new attributes will not be treated as URI attributes, which means their values will not be
284
- * sanitized as URIs using `$compileProvider`'s
285
- * {@link ng.$compileProvider#aHrefSanitizationTrustedUrlList aHrefSanitizationTrustedUrlList} and
286
- * {@link ng.$compileProvider#imgSrcSanitizationTrustedUrlList imgSrcSanitizationTrustedUrlList}.
287
- *
288
- * <div class="alert alert-info">
289
- * This method must be called during the {@link angular.Module#config config} phase. Once the
290
- * `$sanitize` service has been instantiated, this method has no effect.
291
- * </div>
292
- *
293
- * <div class="alert alert-warning">
294
- * Keep in mind that extending the built-in list of attributes may expose your app to XSS or
295
- * other vulnerabilities. Be very mindful of the attributes you add.
296
- * </div>
297
- *
298
- * @param {Array<String>} attrs - A list of valid attributes.
299
- *
300
- * @returns {$sanitizeProvider} Returns self for chaining.
301
- */
302
- this.addValidAttrs = function(attrs) {
303
- if (!hasBeenInstantiated) {
304
- extend(validAttrs, arrayToMap(attrs, true));
305
- }
306
- return this;
307
- };
308
-
309
- //////////////////////////////////////////////////////////////////////////////////////////////////
310
- // Private stuff
311
- //////////////////////////////////////////////////////////////////////////////////////////////////
312
-
313
- bind = angular.bind;
314
- extend = angular.extend;
315
- forEach = angular.forEach;
316
- isArray = angular.isArray;
317
- isDefined = angular.isDefined;
318
- lowercase = angular.$$lowercase;
319
- noop = angular.noop;
320
-
321
- htmlParser = htmlParserImpl;
322
- htmlSanitizeWriter = htmlSanitizeWriterImpl;
323
-
324
- nodeContains = window.Node.prototype.contains || /** @this */ function(arg) {
325
- // eslint-disable-next-line no-bitwise
326
- return !!(this.compareDocumentPosition(arg) & 16);
327
- };
328
-
329
- // Regular Expressions for parsing tags and attributes
330
- var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
331
- // Match everything outside of normal chars and " (quote character)
332
- NON_ALPHANUMERIC_REGEXP = /([^#-~ |!])/g;
333
-
334
-
335
- // Good source of info about elements and attributes
336
- // http://dev.w3.org/html5/spec/Overview.html#semantics
337
- // http://simon.html5.org/html-elements
338
-
339
- // Safe Void Elements - HTML5
340
- // http://dev.w3.org/html5/spec/Overview.html#void-elements
341
- var voidElements = stringToMap('area,br,col,hr,img,wbr');
342
-
343
- // Elements that you can, intentionally, leave open (and which close themselves)
344
- // http://dev.w3.org/html5/spec/Overview.html#optional-tags
345
- var optionalEndTagBlockElements = stringToMap('colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr'),
346
- optionalEndTagInlineElements = stringToMap('rp,rt'),
347
- optionalEndTagElements = extend({},
348
- optionalEndTagInlineElements,
349
- optionalEndTagBlockElements);
350
-
351
- // Safe Block Elements - HTML5
352
- var blockElements = extend({}, optionalEndTagBlockElements, stringToMap('address,article,' +
353
- 'aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,' +
354
- 'h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,section,table,ul'));
355
-
356
- // Inline Elements - HTML5
357
- var inlineElements = extend({}, optionalEndTagInlineElements, stringToMap('a,abbr,acronym,b,' +
358
- 'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,' +
359
- 'samp,small,span,strike,strong,sub,sup,time,tt,u,var'));
360
-
361
- // SVG Elements
362
- // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Elements
363
- // Note: the elements animate,animateColor,animateMotion,animateTransform,set are intentionally omitted.
364
- // They can potentially allow for arbitrary javascript to be executed. See #11290
365
- var svgElements = stringToMap('circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,' +
366
- 'hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,' +
367
- 'radialGradient,rect,stop,svg,switch,text,title,tspan');
368
-
369
- // Blocked Elements (will be stripped)
370
- var blockedElements = stringToMap('script,style');
371
-
372
- var validElements = extend({},
373
- voidElements,
374
- blockElements,
375
- inlineElements,
376
- optionalEndTagElements);
377
-
378
- //Attributes that have href and hence need to be sanitized
379
- var uriAttrs = stringToMap('background,cite,href,longdesc,src,xlink:href,xml:base');
380
-
381
- var htmlAttrs = stringToMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' +
382
- 'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,' +
383
- 'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,' +
384
- 'scope,scrolling,shape,size,span,start,summary,tabindex,target,title,type,' +
385
- 'valign,value,vspace,width');
386
-
387
- // SVG attributes (without "id" and "name" attributes)
388
- // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes
389
- var svgAttrs = stringToMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' +
390
- 'baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,' +
391
- 'cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,' +
392
- 'font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,' +
393
- 'height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,keySplines,keyTimes,lang,' +
394
- 'marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mathematical,' +
395
- 'max,min,offset,opacity,orient,origin,overline-position,overline-thickness,panose-1,' +
396
- 'path,pathLength,points,preserveAspectRatio,r,refX,refY,repeatCount,repeatDur,' +
397
- 'requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,stemv,stop-color,' +
398
- 'stop-opacity,strikethrough-position,strikethrough-thickness,stroke,stroke-dasharray,' +
399
- 'stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,' +
400
- 'stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,underline-position,' +
401
- 'underline-thickness,unicode,unicode-range,units-per-em,values,version,viewBox,visibility,' +
402
- 'width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,xlink:show,xlink:title,' +
403
- 'xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,zoomAndPan', true);
404
-
405
- var validAttrs = extend({},
406
- uriAttrs,
407
- svgAttrs,
408
- htmlAttrs);
409
-
410
- function stringToMap(str, lowercaseKeys) {
411
- return arrayToMap(str.split(','), lowercaseKeys);
412
- }
413
-
414
- function arrayToMap(items, lowercaseKeys) {
415
- var obj = {}, i;
416
- for (i = 0; i < items.length; i++) {
417
- obj[lowercaseKeys ? lowercase(items[i]) : items[i]] = true;
418
- }
419
- return obj;
420
- }
421
-
422
- function addElementsTo(elementsMap, newElements) {
423
- if (newElements && newElements.length) {
424
- extend(elementsMap, arrayToMap(newElements));
425
- }
426
- }
427
-
428
- /**
429
- * Create an inert document that contains the dirty HTML that needs sanitizing.
430
- * We use the DOMParser API by default and fall back to createHTMLDocument if DOMParser is not
431
- * available.
432
- */
433
- var getInertBodyElement /* function(html: string): HTMLBodyElement */ = (function(window, document) {
434
- if (isDOMParserAvailable()) {
435
- return getInertBodyElement_DOMParser;
436
- }
437
-
438
- if (!document || !document.implementation) {
439
- throw $sanitizeMinErr('noinert', 'Can\'t create an inert html document');
440
- }
441
- var inertDocument = document.implementation.createHTMLDocument('inert');
442
- var inertBodyElement = (inertDocument.documentElement || inertDocument.getDocumentElement()).querySelector('body');
443
- return getInertBodyElement_InertDocument;
444
-
445
- function isDOMParserAvailable() {
446
- try {
447
- return !!getInertBodyElement_DOMParser('');
448
- } catch (e) {
449
- return false;
450
- }
451
- }
452
-
453
- function getInertBodyElement_DOMParser(html) {
454
- // We add this dummy element to ensure that the rest of the content is parsed as expected
455
- // e.g. leading whitespace is maintained and tags like `<meta>` do not get hoisted to the `<head>` tag.
456
- html = '<remove></remove>' + html;
457
- try {
458
- var body = new window.DOMParser().parseFromString(html, 'text/html').body;
459
- body.firstChild.remove();
460
- return body;
461
- } catch (e) {
462
- return undefined;
463
- }
464
- }
465
-
466
- function getInertBodyElement_InertDocument(html) {
467
- inertBodyElement.innerHTML = html;
468
-
469
- // Support: IE 9-11 only
470
- // strip custom-namespaced attributes on IE<=11
471
- if (document.documentMode) {
472
- stripCustomNsAttrs(inertBodyElement);
473
- }
474
-
475
- return inertBodyElement;
476
- }
477
- })(window, window.document);
478
-
479
- /**
480
- * @example
481
- * htmlParser(htmlString, {
482
- * start: function(tag, attrs) {},
483
- * end: function(tag) {},
484
- * chars: function(text) {},
485
- * comment: function(text) {}
486
- * });
487
- *
488
- * @param {string} html string
489
- * @param {object} handler
490
- */
491
- function htmlParserImpl(html, handler) {
492
- if (html === null || html === undefined) {
493
- html = '';
494
- } else if (typeof html !== 'string') {
495
- html = '' + html;
496
- }
497
-
498
- var inertBodyElement = getInertBodyElement(html);
499
- if (!inertBodyElement) return '';
500
-
501
- //mXSS protection
502
- var mXSSAttempts = 5;
503
- do {
504
- if (mXSSAttempts === 0) {
505
- throw $sanitizeMinErr('uinput', 'Failed to sanitize html because the input is unstable');
506
- }
507
- mXSSAttempts--;
508
-
509
- // trigger mXSS if it is going to happen by reading and writing the innerHTML
510
- html = inertBodyElement.innerHTML;
511
- inertBodyElement = getInertBodyElement(html);
512
- } while (html !== inertBodyElement.innerHTML);
513
-
514
- var node = inertBodyElement.firstChild;
515
- while (node) {
516
- switch (node.nodeType) {
517
- case 1: // ELEMENT_NODE
518
- handler.start(node.nodeName.toLowerCase(), attrToMap(node.attributes));
519
- break;
520
- case 3: // TEXT NODE
521
- handler.chars(node.textContent);
522
- break;
523
- }
524
-
525
- var nextNode;
526
- if (!(nextNode = node.firstChild)) {
527
- if (node.nodeType === 1) {
528
- handler.end(node.nodeName.toLowerCase());
529
- }
530
- nextNode = getNonDescendant('nextSibling', node);
531
- if (!nextNode) {
532
- while (nextNode == null) {
533
- node = getNonDescendant('parentNode', node);
534
- if (node === inertBodyElement) break;
535
- nextNode = getNonDescendant('nextSibling', node);
536
- if (node.nodeType === 1) {
537
- handler.end(node.nodeName.toLowerCase());
538
- }
539
- }
540
- }
541
- }
542
- node = nextNode;
543
- }
544
-
545
- while ((node = inertBodyElement.firstChild)) {
546
- inertBodyElement.removeChild(node);
547
- }
548
- }
549
-
550
- function attrToMap(attrs) {
551
- var map = {};
552
- for (var i = 0, ii = attrs.length; i < ii; i++) {
553
- var attr = attrs[i];
554
- map[attr.name] = attr.value;
555
- }
556
- return map;
557
- }
558
-
559
-
560
- /**
561
- * Escapes all potentially dangerous characters, so that the
562
- * resulting string can be safely inserted into attribute or
563
- * element text.
564
- * @param value
565
- * @returns {string} escaped text
566
- */
567
- function encodeEntities(value) {
568
- return value.
569
- replace(/&/g, '&amp;').
570
- replace(SURROGATE_PAIR_REGEXP, function(value) {
571
- var hi = value.charCodeAt(0);
572
- var low = value.charCodeAt(1);
573
- return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
574
- }).
575
- replace(NON_ALPHANUMERIC_REGEXP, function(value) {
576
- return '&#' + value.charCodeAt(0) + ';';
577
- }).
578
- replace(/</g, '&lt;').
579
- replace(/>/g, '&gt;');
580
- }
581
-
582
- /**
583
- * create an HTML/XML writer which writes to buffer
584
- * @param {Array} buf use buf.join('') to get out sanitized html string
585
- * @returns {object} in the form of {
586
- * start: function(tag, attrs) {},
587
- * end: function(tag) {},
588
- * chars: function(text) {},
589
- * comment: function(text) {}
590
- * }
591
- */
592
- function htmlSanitizeWriterImpl(buf, uriValidator) {
593
- var ignoreCurrentElement = false;
594
- var out = bind(buf, buf.push);
595
- return {
596
- start: function(tag, attrs) {
597
- tag = lowercase(tag);
598
- if (!ignoreCurrentElement && blockedElements[tag]) {
599
- ignoreCurrentElement = tag;
600
- }
601
- if (!ignoreCurrentElement && validElements[tag] === true) {
602
- out('<');
603
- out(tag);
604
- forEach(attrs, function(value, key) {
605
- var lkey = lowercase(key);
606
- var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background');
607
- if (validAttrs[lkey] === true &&
608
- (uriAttrs[lkey] !== true || uriValidator(value, isImage))) {
609
- out(' ');
610
- out(key);
611
- out('="');
612
- out(encodeEntities(value));
613
- out('"');
614
- }
615
- });
616
- out('>');
617
- }
618
- },
619
- end: function(tag) {
620
- tag = lowercase(tag);
621
- if (!ignoreCurrentElement && validElements[tag] === true && voidElements[tag] !== true) {
622
- out('</');
623
- out(tag);
624
- out('>');
625
- }
626
- // eslint-disable-next-line eqeqeq
627
- if (tag == ignoreCurrentElement) {
628
- ignoreCurrentElement = false;
629
- }
630
- },
631
- chars: function(chars) {
632
- if (!ignoreCurrentElement) {
633
- out(encodeEntities(chars));
634
- }
635
- }
636
- };
637
- }
638
-
639
-
640
- /**
641
- * When IE9-11 comes across an unknown namespaced attribute e.g. 'xlink:foo' it adds 'xmlns:ns1' attribute to declare
642
- * ns1 namespace and prefixes the attribute with 'ns1' (e.g. 'ns1:xlink:foo'). This is undesirable since we don't want
643
- * to allow any of these custom attributes. This method strips them all.
644
- *
645
- * @param node Root element to process
646
- */
647
- function stripCustomNsAttrs(node) {
648
- while (node) {
649
- if (node.nodeType === window.Node.ELEMENT_NODE) {
650
- var attrs = node.attributes;
651
- for (var i = 0, l = attrs.length; i < l; i++) {
652
- var attrNode = attrs[i];
653
- var attrName = attrNode.name.toLowerCase();
654
- if (attrName === 'xmlns:ns1' || attrName.lastIndexOf('ns1:', 0) === 0) {
655
- node.removeAttributeNode(attrNode);
656
- i--;
657
- l--;
658
- }
659
- }
660
- }
661
-
662
- var nextNode = node.firstChild;
663
- if (nextNode) {
664
- stripCustomNsAttrs(nextNode);
665
- }
666
-
667
- node = getNonDescendant('nextSibling', node);
668
- }
669
- }
670
-
671
- function getNonDescendant(propName, node) {
672
- // An element is clobbered if its `propName` property points to one of its descendants
673
- var nextNode = node[propName];
674
- if (nextNode && nodeContains.call(node, nextNode)) {
675
- throw $sanitizeMinErr('elclob', 'Failed to sanitize html because the element is clobbered: {0}', node.outerHTML || node.outerText);
676
- }
677
- return nextNode;
678
- }
679
- }
680
-
681
- function sanitizeText(chars) {
682
- var buf = [];
683
- var writer = htmlSanitizeWriter(buf, noop);
684
- writer.chars(chars);
685
- return buf.join('');
686
- }
687
-
688
-
689
- // define ngSanitize module and register $sanitize service
690
- angular.module('ngSanitize', [])
691
- .provider('$sanitize', $SanitizeProvider)
692
- .info({ angularVersion: '1.8.4-local+sha.4e1bd4b90' });
693
-
694
- /**
695
- * @ngdoc filter
696
- * @name linky
697
- * @kind function
698
- *
699
- * @description
700
- * Finds links in text input and turns them into html links. Supports `http/https/ftp/sftp/mailto` and
701
- * plain email address links.
702
- *
703
- * Requires the {@link ngSanitize `ngSanitize`} module to be installed.
704
- *
705
- * @param {string} text Input text.
706
- * @param {string} [target] Window (`_blank|_self|_parent|_top`) or named frame to open links in.
707
- * @param {object|function(url)} [attributes] Add custom attributes to the link element.
708
- *
709
- * Can be one of:
710
- *
711
- * - `object`: A map of attributes
712
- * - `function`: Takes the url as a parameter and returns a map of attributes
713
- *
714
- * If the map of attributes contains a value for `target`, it overrides the value of
715
- * the target parameter.
716
- *
717
- *
718
- * @returns {string} Html-linkified and {@link $sanitize sanitized} text.
719
- *
720
- * @usage
721
- <span ng-bind-html="linky_expression | linky"></span>
722
- *
723
- * @example
724
- <example module="linkyExample" deps="angular-sanitize.js" name="linky-filter">
725
- <file name="index.html">
726
- <div ng-controller="ExampleController">
727
- Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
728
- <table>
729
- <tr>
730
- <th>Filter</th>
731
- <th>Source</th>
732
- <th>Rendered</th>
733
- </tr>
734
- <tr id="linky-filter">
735
- <td>linky filter</td>
736
- <td>
737
- <pre>&lt;div ng-bind-html="snippet | linky"&gt;<br>&lt;/div&gt;</pre>
738
- </td>
739
- <td>
740
- <div ng-bind-html="snippet | linky"></div>
741
- </td>
742
- </tr>
743
- <tr id="linky-target">
744
- <td>linky target</td>
745
- <td>
746
- <pre>&lt;div ng-bind-html="snippetWithSingleURL | linky:'_blank'"&gt;<br>&lt;/div&gt;</pre>
747
- </td>
748
- <td>
749
- <div ng-bind-html="snippetWithSingleURL | linky:'_blank'"></div>
750
- </td>
751
- </tr>
752
- <tr id="linky-custom-attributes">
753
- <td>linky custom attributes</td>
754
- <td>
755
- <pre>&lt;div ng-bind-html="snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}"&gt;<br>&lt;/div&gt;</pre>
756
- </td>
757
- <td>
758
- <div ng-bind-html="snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}"></div>
759
- </td>
760
- </tr>
761
- <tr id="escaped-html">
762
- <td>no filter</td>
763
- <td><pre>&lt;div ng-bind="snippet"&gt;<br>&lt;/div&gt;</pre></td>
764
- <td><div ng-bind="snippet"></div></td>
765
- </tr>
766
- </table>
767
- </file>
768
- <file name="script.js">
769
- angular.module('linkyExample', ['ngSanitize'])
770
- .controller('ExampleController', ['$scope', function($scope) {
771
- $scope.snippet =
772
- 'Pretty text with some links:\n' +
773
- 'http://angularjs.org/,\n' +
774
- 'mailto:us@somewhere.org,\n' +
775
- 'another@somewhere.org,\n' +
776
- 'and one more: ftp://127.0.0.1/.';
777
- $scope.snippetWithSingleURL = 'http://angularjs.org/';
778
- }]);
779
- </file>
780
- <file name="protractor.js" type="protractor">
781
- it('should linkify the snippet with urls', function() {
782
- expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
783
- toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' +
784
- 'another@somewhere.org, and one more: ftp://127.0.0.1/.');
785
- expect(element.all(by.css('#linky-filter a')).count()).toEqual(4);
786
- });
787
-
788
- it('should not linkify snippet without the linky filter', function() {
789
- expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()).
790
- toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' +
791
- 'another@somewhere.org, and one more: ftp://127.0.0.1/.');
792
- expect(element.all(by.css('#escaped-html a')).count()).toEqual(0);
793
- });
794
-
795
- it('should update', function() {
796
- element(by.model('snippet')).clear();
797
- element(by.model('snippet')).sendKeys('new http://link.');
798
- expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
799
- toBe('new http://link.');
800
- expect(element.all(by.css('#linky-filter a')).count()).toEqual(1);
801
- expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText())
802
- .toBe('new http://link.');
803
- });
804
-
805
- it('should work with the target property', function() {
806
- expect(element(by.id('linky-target')).
807
- element(by.binding("snippetWithSingleURL | linky:'_blank'")).getText()).
808
- toBe('http://angularjs.org/');
809
- expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank');
810
- });
811
-
812
- it('should optionally add custom attributes', function() {
813
- expect(element(by.id('linky-custom-attributes')).
814
- element(by.binding("snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}")).getText()).
815
- toBe('http://angularjs.org/');
816
- expect(element(by.css('#linky-custom-attributes a')).getAttribute('rel')).toEqual('nofollow');
817
- });
818
- </file>
819
- </example>
820
- */
821
- angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
822
- var LINKY_URL_REGEXP =
823
- /((s?ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i,
824
- MAILTO_REGEXP = /^mailto:/i;
825
-
826
- var linkyMinErr = angular.$$minErr('linky');
827
- var isDefined = angular.isDefined;
828
- var isFunction = angular.isFunction;
829
- var isObject = angular.isObject;
830
- var isString = angular.isString;
831
-
832
- return function(text, target, attributes) {
833
- if (text == null || text === '') return text;
834
- if (!isString(text)) throw linkyMinErr('notstring', 'Expected string but received: {0}', text);
835
-
836
- var attributesFn =
837
- isFunction(attributes) ? attributes :
838
- isObject(attributes) ? function getAttributesObject() {return attributes;} :
839
- function getEmptyAttributesObject() {return {};};
840
-
841
- var match;
842
- var raw = text;
843
- var html = [];
844
- var url;
845
- var i;
846
- while ((match = raw.match(LINKY_URL_REGEXP))) {
847
- // We can not end in these as they are sometimes found at the end of the sentence
848
- url = match[0];
849
- // if we did not match ftp/http/www/mailto then assume mailto
850
- if (!match[2] && !match[4]) {
851
- url = (match[3] ? 'http://' : 'mailto:') + url;
852
- }
853
- i = match.index;
854
- addText(raw.substr(0, i));
855
- addLink(url, match[0].replace(MAILTO_REGEXP, ''));
856
- raw = raw.substring(i + match[0].length);
857
- }
858
- addText(raw);
859
- return $sanitize(html.join(''));
860
-
861
- function addText(text) {
862
- if (!text) {
863
- return;
864
- }
865
- html.push(sanitizeText(text));
866
- }
867
-
868
- function addLink(url, text) {
869
- var key, linkAttributes = attributesFn(url);
870
- html.push('<a ');
871
-
872
- for (key in linkAttributes) {
873
- html.push(key + '="' + linkAttributes[key] + '" ');
874
- }
875
-
876
- if (isDefined(target) && !('target' in linkAttributes)) {
877
- html.push('target="',
878
- target,
879
- '" ');
880
- }
881
- html.push('href="',
882
- url.replace(/"/g, '&quot;'),
883
- '">');
884
- addText(text);
885
- html.push('</a>');
886
- }
887
- };
888
- }]);
889
-
890
-
891
- })(window, window.angular);