angular-gem 1.3.2 → 1.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +8 -8
  2. data/lib/angular-gem/version.rb +1 -1
  3. data/vendor/assets/javascripts/1.3.4/angular-animate.js +2136 -0
  4. data/vendor/assets/javascripts/1.3.4/angular-aria.js +321 -0
  5. data/vendor/assets/javascripts/1.3.4/angular-cookies.js +206 -0
  6. data/vendor/assets/javascripts/1.3.4/angular-loader.js +405 -0
  7. data/vendor/assets/javascripts/1.3.4/angular-messages.js +400 -0
  8. data/vendor/assets/javascripts/1.3.4/angular-mocks.js +2380 -0
  9. data/vendor/assets/javascripts/1.3.4/angular-resource.js +667 -0
  10. data/vendor/assets/javascripts/1.3.4/angular-route.js +996 -0
  11. data/vendor/assets/javascripts/1.3.4/angular-sanitize.js +678 -0
  12. data/vendor/assets/javascripts/1.3.4/angular-scenario.js +37269 -0
  13. data/vendor/assets/javascripts/1.3.4/angular-touch.js +622 -0
  14. data/vendor/assets/javascripts/1.3.4/angular.js +25915 -0
  15. data/vendor/assets/javascripts/angular-animate.js +15 -15
  16. data/vendor/assets/javascripts/angular-aria.js +83 -23
  17. data/vendor/assets/javascripts/angular-cookies.js +1 -1
  18. data/vendor/assets/javascripts/angular-loader.js +6 -23
  19. data/vendor/assets/javascripts/angular-messages.js +1 -1
  20. data/vendor/assets/javascripts/angular-mocks.js +21 -17
  21. data/vendor/assets/javascripts/angular-resource.js +1 -1
  22. data/vendor/assets/javascripts/angular-route.js +21 -7
  23. data/vendor/assets/javascripts/angular-sanitize.js +26 -26
  24. data/vendor/assets/javascripts/angular-scenario.js +646 -453
  25. data/vendor/assets/javascripts/angular-touch.js +3 -3
  26. data/vendor/assets/javascripts/angular.js +641 -448
  27. metadata +14 -2
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.2
2
+ * @license AngularJS v1.3.4
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -218,29 +218,29 @@ var validElements = angular.extend({},
218
218
  //Attributes that have href and hence need to be sanitized
219
219
  var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap,xlink:href");
220
220
 
221
- var htmlAttrs = makeMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+
222
- 'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+
223
- 'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+
224
- 'scope,scrolling,shape,size,span,start,summary,target,title,type,'+
221
+ var htmlAttrs = makeMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' +
222
+ 'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,' +
223
+ 'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,' +
224
+ 'scope,scrolling,shape,size,span,start,summary,target,title,type,' +
225
225
  'valign,value,vspace,width');
226
226
 
227
227
  // SVG attributes (without "id" and "name" attributes)
228
228
  // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes
229
- var svgAttrs = makeMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,'+
230
- 'attributeName,attributeType,baseProfile,bbox,begin,by,calcMode,cap-height,class,color,'+
231
- 'color-rendering,content,cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,'+
232
- 'font-size,font-stretch,font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,'+
233
- 'gradientUnits,hanging,height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,'+
234
- 'keySplines,keyTimes,lang,marker-end,marker-mid,marker-start,markerHeight,markerUnits,'+
235
- 'markerWidth,mathematical,max,min,offset,opacity,orient,origin,overline-position,'+
236
- 'overline-thickness,panose-1,path,pathLength,points,preserveAspectRatio,r,refX,refY,'+
237
- 'repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,'+
238
- 'stemv,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,stroke,'+
239
- 'stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,'+
240
- 'stroke-opacity,stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,'+
241
- 'underline-position,underline-thickness,unicode,unicode-range,units-per-em,values,version,'+
242
- 'viewBox,visibility,width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,'+
243
- 'xlink:show,xlink:title,xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,'+
229
+ var svgAttrs = makeMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' +
230
+ 'attributeName,attributeType,baseProfile,bbox,begin,by,calcMode,cap-height,class,color,' +
231
+ 'color-rendering,content,cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,' +
232
+ 'font-size,font-stretch,font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,' +
233
+ 'gradientUnits,hanging,height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,' +
234
+ 'keySplines,keyTimes,lang,marker-end,marker-mid,marker-start,markerHeight,markerUnits,' +
235
+ 'markerWidth,mathematical,max,min,offset,opacity,orient,origin,overline-position,' +
236
+ 'overline-thickness,panose-1,path,pathLength,points,preserveAspectRatio,r,refX,refY,' +
237
+ 'repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,' +
238
+ 'stemv,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,stroke,' +
239
+ 'stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,' +
240
+ 'stroke-opacity,stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,' +
241
+ 'underline-position,underline-thickness,unicode,unicode-range,units-per-em,values,version,' +
242
+ 'viewBox,visibility,width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,' +
243
+ 'xlink:show,xlink:title,xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,' +
244
244
  'zoomAndPan');
245
245
 
246
246
  var validAttrs = angular.extend({},
@@ -661,13 +661,13 @@ angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
661
661
  function addLink(url, text) {
662
662
  html.push('<a ');
663
663
  if (angular.isDefined(target)) {
664
- html.push('target="');
665
- html.push(target);
666
- html.push('" ');
664
+ html.push('target="',
665
+ target,
666
+ '" ');
667
667
  }
668
- html.push('href="');
669
- html.push(url);
670
- html.push('">');
668
+ html.push('href="',
669
+ url.replace('"', '&quot;'),
670
+ '">');
671
671
  addText(text);
672
672
  html.push('</a>');
673
673
  }
@@ -9190,7 +9190,7 @@ return jQuery;
9190
9190
  }));
9191
9191
 
9192
9192
  /**
9193
- * @license AngularJS v1.3.2
9193
+ * @license AngularJS v1.3.4
9194
9194
  * (c) 2010-2014 Google, Inc. http://angularjs.org
9195
9195
  * License: MIT
9196
9196
  */
