angularjs-rails 1.6.8 → 1.8.0

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.
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @license AngularJS v1.6.8
3
- * (c) 2010-2017 Google, Inc. http://angularjs.org
2
+ * @license AngularJS v1.8.0
3
+ * (c) 2010-2020 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
6
6
  (function(window, angular) {'use strict';
@@ -32,6 +32,52 @@ function shallowCopy(src, dst) {
32
32
  return dst || src;
33
33
  }
34
34
 
35
+ /* global routeToRegExp: true */
36
+
37
+ /**
38
+ * @param {string} path - The path to parse. (It is assumed to have query and hash stripped off.)
39
+ * @param {Object} opts - Options.
40
+ * @return {Object} - An object containing an array of path parameter names (`keys`) and a regular
41
+ * expression (`regexp`) that can be used to identify a matching URL and extract the path
42
+ * parameter values.
43
+ *
44
+ * @description
45
+ * Parses the given path, extracting path parameter names and a regular expression to match URLs.
46
+ *
47
+ * Originally inspired by `pathRexp` in `visionmedia/express/lib/utils.js`.
48
+ */
49
+ function routeToRegExp(path, opts) {
50
+ var keys = [];
51
+
52
+ var pattern = path
53
+ .replace(/([().])/g, '\\$1')
54
+ .replace(/(\/)?:(\w+)(\*\?|[?*])?/g, function(_, slash, key, option) {
55
+ var optional = option === '?' || option === '*?';
56
+ var star = option === '*' || option === '*?';
57
+ keys.push({name: key, optional: optional});
58
+ slash = slash || '';
59
+ return (
60
+ (optional ? '(?:' + slash : slash + '(?:') +
61
+ (star ? '(.+?)' : '([^/]+)') +
62
+ (optional ? '?)?' : ')')
63
+ );
64
+ })
65
+ .replace(/([/$*])/g, '\\$1');
66
+
67
+ if (opts.ignoreTrailingSlashes) {
68
+ pattern = pattern.replace(/\/+$/, '') + '/*';
69
+ }
70
+
71
+ return {
72
+ keys: keys,
73
+ regexp: new RegExp(
74
+ '^' + pattern + '(?:[?#]|$)',
75
+ opts.caseInsensitiveMatch ? 'i' : ''
76
+ )
77
+ };
78
+ }
79
+
80
+ /* global routeToRegExp: false */
35
81
  /* global shallowCopy: false */
36
82
 
37
83
  // `isArray` and `isObject` are necessary for `shallowCopy()` (included via `src/shallowCopy.js`).
@@ -55,7 +101,7 @@ var noop;
55
101
  /* global -ngRouteModule */
56
102
  var ngRouteModule = angular.
57
103
  module('ngRoute', []).
58
- info({ angularVersion: '1.6.8' }).
104
+ info({ angularVersion: '1.8.0' }).
59
105
  provider('$route', $RouteProvider).
60
106
  // Ensure `$route` will be instantiated in time to capture the initial `$locationChangeSuccess`
61
107
  // event (unless explicitly disabled). This is necessary in case `ngView` is included in an
@@ -215,11 +261,22 @@ function $RouteProvider() {
215
261
  * `redirectTo` takes precedence over `resolveRedirectTo`, so specifying both on the same
216
262
  * route definition, will cause the latter to be ignored.
217
263
  *
264
+ * - `[reloadOnUrl=true]` - `{boolean=}` - reload route when any part of the URL changes
265
+ * (including the path) even if the new URL maps to the same route.
266
+ *
267
+ * If the option is set to `false` and the URL in the browser changes, but the new URL maps
268
+ * to the same route, then a `$routeUpdate` event is broadcasted on the root scope (without
269
+ * reloading the route).
270
+ *
218
271
  * - `[reloadOnSearch=true]` - `{boolean=}` - reload route when only `$location.search()`
219
272
  * or `$location.hash()` changes.
220
273
  *
221
- * If the option is set to `false` and url in the browser changes, then
222
- * `$routeUpdate` event is broadcasted on the root scope.
274
+ * If the option is set to `false` and the URL in the browser changes, then a `$routeUpdate`
275
+ * event is broadcasted on the root scope (without reloading the route).
276
+ *
277
+ * <div class="alert alert-warning">
278
+ * **Note:** This option has no effect if `reloadOnUrl` is set to `false`.
279
+ * </div>
223
280
  *
224
281
  * - `[caseInsensitiveMatch=false]` - `{boolean=}` - match routes without being case sensitive
225
282
  *
@@ -234,6 +291,9 @@ function $RouteProvider() {
234
291
  this.when = function(path, route) {
235
292
  //copy original route object to preserve params inherited from proto chain
236
293
  var routeCopy = shallowCopy(route);
294
+ if (angular.isUndefined(routeCopy.reloadOnUrl)) {
295
+ routeCopy.reloadOnUrl = true;
296
+ }
237
297
  if (angular.isUndefined(routeCopy.reloadOnSearch)) {
238
298
  routeCopy.reloadOnSearch = true;
239
299
  }
@@ -242,7 +302,8 @@ function $RouteProvider() {
242
302
  }
243
303
  routes[path] = angular.extend(
244
304
  routeCopy,
245
- path && pathRegExp(path, routeCopy)
305
+ {originalPath: path},
306
+ path && routeToRegExp(path, routeCopy)
246
307
  );
247
308
 
248
309
  // create redirection for trailing slashes
@@ -252,8 +313,8 @@ function $RouteProvider() {
252
313
  : path + '/';
253
314
 
254
315
  routes[redirectPath] = angular.extend(
255
- {redirectTo: path},
256
- pathRegExp(redirectPath, routeCopy)
316
+ {originalPath: path, redirectTo: path},
317
+ routeToRegExp(redirectPath, routeCopy)
257
318
  );
258
319
  }
259
320
 
@@ -271,47 +332,6 @@ function $RouteProvider() {
271
332
  */
272
333
  this.caseInsensitiveMatch = false;
273
334
 
274
- /**
275
- * @param path {string} path
276
- * @param opts {Object} options
277
- * @return {?Object}
278
- *
279
- * @description
280
- * Normalizes the given path, returning a regular expression
281
- * and the original path.
282
- *
283
- * Inspired by pathRexp in visionmedia/express/lib/utils.js.
284
- */
285
- function pathRegExp(path, opts) {
286
- var insensitive = opts.caseInsensitiveMatch,
287
- ret = {
288
- originalPath: path,
289
- regexp: path
290
- },
291
- keys = ret.keys = [];
292
-
293
- path = path
294
- .replace(/([().])/g, '\\$1')
295
- .replace(/(\/)?:(\w+)(\*\?|[?*])?/g, function(_, slash, key, option) {
296
- var optional = (option === '?' || option === '*?') ? '?' : null;
297
- var star = (option === '*' || option === '*?') ? '*' : null;
298
- keys.push({ name: key, optional: !!optional });
299
- slash = slash || '';
300
- return ''
301
- + (optional ? '' : slash)
302
- + '(?:'
303
- + (optional ? slash : '')
304
- + (star && '(.+?)' || '([^/]+)')
305
- + (optional || '')
306
- + ')'
307
- + (optional || '');
308
- })
309
- .replace(/([/$*])/g, '\\$1');
310
-
311
- ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : '');
312
- return ret;
313
- }
314
-
315
335
  /**
316
336
  * @ngdoc method
317
337
  * @name $routeProvider#otherwise
@@ -576,8 +596,9 @@ function $RouteProvider() {
576
596
  * @name $route#$routeUpdate
577
597
  * @eventType broadcast on root scope
578
598
  * @description
579
- * The `reloadOnSearch` property has been set to false, and we are reusing the same
580
- * instance of the Controller.
599
+ * Broadcasted if the same instance of a route (including template, controller instance,
600
+ * resolved dependencies, etc.) is being reused. This can happen if either `reloadOnSearch` or
601
+ * `reloadOnUrl` has been set to `false`.
581
602
  *
582
603
  * @param {Object} angularEvent Synthetic event object
583
604
  * @param {Route} current Current/previous route information.
@@ -637,7 +658,7 @@ function $RouteProvider() {
637
658
  // interpolate modifies newParams, only query params are left
638
659
  $location.search(newParams);
639
660
  } else {
640
- throw $routeMinErr('norout', 'Tried updating route when with no current route');
661
+ throw $routeMinErr('norout', 'Tried updating route with no current route');
641
662
  }
642
663
  }
643
664
  };
@@ -685,9 +706,7 @@ function $RouteProvider() {
685
706
  var lastRoute = $route.current;
686
707
 
687
708
  preparedRoute = parseRoute();
688
- preparedRouteIsUpdateOnly = preparedRoute && lastRoute && preparedRoute.$$route === lastRoute.$$route
689
- && angular.equals(preparedRoute.pathParams, lastRoute.pathParams)
690
- && !preparedRoute.reloadOnSearch && !forceReload;
709
+ preparedRouteIsUpdateOnly = isNavigationUpdateOnly(preparedRoute, lastRoute);
691
710
 
692
711
  if (!preparedRouteIsUpdateOnly && (lastRoute || preparedRoute)) {
693
712
  if ($rootScope.$broadcast('$routeChangeStart', preparedRoute, lastRoute).defaultPrevented) {
@@ -712,7 +731,7 @@ function $RouteProvider() {
712
731
 
713
732
  var nextRoutePromise = $q.resolve(nextRoute);
714
733
 
715
- $browser.$$incOutstandingRequestCount();
734
+ $browser.$$incOutstandingRequestCount('$route');
716
735
 
717
736
  nextRoutePromise.
718
737
  then(getRedirectionData).
@@ -740,7 +759,7 @@ function $RouteProvider() {
740
759
  // `outstandingRequestCount` to hit zero. This is important in case we are redirecting
741
760
  // to a new route which also requires some asynchronous work.
742
761
 
743
- $browser.$$completeOutstandingRequest(noop);
762
+ $browser.$$completeOutstandingRequest(noop, '$route');
744
763
  });
745
764
  }
746
765
  }
@@ -867,6 +886,29 @@ function $RouteProvider() {
867
886
  return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}});
868
887
  }
869
888
 
889
+ /**
890
+ * @param {Object} newRoute - The new route configuration (as returned by `parseRoute()`).
891
+ * @param {Object} oldRoute - The previous route configuration (as returned by `parseRoute()`).
892
+ * @returns {boolean} Whether this is an "update-only" navigation, i.e. the URL maps to the same
893
+ * route and it can be reused (based on the config and the type of change).
894
+ */
895
+ function isNavigationUpdateOnly(newRoute, oldRoute) {
896
+ // IF this is not a forced reload
897
+ return !forceReload
898
+ // AND both `newRoute`/`oldRoute` are defined
899
+ && newRoute && oldRoute
900
+ // AND they map to the same Route Definition Object
901
+ && (newRoute.$$route === oldRoute.$$route)
902
+ // AND `reloadOnUrl` is disabled
903
+ && (!newRoute.reloadOnUrl
904
+ // OR `reloadOnSearch` is disabled
905
+ || (!newRoute.reloadOnSearch
906
+ // AND both routes have the same path params
907
+ && angular.equals(newRoute.pathParams, oldRoute.pathParams)
908
+ )
909
+ );
910
+ }
911
+
870
912
  /**
871
913
  * @returns {string} interpolation of the redirect path with the parameters
872
914
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @license AngularJS v1.6.8
3
- * (c) 2010-2017 Google, Inc. http://angularjs.org
2
+ * @license AngularJS v1.8.0
3
+ * (c) 2010-2020 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
6
6
  (function(window, angular) {'use strict';
@@ -20,6 +20,7 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize');
20
20
  var bind;
21
21
  var extend;
22
22
  var forEach;
23
+ var isArray;
23
24
  var isDefined;
24
25
  var lowercase;
25
26
  var noop;
@@ -46,12 +47,11 @@ var htmlSanitizeWriter;
46
47
  * Sanitizes an html string by stripping all potentially dangerous tokens.
47
48
  *
48
49
  * 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
+ * then serialized back to a properly escaped HTML string. This means that no unsafe input can make
50
51
  * it into the returned string.
51
52
  *
52
53
  * The whitelist for URL sanitization of attribute values is configured using the functions
53
- * `aHrefSanitizationWhitelist` and `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider
54
- * `$compileProvider`}.
54
+ * `aHrefSanitizationWhitelist` and `imgSrcSanitizationWhitelist` of {@link $compileProvider}.
55
55
  *
56
56
  * The input may also contain SVG markup if this is enabled via {@link $sanitizeProvider}.
57
57
  *
@@ -150,9 +150,11 @@ var htmlSanitizeWriter;
150
150
  * Creates and configures {@link $sanitize} instance.
151
151
  */
152
152
  function $SanitizeProvider() {
153
+ var hasBeenInstantiated = false;
153
154
  var svgEnabled = false;
154
155
 
155
156
  this.$get = ['$$sanitizeUri', function($$sanitizeUri) {
157
+ hasBeenInstantiated = true;
156
158
  if (svgEnabled) {
157
159
  extend(validElements, svgElements);
158
160
  }
@@ -193,7 +195,7 @@ function $SanitizeProvider() {
193
195
  * </div>
194
196
  *
195
197
  * @param {boolean=} flag Enable or disable SVG support in the sanitizer.
196
- * @returns {boolean|ng.$sanitizeProvider} Returns the currently configured value if called
198
+ * @returns {boolean|$sanitizeProvider} Returns the currently configured value if called
197
199
  * without an argument or self for chaining otherwise.
198
200
  */
199
201
  this.enableSvg = function(enableSvg) {
@@ -205,6 +207,105 @@ function $SanitizeProvider() {
205
207
  }
206
208
  };
207
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#aHrefSanitizationWhitelist aHrefSanitizationWhitelist} and
286
+ * {@link ng.$compileProvider#imgSrcSanitizationWhitelist imgSrcSanitizationWhitelist}.
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
+
208
309
  //////////////////////////////////////////////////////////////////////////////////////////////////
209
310
  // Private stuff
210
311
  //////////////////////////////////////////////////////////////////////////////////////////////////
@@ -212,8 +313,9 @@ function $SanitizeProvider() {
212
313
  bind = angular.bind;
213
314
  extend = angular.extend;
214
315
  forEach = angular.forEach;
316
+ isArray = angular.isArray;
215
317
  isDefined = angular.isDefined;
216
- lowercase = angular.lowercase;
318
+ lowercase = angular.$$lowercase;
217
319
  noop = angular.noop;
218
320
 
219
321
  htmlParser = htmlParserImpl;
@@ -236,23 +338,23 @@ function $SanitizeProvider() {
236
338
 
237
339
  // Safe Void Elements - HTML5
238
340
  // http://dev.w3.org/html5/spec/Overview.html#void-elements
239
- var voidElements = toMap('area,br,col,hr,img,wbr');
341
+ var voidElements = stringToMap('area,br,col,hr,img,wbr');
240
342
 
241
343
  // Elements that you can, intentionally, leave open (and which close themselves)
242
344
  // http://dev.w3.org/html5/spec/Overview.html#optional-tags
243
- var optionalEndTagBlockElements = toMap('colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr'),
244
- optionalEndTagInlineElements = toMap('rp,rt'),
345
+ var optionalEndTagBlockElements = stringToMap('colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr'),
346
+ optionalEndTagInlineElements = stringToMap('rp,rt'),
245
347
  optionalEndTagElements = extend({},
246
348
  optionalEndTagInlineElements,
247
349
  optionalEndTagBlockElements);
248
350
 
249
351
  // Safe Block Elements - HTML5
250
- var blockElements = extend({}, optionalEndTagBlockElements, toMap('address,article,' +
352
+ var blockElements = extend({}, optionalEndTagBlockElements, stringToMap('address,article,' +
251
353
  'aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,' +
252
354
  'h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,section,table,ul'));
253
355
 
254
356
  // Inline Elements - HTML5
255
- var inlineElements = extend({}, optionalEndTagInlineElements, toMap('a,abbr,acronym,b,' +
357
+ var inlineElements = extend({}, optionalEndTagInlineElements, stringToMap('a,abbr,acronym,b,' +
256
358
  'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,' +
257
359
  'samp,small,span,strike,strong,sub,sup,time,tt,u,var'));
258
360
 
@@ -260,12 +362,12 @@ function $SanitizeProvider() {
260
362
  // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Elements
261
363
  // Note: the elements animate,animateColor,animateMotion,animateTransform,set are intentionally omitted.
262
364
  // They can potentially allow for arbitrary javascript to be executed. See #11290
263
- var svgElements = toMap('circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,' +
365
+ var svgElements = stringToMap('circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,' +
264
366
  'hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,' +
265
367
  'radialGradient,rect,stop,svg,switch,text,title,tspan');
266
368
 
267
369
  // Blocked Elements (will be stripped)
268
- var blockedElements = toMap('script,style');
370
+ var blockedElements = stringToMap('script,style');
269
371
 
270
372
  var validElements = extend({},
271
373
  voidElements,
@@ -274,9 +376,9 @@ function $SanitizeProvider() {
274
376
  optionalEndTagElements);
275
377
 
276
378
  //Attributes that have href and hence need to be sanitized
277
- var uriAttrs = toMap('background,cite,href,longdesc,src,xlink:href');
379
+ var uriAttrs = stringToMap('background,cite,href,longdesc,src,xlink:href,xml:base');
278
380
 
279
- var htmlAttrs = toMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' +
381
+ var htmlAttrs = stringToMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' +
280
382
  'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,' +
281
383
  'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,' +
282
384
  'scope,scrolling,shape,size,span,start,summary,tabindex,target,title,type,' +
@@ -284,7 +386,7 @@ function $SanitizeProvider() {
284
386
 
285
387
  // SVG attributes (without "id" and "name" attributes)
286
388
  // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes
287
- var svgAttrs = toMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' +
389
+ var svgAttrs = stringToMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' +
288
390
  'baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,' +
289
391
  'cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,' +
290
392
  'font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,' +
@@ -305,14 +407,24 @@ function $SanitizeProvider() {
305
407
  svgAttrs,
306
408
  htmlAttrs);
307
409
 
308
- function toMap(str, lowercaseKeys) {
309
- var obj = {}, items = str.split(','), i;
410
+ function stringToMap(str, lowercaseKeys) {
411
+ return arrayToMap(str.split(','), lowercaseKeys);
412
+ }
413
+
414
+ function arrayToMap(items, lowercaseKeys) {
415
+ var obj = {}, i;
310
416
  for (i = 0; i < items.length; i++) {
311
417
  obj[lowercaseKeys ? lowercase(items[i]) : items[i]] = true;
312
418
  }
313
419
  return obj;
314
420
  }
315
421
 
422
+ function addElementsTo(elementsMap, newElements) {
423
+ if (newElements && newElements.length) {
424
+ extend(elementsMap, arrayToMap(newElements));
425
+ }
426
+ }
427
+
316
428
  /**
317
429
  * Create an inert document that contains the dirty HTML that needs sanitizing
318
430
  * Depending upon browser support we use one of three strategies for doing this.
@@ -599,7 +711,7 @@ function sanitizeText(chars) {
599
711
  // define ngSanitize module and register $sanitize service
600
712
  angular.module('ngSanitize', [])
601
713
  .provider('$sanitize', $SanitizeProvider)
602
- .info({ angularVersion: '1.6.8' });
714
+ .info({ angularVersion: '1.8.0' });
603
715
 
604
716
  /**
605
717
  * @ngdoc filter