angularjs-rails 1.6.8 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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