@@ -9234,40 +9234,23 @@ function minErr(module, ErrorConstructor) {
9234
9234
  prefix = '[' + (module ? module + ':' : '') + code + '] ',
9235
9235
  template = arguments[1],
9236
9236
  templateArgs = arguments,
9237
- stringify = function(obj) {
9238
- if (typeof obj === 'function') {
9239
- return obj.toString().replace(/ \{[\s\S]*$/, '');
9240
- } else if (typeof obj === 'undefined') {
9241
- return 'undefined';
9242
- } else if (typeof obj !== 'string') {
9243
- return JSON.stringify(obj);
9244
- }
9245
- return obj;
9246
- },
9237
+
9247
9238
  message, i;
9248
9239
 
9249
9240
  message = prefix + template.replace(/\{\d+\}/g, function(match) {
9250
9241
  var index = +match.slice(1, -1), arg;
9251
9242
 
9252
9243
  if (index + 2 < templateArgs.length) {
9253
- arg = templateArgs[index + 2];
9254
- if (typeof arg === 'function') {
9255
- return arg.toString().replace(/ ?\{[\s\S]*$/, '');
9256
- } else if (typeof arg === 'undefined') {
9257
- return 'undefined';
9258
- } else if (typeof arg !== 'string') {
9259
- return toJson(arg);
9260
- }
9261
- return arg;
9244
+ return toDebugString(templateArgs[index + 2]);
9262
9245
  }
9263
9246
  return match;
9264
9247
  });
9265
9248
 
9266
- message = message + '\nhttp://errors.angularjs.org/1.3.2/' +
9249
+ message = message + '\nhttp://errors.angularjs.org/1.3.4/' +
9267
9250
  (module ? module + '/' : '') + code;
9268
9251
  for (i = 2; i < arguments.length; i++) {
9269
- message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
9270
- encodeURIComponent(stringify(arguments[i]));
9252
+ message = message + (i == 2 ? '?' : '&') + 'p' + (i - 2) + '=' +
9253
+ encodeURIComponent(toDebugString(arguments[i]));
9271
9254
  }
9272
9255
  return new ErrorConstructor(message);
9273
9256
  };
@@ -9635,7 +9618,7 @@ function int(str) {
9635
9618
 
9636
9619
 
9637
9620
  function inherit(parent, extra) {
9638
- return extend(new (extend(function() {}, {prototype:parent}))(), extra);
9621
+ return extend(Object.create(parent), extra);
9639
9622
  }
9640
9623
 
9641
9624
  /**
@@ -9898,7 +9881,7 @@ function makeMap(str) {
9898
9881
 
9899
9882
 
9900
9883
  function nodeName_(element) {
9901
- return lowercase(element.nodeName || element[0].nodeName);
9884
+ return lowercase(element.nodeName || (element[0] && element[0].nodeName));
9902
9885
  }
9903
9886
 
9904
9887
  function includes(array, obj) {
@@ -9907,7 +9890,7 @@ function includes(array, obj) {
9907
9890
 
9908
9891
  function arrayRemove(array, value) {
9909
9892
  var index = array.indexOf(value);
9910
- if (index >=0)
9893
+ if (index >= 0)
9911
9894
  array.splice(index, 1);
9912
9895
  return value;
9913
9896
  }
@@ -10108,7 +10091,7 @@ function equals(o1, o2) {
10108
10091
  if (isArray(o1)) {
10109
10092
  if (!isArray(o2)) return false;
10110
10093
  if ((length = o1.length) == o2.length) {
10111
- for (key=0; key<length; key++) {
10094
+ for (key = 0; key < length; key++) {
10112
10095
  if (!equals(o1[key], o2[key])) return false;
10113
10096
  }
10114
10097
  return true;
@@ -10194,7 +10177,7 @@ function bind(self, fn) {
10194
10177
  return curryArgs.length
10195
10178
  ? function() {
10196
10179
  return arguments.length
10197
- ? fn.apply(self, curryArgs.concat(slice.call(arguments, 0)))
10180
+ ? fn.apply(self, concat(curryArgs, arguments, 0))
10198
10181
  : fn.apply(self, curryArgs);
10199
10182
  }
10200
10183
  : function() {
@@ -10394,7 +10377,7 @@ var ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-'];
10394
10377
  function getNgAttribute(element, ngAttr) {
10395
10378
  var attr, i, ii = ngAttrPrefixes.length;
10396
10379
  element = jqLite(element);
10397
- for (i=0; i<ii; ++i) {
10380
+ for (i = 0; i < ii; ++i) {
10398
10381
  attr = ngAttrPrefixes[i] + ngAttr;
10399
10382
  if (isString(attr = element.attr(attr))) {
10400
10383
  return attr;
@@ -10604,8 +10587,8 @@ function angularInit(element, bootstrap) {
10604
10587
  * @param {Object=} config an object for defining configuration options for the application. The
10605
10588
  * following keys are supported:
10606
10589
  *
10607
- * - `strictDi`: disable automatic function annotation for the application. This is meant to
10608
- * assist in finding bugs which break minified code.
10590
+ * * `strictDi` - disable automatic function annotation for the application. This is meant to
10591
+ * assist in finding bugs which break minified code. Defaults to `false`.
10609
10592
  *
10610
10593
  * @returns {auto.$injector} Returns the newly created injector for this app.
10611
10594
  */
@@ -11179,6 +11162,34 @@ function setupModuleLoader(window) {
11179
11162
 
11180
11163
  }
11181
11164
 
11165
+ /* global: toDebugString: true */
11166
+
11167
+ function serializeObject(obj) {
11168
+ var seen = [];
11169
+
11170
+ return JSON.stringify(obj, function(key, val) {
11171
+ val = toJsonReplacer(key, val);
11172
+ if (isObject(val)) {
11173
+
11174
+ if (seen.indexOf(val) >= 0) return '<<already seen>>';
11175
+
11176
+ seen.push(val);
11177
+ }
11178
+ return val;
11179
+ });
11180
+ }
11181
+
11182
+ function toDebugString(obj) {
11183
+ if (typeof obj === 'function') {
11184
+ return obj.toString().replace(/ \{[\s\S]*$/, '');
11185
+ } else if (typeof obj === 'undefined') {
11186
+ return 'undefined';
11187
+ } else if (typeof obj !== 'string') {
11188
+ return serializeObject(obj);
11189
+ }
11190
+ return obj;
11191
+ }
11192
+
11182
11193
  /* global angularModule: true,
11183
11194
  version: true,
11184
11195
 
@@ -11281,11 +11292,11 @@ function setupModuleLoader(window) {
11281
11292
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
11282
11293
  */
11283
11294
  var version = {
11284
- full: '1.3.2', // all of these placeholder strings will be replaced by grunt's
11295
+ full: '1.3.4', // all of these placeholder strings will be replaced by grunt's
11285
11296
  major: 1, // package task
11286
11297
  minor: 3,
11287
- dot: 2,
11288
- codeName: 'cardiovasculatory-magnification'
11298
+ dot: 4,
11299
+ codeName: 'highfalutin-petroglyph'
11289
11300
  };
11290
11301
 
11291
11302
 
@@ -11508,10 +11519,12 @@ function publishExternalAPI(angular) {
11508
11519
  * `'ngModel'`).
11509
11520
  * - `injector()` - retrieves the injector of the current element or its parent.
11510
11521
  * - `scope()` - retrieves the {@link ng.$rootScope.Scope scope} of the current
11511
- * element or its parent.
11522
+ * element or its parent. Requires {@link guide/production#disabling-debug-data Debug Data} to
11523
+ * be enabled.
11512
11524
  * - `isolateScope()` - retrieves an isolate {@link ng.$rootScope.Scope scope} if one is attached directly to the
11513
11525
  * current element. This getter should be used only on elements that contain a directive which starts a new isolate
11514
11526
  * scope. Calling `scope()` on this element always returns the original non-isolate scope.
11527
+ * Requires {@link guide/production#disabling-debug-data Debug Data} to be enabled.
11515
11528
  * - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top
11516
11529
  * parent element is reached.
11517
11530
  *
@@ -12018,7 +12031,7 @@ forEach({
12018
12031
  }
12019
12032
  } else {
12020
12033
  return (element[name] ||
12021
- (element.attributes.getNamedItem(name)|| noop).specified)
12034
+ (element.attributes.getNamedItem(name) || noop).specified)
12022
12035
  ? lowercasedName
12023
12036
  : undefined;
12024
12037
  }
@@ -12506,9 +12519,10 @@ HashMap.prototype = {
12506
12519
  * Creates an injector object that can be used for retrieving services as well as for
12507
12520
  * dependency injection (see {@link guide/di dependency injection}).
12508
12521
  *
12509
-
12510
12522
  * @param {Array.<string|Function>} modules A list of module functions or their aliases. See
12511
- * {@link angular.module}. The `ng` module must be explicitly added.
12523
+ * {@link angular.module}. The `ng` module must be explicitly added.
12524
+ * @param {boolean=} [strictDi=false] Whether the injector should be in strict mode, which
12525
+ * disallows argument name annotation inference.
12512
12526
  * @returns {injector} Injector object. See {@link auto.$injector $injector}.
12513
12527
  *
12514
12528
  * @example
@@ -12654,8 +12668,10 @@ function annotate(fn, strictDi, name) {
12654
12668
  * ## Inference
12655
12669
  *
12656
12670
  * In JavaScript calling `toString()` on a function returns the function definition. The definition
12657
- * can then be parsed and the function arguments can be extracted. *NOTE:* This does not work with
12658
- * minification, and obfuscation tools since these tools change the argument names.
12671
+ * can then be parsed and the function arguments can be extracted. This method of discovering
12672
+ * annotations is disallowed when the injector is in strict mode.
12673
+ * *NOTE:* This does not work with minification, and obfuscation tools since these tools change the
12674
+ * argument names.
12659
12675
  *
12660
12676
  * ## `$inject` Annotation
12661
12677
  * By adding an `$inject` property onto a function the injection parameters can be specified.
@@ -12740,6 +12756,8 @@ function annotate(fn, strictDi, name) {
12740
12756
  * expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
12741
12757
  * ```
12742
12758
  *
12759
+ * You can disallow this method by using strict injection mode.
12760
+ *
12743
12761
  * This method does not work with code minification / obfuscation. For this reason the following
12744
12762
  * annotation strategies are supported.
12745
12763
  *
@@ -12792,6 +12810,8 @@ function annotate(fn, strictDi, name) {
12792
12810
  * @param {Function|Array.<string|Function>} fn Function for which dependent service names need to
12793
12811
  * be retrieved as described above.
12794
12812
  *
12813
+ * @param {boolean=} [strictDi=false] Disallow argument name annotation inference.
12814
+ *
12795
12815
  * @returns {Array.<string>} The names of the services which the function requires.
12796
12816
  */
12797
12817
 
@@ -13311,14 +13331,11 @@ function createInjector(modulesToLoad, strictDi) {
13311
13331
  }
13312
13332
 
13313
13333
  function instantiate(Type, locals, serviceName) {
13314
- var Constructor = function() {},
13315
- instance, returnedValue;
13316
-
13317
13334
  // Check if Type is annotated and use just the given function at n-1 as parameter
13318
13335
  // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);
13319
- Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Type).prototype;
13320
- instance = new Constructor();
13321
- returnedValue = invoke(Type, instance, locals, serviceName);
13336
+ // Object creation: http://jsperf.com/create-constructor/2
13337
+ var instance = Object.create((isArray(Type) ? Type[Type.length - 1] : Type).prototype);
13338
+ var returnedValue = invoke(Type, instance, locals, serviceName);
13322
13339
 
13323
13340
  return isObject(returnedValue) || isFunction(returnedValue) ? returnedValue : instance;
13324
13341
  }
@@ -13354,7 +13371,7 @@ function $AnchorScrollProvider() {
13354
13371
  * @name $anchorScrollProvider#disableAutoScrolling
13355
13372
  *
13356
13373
  * @description
13357
- * By default, {@link ng.$anchorScroll $anchorScroll()} will automatically will detect changes to
13374
+ * By default, {@link ng.$anchorScroll $anchorScroll()} will automatically detect changes to
13358
13375
  * {@link ng.$location#hash $location.hash()} and scroll to the element matching the new hash.<br />
13359
13376
  * Use this method to disable automatic scrolling.
13360
13377
  *
@@ -14003,8 +14020,7 @@ function $$AsyncCallbackProvider() {
14003
14020
  /**
14004
14021
  * @param {object} window The global window object.
14005
14022
  * @param {object} document jQuery wrapped document.
14006
- * @param {function()} XHR XMLHttpRequest constructor.
14007
- * @param {object} $log console.log or an object with the same interface.
14023
+ * @param {object} $log window.console or an object with the same interface.
14008
14024
  * @param {object} $sniffer $sniffer service
14009
14025
  */
14010
14026
  function Browser(window, document, $log, $sniffer) {
@@ -14155,7 +14171,7 @@ function Browser(window, document, $log, $sniffer) {
14155
14171
  // IE<10 from getting into redirect loop when in LocationHashbangInHtml5Url mode.
14156
14172
  // See https://github.com/angular/angular.js/commit/ffb2701
14157
14173
  if (lastBrowserUrl === url && (!$sniffer.history || sameState)) {
14158
- return;
14174
+ return self;
14159
14175
  }
14160
14176
  var sameBase = lastBrowserUrl && stripHash(lastBrowserUrl) === stripHash(url);
14161
14177
  lastBrowserUrl = url;
@@ -14354,8 +14370,8 @@ function Browser(window, document, $log, $sniffer) {
14354
14370
  // - 20 cookies per unique domain
14355
14371
  // - 4096 bytes per cookie
14356
14372
  if (cookieLength > 4096) {
14357
- $log.warn("Cookie '"+ name +
14358
- "' possibly not set or overflowed because it was too large ("+
14373
+ $log.warn("Cookie '" + name +
14374
+ "' possibly not set or overflowed because it was too large (" +
14359
14375
  cookieLength + " > 4096 bytes)!");
14360
14376
  }
14361
14377
  }
@@ -15020,7 +15036,7 @@ function $TemplateCacheProvider() {
15020
15036
  *
15021
15037
  *
15022
15038
  * #### `bindToController`
15023
- * When an isolate scope is used for a component (see above), and `controllerAs` is used, `bindToController` will
15039
+ * When an isolate scope is used for a component (see above), and `controllerAs` is used, `bindToController: true` will
15024
15040
  * allow a component to have its properties bound to the controller, rather than to scope. When the controller
15025
15041
  * is instantiated, the initial values of the isolate scope bindings are already available.
15026
15042
  *
@@ -15869,16 +15885,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15869
15885
 
15870
15886
  // for each tuples
15871
15887
  var nbrUrisWith2parts = Math.floor(rawUris.length / 2);
15872
- for (var i=0; i<nbrUrisWith2parts; i++) {
15873
- var innerIdx = i*2;
15888
+ for (var i = 0; i < nbrUrisWith2parts; i++) {
15889
+ var innerIdx = i * 2;
15874
15890
  // sanitize the uri
15875
15891
  result += $$sanitizeUri(trim(rawUris[innerIdx]), true);
15876
15892
  // add the descriptor
15877
- result += (" " + trim(rawUris[innerIdx+1]));
15893
+ result += (" " + trim(rawUris[innerIdx + 1]));
15878
15894
  }
15879
15895
 
15880
15896
  // split the last item into uri and descriptor
15881
- var lastTuple = trim(rawUris[i*2]).split(/\s/);
15897
+ var lastTuple = trim(rawUris[i * 2]).split(/\s/);
15882
15898
 
15883
15899
  // sanitize the last uri
15884
15900
  result += $$sanitizeUri(trim(lastTuple[0]), true);
@@ -16072,7 +16088,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16072
16088
  if (!node) {
16073
16089
  return 'html';
16074
16090
  } else {
16075
- return nodeName_(node) !== 'foreignobject' && node.toString().match(/SVG/) ? 'svg': 'html';
16091
+ return nodeName_(node) !== 'foreignobject' && node.toString().match(/SVG/) ? 'svg' : 'html';
16076
16092
  }
16077
16093
  }
16078
16094
 
@@ -16885,7 +16901,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16885
16901
  var match = null;
16886
16902
  if (hasDirectives.hasOwnProperty(name)) {
16887
16903
  for (var directive, directives = $injector.get(name + Suffix),
16888
- i = 0, ii = directives.length; i<ii; i++) {
16904
+ i = 0, ii = directives.length; i < ii; i++) {
16889
16905
  try {
16890
16906
  directive = directives[i];
16891
16907
  if ((maxPriority === undefined || maxPriority > directive.priority) &&
@@ -16914,7 +16930,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16914
16930
  function directiveIsMultiElement(name) {
16915
16931
  if (hasDirectives.hasOwnProperty(name)) {
16916
16932
  for (var directive, directives = $injector.get(name + Suffix),
16917
- i = 0, ii = directives.length; i<ii; i++) {
16933
+ i = 0, ii = directives.length; i < ii; i++) {
16918
16934
  directive = directives[i];
16919
16935
  if (directive.multiElement) {
16920
16936
  return true;
@@ -17067,10 +17083,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
17067
17083
  var childBoundTranscludeFn = boundTranscludeFn;
17068
17084
  if (scope.$$destroyed) return;
17069
17085
  if (linkQueue) {
17070
- linkQueue.push(scope);
17071
- linkQueue.push(node);
17072
- linkQueue.push(rootElement);
17073
- linkQueue.push(childBoundTranscludeFn);
17086
+ linkQueue.push(scope,
17087
+ node,
17088
+ rootElement,
17089
+ childBoundTranscludeFn);
17074
17090
  } else {
17075
17091
  if (afterTemplateNodeLinkFn.transcludeOnThisElement) {
17076
17092
  childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);
@@ -17133,7 +17149,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
17133
17149
  case 'svg':
17134
17150
  case 'math':
17135
17151
  var wrapper = document.createElement('div');
17136
- wrapper.innerHTML = '<'+type+'>'+template+'</'+type+'>';
17152
+ wrapper.innerHTML = '<' + type + '>' + template + '</' + type + '>';
17137
17153
  return wrapper.childNodes[0].childNodes;
17138
17154
  default:
17139
17155
  return template;
@@ -17490,6 +17506,10 @@ function $ControllerProvider() {
17490
17506
  * * if $controllerProvider#allowGlobals, check `window[constructor]` on the global
17491
17507
  * `window` object (not recommended)
17492
17508
  *
17509
+ * The string can use the `controller as property` syntax, where the controller instance is published
17510
+ * as the specified property on the `scope`; the `scope` must be injected into `locals` param for this
17511
+ * to work correctly.
17512
+ *
17493
17513
  * @param {Object} locals Injection locals for Controller.
17494
17514
  * @return {Object} Instance of given controller.
17495
17515
  *
@@ -17535,10 +17555,10 @@ function $ControllerProvider() {
17535
17555
  //
17536
17556
  // This feature is not intended for use by applications, and is thus not documented
17537
17557
  // publicly.
17538
- var Constructor = function() {};
17539
- Constructor.prototype = (isArray(expression) ?
17558
+ // Object creation: http://jsperf.com/create-constructor/2
17559
+ var controllerPrototype = (isArray(expression) ?
17540
17560
  expression[expression.length - 1] : expression).prototype;
17541
- instance = new Constructor();
17561
+ instance = Object.create(controllerPrototype);
17542
17562
 
17543
17563
  if (identifier) {
17544
17564
  addIdentifier(locals, identifier, instance, constructor || expression.name);
@@ -17664,7 +17684,7 @@ function defaultHttpResponseTransform(data, headers) {
17664
17684
  // strip json vulnerability protection prefix
17665
17685
  data = data.replace(JSON_PROTECTION_PREFIX, '');
17666
17686
  var contentType = headers('Content-Type');
17667
- if ((contentType && contentType.indexOf(APPLICATION_JSON) === 0) ||
17687
+ if ((contentType && contentType.indexOf(APPLICATION_JSON) === 0 && data.trim()) ||
17668
17688
  (JSON_START.test(data) && JSON_END.test(data))) {
17669
17689
  data = fromJson(data);
17670
17690
  }
@@ -17679,7 +17699,7 @@ function defaultHttpResponseTransform(data, headers) {
17679
17699
  * @returns {Object} Parsed headers as key value object
17680
17700
  */
17681
17701
  function parseHeaders(headers) {
17682
- var parsed = {}, key, val, i;
17702
+ var parsed = createMap(), key, val, i;
17683
17703
 
17684
17704
  if (!headers) return parsed;
17685
17705
 
@@ -17716,7 +17736,11 @@ function headersGetter(headers) {
17716
17736
  if (!headersObj) headersObj = parseHeaders(headers);
17717
17737
 
17718
17738
  if (name) {
17719
- return headersObj[lowercase(name)] || null;
17739
+ var value = headersObj[lowercase(name)];
17740
+ if (value === void 0) {
17741
+ value = null;
17742
+ }
17743
+ return value;
17720
17744
  }
17721
17745
 
17722
17746
  return headersObj;
@@ -17765,6 +17789,11 @@ function $HttpProvider() {
17765
17789
  *
17766
17790
  * Object containing default values for all {@link ng.$http $http} requests.
17767
17791
  *
17792
+ * - **`defaults.cache`** - {Object} - an object built with {@link ng.$cacheFactory `$cacheFactory`}
17793
+ * that will provide the cache for all requests who set their `cache` property to `true`.
17794
+ * If you set the `default.cache = false` then only requests that specify their own custom
17795
+ * cache object will be cached. See {@link $http#caching $http Caching} for more information.
17796
+ *
17768
17797
  * - **`defaults.xsrfCookieName`** - {string} - Name of cookie containing the XSRF token.
17769
17798
  * Defaults value is `'XSRF-TOKEN'`.
17770
17799
  *
@@ -17778,6 +17807,7 @@ function $HttpProvider() {
17778
17807
  * - **`defaults.headers.post`**
17779
17808
  * - **`defaults.headers.put`**
17780
17809
  * - **`defaults.headers.patch`**
17810
+ *
17781
17811
  **/
17782
17812
  var defaults = this.defaults = {
17783
17813
  // transform incoming response data
@@ -17992,6 +18022,21 @@ function $HttpProvider() {
17992
18022
  * In addition, you can supply a `headers` property in the config object passed when
17993
18023
  * calling `$http(config)`, which overrides the defaults without changing them globally.
17994
18024
  *
18025
+ * To explicitly remove a header automatically added via $httpProvider.defaults.headers on a per request basis,
18026
+ * Use the `headers` property, setting the desired header to `undefined`. For example:
18027
+ *
18028
+ * ```js
18029
+ * var req = {
18030
+ * method: 'POST',
18031
+ * url: 'http://example.com',
18032
+ * headers: {
18033
+ * 'Content-Type': undefined
18034
+ * },
18035
+ * data: { test: 'test' },
18036
+ * }
18037
+ *
18038
+ * $http(req).success(function(){...}).error(function(){...});
18039
+ * ```
17995
18040
  *
17996
18041
  * ## Transforming Requests and Responses
17997
18042
  *
@@ -18371,6 +18416,10 @@ function $HttpProvider() {
18371
18416
  };
18372
18417
  var headers = mergeHeaders(requestConfig);
18373
18418
 
18419
+ if (!angular.isObject(requestConfig)) {
18420
+ throw minErr('$http')('badreq', 'Http request configuration must be an object. Received: {0}', requestConfig);
18421
+ }
18422
+
18374
18423
  extend(config, requestConfig);
18375
18424
  config.headers = headers;
18376
18425
  config.method = uppercase(config.method);
@@ -19235,7 +19284,8 @@ function $InterpolateProvider() {
19235
19284
 
19236
19285
  function parseStringifyInterceptor(value) {
19237
19286
  try {
19238
- return stringify(getValue(value));
19287
+ value = getValue(value);
19288
+ return allOrNothing && !isDefined(value) ? value : stringify(value);
19239
19289
  } catch (err) {
19240
19290
  var newErr = $interpolateMinErr('interr', "Can't interpolate: {0}\n{1}", text,
19241
19291
  err.toString());
@@ -19559,8 +19609,8 @@ function encodePath(path) {
19559
19609
  return segments.join('/');
19560
19610
  }
19561
19611
 
19562
- function parseAbsoluteUrl(absoluteUrl, locationObj, appBase) {
19563
- var parsedUrl = urlResolve(absoluteUrl, appBase);
19612
+ function parseAbsoluteUrl(absoluteUrl, locationObj) {
19613
+ var parsedUrl = urlResolve(absoluteUrl);
19564
19614
 
19565
19615
  locationObj.$$protocol = parsedUrl.protocol;
19566
19616
  locationObj.$$host = parsedUrl.hostname;
@@ -19568,12 +19618,12 @@ function parseAbsoluteUrl(absoluteUrl, locationObj, appBase) {
19568
19618
  }
19569
19619
 
19570
19620
 
19571
- function parseAppUrl(relativeUrl, locationObj, appBase) {
19621
+ function parseAppUrl(relativeUrl, locationObj) {
19572
19622
  var prefixed = (relativeUrl.charAt(0) !== '/');
19573
19623
  if (prefixed) {
19574
19624
  relativeUrl = '/' + relativeUrl;
19575
19625
  }
19576
- var match = urlResolve(relativeUrl, appBase);
19626
+ var match = urlResolve(relativeUrl);
19577
19627
  locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ?
19578
19628
  match.pathname.substring(1) : match.pathname);
19579
19629
  locationObj.$$search = parseKeyValue(match.search);
@@ -19628,7 +19678,7 @@ function LocationHtml5Url(appBase, basePrefix) {
19628
19678
  this.$$html5 = true;
19629
19679
  basePrefix = basePrefix || '';
19630
19680
  var appBaseNoFile = stripFile(appBase);
19631
- parseAbsoluteUrl(appBase, this, appBase);
19681
+ parseAbsoluteUrl(appBase, this);
19632
19682
 
19633
19683
 
19634
19684
  /**
@@ -19643,7 +19693,7 @@ function LocationHtml5Url(appBase, basePrefix) {
19643
19693
  appBaseNoFile);
19644
19694
  }
19645
19695
 
19646
- parseAppUrl(pathUrl, this, appBase);
19696
+ parseAppUrl(pathUrl, this);
19647
19697
 
19648
19698
  if (!this.$$path) {
19649
19699
  this.$$path = '/';
@@ -19706,7 +19756,7 @@ function LocationHtml5Url(appBase, basePrefix) {
19706
19756
  function LocationHashbangUrl(appBase, hashPrefix) {
19707
19757
  var appBaseNoFile = stripFile(appBase);
19708
19758
 
19709
- parseAbsoluteUrl(appBase, this, appBase);
19759
+ parseAbsoluteUrl(appBase, this);
19710
19760
 
19711
19761
 
19712
19762
  /**
@@ -19726,7 +19776,7 @@ function LocationHashbangUrl(appBase, hashPrefix) {
19726
19776
  throw $locationMinErr('ihshprfx', 'Invalid url "{0}", missing hash prefix "{1}".', url,
19727
19777
  hashPrefix);
19728
19778
  }
19729
- parseAppUrl(withoutHashUrl, this, appBase);
19779
+ parseAppUrl(withoutHashUrl, this);
19730
19780
 
19731
19781
  this.$$path = removeWindowsDriveName(this.$$path, withoutHashUrl, appBase);
19732
19782
 
@@ -19864,6 +19914,13 @@ var locationPrototype = {
19864
19914
  * Return full url representation with all segments encoded according to rules specified in
19865
19915
  * [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt).
19866
19916
  *
19917
+ *
19918
+ * ```js
19919
+ * // given url http://example.com/#/some/path?foo=bar&baz=xoxo
19920
+ * var absUrl = $location.absUrl();
19921
+ * // => "http://example.com/#/some/path?foo=bar&baz=xoxo"
19922
+ * ```
19923
+ *
19867
19924
  * @return {string} full url
19868
19925
  */
19869
19926
  absUrl: locationGetter('$$absUrl'),
@@ -19879,6 +19936,13 @@ var locationPrototype = {
19879
19936
  *
19880
19937
  * Change path, search and hash, when called with parameter and return `$location`.
19881
19938
  *
19939
+ *
19940
+ * ```js
19941
+ * // given url http://example.com/#/some/path?foo=bar&baz=xoxo
19942
+ * var url = $location.url();
19943
+ * // => "/some/path?foo=bar&baz=xoxo"
19944
+ * ```
19945
+ *
19882
19946
  * @param {string=} url New url without base prefix (e.g. `/path?a=b#hash`)
19883
19947
  * @return {string} url
19884
19948
  */
@@ -19887,8 +19951,8 @@ var locationPrototype = {
19887
19951
  return this.$$url;
19888
19952
 
19889
19953
  var match = PATH_MATCH.exec(url);
19890
- if (match[1]) this.path(decodeURIComponent(match[1]));
19891
- if (match[2] || match[1]) this.search(match[3] || '');
19954
+ if (match[1] || url === '') this.path(decodeURIComponent(match[1]));
19955
+ if (match[2] || match[1] || url === '') this.search(match[3] || '');
19892
19956
  this.hash(match[5] || '');
19893
19957
 
19894
19958
  return this;
@@ -19903,6 +19967,13 @@ var locationPrototype = {
19903
19967
  *
19904
19968
  * Return protocol of current url.
19905
19969
  *
19970
+ *
19971
+ * ```js
19972
+ * // given url http://example.com/#/some/path?foo=bar&baz=xoxo
19973
+ * var protocol = $location.protocol();
19974
+ * // => "http"
19975
+ * ```
19976
+ *
19906
19977
  * @return {string} protocol of current url
19907
19978
  */
19908
19979
  protocol: locationGetter('$$protocol'),
@@ -19916,6 +19987,13 @@ var locationPrototype = {
19916
19987
  *
19917
19988
  * Return host of current url.
19918
19989
  *
19990
+ *
19991
+ * ```js
19992
+ * // given url http://example.com/#/some/path?foo=bar&baz=xoxo
19993
+ * var host = $location.host();
19994
+ * // => "example.com"
19995
+ * ```
19996
+ *
19919
19997
  * @return {string} host of current url.
19920
19998
  */
19921
19999
  host: locationGetter('$$host'),
@@ -19929,6 +20007,13 @@ var locationPrototype = {
19929
20007
  *
19930
20008
  * Return port of current url.
19931
20009
  *
20010
+ *
20011
+ * ```js
20012
+ * // given url http://example.com/#/some/path?foo=bar&baz=xoxo
20013
+ * var port = $location.port();
20014
+ * // => 80
20015
+ * ```
20016
+ *
19932
20017
  * @return {Number} port
19933
20018
  */
19934
20019
  port: locationGetter('$$port'),
@@ -19947,6 +20032,13 @@ var locationPrototype = {
19947
20032
  * Note: Path should always begin with forward slash (/), this method will add the forward slash
19948
20033
  * if it is missing.
19949
20034
  *
20035
+ *
20036
+ * ```js
20037
+ * // given url http://example.com/#/some/path?foo=bar&baz=xoxo
20038
+ * var path = $location.path();
20039
+ * // => "/some/path"
20040
+ * ```
20041
+ *
19950
20042
  * @param {(string|number)=} path New path
19951
20043
  * @return {string} path
19952
20044
  */
@@ -19972,10 +20064,9 @@ var locationPrototype = {
19972
20064
  * var searchObject = $location.search();
19973
20065
  * // => {foo: 'bar', baz: 'xoxo'}
19974
20066
  *
19975
- *
19976
20067
  * // set foo to 'yipee'
19977
20068
  * $location.search('foo', 'yipee');
19978
- * // => $location
20069
+ * // $location.search() => {foo: 'yipee', baz: 'xoxo'}
19979
20070
  * ```
19980
20071
  *
19981
20072
  * @param {string|Object.<string>|Object.<Array.<string>>} search New search params - string or
@@ -20045,6 +20136,13 @@ var locationPrototype = {
20045
20136
  *
20046
20137
  * Change hash fragment when called with parameter and return `$location`.
20047
20138
  *
20139
+ *
20140
+ * ```js
20141
+ * // given url http://example.com/some/path?foo=bar&baz=xoxo#hashValue
20142
+ * var hash = $location.hash();
20143
+ * // => "hashValue"
20144
+ * ```
20145
+ *
20048
20146
  * @param {(string|number)=} hash New hash fragment
20049
20147
  * @return {string} hash
20050
20148
  */
@@ -20366,11 +20464,19 @@ function $LocationProvider() {
20366
20464
  $rootScope.$evalAsync(function() {
20367
20465
  var oldUrl = $location.absUrl();
20368
20466
  var oldState = $location.$$state;
20467
+ var defaultPrevented;
20369
20468
 
20370
20469
  $location.$$parse(newUrl);
20371
20470
  $location.$$state = newState;
20372
- if ($rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,
20373
- newState, oldState).defaultPrevented) {
20471
+
20472
+ defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,
20473
+ newState, oldState).defaultPrevented;
20474
+
20475
+ // if the location was changed by a `$locationChangeStart` handler then stop
20476
+ // processing this location change
20477
+ if ($location.absUrl() !== newUrl) return;
20478
+
20479
+ if (defaultPrevented) {
20374
20480
  $location.$$parse(oldUrl);
20375
20481
  $location.$$state = oldState;
20376
20482
  setBrowserUrlWithFallback(oldUrl, false, oldState);
@@ -20394,13 +20500,20 @@ function $LocationProvider() {
20394
20500
  initializing = false;
20395
20501
 
20396
20502
  $rootScope.$evalAsync(function() {
20397
- if ($rootScope.$broadcast('$locationChangeStart', $location.absUrl(), oldUrl,
20398
- $location.$$state, oldState).defaultPrevented) {
20503
+ var newUrl = $location.absUrl();
20504
+ var defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,
20505
+ $location.$$state, oldState).defaultPrevented;
20506
+
20507
+ // if the location was changed by a `$locationChangeStart` handler then stop
20508
+ // processing this location change
20509
+ if ($location.absUrl() !== newUrl) return;
20510
+
20511
+ if (defaultPrevented) {
20399
20512
  $location.$$parse(oldUrl);
20400
20513
  $location.$$state = oldState;
20401
20514
  } else {
20402
20515
  if (urlOrStateChanged) {
20403
- setBrowserUrlWithFallback($location.absUrl(), currentReplace,
20516
+ setBrowserUrlWithFallback(newUrl, currentReplace,
20404
20517
  oldState === $location.$$state ? null : $location.$$state);
20405
20518
  }
20406
20519
  afterLocationChange(oldUrl, oldState);
@@ -20590,7 +20703,7 @@ var $parseMinErr = minErr('$parse');
20590
20703
  // Sandboxing Angular Expressions
20591
20704
  // ------------------------------
20592
20705
  // Angular expressions are generally considered safe because these expressions only have direct
20593
- // access to $scope and locals. However, one can obtain the ability to execute arbitrary JS code by
20706
+ // access to `$scope` and locals. However, one can obtain the ability to execute arbitrary JS code by
20594
20707
  // obtaining a reference to native JS functions such as the Function constructor.
20595
20708
  //
20596
20709
  // As an example, consider the following Angular expression:
@@ -20599,7 +20712,7 @@ var $parseMinErr = minErr('$parse');
20599
20712
  //
20600
20713
  // This sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits
20601
20714
  // against the expression language, but not to prevent exploits that were enabled by exposing
20602
- // sensitive JavaScript or browser apis on Scope. Exposing such objects on a Scope is never a good
20715
+ // sensitive JavaScript or browser APIs on Scope. Exposing such objects on a Scope is never a good
20603
20716
  // practice and therefore we are not even trying to protect against interaction with an object
20604
20717
  // explicitly exposed in this way.
20605
20718
  //
@@ -20607,6 +20720,8 @@ var $parseMinErr = minErr('$parse');
20607
20720
  // window or some DOM object that has a reference to window is published onto a Scope.
20608
20721
  // Similarly we prevent invocations of function known to be dangerous, as well as assignments to
20609
20722
  // native objects.
20723
+ //
20724
+ // See https://docs.angularjs.org/guide/security
20610
20725
 
20611
20726
 
20612
20727
  function ensureSafeMemberName(name, fullExpression) {
@@ -20615,7 +20730,7 @@ function ensureSafeMemberName(name, fullExpression) {
20615
20730
  || name === "__proto__") {
20616
20731
  throw $parseMinErr('isecfld',
20617
20732
  'Attempting to access a disallowed field in Angular expressions! '
20618
- +'Expression: {0}', fullExpression);
20733
+ + 'Expression: {0}', fullExpression);
20619
20734
  }
20620
20735
  return name;
20621
20736
  }
@@ -20692,24 +20807,24 @@ var OPERATORS = extend(createMap(), {
20692
20807
  }
20693
20808
  return a;
20694
20809
  }
20695
- return isDefined(b)?b:undefined;},
20810
+ return isDefined(b) ? b : undefined;},
20696
20811
  '-':function(self, locals, a, b) {
20697
20812
  a=a(self, locals); b=b(self, locals);
20698
- return (isDefined(a)?a:0)-(isDefined(b)?b:0);
20813
+ return (isDefined(a) ? a : 0) - (isDefined(b) ? b : 0);
20699
20814
  },
20700
- '*':function(self, locals, a, b) {return a(self, locals)*b(self, locals);},
20701
- '/':function(self, locals, a, b) {return a(self, locals)/b(self, locals);},
20702
- '%':function(self, locals, a, b) {return a(self, locals)%b(self, locals);},
20703
- '===':function(self, locals, a, b) {return a(self, locals)===b(self, locals);},
20704
- '!==':function(self, locals, a, b) {return a(self, locals)!==b(self, locals);},
20705
- '==':function(self, locals, a, b) {return a(self, locals)==b(self, locals);},
20706
- '!=':function(self, locals, a, b) {return a(self, locals)!=b(self, locals);},
20707
- '<':function(self, locals, a, b) {return a(self, locals)<b(self, locals);},
20708
- '>':function(self, locals, a, b) {return a(self, locals)>b(self, locals);},
20709
- '<=':function(self, locals, a, b) {return a(self, locals)<=b(self, locals);},
20710
- '>=':function(self, locals, a, b) {return a(self, locals)>=b(self, locals);},
20711
- '&&':function(self, locals, a, b) {return a(self, locals)&&b(self, locals);},
20712
- '||':function(self, locals, a, b) {return a(self, locals)||b(self, locals);},
20815
+ '*':function(self, locals, a, b) {return a(self, locals) * b(self, locals);},
20816
+ '/':function(self, locals, a, b) {return a(self, locals) / b(self, locals);},
20817
+ '%':function(self, locals, a, b) {return a(self, locals) % b(self, locals);},
20818
+ '===':function(self, locals, a, b) {return a(self, locals) === b(self, locals);},
20819
+ '!==':function(self, locals, a, b) {return a(self, locals) !== b(self, locals);},
20820
+ '==':function(self, locals, a, b) {return a(self, locals) == b(self, locals);},
20821
+ '!=':function(self, locals, a, b) {return a(self, locals) != b(self, locals);},
20822
+ '<':function(self, locals, a, b) {return a(self, locals) < b(self, locals);},
20823
+ '>':function(self, locals, a, b) {return a(self, locals) > b(self, locals);},
20824
+ '<=':function(self, locals, a, b) {return a(self, locals) <= b(self, locals);},
20825
+ '>=':function(self, locals, a, b) {return a(self, locals) >= b(self, locals);},
20826
+ '&&':function(self, locals, a, b) {return a(self, locals) && b(self, locals);},
20827
+ '||':function(self, locals, a, b) {return a(self, locals) || b(self, locals);},
20713
20828
  '!':function(self, locals, a) {return !a(self, locals);},
20714
20829
 
20715
20830
  //Tokenized as operators but parsed as assignment/filters
@@ -20735,44 +20850,31 @@ Lexer.prototype = {
20735
20850
  lex: function(text) {
20736
20851
  this.text = text;
20737
20852
  this.index = 0;
20738
- this.ch = undefined;
20739
20853
  this.tokens = [];
20740
20854
 
20741
20855
  while (this.index < this.text.length) {
20742
- this.ch = this.text.charAt(this.index);
20743
- if (this.is('"\'')) {
20744
- this.readString(this.ch);
20745
- } else if (this.isNumber(this.ch) || this.is('.') && this.isNumber(this.peek())) {
20856
+ var ch = this.text.charAt(this.index);
20857
+ if (ch === '"' || ch === "'") {
20858
+ this.readString(ch);
20859
+ } else if (this.isNumber(ch) || ch === '.' && this.isNumber(this.peek())) {
20746
20860
  this.readNumber();
20747
- } else if (this.isIdent(this.ch)) {
20861
+ } else if (this.isIdent(ch)) {
20748
20862
  this.readIdent();
20749
- } else if (this.is('(){}[].,;:?')) {
20750
- this.tokens.push({
20751
- index: this.index,
20752
- text: this.ch
20753
- });
20863
+ } else if (this.is(ch, '(){}[].,;:?')) {
20864
+ this.tokens.push({index: this.index, text: ch});
20754
20865
  this.index++;
20755
- } else if (this.isWhitespace(this.ch)) {
20866
+ } else if (this.isWhitespace(ch)) {
20756
20867
  this.index++;
20757
20868
  } else {
20758
- var ch2 = this.ch + this.peek();
20869
+ var ch2 = ch + this.peek();
20759
20870
  var ch3 = ch2 + this.peek(2);
20760
- var fn = OPERATORS[this.ch];
20761
- var fn2 = OPERATORS[ch2];
20762
- var fn3 = OPERATORS[ch3];
20763
- if (fn3) {
20764
- this.tokens.push({index: this.index, text: ch3, fn: fn3});
20765
- this.index += 3;
20766
- } else if (fn2) {
20767
- this.tokens.push({index: this.index, text: ch2, fn: fn2});
20768
- this.index += 2;
20769
- } else if (fn) {
20770
- this.tokens.push({
20771
- index: this.index,
20772
- text: this.ch,
20773
- fn: fn
20774
- });
20775
- this.index += 1;
20871
+ var op1 = OPERATORS[ch];
20872
+ var op2 = OPERATORS[ch2];
20873
+ var op3 = OPERATORS[ch3];
20874
+ if (op1 || op2 || op3) {
20875
+ var token = op3 ? ch3 : (op2 ? ch2 : ch);
20876
+ this.tokens.push({index: this.index, text: token, operator: true});
20877
+ this.index += token.length;
20776
20878
  } else {
20777
20879
  this.throwError('Unexpected next character ', this.index, this.index + 1);
20778
20880
  }
@@ -20781,8 +20883,8 @@ Lexer.prototype = {
20781
20883
  return this.tokens;
20782
20884
  },
20783
20885
 
20784
- is: function(chars) {
20785
- return chars.indexOf(this.ch) !== -1;
20886
+ is: function(ch, chars) {
20887
+ return chars.indexOf(ch) !== -1;
20786
20888
  },
20787
20889
 
20788
20890
  peek: function(i) {
@@ -20791,7 +20893,7 @@ Lexer.prototype = {
20791
20893
  },
20792
20894
 
20793
20895
  isNumber: function(ch) {
20794
- return ('0' <= ch && ch <= '9');
20896
+ return ('0' <= ch && ch <= '9') && typeof ch === "string";
20795
20897
  },
20796
20898
 
20797
20899
  isWhitespace: function(ch) {
@@ -20844,79 +20946,28 @@ Lexer.prototype = {
20844
20946
  }
20845
20947
  this.index++;
20846
20948
  }
20847
- number = 1 * number;
20848
20949
  this.tokens.push({
20849
20950
  index: start,
20850
20951
  text: number,
20851
20952
  constant: true,
20852
- fn: function() { return number; }
20953
+ value: Number(number)
20853
20954
  });
20854
20955
  },
20855
20956
 
20856
20957
  readIdent: function() {
20857
- var expression = this.text;
20858
-
20859
- var ident = '';
20860
20958
  var start = this.index;
20861
-
20862
- var lastDot, peekIndex, methodName, ch;
20863
-
20864
20959
  while (this.index < this.text.length) {
20865
- ch = this.text.charAt(this.index);
20866
- if (ch === '.' || this.isIdent(ch) || this.isNumber(ch)) {
20867
- if (ch === '.') lastDot = this.index;
20868
- ident += ch;
20869
- } else {
20960
+ var ch = this.text.charAt(this.index);
20961
+ if (!(this.isIdent(ch) || this.isNumber(ch))) {
20870
20962
  break;
20871
20963
  }
20872
20964
  this.index++;
20873
20965
  }
20874
-
20875
- //check if the identifier ends with . and if so move back one char
20876
- if (lastDot && ident[ident.length - 1] === '.') {
20877
- this.index--;
20878
- ident = ident.slice(0, -1);
20879
- lastDot = ident.lastIndexOf('.');
20880
- if (lastDot === -1) {
20881
- lastDot = undefined;
20882
- }
20883
- }
20884
-
20885
- //check if this is not a method invocation and if it is back out to last dot
20886
- if (lastDot) {
20887
- peekIndex = this.index;
20888
- while (peekIndex < this.text.length) {
20889
- ch = this.text.charAt(peekIndex);
20890
- if (ch === '(') {
20891
- methodName = ident.substr(lastDot - start + 1);
20892
- ident = ident.substr(0, lastDot - start);
20893
- this.index = peekIndex;
20894
- break;
20895
- }
20896
- if (this.isWhitespace(ch)) {
20897
- peekIndex++;
20898
- } else {
20899
- break;
20900
- }
20901
- }
20902
- }
20903
-
20904
20966
  this.tokens.push({
20905
20967
  index: start,
20906
- text: ident,
20907
- fn: CONSTANTS[ident] || getterFn(ident, this.options, expression)
20968
+ text: this.text.slice(start, this.index),
20969
+ identifier: true
20908
20970
  });
20909
-
20910
- if (methodName) {
20911
- this.tokens.push({
20912
- index: lastDot,
20913
- text: '.'
20914
- });
20915
- this.tokens.push({
20916
- index: lastDot + 1,
20917
- text: methodName
20918
- });
20919
- }
20920
20971
  },
20921
20972
 
20922
20973
  readString: function(quote) {
@@ -20947,9 +20998,8 @@ Lexer.prototype = {
20947
20998
  this.tokens.push({
20948
20999
  index: start,
20949
21000
  text: rawString,
20950
- string: string,
20951
21001
  constant: true,
20952
- fn: function() { return string; }
21002
+ value: string
20953
21003
  });
20954
21004
  return;
20955
21005
  } else {
@@ -21010,16 +21060,12 @@ Parser.prototype = {
21010
21060
  primary = this.arrayDeclaration();
21011
21061
  } else if (this.expect('{')) {
21012
21062
  primary = this.object();
21063
+ } else if (this.peek().identifier) {
21064
+ primary = this.identifier();
21065
+ } else if (this.peek().constant) {
21066
+ primary = this.constant();
21013
21067
  } else {
21014
- var token = this.expect();
21015
- primary = token.fn;
21016
- if (!primary) {
21017
- this.throwError('not a primary expression', token);
21018
- }
21019
- if (token.constant) {
21020
- primary.constant = true;
21021
- primary.literal = true;
21022
- }
21068
+ this.throwError('not a primary expression', this.peek());
21023
21069
  }
21024
21070
 
21025
21071
  var next, context;
@@ -21053,8 +21099,11 @@ Parser.prototype = {
21053
21099
  },
21054
21100
 
21055
21101
  peek: function(e1, e2, e3, e4) {
21056
- if (this.tokens.length > 0) {
21057
- var token = this.tokens[0];
21102
+ return this.peekAhead(0, e1, e2, e3, e4);
21103
+ },
21104
+ peekAhead: function(i, e1, e2, e3, e4) {
21105
+ if (this.tokens.length > i) {
21106
+ var token = this.tokens[i];
21058
21107
  var t = token.text;
21059
21108
  if (t === e1 || t === e2 || t === e3 || t === e4 ||
21060
21109
  (!e1 && !e2 && !e3 && !e4)) {
@@ -21074,12 +21123,19 @@ Parser.prototype = {
21074
21123
  },
21075
21124
 
21076
21125
  consume: function(e1) {
21077
- if (!this.expect(e1)) {
21126
+ if (this.tokens.length === 0) {
21127
+ throw $parseMinErr('ueoe', 'Unexpected end of expression: {0}', this.text);
21128
+ }
21129
+
21130
+ var token = this.expect(e1);
21131
+ if (!token) {
21078
21132
  this.throwError('is unexpected, expecting [' + e1 + ']', this.peek());
21079
21133
  }
21134
+ return token;
21080
21135
  },
21081
21136
 
21082
- unaryFn: function(fn, right) {
21137
+ unaryFn: function(op, right) {
21138
+ var fn = OPERATORS[op];
21083
21139
  return extend(function $parseUnaryFn(self, locals) {
21084
21140
  return fn(self, locals, right);
21085
21141
  }, {
@@ -21088,7 +21144,8 @@ Parser.prototype = {
21088
21144
  });
21089
21145
  },
21090
21146
 
21091
- binaryFn: function(left, fn, right, isBranching) {
21147
+ binaryFn: function(left, op, right, isBranching) {
21148
+ var fn = OPERATORS[op];
21092
21149
  return extend(function $parseBinaryFn(self, locals) {
21093
21150
  return fn(self, locals, left, right);
21094
21151
  }, {
@@ -21097,6 +21154,28 @@ Parser.prototype = {
21097
21154
  });
21098
21155
  },
21099
21156
 
21157
+ identifier: function() {
21158
+ var id = this.consume().text;
21159
+
21160
+ //Continue reading each `.identifier` unless it is a method invocation
21161
+ while (this.peek('.') && this.peekAhead(1).identifier && !this.peekAhead(2, '(')) {
21162
+ id += this.consume().text + this.consume().text;
21163
+ }
21164
+
21165
+ return CONSTANTS[id] || getterFn(id, this.options, this.text);
21166
+ },
21167
+
21168
+ constant: function() {
21169
+ var value = this.consume().value;
21170
+
21171
+ return extend(function $parseConstant() {
21172
+ return value;
21173
+ }, {
21174
+ constant: true,
21175
+ literal: true
21176
+ });
21177
+ },
21178
+
21100
21179
  statements: function() {
21101
21180
  var statements = [];
21102
21181
  while (true) {
@@ -21128,8 +21207,7 @@ Parser.prototype = {
21128
21207
  },
21129
21208
 
21130
21209
  filter: function(inputFn) {
21131
- var token = this.expect();
21132
- var fn = this.$filter(token.text);
21210
+ var fn = this.$filter(this.consume().text);
21133
21211
  var argsFn;
21134
21212
  var args;
21135
21213
 
@@ -21192,7 +21270,7 @@ Parser.prototype = {
21192
21270
  var token;
21193
21271
  if ((token = this.expect('?'))) {
21194
21272
  middle = this.assignment();
21195
- if ((token = this.expect(':'))) {
21273
+ if (this.consume(':')) {
21196
21274
  var right = this.assignment();
21197
21275
 
21198
21276
  return extend(function $parseTernary(self, locals) {
@@ -21200,9 +21278,6 @@ Parser.prototype = {
21200
21278
  }, {
21201
21279
  constant: left.constant && middle.constant && right.constant
21202
21280
  });
21203
-
21204
- } else {
21205
- this.throwError('expected :', token);
21206
21281
  }
21207
21282
  }
21208
21283
 
@@ -21213,7 +21288,7 @@ Parser.prototype = {
21213
21288
  var left = this.logicalAND();
21214
21289
  var token;
21215
21290
  while ((token = this.expect('||'))) {
21216
- left = this.binaryFn(left, token.fn, this.logicalAND(), true);
21291
+ left = this.binaryFn(left, token.text, this.logicalAND(), true);
21217
21292
  }
21218
21293
  return left;
21219
21294
  },
@@ -21222,7 +21297,7 @@ Parser.prototype = {
21222
21297
  var left = this.equality();
21223
21298
  var token;
21224
21299
  if ((token = this.expect('&&'))) {
21225
- left = this.binaryFn(left, token.fn, this.logicalAND(), true);
21300
+ left = this.binaryFn(left, token.text, this.logicalAND(), true);
21226
21301
  }
21227
21302
  return left;
21228
21303
  },
@@ -21231,7 +21306,7 @@ Parser.prototype = {
21231
21306
  var left = this.relational();
21232
21307
  var token;
21233
21308
  if ((token = this.expect('==','!=','===','!=='))) {
21234
- left = this.binaryFn(left, token.fn, this.equality());
21309
+ left = this.binaryFn(left, token.text, this.equality());
21235
21310
  }
21236
21311
  return left;
21237
21312
  },
@@ -21240,7 +21315,7 @@ Parser.prototype = {
21240
21315
  var left = this.additive();
21241
21316
  var token;
21242
21317
  if ((token = this.expect('<', '>', '<=', '>='))) {
21243
- left = this.binaryFn(left, token.fn, this.relational());
21318
+ left = this.binaryFn(left, token.text, this.relational());
21244
21319
  }
21245
21320
  return left;
21246
21321
  },
@@ -21249,7 +21324,7 @@ Parser.prototype = {
21249
21324
  var left = this.multiplicative();
21250
21325
  var token;
21251
21326
  while ((token = this.expect('+','-'))) {
21252
- left = this.binaryFn(left, token.fn, this.multiplicative());
21327
+ left = this.binaryFn(left, token.text, this.multiplicative());
21253
21328
  }
21254
21329
  return left;
21255
21330
  },
@@ -21258,7 +21333,7 @@ Parser.prototype = {
21258
21333
  var left = this.unary();
21259
21334
  var token;
21260
21335
  while ((token = this.expect('*','/','%'))) {
21261
- left = this.binaryFn(left, token.fn, this.unary());
21336
+ left = this.binaryFn(left, token.text, this.unary());
21262
21337
  }
21263
21338
  return left;
21264
21339
  },
@@ -21268,9 +21343,9 @@ Parser.prototype = {
21268
21343
  if (this.expect('+')) {
21269
21344
  return this.primary();
21270
21345
  } else if ((token = this.expect('-'))) {
21271
- return this.binaryFn(Parser.ZERO, token.fn, this.unary());
21346
+ return this.binaryFn(Parser.ZERO, token.text, this.unary());
21272
21347
  } else if ((token = this.expect('!'))) {
21273
- return this.unaryFn(token.fn, this.unary());
21348
+ return this.unaryFn(token.text, this.unary());
21274
21349
  } else {
21275
21350
  return this.primary();
21276
21351
  }
@@ -21278,7 +21353,7 @@ Parser.prototype = {
21278
21353
 
21279
21354
  fieldAccess: function(object) {
21280
21355
  var expression = this.text;
21281
- var field = this.expect().text;
21356
+ var field = this.consume().text;
21282
21357
  var getter = getterFn(field, this.options, expression);
21283
21358
 
21284
21359
  return extend(function $parseFieldAccess(scope, locals, self) {
@@ -21363,8 +21438,7 @@ Parser.prototype = {
21363
21438
  // Support trailing commas per ES5.1.
21364
21439
  break;
21365
21440
  }
21366
- var elementFn = this.expression();
21367
- elementFns.push(elementFn);
21441
+ elementFns.push(this.expression());
21368
21442
  } while (this.expect(','));
21369
21443
  }
21370
21444
  this.consume(']');
@@ -21390,11 +21464,16 @@ Parser.prototype = {
21390
21464
  // Support trailing commas per ES5.1.
21391
21465
  break;
21392
21466
  }
21393
- var token = this.expect();
21394
- keys.push(token.string || token.text);
21467
+ var token = this.consume();
21468
+ if (token.constant) {
21469
+ keys.push(token.value);
21470
+ } else if (token.identifier) {
21471
+ keys.push(token.text);
21472
+ } else {
21473
+ this.throwError("invalid key", token);
21474
+ }
21395
21475
  this.consume(':');
21396
- var value = this.expression();
21397
- valueFns.push(value);
21476
+ valueFns.push(this.expression());
21398
21477
  } while (this.expect(','));
21399
21478
  }
21400
21479
  this.consume('}');
@@ -21836,13 +21915,21 @@ function $ParseProvider() {
21836
21915
 
21837
21916
  function addInterceptor(parsedExpression, interceptorFn) {
21838
21917
  if (!interceptorFn) return parsedExpression;
21918
+ var watchDelegate = parsedExpression.$$watchDelegate;
21839
21919
 
21840
- var fn = function interceptedExpression(scope, locals) {
21920
+ var regularWatch =
21921
+ watchDelegate !== oneTimeLiteralWatchDelegate &&
21922
+ watchDelegate !== oneTimeWatchDelegate;
21923
+
21924
+ var fn = regularWatch ? function regularInterceptedExpression(scope, locals) {
21925
+ var value = parsedExpression(scope, locals);
21926
+ return interceptorFn(value, scope, locals);
21927
+ } : function oneTimeInterceptedExpression(scope, locals) {
21841
21928
  var value = parsedExpression(scope, locals);
21842
21929
  var result = interceptorFn(value, scope, locals);
21843
21930
  // we only return the interceptor's result if the
21844
21931
  // initial value is defined (for bind-once)
21845
- return isDefined(value) || interceptorFn.$stateful ? result : value;
21932
+ return isDefined(value) ? result : value;
21846
21933
  };
21847
21934
 
21848
21935
  // Propagate $$watchDelegates other then inputsWatchDelegate
@@ -21867,7 +21954,11 @@ function $ParseProvider() {
21867
21954
  * @requires $rootScope
21868
21955
  *
21869
21956
  * @description
21870
- * A promise/deferred implementation inspired by [Kris Kowal's Q](https://github.com/kriskowal/q).
21957
+ * A service that helps you run functions asynchronously, and use their return values (or exceptions)
21958
+ * when they are done processing.
21959
+ *
21960
+ * This is an implementation of promises/deferred objects inspired by
21961
+ * [Kris Kowal's Q](https://github.com/kriskowal/q).
21871
21962
  *
21872
21963
  * $q can be used in two fashions --- one which is more similar to Kris Kowal's Q or jQuery's Deferred
21873
21964
  * implementations, and the other which resembles ES6 promises to some degree.
@@ -22003,16 +22094,12 @@ function $ParseProvider() {
22003
22094
  *
22004
22095
  * - `catch(errorCallback)` – shorthand for `promise.then(null, errorCallback)`
22005
22096
  *
22006
- * - `finally(callback)` – allows you to observe either the fulfillment or rejection of a promise,
22097
+ * - `finally(callback, notifyCallback)` – allows you to observe either the fulfillment or rejection of a promise,
22007
22098
  * but to do so without modifying the final value. This is useful to release resources or do some
22008
22099
  * clean-up that needs to be done whether the promise was rejected or resolved. See the [full
22009
22100
  * specification](https://github.com/kriskowal/q/wiki/API-Reference#promisefinallycallback) for
22010
22101
  * more information.
22011
22102
  *
22012
- * Because `finally` is a reserved word in JavaScript and reserved keywords are not supported as
22013
- * property names by ES3, you'll need to invoke the method like `promise['finally'](callback)` to
22014
- * make your code IE8 and Android 2.x compatible.
22015
- *
22016
22103
  * # Chaining promises
22017
22104
  *
22018
22105
  * Because calling the `then` method of a promise returns a new derived promise, it is easily
@@ -23235,11 +23322,11 @@ function $RootScopeProvider() {
23235
23322
  if (ttl < 5) {
23236
23323
  logIdx = 4 - ttl;
23237
23324
  if (!watchLog[logIdx]) watchLog[logIdx] = [];
23238
- logMsg = (isFunction(watch.exp))
23239
- ? 'fn: ' + (watch.exp.name || watch.exp.toString())
23240
- : watch.exp;
23241
- logMsg += '; newVal: ' + toJson(value) + '; oldVal: ' + toJson(last);
23242
- watchLog[logIdx].push(logMsg);
23325
+ watchLog[logIdx].push({
23326
+ msg: isFunction(watch.exp) ? 'fn: ' + (watch.exp.name || watch.exp.toString()) : watch.exp,
23327
+ newVal: value,
23328
+ oldVal: last
23329
+ });
23243
23330
  }
23244
23331
  } else if (watch === lastDirtyWatch) {
23245
23332
  // If the most recently dirty watcher is now clean, short circuit since the remaining watchers
@@ -23272,7 +23359,7 @@ function $RootScopeProvider() {
23272
23359
  throw $rootScopeMinErr('infdig',
23273
23360
  '{0} $digest() iterations reached. Aborting!\n' +
23274
23361
  'Watchers fired in the last 5 iterations: {1}',
23275
- TTL, toJson(watchLog));
23362
+ TTL, watchLog);
23276
23363
  }
23277
23364
 
23278
23365
  } while (dirty || asyncQueue.length);
@@ -23623,7 +23710,7 @@ function $RootScopeProvider() {
23623
23710
  do {
23624
23711
  namedListeners = scope.$$listeners[name] || empty;
23625
23712
  event.currentScope = scope;
23626
- for (i=0, length=namedListeners.length; i<length; i++) {
23713
+ for (i = 0, length = namedListeners.length; i < length; i++) {
23627
23714
 
23628
23715
  // if listeners were deregistered, defragment the array
23629
23716
  if (!namedListeners[i]) {
@@ -23697,7 +23784,7 @@ function $RootScopeProvider() {
23697
23784
  while ((current = next)) {
23698
23785
  event.currentScope = current;
23699
23786
  listeners = current.$$listeners[name] || [];
23700
- for (i=0, length = listeners.length; i<length; i++) {
23787
+ for (i = 0, length = listeners.length; i < length; i++) {
23701
23788
  // if listeners were deregistered, defragment the array
23702
23789
  if (!listeners[i]) {
23703
23790
  listeners.splice(i, 1);
@@ -23853,7 +23940,7 @@ function $$SanitizeUriProvider() {
23853
23940
  var normalizedVal;
23854
23941
  normalizedVal = urlResolve(uri).href;
23855
23942
  if (normalizedVal !== '' && !normalizedVal.match(regex)) {
23856
- return 'unsafe:'+normalizedVal;
23943
+ return 'unsafe:' + normalizedVal;
23857
23944
  }
23858
23945
  return uri;
23859
23946
  };
@@ -24952,7 +25039,7 @@ function $SnifferProvider() {
24952
25039
  transitions = !!(('transition' in bodyStyle) || (vendorPrefix + 'Transition' in bodyStyle));
24953
25040
  animations = !!(('animation' in bodyStyle) || (vendorPrefix + 'Animation' in bodyStyle));
24954
25041
 
24955
- if (android && (!transitions||!animations)) {
25042
+ if (android && (!transitions || !animations)) {
24956
25043
  transitions = isString(document.body.style.webkitTransition);
24957
25044
  animations = isString(document.body.style.webkitAnimation);
24958
25045
  }
@@ -25023,7 +25110,7 @@ function $TemplateRequestProvider() {
25023
25110
  if (isArray(transformResponse)) {
25024
25111
  var original = transformResponse;
25025
25112
  transformResponse = [];
25026
- for (var i=0; i<original.length; ++i) {
25113
+ for (var i = 0; i < original.length; ++i) {
25027
25114
  var transformer = original[i];
25028
25115
  if (transformer !== defaultHttpResponseTransform) {
25029
25116
  transformResponse.push(transformer);
@@ -25267,7 +25354,7 @@ function $TimeoutProvider() {
25267
25354
  // exactly the behavior needed here. There is little value is mocking these out for this
25268
25355
  // service.
25269
25356
  var urlParsingNode = document.createElement("a");
25270
- var originUrl = urlResolve(window.location.href, true);
25357
+ var originUrl = urlResolve(window.location.href);
25271
25358
 
25272
25359
 
25273
25360
  /**
@@ -25322,7 +25409,7 @@ var originUrl = urlResolve(window.location.href, true);
25322
25409
  * | pathname | The pathname, beginning with "/"
25323
25410
  *
25324
25411
  */
25325
- function urlResolve(url, base) {
25412
+ function urlResolve(url) {
25326
25413
  var href = url;
25327
25414
 
25328
25415
  if (msie) {
@@ -25702,8 +25789,8 @@ function filterFilter() {
25702
25789
  }
25703
25790
  return false;
25704
25791
  }
25705
- text = (''+text).toLowerCase();
25706
- return (''+obj).toLowerCase().indexOf(text) > -1;
25792
+ text = ('' + text).toLowerCase();
25793
+ return ('' + obj).toLowerCase().indexOf(text) > -1;
25707
25794
  };
25708
25795
  }
25709
25796
  }
@@ -25787,7 +25874,7 @@ function filterFilter() {
25787
25874
  *
25788
25875
  * @param {number} amount Input to filter.
25789
25876
  * @param {string=} symbol Currency symbol or identifier to be displayed.
25790
- * @param {number=} fractionSize Number of decimal places to round the amount to.
25877
+ * @param {number=} fractionSize Number of decimal places to round the amount to, defaults to default max fraction size for current locale
25791
25878
  * @returns {string} Formatted number.
25792
25879
  *
25793
25880
  *
@@ -25837,8 +25924,7 @@ function currencyFilter($locale) {
25837
25924
  }
25838
25925
 
25839
25926
  if (isUndefined(fractionSize)) {
25840
- // TODO: read the default value from the locale file
25841
- fractionSize = 2;
25927
+ fractionSize = formats.PATTERNS[1].maxFrac;
25842
25928
  }
25843
25929
 
25844
25930
  // if null or undefined pass it through
@@ -25963,7 +26049,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
25963
26049
  if (whole.length >= (lgroup + group)) {
25964
26050
  pos = whole.length - lgroup;
25965
26051
  for (i = 0; i < pos; i++) {
25966
- if ((pos - i)%group === 0 && i !== 0) {
26052
+ if ((pos - i) % group === 0 && i !== 0) {
25967
26053
  formatedText += groupSep;
25968
26054
  }
25969
26055
  formatedText += whole.charAt(i);
@@ -25971,7 +26057,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
25971
26057
  }
25972
26058
 
25973
26059
  for (i = pos; i < whole.length; i++) {
25974
- if ((whole.length - i)%lgroup === 0 && i !== 0) {
26060
+ if ((whole.length - i) % lgroup === 0 && i !== 0) {
25975
26061
  formatedText += groupSep;
25976
26062
  }
25977
26063
  formatedText += whole.charAt(i);
@@ -25990,9 +26076,9 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
25990
26076
  }
25991
26077
  }
25992
26078
 
25993
- parts.push(isNegative ? pattern.negPre : pattern.posPre);
25994
- parts.push(formatedText);
25995
- parts.push(isNegative ? pattern.negSuf : pattern.posSuf);
26079
+ parts.push(isNegative ? pattern.negPre : pattern.posPre,
26080
+ formatedText,
26081
+ isNegative ? pattern.negSuf : pattern.posSuf);
25996
26082
  return parts.join('');
25997
26083
  }
25998
26084
 
@@ -26211,10 +26297,10 @@ function dateFilter($locale) {
26211
26297
  tzMin = int(match[9] + match[11]);
26212
26298
  }
26213
26299
  dateSetter.call(date, int(match[1]), int(match[2]) - 1, int(match[3]));
26214
- var h = int(match[4]||0) - tzHour;
26215
- var m = int(match[5]||0) - tzMin;
26216
- var s = int(match[6]||0);
26217
- var ms = Math.round(parseFloat('0.' + (match[7]||0)) * 1000);
26300
+ var h = int(match[4] || 0) - tzHour;
26301
+ var m = int(match[5] || 0) - tzMin;
26302
+ var s = int(match[6] || 0);
26303
+ var ms = Math.round(parseFloat('0.' + (match[7] || 0)) * 1000);
26218
26304
  timeSetter.call(date, h, m, s, ms);
26219
26305
  return date;
26220
26306
  }
@@ -26446,7 +26532,7 @@ function limitToFilter() {
26446
26532
  n = input.length;
26447
26533
  }
26448
26534
 
26449
- for (; i<n; i++) {
26535
+ for (; i < n; i++) {
26450
26536
  out.push(input[i]);
26451
26537
  }
26452
26538
 
@@ -26573,7 +26659,7 @@ orderByFilter.$inject = ['$parse'];
26573
26659
  function orderByFilter($parse) {
26574
26660
  return function(array, sortPredicate, reverseOrder) {
26575
26661
  if (!(isArrayLike(array))) return array;
26576
- sortPredicate = isArray(sortPredicate) ? sortPredicate: [sortPredicate];
26662
+ sortPredicate = isArray(sortPredicate) ? sortPredicate : [sortPredicate];
26577
26663
  if (sortPredicate.length === 0) { sortPredicate = ['+']; }
26578
26664
  sortPredicate = sortPredicate.map(function(predicate) {
26579
26665
  var descending = false, get = predicate || identity;
@@ -26600,9 +26686,7 @@ function orderByFilter($parse) {
26600
26686
  return compare(get(a),get(b));
26601
26687
  }, descending);
26602
26688
  });
26603
- var arrayCopy = [];
26604
- for (var i = 0; i < array.length; i++) { arrayCopy.push(array[i]); }
26605
- return arrayCopy.sort(reverseComparator(comparator, reverseOrder));
26689
+ return slice.call(array).sort(reverseComparator(comparator, reverseOrder));
26606
26690
 
26607
26691
  function comparator(o1, o2) {
26608
26692
  for (var i = 0; i < sortPredicate.length; i++) {
@@ -27574,9 +27658,7 @@ var formDirectiveFactory = function(isNgForm) {
27574
27658
  controller.$setSubmitted();
27575
27659
  });
27576
27660
 
27577
- event.preventDefault
27578
- ? event.preventDefault()
27579
- : event.returnValue = false; // IE
27661
+ event.preventDefault();
27580
27662
  };
27581
27663
 
27582
27664
  addEventListenerFn(formElement[0], 'submit', handleFormSubmission);
@@ -27663,10 +27745,16 @@ var inputType = {
27663
27745
  * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
27664
27746
  * minlength.
27665
27747
  * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
27666
- * maxlength.
27667
- * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the
27668
- * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
27669
- * patterns defined as scope expressions.
27748
+ * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
27749
+ * any length.
27750
+ * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
27751
+ * that contains the regular expression body that will be converted to a regular expression
27752
+ * as in the ngPattern directive.
27753
+ * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
27754
+ * a RegExp found by evaluating the Angular expression given in the attribute value.
27755
+ * If the expression evaluates to a RegExp object then this is used directly.
27756
+ * If the expression is a string then it will be converted to a RegExp after wrapping it in `^` and `$`
27757
+ * characters. For instance, `"abc"` will be converted to `new RegExp('^abc$')`.
27670
27758
  * @param {string=} ngChange Angular expression to be executed when input changes due to user
27671
27759
  * interaction with the input element.
27672
27760
  * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.
@@ -28206,10 +28294,16 @@ var inputType = {
28206
28294
  * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
28207
28295
  * minlength.
28208
28296
  * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
28209
- * maxlength.
28210
- * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the
28211
- * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
28212
- * patterns defined as scope expressions.
28297
+ * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
28298
+ * any length.
28299
+ * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
28300
+ * that contains the regular expression body that will be converted to a regular expression
28301
+ * as in the ngPattern directive.
28302
+ * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
28303
+ * a RegExp found by evaluating the Angular expression given in the attribute value.
28304
+ * If the expression evaluates to a RegExp object then this is used directly.
28305
+ * If the expression is a string then it will be converted to a RegExp after wrapping it in `^` and `$`
28306
+ * characters. For instance, `"abc"` will be converted to `new RegExp('^abc$')`.
28213
28307
  * @param {string=} ngChange Angular expression to be executed when input changes due to user
28214
28308
  * interaction with the input element.
28215
28309
  *
@@ -28288,10 +28382,16 @@ var inputType = {
28288
28382
  * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
28289
28383
  * minlength.
28290
28384
  * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
28291
- * maxlength.
28292
- * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the
28293
- * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
28294
- * patterns defined as scope expressions.
28385
+ * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
28386
+ * any length.
28387
+ * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
28388
+ * that contains the regular expression body that will be converted to a regular expression
28389
+ * as in the ngPattern directive.
28390
+ * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
28391
+ * a RegExp found by evaluating the Angular expression given in the attribute value.
28392
+ * If the expression evaluates to a RegExp object then this is used directly.
28393
+ * If the expression is a string then it will be converted to a RegExp after wrapping it in `^` and `$`
28394
+ * characters. For instance, `"abc"` will be converted to `new RegExp('^abc$')`.
28295
28395
  * @param {string=} ngChange Angular expression to be executed when input changes due to user
28296
28396
  * interaction with the input element.
28297
28397
  *
@@ -28371,10 +28471,16 @@ var inputType = {
28371
28471
  * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
28372
28472
  * minlength.
28373
28473
  * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
28374
- * maxlength.
28375
- * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the
28376
- * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
28377
- * patterns defined as scope expressions.
28474
+ * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
28475
+ * any length.
28476
+ * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
28477
+ * that contains the regular expression body that will be converted to a regular expression
28478
+ * as in the ngPattern directive.
28479
+ * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
28480
+ * a RegExp found by evaluating the Angular expression given in the attribute value.
28481
+ * If the expression evaluates to a RegExp object then this is used directly.
28482
+ * If the expression is a string then it will be converted to a RegExp after wrapping it in `^` and `$`
28483
+ * characters. For instance, `"abc"` will be converted to `new RegExp('^abc$')`.
28378
28484
  * @param {string=} ngChange Angular expression to be executed when input changes due to user
28379
28485
  * interaction with the input element.
28380
28486
  *
@@ -28637,7 +28743,7 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
28637
28743
  element.on('change', listener);
28638
28744
 
28639
28745
  ctrl.$render = function() {
28640
- element.val(ctrl.$isEmpty(ctrl.$modelValue) ? '' : ctrl.$viewValue);
28746
+ element.val(ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue);
28641
28747
  };
28642
28748
  }
28643
28749
 
@@ -28685,8 +28791,8 @@ function createDateParser(regexp, mapping) {
28685
28791
  // When a date is JSON'ified to wraps itself inside of an extra
28686
28792
  // set of double quotes. This makes the date parsing code unable
28687
28793
  // to match the date string and parse it as a date.
28688
- if (iso.charAt(0) == '"' && iso.charAt(iso.length-1) == '"') {
28689
- iso = iso.substring(1, iso.length-1);
28794
+ if (iso.charAt(0) == '"' && iso.charAt(iso.length - 1) == '"') {
28795
+ iso = iso.substring(1, iso.length - 1);
28690
28796
  }
28691
28797
  if (ISO_DATE_REGEXP.test(iso)) {
28692
28798
  return new Date(iso);
@@ -28747,10 +28853,10 @@ function createDateInputType(type, regexp, parseDate, format) {
28747
28853
  });
28748
28854
 
28749
28855
  ctrl.$formatters.push(function(value) {
28750
- if (!ctrl.$isEmpty(value)) {
28751
- if (!isDate(value)) {
28752
- throw $ngModelMinErr('datefmt', 'Expected `{0}` to be a date', value);
28753
- }
28856
+ if (value && !isDate(value)) {
28857
+ throw $ngModelMinErr('datefmt', 'Expected `{0}` to be a date', value);
28858
+ }
28859
+ if (isValidDate(value)) {
28754
28860
  previousDate = value;
28755
28861
  if (previousDate && timezone === 'UTC') {
28756
28862
  var timezoneOffset = 60000 * previousDate.getTimezoneOffset();
@@ -28759,14 +28865,14 @@ function createDateInputType(type, regexp, parseDate, format) {
28759
28865
  return $filter('date')(value, format, timezone);
28760
28866
  } else {
28761
28867
  previousDate = null;
28868
+ return '';
28762
28869
  }
28763
- return '';
28764
28870
  });
28765
28871
 
28766
28872
  if (isDefined(attr.min) || attr.ngMin) {
28767
28873
  var minVal;
28768
28874
  ctrl.$validators.min = function(value) {
28769
- return ctrl.$isEmpty(value) || isUndefined(minVal) || parseDate(value) >= minVal;
28875
+ return !isValidDate(value) || isUndefined(minVal) || parseDate(value) >= minVal;
28770
28876
  };
28771
28877
  attr.$observe('min', function(val) {
28772
28878
  minVal = parseObservedDateValue(val);
@@ -28777,18 +28883,18 @@ function createDateInputType(type, regexp, parseDate, format) {
28777
28883
  if (isDefined(attr.max) || attr.ngMax) {
28778
28884
  var maxVal;
28779
28885
  ctrl.$validators.max = function(value) {
28780
- return ctrl.$isEmpty(value) || isUndefined(maxVal) || parseDate(value) <= maxVal;
28886
+ return !isValidDate(value) || isUndefined(maxVal) || parseDate(value) <= maxVal;
28781
28887
  };
28782
28888
  attr.$observe('max', function(val) {
28783
28889
  maxVal = parseObservedDateValue(val);
28784
28890
  ctrl.$validate();
28785
28891
  });
28786
28892
  }
28787
- // Override the standard $isEmpty to detect invalid dates as well
28788
- ctrl.$isEmpty = function(value) {
28893
+
28894
+ function isValidDate(value) {
28789
28895
  // Invalid Date: getTime() returns NaN
28790
- return !value || (value.getTime && value.getTime() !== value.getTime());
28791
- };
28896
+ return value && !(value.getTime && value.getTime() !== value.getTime());
28897
+ }
28792
28898
 
28793
28899
  function parseObservedDateValue(val) {
28794
28900
  return isDefined(val) ? (isDate(val) ? val : parseDate(val)) : undefined;
@@ -28872,7 +28978,8 @@ function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) {
28872
28978
  stringBasedInputType(ctrl);
28873
28979
 
28874
28980
  ctrl.$$parserName = 'url';
28875
- ctrl.$validators.url = function(value) {
28981
+ ctrl.$validators.url = function(modelValue, viewValue) {
28982
+ var value = modelValue || viewValue;
28876
28983
  return ctrl.$isEmpty(value) || URL_REGEXP.test(value);
28877
28984
  };
28878
28985
  }
@@ -28884,7 +28991,8 @@ function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) {
28884
28991
  stringBasedInputType(ctrl);
28885
28992
 
28886
28993
  ctrl.$$parserName = 'email';
28887
- ctrl.$validators.email = function(value) {
28994
+ ctrl.$validators.email = function(modelValue, viewValue) {
28995
+ var value = modelValue || viewValue;
28888
28996
  return ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value);
28889
28997
  };
28890
28998
  }
@@ -28938,9 +29046,11 @@ function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filt
28938
29046
  element[0].checked = ctrl.$viewValue;
28939
29047
  };
28940
29048
 
28941
- // Override the standard `$isEmpty` because an empty checkbox is never equal to the trueValue
29049
+ // Override the standard `$isEmpty` because the $viewValue of an empty checkbox is always set to `false`
29050
+ // This is because of the parser below, which compares the `$modelValue` with `trueValue` to convert
29051
+ // it to a boolean.
28942
29052
  ctrl.$isEmpty = function(value) {
28943
- return value !== trueValue;
29053
+ return value === false;
28944
29054
  };
28945
29055
 
28946
29056
  ctrl.$formatters.push(function(value) {
@@ -28972,7 +29082,8 @@ function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filt
28972
29082
  * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
28973
29083
  * minlength.
28974
29084
  * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
28975
- * maxlength.
29085
+ * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any
29086
+ * length.
28976
29087
  * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the
28977
29088
  * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
28978
29089
  * patterns defined as scope expressions.
@@ -29004,7 +29115,8 @@ function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filt
29004
29115
  * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
29005
29116
  * minlength.
29006
29117
  * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
29007
- * maxlength.
29118
+ * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any
29119
+ * length.
29008
29120
  * @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the
29009
29121
  * RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
29010
29122
  * patterns defined as scope expressions.
@@ -29133,12 +29245,17 @@ var VALID_CLASS = 'ng-valid',
29133
29245
  * @property {string} $viewValue Actual string value in the view.
29134
29246
  * @property {*} $modelValue The value in the model that the control is bound to.
29135
29247
  * @property {Array.<Function>} $parsers Array of functions to execute, as a pipeline, whenever
29136
- the control reads value from the DOM. The functions are called in array order, each passing the value
29137
- through to the next. The last return value is forwarded to the $validators collection.
29138
- Used to sanitize / convert the value.
29139
- Returning undefined from a parser means a parse error occurred. No $validators will
29140
- run and the 'ngModel' will not be updated until the parse error is resolved. The parse error is stored
29141
- in 'ngModel.$error.parse'.
29248
+ the control reads value from the DOM. The functions are called in array order, each passing
29249
+ its return value through to the next. The last return value is forwarded to the
29250
+ {@link ngModel.NgModelController#$validators `$validators`} collection.
29251
+
29252
+ Parsers are used to sanitize / convert the {@link ngModel.NgModelController#$viewValue
29253
+ `$viewValue`}.
29254
+
29255
+ Returning `undefined` from a parser means a parse error occurred. In that case,
29256
+ no {@link ngModel.NgModelController#$validators `$validators`} will run and the `ngModel`
29257
+ will be set to `undefined` unless {@link ngModelOptions `ngModelOptions.allowInvalid`}
29258
+ is set to `true`. The parse error is stored in `ngModel.$error.parse`.
29142
29259
 
29143
29260
  *
29144
29261
  * @property {Array.<Function>} $formatters Array of functions to execute, as a pipeline, whenever
@@ -29215,13 +29332,18 @@ var VALID_CLASS = 'ng-valid',
29215
29332
  *
29216
29333
  * @description
29217
29334
  *
29218
- * `NgModelController` provides API for the `ng-model` directive. The controller contains
29219
- * services for data-binding, validation, CSS updates, and value formatting and parsing. It
29220
- * purposefully does not contain any logic which deals with DOM rendering or listening to
29221
- * DOM events. Such DOM related logic should be provided by other directives which make use of
29222
- * `NgModelController` for data-binding.
29335
+ * `NgModelController` provides API for the {@link ngModel `ngModel`} directive.
29336
+ * The controller contains services for data-binding, validation, CSS updates, and value formatting
29337
+ * and parsing. It purposefully does not contain any logic which deals with DOM rendering or
29338
+ * listening to DOM events.
29339
+ * Such DOM related logic should be provided by other directives which make use of
29340
+ * `NgModelController` for data-binding to control elements.
29341
+ * Angular provides this DOM logic for most {@link input `input`} elements.
29342
+ * At the end of this page you can find a {@link ngModel.NgModelController#custom-control-example
29343
+ * custom control example} that uses `ngModelController` to bind to `contenteditable` elements.
29223
29344
  *
29224
- * ## Custom Control Example
29345
+ * @example
29346
+ * ### Custom Control Example
29225
29347
  * This example shows how to use `NgModelController` with a custom control to achieve
29226
29348
  * data-binding. Notice how different directives (`contenteditable`, `ng-model`, and `required`)
29227
29349
  * collaborate together to achieve the desired result.
@@ -29263,7 +29385,7 @@ var VALID_CLASS = 'ng-valid',
29263
29385
 
29264
29386
  // Listen for change events to enable binding
29265
29387
  element.on('blur keyup change', function() {
29266
- scope.$apply(read);
29388
+ scope.$evalAsync(read);
29267
29389
  });
29268
29390
  read(); // initialize
29269
29391
 
@@ -29318,6 +29440,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29318
29440
  function($scope, $exceptionHandler, $attr, $element, $parse, $animate, $timeout, $rootScope, $q, $interpolate) {
29319
29441
  this.$viewValue = Number.NaN;
29320
29442
  this.$modelValue = Number.NaN;
29443
+ this.$$rawModelValue = undefined; // stores the parsed modelValue / model set from scope regardless of validity.
29321
29444
  this.$validators = {};
29322
29445
  this.$asyncValidators = {};
29323
29446
  this.$parsers = [];
@@ -29336,32 +29459,33 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29336
29459
 
29337
29460
 
29338
29461
  var parsedNgModel = $parse($attr.ngModel),
29462
+ parsedNgModelAssign = parsedNgModel.assign,
29463
+ ngModelGet = parsedNgModel,
29464
+ ngModelSet = parsedNgModelAssign,
29339
29465
  pendingDebounce = null,
29340
29466
  ctrl = this;
29341
29467
 
29342
- var ngModelGet = function ngModelGet() {
29343
- var modelValue = parsedNgModel($scope);
29344
- if (ctrl.$options && ctrl.$options.getterSetter && isFunction(modelValue)) {
29345
- modelValue = modelValue();
29346
- }
29347
- return modelValue;
29348
- };
29349
-
29350
- var ngModelSet = function ngModelSet(newValue) {
29351
- var getterSetter;
29352
- if (ctrl.$options && ctrl.$options.getterSetter &&
29353
- isFunction(getterSetter = parsedNgModel($scope))) {
29354
-
29355
- getterSetter(ctrl.$modelValue);
29356
- } else {
29357
- parsedNgModel.assign($scope, ctrl.$modelValue);
29358
- }
29359
- };
29360
-
29361
29468
  this.$$setOptions = function(options) {
29362
29469
  ctrl.$options = options;
29470
+ if (options && options.getterSetter) {
29471
+ var invokeModelGetter = $parse($attr.ngModel + '()'),
29472
+ invokeModelSetter = $parse($attr.ngModel + '($$$p)');
29363
29473
 
29364
- if (!parsedNgModel.assign && (!options || !options.getterSetter)) {
29474
+ ngModelGet = function($scope) {
29475
+ var modelValue = parsedNgModel($scope);
29476
+ if (isFunction(modelValue)) {
29477
+ modelValue = invokeModelGetter($scope);
29478
+ }
29479
+ return modelValue;
29480
+ };
29481
+ ngModelSet = function($scope, newValue) {
29482
+ if (isFunction(parsedNgModel($scope))) {
29483
+ invokeModelSetter($scope, {$$$p: ctrl.$modelValue});
29484
+ } else {
29485
+ parsedNgModelAssign($scope, ctrl.$modelValue);
29486
+ }
29487
+ };
29488
+ } else if (!parsedNgModel.assign) {
29365
29489
  throw $ngModelMinErr('nonassign', "Expression '{0}' is non-assignable. Element: {1}",
29366
29490
  $attr.ngModel, startingTag($element));
29367
29491
  }
@@ -29394,17 +29518,18 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29394
29518
  * @name ngModel.NgModelController#$isEmpty
29395
29519
  *
29396
29520
  * @description
29397
- * This is called when we need to determine if the value of the input is empty.
29521
+ * This is called when we need to determine if the value of an input is empty.
29398
29522
  *
29399
29523
  * For instance, the required directive does this to work out if the input has data or not.
29524
+ *
29400
29525
  * The default `$isEmpty` function checks whether the value is `undefined`, `''`, `null` or `NaN`.
29401
29526
  *
29402
29527
  * You can override this for input directives whose concept of being empty is different to the
29403
29528
  * default. The `checkboxInputType` directive does this because in its case a value of `false`
29404
29529
  * implies empty.
29405
29530
  *
29406
- * @param {*} value Model value to check.
29407
- * @returns {boolean} True if `value` is empty.
29531
+ * @param {*} value The value of the input to check for emptiness.
29532
+ * @returns {boolean} True if `value` is "empty".
29408
29533
  */
29409
29534
  this.$isEmpty = function(value) {
29410
29535
  return isUndefined(value) || value === '' || value === null || value !== value;
@@ -29455,9 +29580,9 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29455
29580
  * @description
29456
29581
  * Sets the control to its pristine state.
29457
29582
  *
29458
- * This method can be called to remove the 'ng-dirty' class and set the control to its pristine
29459
- * state (ng-pristine class). A model is considered to be pristine when the model has not been changed
29460
- * from when first compiled within then form.
29583
+ * This method can be called to remove the `ng-dirty` class and set the control to its pristine
29584
+ * state (`ng-pristine` class). A model is considered to be pristine when the control
29585
+ * has not been changed from when first compiled.
29461
29586
  */
29462
29587
  this.$setPristine = function() {
29463
29588
  ctrl.$dirty = false;
@@ -29466,6 +29591,25 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29466
29591
  $animate.addClass($element, PRISTINE_CLASS);
29467
29592
  };
29468
29593
 
29594
+ /**
29595
+ * @ngdoc method
29596
+ * @name ngModel.NgModelController#$setDirty
29597
+ *
29598
+ * @description
29599
+ * Sets the control to its dirty state.
29600
+ *
29601
+ * This method can be called to remove the `ng-pristine` class and set the control to its dirty
29602
+ * state (`ng-dirty` class). A model is considered to be dirty when the control has been changed
29603
+ * from when first compiled.
29604
+ */
29605
+ this.$setDirty = function() {
29606
+ ctrl.$dirty = true;
29607
+ ctrl.$pristine = false;
29608
+ $animate.removeClass($element, PRISTINE_CLASS);
29609
+ $animate.addClass($element, DIRTY_CLASS);
29610
+ parentForm.$setDirty();
29611
+ };
29612
+
29469
29613
  /**
29470
29614
  * @ngdoc method
29471
29615
  * @name ngModel.NgModelController#$setUntouched
@@ -29473,8 +29617,8 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29473
29617
  * @description
29474
29618
  * Sets the control to its untouched state.
29475
29619
  *
29476
- * This method can be called to remove the 'ng-touched' class and set the control to its
29477
- * untouched state (ng-untouched class). Upon compilation, a model is set as untouched
29620
+ * This method can be called to remove the `ng-touched` class and set the control to its
29621
+ * untouched state (`ng-untouched` class). Upon compilation, a model is set as untouched
29478
29622
  * by default, however this function can be used to restore that state if the model has
29479
29623
  * already been touched by the user.
29480
29624
  */
@@ -29491,10 +29635,9 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29491
29635
  * @description
29492
29636
  * Sets the control to its touched state.
29493
29637
  *
29494
- * This method can be called to remove the 'ng-untouched' class and set the control to its
29495
- * touched state (ng-touched class). A model is considered to be touched when the user has
29496
- * first interacted (focussed) on the model input element and then shifted focus away (blurred)
29497
- * from the input element.
29638
+ * This method can be called to remove the `ng-untouched` class and set the control to its
29639
+ * touched state (`ng-touched` class). A model is considered to be touched when the user has
29640
+ * first focused the control element and then shifted focus away from the control (blur event).
29498
29641
  */
29499
29642
  this.$setTouched = function() {
29500
29643
  ctrl.$touched = true;
@@ -29572,14 +29715,51 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29572
29715
  * @name ngModel.NgModelController#$validate
29573
29716
  *
29574
29717
  * @description
29575
- * Runs each of the registered validators (first synchronous validators and then asynchronous validators).
29718
+ * Runs each of the registered validators (first synchronous validators and then
29719
+ * asynchronous validators).
29720
+ * If the validity changes to invalid, the model will be set to `undefined`,
29721
+ * unless {@link ngModelOptions `ngModelOptions.allowInvalid`} is `true`.
29722
+ * If the validity changes to valid, it will set the model to the last available valid
29723
+ * modelValue, i.e. either the last parsed value or the last value set from the scope.
29576
29724
  */
29577
29725
  this.$validate = function() {
29578
29726
  // ignore $validate before model is initialized
29579
29727
  if (isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue)) {
29580
29728
  return;
29581
29729
  }
29582
- this.$$parseAndValidate();
29730
+
29731
+ var viewValue = ctrl.$$lastCommittedViewValue;
29732
+ // Note: we use the $$rawModelValue as $modelValue might have been
29733
+ // set to undefined during a view -> model update that found validation
29734
+ // errors. We can't parse the view here, since that could change
29735
+ // the model although neither viewValue nor the model on the scope changed
29736
+ var modelValue = ctrl.$$rawModelValue;
29737
+
29738
+ // Check if the there's a parse error, so we don't unset it accidentially
29739
+ var parserName = ctrl.$$parserName || 'parse';
29740
+ var parserValid = ctrl.$error[parserName] ? false : undefined;
29741
+
29742
+ var prevValid = ctrl.$valid;
29743
+ var prevModelValue = ctrl.$modelValue;
29744
+
29745
+ var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid;
29746
+
29747
+ ctrl.$$runValidators(parserValid, modelValue, viewValue, function(allValid) {
29748
+ // If there was no change in validity, don't update the model
29749
+ // This prevents changing an invalid modelValue to undefined
29750
+ if (!allowInvalid && prevValid !== allValid) {
29751
+ // Note: Don't check ctrl.$valid here, as we could have
29752
+ // external validators (e.g. calculated on the server),
29753
+ // that just call $setValidity and need the model value
29754
+ // to calculate their validity.
29755
+ ctrl.$modelValue = allValid ? modelValue : undefined;
29756
+
29757
+ if (ctrl.$modelValue !== prevModelValue) {
29758
+ ctrl.$$writeModelToScope();
29759
+ }
29760
+ }
29761
+ });
29762
+
29583
29763
  };
29584
29764
 
29585
29765
  this.$$runValidators = function(parseValid, modelValue, viewValue, doneCallback) {
@@ -29698,11 +29878,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29698
29878
 
29699
29879
  // change to dirty
29700
29880
  if (ctrl.$pristine) {
29701
- ctrl.$dirty = true;
29702
- ctrl.$pristine = false;
29703
- $animate.removeClass($element, PRISTINE_CLASS);
29704
- $animate.addClass($element, DIRTY_CLASS);
29705
- parentForm.$setDirty();
29881
+ this.$setDirty();
29706
29882
  }
29707
29883
  this.$$parseAndValidate();
29708
29884
  };
@@ -29723,10 +29899,11 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29723
29899
  }
29724
29900
  if (isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue)) {
29725
29901
  // ctrl.$modelValue has not been touched yet...
29726
- ctrl.$modelValue = ngModelGet();
29902
+ ctrl.$modelValue = ngModelGet($scope);
29727
29903
  }
29728
29904
  var prevModelValue = ctrl.$modelValue;
29729
29905
  var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid;
29906
+ ctrl.$$rawModelValue = modelValue;
29730
29907
  if (allowInvalid) {
29731
29908
  ctrl.$modelValue = modelValue;
29732
29909
  writeToModelIfNeeded();
@@ -29750,7 +29927,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29750
29927
  };
29751
29928
 
29752
29929
  this.$$writeModelToScope = function() {
29753
- ngModelSet(ctrl.$modelValue);
29930
+ ngModelSet($scope, ctrl.$modelValue);
29754
29931
  forEach(ctrl.$viewChangeListeners, function(listener) {
29755
29932
  try {
29756
29933
  listener();
@@ -29846,12 +30023,12 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29846
30023
  // ng-change executes in apply phase
29847
30024
  // 4. view should be changed back to 'a'
29848
30025
  $scope.$watch(function ngModelWatch() {
29849
- var modelValue = ngModelGet();
30026
+ var modelValue = ngModelGet($scope);
29850
30027
 
29851
30028
  // if scope model value and ngModel value are out of sync
29852
30029
  // TODO(perf): why not move this to the action fn?
29853
30030
  if (modelValue !== ctrl.$modelValue) {
29854
- ctrl.$modelValue = modelValue;
30031
+ ctrl.$modelValue = ctrl.$$rawModelValue = modelValue;
29855
30032
 
29856
30033
  var formatters = ctrl.$formatters,
29857
30034
  idx = formatters.length;
@@ -30036,7 +30213,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
30036
30213
  </file>
30037
30214
  * </example>
30038
30215
  */
30039
- var ngModelDirective = function() {
30216
+ var ngModelDirective = ['$rootScope', function($rootScope) {
30040
30217
  return {
30041
30218
  restrict: 'A',
30042
30219
  require: ['ngModel', '^?form', '^?ngModelOptions'],
@@ -30080,15 +30257,17 @@ var ngModelDirective = function() {
30080
30257
  element.on('blur', function(ev) {
30081
30258
  if (modelCtrl.$touched) return;
30082
30259
 
30083
- scope.$apply(function() {
30084
- modelCtrl.$setTouched();
30085
- });
30260
+ if ($rootScope.$$phase) {
30261
+ scope.$evalAsync(modelCtrl.$setTouched);
30262
+ } else {
30263
+ scope.$apply(modelCtrl.$setTouched);
30264
+ }
30086
30265
  });
30087
30266
  }
30088
30267
  };
30089
30268
  }
30090
30269
  };
30091
- };
30270
+ }];
30092
30271
 
30093
30272
 
30094
30273
  /**
@@ -30177,8 +30356,8 @@ var requiredDirective = function() {
30177
30356
  if (!ctrl) return;
30178
30357
  attr.required = true; // force truthy in case we are on non input element
30179
30358
 
30180
- ctrl.$validators.required = function(value) {
30181
- return !attr.required || !ctrl.$isEmpty(value);
30359
+ ctrl.$validators.required = function(modelValue, viewValue) {
30360
+ return !attr.required || !ctrl.$isEmpty(viewValue);
30182
30361
  };
30183
30362
 
30184
30363
  attr.$observe('required', function() {
@@ -30199,7 +30378,7 @@ var patternDirective = function() {
30199
30378
  var regexp, patternExp = attr.ngPattern || attr.pattern;
30200
30379
  attr.$observe('pattern', function(regex) {
30201
30380
  if (isString(regex) && regex.length > 0) {
30202
- regex = new RegExp(regex);
30381
+ regex = new RegExp('^' + regex + '$');
30203
30382
  }
30204
30383
 
30205
30384
  if (regex && !regex.test) {
@@ -30227,13 +30406,14 @@ var maxlengthDirective = function() {
30227
30406
  link: function(scope, elm, attr, ctrl) {
30228
30407
  if (!ctrl) return;
30229
30408
 
30230
- var maxlength = 0;
30409
+ var maxlength = -1;
30231
30410
  attr.$observe('maxlength', function(value) {
30232
- maxlength = int(value) || 0;
30411
+ var intVal = int(value);
30412
+ maxlength = isNaN(intVal) ? -1 : intVal;
30233
30413
  ctrl.$validate();
30234
30414
  });
30235
30415
  ctrl.$validators.maxlength = function(modelValue, viewValue) {
30236
- return ctrl.$isEmpty(modelValue) || viewValue.length <= maxlength;
30416
+ return (maxlength < 0) || ctrl.$isEmpty(modelValue) || (viewValue.length <= maxlength);
30237
30417
  };
30238
30418
  }
30239
30419
  };
@@ -30252,7 +30432,7 @@ var minlengthDirective = function() {
30252
30432
  ctrl.$validate();
30253
30433
  });
30254
30434
  ctrl.$validators.minlength = function(modelValue, viewValue) {
30255
- return ctrl.$isEmpty(modelValue) || viewValue.length >= minlength;
30435
+ return ctrl.$isEmpty(viewValue) || viewValue.length >= minlength;
30256
30436
  };
30257
30437
  }
30258
30438
  };
@@ -30490,7 +30670,7 @@ var ngValueDirective = function() {
30490
30670
  * `ngModelOptions` has an effect on the element it's declared on and its descendants.
30491
30671
  *
30492
30672
  * @param {Object} ngModelOptions options to apply to the current model. Valid keys are:
30493
- * - `updateOn`: string specifying which event should be the input bound to. You can set several
30673
+ * - `updateOn`: string specifying which event should the input be bound to. You can set several
30494
30674
  * events using an space delimited list. There is a special event called `default` that
30495
30675
  * matches the default events belonging of the control.
30496
30676
  * - `debounce`: integer value which contains the debounce model update value in milliseconds. A
@@ -30880,12 +31060,11 @@ var ngBindTemplateDirective = ['$interpolate', '$compile', function($interpolate
30880
31060
  * @name ngBindHtml
30881
31061
  *
30882
31062
  * @description
30883
- * Creates a binding that will innerHTML the result of evaluating the `expression` into the current
30884
- * element in a secure way. By default, the innerHTML-ed content will be sanitized using the {@link
30885
- * ngSanitize.$sanitize $sanitize} service. To utilize this functionality, ensure that `$sanitize`
30886
- * is available, for example, by including {@link ngSanitize} in your module's dependencies (not in
30887
- * core Angular). In order to use {@link ngSanitize} in your module's dependencies, you need to
30888
- * include "angular-sanitize.js" in your application.
31063
+ * Evaluates the expression and inserts the resulting HTML into the element in a secure way. By default,
31064
+ * the resulting HTML content will be sanitized using the {@link ngSanitize.$sanitize $sanitize} service.
31065
+ * To utilize this functionality, ensure that `$sanitize` is available, for example, by including {@link
31066
+ * ngSanitize} in your module's dependencies (not in core Angular). In order to use {@link ngSanitize}
31067
+ * in your module's dependencies, you need to include "angular-sanitize.js" in your application.
30889
31068
  *
30890
31069
  * You may also bypass sanitization for values you know are safe. To do so, bind to
30891
31070
  * an explicitly trusted value via {@link ng.$sce#trustAsHtml $sce.trustAsHtml}. See the example
@@ -32949,7 +33128,9 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
32949
33128
  </example>
32950
33129
  */
32951
33130
  var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interpolate) {
32952
- var BRACE = /{}/g;
33131
+ var BRACE = /{}/g,
33132
+ IS_WHEN = /^when(Minus)?(.+)$/;
33133
+
32953
33134
  return {
32954
33135
  restrict: 'EA',
32955
33136
  link: function(scope, element, attr) {
@@ -32960,34 +33141,44 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
32960
33141
  whensExpFns = {},
32961
33142
  startSymbol = $interpolate.startSymbol(),
32962
33143
  endSymbol = $interpolate.endSymbol(),
32963
- isWhen = /^when(Minus)?(.+)$/;
33144
+ braceReplacement = startSymbol + numberExp + '-' + offset + endSymbol,
33145
+ watchRemover = angular.noop,
33146
+ lastCount;
32964
33147
 
32965
33148
  forEach(attr, function(expression, attributeName) {
32966
- if (isWhen.test(attributeName)) {
32967
- whens[lowercase(attributeName.replace('when', '').replace('Minus', '-'))] =
32968
- element.attr(attr.$attr[attributeName]);
33149
+ var tmpMatch = IS_WHEN.exec(attributeName);
33150
+ if (tmpMatch) {
33151
+ var whenKey = (tmpMatch[1] ? '-' : '') + lowercase(tmpMatch[2]);
33152
+ whens[whenKey] = element.attr(attr.$attr[attributeName]);
32969
33153
  }
32970
33154
  });
32971
33155
  forEach(whens, function(expression, key) {
32972
- whensExpFns[key] =
32973
- $interpolate(expression.replace(BRACE, startSymbol + numberExp + '-' +
32974
- offset + endSymbol));
33156
+ whensExpFns[key] = $interpolate(expression.replace(BRACE, braceReplacement));
33157
+
32975
33158
  });
32976
33159
 
32977
- scope.$watch(function ngPluralizeWatch() {
32978
- var value = parseFloat(scope.$eval(numberExp));
33160
+ scope.$watch(numberExp, function ngPluralizeWatchAction(newVal) {
33161
+ var count = parseFloat(newVal);
33162
+ var countIsNaN = isNaN(count);
32979
33163
 
32980
- if (!isNaN(value)) {
32981
- //if explicit number rule such as 1, 2, 3... is defined, just use it. Otherwise,
32982
- //check it against pluralization rules in $locale service
32983
- if (!(value in whens)) value = $locale.pluralCat(value - offset);
32984
- return whensExpFns[value](scope);
32985
- } else {
32986
- return '';
33164
+ if (!countIsNaN && !(count in whens)) {
33165
+ // If an explicit number rule such as 1, 2, 3... is defined, just use it.
33166
+ // Otherwise, check it against pluralization rules in $locale service.
33167
+ count = $locale.pluralCat(count - offset);
33168
+ }
33169
+
33170
+ // If both `count` and `lastCount` are NaN, we don't need to re-register a watch.
33171
+ // In JS `NaN !== NaN`, so we have to exlicitly check.
33172
+ if ((count !== lastCount) && !(countIsNaN && isNaN(lastCount))) {
33173
+ watchRemover();
33174
+ watchRemover = scope.$watch(whensExpFns[count], updateElementText);
33175
+ lastCount = count;
32987
33176
  }
32988
- }, function ngPluralizeWatchAction(newVal) {
32989
- element.text(newVal);
32990
33177
  });
33178
+
33179
+ function updateElementText(newText) {
33180
+ element.text(newText || '');
33181
+ }
32991
33182
  }
32992
33183
  };
32993
33184
  }];
@@ -33358,7 +33549,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
33358
33549
  });
33359
33550
  throw ngRepeatMinErr('dupes',
33360
33551
  "Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}, Duplicate value: {2}",
33361
- expression, trackById, toJson(value));
33552
+ expression, trackById, value);
33362
33553
  } else {
33363
33554
  // new never before seen block
33364
33555
  nextBlockOrder[index] = {id: trackById, scope: undefined, clone: undefined};
@@ -33469,17 +33660,17 @@ var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';
33469
33660
  *
33470
33661
  * ### Overriding `.ng-hide`
33471
33662
  *
33472
- * By default, the `.ng-hide` class will style the element with `display:none!important`. If you wish to change
33663
+ * By default, the `.ng-hide` class will style the element with `display: none!important`. If you wish to change
33473
33664
  * the hide behavior with ngShow/ngHide then this can be achieved by restating the styles for the `.ng-hide`
33474
33665
  * class in CSS:
33475
33666
  *
33476
33667
  * ```css
33477
33668
  * .ng-hide {
33478
33669
  * /&#42; this is just another form of hiding an element &#42;/
33479
- * display:block!important;
33480
- * position:absolute;
33481
- * top:-9999px;
33482
- * left:-9999px;
33670
+ * display: block!important;
33671
+ * position: absolute;
33672
+ * top: -9999px;
33673
+ * left: -9999px;
33483
33674
  * }
33484
33675
  * ```
33485
33676
  *
@@ -33499,13 +33690,13 @@ var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';
33499
33690
  * .my-element.ng-hide-add, .my-element.ng-hide-remove {
33500
33691
  * /&#42; this is required as of 1.3x to properly
33501
33692
  * apply all styling in a show/hide animation &#42;/
33502
- * transition:0s linear all;
33693
+ * transition: 0s linear all;
33503
33694
  * }
33504
33695
  *
33505
33696
  * .my-element.ng-hide-add-active,
33506
33697
  * .my-element.ng-hide-remove-active {
33507
33698
  * /&#42; the transition is defined in the active class &#42;/
33508
- * transition:1s linear all;
33699
+ * transition: 1s linear all;
33509
33700
  * }
33510
33701
  *
33511
33702
  * .my-element.ng-hide-add { ... }
@@ -33547,29 +33738,29 @@ var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';
33547
33738
  </file>
33548
33739
  <file name="animations.css">
33549
33740
  .animate-show {
33550
- line-height:20px;
33551
- opacity:1;
33552
- padding:10px;
33553
- border:1px solid black;
33554
- background:white;
33741
+ line-height: 20px;
33742
+ opacity: 1;
33743
+ padding: 10px;
33744
+ border: 1px solid black;
33745
+ background: white;
33555
33746
  }
33556
33747
 
33557
33748
  .animate-show.ng-hide-add.ng-hide-add-active,
33558
33749
  .animate-show.ng-hide-remove.ng-hide-remove-active {
33559
- -webkit-transition:all linear 0.5s;
33560
- transition:all linear 0.5s;
33750
+ -webkit-transition: all linear 0.5s;
33751
+ transition: all linear 0.5s;
33561
33752
  }
33562
33753
 
33563
33754
  .animate-show.ng-hide {
33564
- line-height:0;
33565
- opacity:0;
33566
- padding:0 10px;
33755
+ line-height: 0;
33756
+ opacity: 0;
33757
+ padding: 0 10px;
33567
33758
  }
33568
33759
 
33569
33760
  .check-element {
33570
- padding:10px;
33571
- border:1px solid black;
33572
- background:white;
33761
+ padding: 10px;
33762
+ border: 1px solid black;
33763
+ background: white;
33573
33764
  }
33574
33765
  </file>
33575
33766
  <file name="protractor.js" type="protractor">
@@ -33643,17 +33834,17 @@ var ngShowDirective = ['$animate', function($animate) {
33643
33834
  *
33644
33835
  * ### Overriding `.ng-hide`
33645
33836
  *
33646
- * By default, the `.ng-hide` class will style the element with `display:none!important`. If you wish to change
33837
+ * By default, the `.ng-hide` class will style the element with `display: none!important`. If you wish to change
33647
33838
  * the hide behavior with ngShow/ngHide then this can be achieved by restating the styles for the `.ng-hide`
33648
33839
  * class in CSS:
33649
33840
  *
33650
33841
  * ```css
33651
33842
  * .ng-hide {
33652
33843
  * /&#42; this is just another form of hiding an element &#42;/
33653
- * display:block!important;
33654
- * position:absolute;
33655
- * top:-9999px;
33656
- * left:-9999px;
33844
+ * display: block!important;
33845
+ * position: absolute;
33846
+ * top: -9999px;
33847
+ * left: -9999px;
33657
33848
  * }
33658
33849
  * ```
33659
33850
  *
@@ -33670,7 +33861,7 @@ var ngShowDirective = ['$animate', function($animate) {
33670
33861
  * //a working example can be found at the bottom of this page
33671
33862
  * //
33672
33863
  * .my-element.ng-hide-add, .my-element.ng-hide-remove {
33673
- * transition:0.5s linear all;
33864
+ * transition: 0.5s linear all;
33674
33865
  * }
33675
33866
  *
33676
33867
  * .my-element.ng-hide-add { ... }
@@ -33712,25 +33903,25 @@ var ngShowDirective = ['$animate', function($animate) {
33712
33903
  </file>
33713
33904
  <file name="animations.css">
33714
33905
  .animate-hide {
33715
- -webkit-transition:all linear 0.5s;
33716
- transition:all linear 0.5s;
33717
- line-height:20px;
33718
- opacity:1;
33719
- padding:10px;
33720
- border:1px solid black;
33721
- background:white;
33906
+ -webkit-transition: all linear 0.5s;
33907
+ transition: all linear 0.5s;
33908
+ line-height: 20px;
33909
+ opacity: 1;
33910
+ padding: 10px;
33911
+ border: 1px solid black;
33912
+ background: white;
33722
33913
  }
33723
33914
 
33724
33915
  .animate-hide.ng-hide {
33725
- line-height:0;
33726
- opacity:0;
33727
- padding:0 10px;
33916
+ line-height: 0;
33917
+ opacity: 0;
33918
+ padding: 0 10px;
33728
33919
  }
33729
33920
 
33730
33921
  .check-element {
33731
- padding:10px;
33732
- border:1px solid black;
33733
- background:white;
33922
+ padding: 10px;
33923
+ border: 1px solid black;
33924
+ background: white;
33734
33925
  }
33735
33926
  </file>
33736
33927
  <file name="protractor.js" type="protractor">
@@ -34164,7 +34355,7 @@ var ngOptionsMinErr = minErr('ngOptions');
34164
34355
  * In many cases, `ngRepeat` can be used on `<option>` elements instead of `ngOptions` to achieve a
34165
34356
  * similar result. However, the `ngOptions` provides some benefits such as reducing memory and
34166
34357
  * increasing speed by not creating a new scope for each repeated instance, as well as providing
34167
- * more flexibility in how the `select`'s model is assigned via `select as`. `ngOptions should be
34358
+ * more flexibility in how the `select`'s model is assigned via `select as`. `ngOptions` should be
34168
34359
  * used when the `select` model needs to be bound to a non-string value. This is because an option
34169
34360
  * element can only be bound to string values at present.
34170
34361
  *
@@ -34762,13 +34953,14 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
34762
34953
  lastElement = null; // start at the beginning
34763
34954
  for (index = 0, length = optionGroup.length; index < length; index++) {
34764
34955
  option = optionGroup[index];
34765
- if ((existingOption = existingOptions[index+1])) {
34956
+ if ((existingOption = existingOptions[index + 1])) {
34766
34957
  // reuse elements
34767
34958
  lastElement = existingOption.element;
34768
34959
  if (existingOption.label !== option.label) {
34769
34960
  updateLabelMap(labelMap, existingOption.label, false);
34770
34961
  updateLabelMap(labelMap, option.label, true);
34771
34962
  lastElement.text(existingOption.label = option.label);
34963
+ lastElement.prop('label', existingOption.label);
34772
34964
  }
34773
34965
  if (existingOption.id !== option.id) {
34774
34966
  lastElement.val(existingOption.id = option.id);
@@ -34798,6 +34990,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
34798
34990
  .val(option.id)
34799
34991
  .prop('selected', option.selected)
34800
34992
  .attr('selected', option.selected)
34993
+ .prop('label', option.label)
34801
34994
  .text(option.label);
34802
34995
  }
34803
34996
 
@@ -35109,10 +35302,10 @@ function callerFile(offset) {
35109
35302
  if (line) {
35110
35303
  if (line.indexOf('@') !== -1) {
35111
35304
  // Firefox
35112
- line = line.substring(line.indexOf('@')+1);
35305
+ line = line.substring(line.indexOf('@') + 1);
35113
35306
  } else {
35114
35307
  // Chrome
35115
- line = line.substring(line.indexOf('(')+1).replace(')', '');
35308
+ line = line.substring(line.indexOf('(') + 1).replace(')', '');
35116
35309
  }
35117
35310
  }
35118
35311
 
@@ -35196,7 +35389,7 @@ _jQuery.fn.bindings = function(windowJquery, bindExp) {
35196
35389
  var element = windowJquery(this),
35197
35390
  bindings;
35198
35391
  if (bindings = element.data('$binding')) {
35199
- for (var expressions = [], binding, j=0, jj=bindings.length; j<jj; j++) {
35392
+ for (var expressions = [], binding, j=0, jj=bindings.length; j < jj; j++) {
35200
35393
  binding = bindings[j];
35201
35394
 
35202
35395
  if (binding.expressions) {
@@ -35572,7 +35765,7 @@ angular.scenario.Describe.prototype.it = function(name, body) {
35572
35765
  */
35573
35766
  angular.scenario.Describe.prototype.iit = function(name, body) {
35574
35767
  this.it.apply(this, arguments);
35575
- this.its[this.its.length-1].only = true;
35768
+ this.its[this.its.length - 1].only = true;
35576
35769
  };
35577
35770
 
35578
35771
  /**
@@ -35884,7 +36077,7 @@ angular.scenario.ObjectModel.Spec.prototype.addStep = function(name) {
35884
36077
  * @return {Object} the step
35885
36078
  */
35886
36079
  angular.scenario.ObjectModel.Spec.prototype.getLastStep = function() {
35887
- return this.steps[this.steps.length-1];
36080
+ return this.steps[this.steps.length - 1];
35888
36081
  };
35889
36082
 
35890
36083
  /**
@@ -36459,7 +36652,7 @@ angular.scenario.dsl('expect', function() {
36459
36652
  */
36460
36653
  angular.scenario.dsl('using', function() {
36461
36654
  return function(selector, label) {
36462
- this.selector = _jQuery.trim((this.selector||'') + ' ' + selector);
36655
+ this.selector = _jQuery.trim((this.selector || '') + ' ' + selector);
36463
36656
  if (angular.isString(label) && label.length) {
36464
36657
  this.label = label + ' ( ' + this.selector + ' )';
36465
36658
  } else {