angular-gem 1.3.2 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 {