angularjs-rails 1.3.4 → 1.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/lib/angularjs-rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/angular-animate.js +121 -120
  4. data/vendor/assets/javascripts/angular-aria.js +39 -28
  5. data/vendor/assets/javascripts/angular-cookies.js +1 -1
  6. data/vendor/assets/javascripts/angular-loader.js +2 -2
  7. data/vendor/assets/javascripts/angular-messages.js +1 -1
  8. data/vendor/assets/javascripts/angular-mocks.js +10 -8
  9. data/vendor/assets/javascripts/angular-resource.js +1 -1
  10. data/vendor/assets/javascripts/angular-route.js +2 -3
  11. data/vendor/assets/javascripts/angular-sanitize.js +7 -5
  12. data/vendor/assets/javascripts/angular-scenario.js +316 -231
  13. data/vendor/assets/javascripts/angular-touch.js +1 -1
  14. data/vendor/assets/javascripts/angular.js +314 -229
  15. data/vendor/assets/javascripts/unstable/angular-animate.js +121 -120
  16. data/vendor/assets/javascripts/unstable/angular-aria.js +39 -28
  17. data/vendor/assets/javascripts/unstable/angular-cookies.js +1 -1
  18. data/vendor/assets/javascripts/unstable/angular-loader.js +2 -2
  19. data/vendor/assets/javascripts/unstable/angular-messages.js +1 -1
  20. data/vendor/assets/javascripts/unstable/angular-mocks.js +10 -8
  21. data/vendor/assets/javascripts/unstable/angular-resource.js +1 -1
  22. data/vendor/assets/javascripts/unstable/angular-route.js +2 -3
  23. data/vendor/assets/javascripts/unstable/angular-sanitize.js +7 -5
  24. data/vendor/assets/javascripts/unstable/angular-scenario.js +316 -231
  25. data/vendor/assets/javascripts/unstable/angular-touch.js +1 -1
  26. data/vendor/assets/javascripts/unstable/angular.js +314 -229
  27. metadata +2 -2
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.4
2
+ * @license AngularJS v1.3.36
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.4
2
+ * @license AngularJS v1.3.36
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -55,7 +55,7 @@ function minErr(module, ErrorConstructor) {
55
55
  return match;
56
56
  });
57
57
 
58
- message = message + '\nhttp://errors.angularjs.org/1.3.4/' +
58
+ message = message + '\nhttp://errors.angularjs.org/1.3.36/' +
59
59
  (module ? module + '/' : '') + code;
60
60
  for (i = 2; i < arguments.length; i++) {
61
61
  message = message + (i == 2 ? '?' : '&') + 'p' + (i - 2) + '=' +
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.4
2
+ * @license AngularJS v1.3.36
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.4
2
+ * @license AngularJS v1.3.36
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1119,7 +1119,7 @@ angular.mock.dump = function(object) {
1119
1119
  ```
1120
1120
  */
1121
1121
  angular.mock.$HttpBackendProvider = function() {
1122
- this.$get = ['$rootScope', createHttpBackendMock];
1122
+ this.$get = ['$rootScope', '$timeout', createHttpBackendMock];
1123
1123
  };
1124
1124
 
1125
1125
  /**
@@ -1136,7 +1136,7 @@ angular.mock.$HttpBackendProvider = function() {
1136
1136
  * @param {Object=} $browser Auto-flushing enabled if specified
1137
1137
  * @return {Object} Instance of $httpBackend mock
1138
1138
  */
1139
- function createHttpBackendMock($rootScope, $delegate, $browser) {
1139
+ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
1140
1140
  var definitions = [],
1141
1141
  expectations = [],
1142
1142
  responses = [],
@@ -1149,7 +1149,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
1149
1149
  return function() {
1150
1150
  return angular.isNumber(status)
1151
1151
  ? [status, data, headers, statusText]
1152
- : [200, status, data];
1152
+ : [200, status, data, headers];
1153
1153
  };
1154
1154
  }
1155
1155
 
@@ -1166,7 +1166,9 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
1166
1166
  }
1167
1167
 
1168
1168
  function wrapResponse(wrapped) {
1169
- if (!$browser && timeout && timeout.then) timeout.then(handleTimeout);
1169
+ if (!$browser && timeout) {
1170
+ timeout.then ? timeout.then(handleTimeout) : $timeout(handleTimeout, timeout);
1171
+ }
1170
1172
 
1171
1173
  return handleResponse;
1172
1174
 
@@ -2040,7 +2042,7 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {
2040
2042
  */
2041
2043
  angular.mock.e2e = {};
2042
2044
  angular.mock.e2e.$httpBackendDecorator =
2043
- ['$rootScope', '$delegate', '$browser', createHttpBackendMock];
2045
+ ['$rootScope', '$timeout', '$delegate', '$browser', createHttpBackendMock];
2044
2046
 
2045
2047
 
2046
2048
  /**
@@ -2054,7 +2056,7 @@ angular.mock.e2e.$httpBackendDecorator =
2054
2056
  *
2055
2057
  * In addition to all the regular `Scope` methods, the following helper methods are available:
2056
2058
  */
2057
- angular.mock.$RootScopeDecorator = function($delegate) {
2059
+ angular.mock.$RootScopeDecorator = ['$delegate', function($delegate) {
2058
2060
 
2059
2061
  var $rootScopePrototype = Object.getPrototypeOf($delegate);
2060
2062
 
@@ -2126,7 +2128,7 @@ angular.mock.$RootScopeDecorator = function($delegate) {
2126
2128
 
2127
2129
  return count;
2128
2130
  }
2129
- };
2131
+ }];
2130
2132
 
2131
2133
 
2132
2134
  if (window.jasmine || window.mocha) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.4
2
+ * @license AngularJS v1.3.36
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.4
2
+ * @license AngularJS v1.3.36
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -180,7 +180,7 @@ function $RouteProvider() {
180
180
  * @description
181
181
  *
182
182
  * A boolean property indicating if routes defined
183
- * using this provider should be matched using a case sensitive
183
+ * using this provider should be matched using a case insensitive
184
184
  * algorithm. Defaults to `false`.
185
185
  */
186
186
  this.caseInsensitiveMatch = false;
@@ -788,7 +788,6 @@ ngRouteModule.directive('ngView', ngViewFillContentFactory);
788
788
  .view-animate-container {
789
789
  position:relative;
790
790
  height:100px!important;
791
- position:relative;
792
791
  background:white;
793
792
  border:1px solid black;
794
793
  height:40px;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.4
2
+ * @license AngularJS v1.3.36
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -628,7 +628,7 @@ angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider);
628
628
  */
629
629
  angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
630
630
  var LINKY_URL_REGEXP =
631
- /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"]/,
631
+ /((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"”’]/,
632
632
  MAILTO_REGEXP = /^mailto:/;
633
633
 
634
634
  return function(text, target) {
@@ -641,8 +641,10 @@ angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
641
641
  while ((match = raw.match(LINKY_URL_REGEXP))) {
642
642
  // We can not end in these as they are sometimes found at the end of the sentence
643
643
  url = match[0];
644
- // if we did not match ftp/http/mailto then assume mailto
645
- if (match[2] == match[3]) url = 'mailto:' + url;
644
+ // if we did not match ftp/http/www/mailto then assume mailto
645
+ if (!match[2] && !match[4]) {
646
+ url = (match[3] ? 'http://' : 'mailto:') + url;
647
+ }
646
648
  i = match.index;
647
649
  addText(raw.substr(0, i));
648
650
  addLink(url, match[0].replace(MAILTO_REGEXP, ''));
@@ -666,7 +668,7 @@ angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
666
668
  '" ');
667
669
  }
668
670
  html.push('href="',
669
- url.replace('"', '&quot;'),
671
+ url.replace(/"/g, '&quot;'),
670
672
  '">');
671
673
  addText(text);
672
674
  html.push('</a>');
@@ -9190,7 +9190,7 @@ return jQuery;
9190
9190
  }));
9191
9191
 
9192
9192
  /**
9193
- * @license AngularJS v1.3.4
9193
+ * @license AngularJS v1.3.36
9194
9194
  * (c) 2010-2014 Google, Inc. http://angularjs.org
9195
9195
  * License: MIT
9196
9196
  */
@@ -9246,7 +9246,7 @@ function minErr(module, ErrorConstructor) {
9246
9246
  return match;
9247
9247
  });
9248
9248
 
9249
- message = message + '\nhttp://errors.angularjs.org/1.3.4/' +
9249
+ message = message + '\nhttp://errors.angularjs.org/1.3.36/' +
9250
9250
  (module ? module + '/' : '') + code;
9251
9251
  for (i = 2; i < arguments.length; i++) {
9252
9252
  message = message + (i == 2 ? '?' : '&') + 'p' + (i - 2) + '=' +
@@ -9418,8 +9418,8 @@ if ('i' !== 'I'.toLowerCase()) {
9418
9418
  }
9419
9419
 
9420
9420
 
9421
- var /** holds major version number for IE or NaN for real browsers */
9422
- msie,
9421
+ var
9422
+ msie, // holds major version number for IE, or NaN if UA is not IE.
9423
9423
  jqLite, // delay binding since jQuery could be loaded after us.
9424
9424
  jQuery, // delay binding
9425
9425
  slice = [].slice,
@@ -10220,12 +10220,16 @@ function toJsonReplacer(key, value) {
10220
10220
  * stripped since angular uses this notation internally.
10221
10221
  *
10222
10222
  * @param {Object|Array|Date|string|number} obj Input to be serialized into JSON.
10223
- * @param {boolean=} pretty If set to true, the JSON output will contain newlines and whitespace.
10223
+ * @param {boolean|number=} pretty If set to true, the JSON output will contain newlines and whitespace.
10224
+ * If set to an integer, the JSON output will contain that many spaces per indentation (the default is 2).
10224
10225
  * @returns {string|undefined} JSON-ified string representing `obj`.
10225
10226
  */
10226
10227
  function toJson(obj, pretty) {
10227
10228
  if (typeof obj === 'undefined') return undefined;
10228
- return JSON.stringify(obj, toJsonReplacer, pretty ? ' ' : null);
10229
+ if (!isNumber(pretty)) {
10230
+ pretty = pretty ? 2 : null;
10231
+ }
10232
+ return JSON.stringify(obj, toJsonReplacer, pretty);
10229
10233
  }
10230
10234
 
10231
10235
 
@@ -11273,7 +11277,8 @@ function toDebugString(obj) {
11273
11277
  $TimeoutProvider,
11274
11278
  $$RAFProvider,
11275
11279
  $$AsyncCallbackProvider,
11276
- $WindowProvider
11280
+ $WindowProvider,
11281
+ $$jqLiteProvider
11277
11282
  */
11278
11283
 
11279
11284
 
@@ -11292,11 +11297,11 @@ function toDebugString(obj) {
11292
11297
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
11293
11298
  */
11294
11299
  var version = {
11295
- full: '1.3.4', // all of these placeholder strings will be replaced by grunt's
11300
+ full: '1.3.36', // all of these placeholder strings will be replaced by grunt's
11296
11301
  major: 1, // package task
11297
11302
  minor: 3,
11298
- dot: 4,
11299
- codeName: 'highfalutin-petroglyph'
11303
+ dot: 36,
11304
+ codeName: 'robofunky-danceblaster'
11300
11305
  };
11301
11306
 
11302
11307
 
@@ -11426,7 +11431,8 @@ function publishExternalAPI(angular) {
11426
11431
  $timeout: $TimeoutProvider,
11427
11432
  $window: $WindowProvider,
11428
11433
  $$rAF: $$RAFProvider,
11429
- $$asyncCallback: $$AsyncCallbackProvider
11434
+ $$asyncCallback: $$AsyncCallbackProvider,
11435
+ $$jqLite: $$jqLiteProvider
11430
11436
  });
11431
11437
  }
11432
11438
  ]);
@@ -12436,6 +12442,27 @@ forEach({
12436
12442
  JQLite.prototype.unbind = JQLite.prototype.off;
12437
12443
  });
12438
12444
 
12445
+
12446
+ // Provider for private $$jqLite service
12447
+ function $$jqLiteProvider() {
12448
+ this.$get = function $$jqLite() {
12449
+ return extend(JQLite, {
12450
+ hasClass: function(node, classes) {
12451
+ if (node.attr) node = node[0];
12452
+ return jqLiteHasClass(node, classes);
12453
+ },
12454
+ addClass: function(node, classes) {
12455
+ if (node.attr) node = node[0];
12456
+ return jqLiteAddClass(node, classes);
12457
+ },
12458
+ removeClass: function(node, classes) {
12459
+ if (node.attr) node = node[0];
12460
+ return jqLiteRemoveClass(node, classes);
12461
+ }
12462
+ });
12463
+ };
12464
+ }
12465
+
12439
12466
  /**
12440
12467
  * Computes a hash of an 'obj'.
12441
12468
  * Hash of a:
@@ -12688,6 +12715,7 @@ function annotate(fn, strictDi, name) {
12688
12715
  * Return an instance of the service.
12689
12716
  *
12690
12717
  * @param {string} name The name of the instance to retrieve.
12718
+ * @param {string} caller An optional string to provide the origin of the function call for error messages.
12691
12719
  * @return {*} The instance.
12692
12720
  */
12693
12721
 
@@ -13138,14 +13166,17 @@ function createInjector(modulesToLoad, strictDi) {
13138
13166
  }
13139
13167
  },
13140
13168
  providerInjector = (providerCache.$injector =
13141
- createInternalInjector(providerCache, function() {
13169
+ createInternalInjector(providerCache, function(serviceName, caller) {
13170
+ if (angular.isString(caller)) {
13171
+ path.push(caller);
13172
+ }
13142
13173
  throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- '));
13143
13174
  })),
13144
13175
  instanceCache = {},
13145
13176
  instanceInjector = (instanceCache.$injector =
13146
- createInternalInjector(instanceCache, function(servicename) {
13147
- var provider = providerInjector.get(servicename + providerSuffix);
13148
- return instanceInjector.invoke(provider.$get, provider, undefined, servicename);
13177
+ createInternalInjector(instanceCache, function(serviceName, caller) {
13178
+ var provider = providerInjector.get(serviceName + providerSuffix, caller);
13179
+ return instanceInjector.invoke(provider.$get, provider, undefined, serviceName);
13149
13180
  }));
13150
13181
 
13151
13182
 
@@ -13180,7 +13211,7 @@ function createInjector(modulesToLoad, strictDi) {
13180
13211
 
13181
13212
  function enforceReturnValue(name, factory) {
13182
13213
  return function enforcedReturnValue() {
13183
- var result = instanceInjector.invoke(factory, this, undefined, name);
13214
+ var result = instanceInjector.invoke(factory, this);
13184
13215
  if (isUndefined(result)) {
13185
13216
  throw $injectorMinErr('undef', "Provider '{0}' must return a value from $get factory method.", name);
13186
13217
  }
@@ -13275,7 +13306,7 @@ function createInjector(modulesToLoad, strictDi) {
13275
13306
 
13276
13307
  function createInternalInjector(cache, factory) {
13277
13308
 
13278
- function getService(serviceName) {
13309
+ function getService(serviceName, caller) {
13279
13310
  if (cache.hasOwnProperty(serviceName)) {
13280
13311
  if (cache[serviceName] === INSTANTIATING) {
13281
13312
  throw $injectorMinErr('cdep', 'Circular dependency found: {0}',
@@ -13286,7 +13317,7 @@ function createInjector(modulesToLoad, strictDi) {
13286
13317
  try {
13287
13318
  path.unshift(serviceName);
13288
13319
  cache[serviceName] = INSTANTIATING;
13289
- return cache[serviceName] = factory(serviceName);
13320
+ return cache[serviceName] = factory(serviceName, caller);
13290
13321
  } catch (err) {
13291
13322
  if (cache[serviceName] === INSTANTIATING) {
13292
13323
  delete cache[serviceName];
@@ -13318,7 +13349,7 @@ function createInjector(modulesToLoad, strictDi) {
13318
13349
  args.push(
13319
13350
  locals && locals.hasOwnProperty(key)
13320
13351
  ? locals[key]
13321
- : getService(key)
13352
+ : getService(key, serviceName)
13322
13353
  );
13323
13354
  }
13324
13355
  if (isArray(fn)) {
@@ -14062,6 +14093,11 @@ function Browser(window, document, $log, $sniffer) {
14062
14093
  }
14063
14094
  }
14064
14095
 
14096
+ function getHash(url) {
14097
+ var index = url.indexOf('#');
14098
+ return index === -1 ? '' : url.substr(index + 1);
14099
+ }
14100
+
14065
14101
  /**
14066
14102
  * @private
14067
14103
  * Note: this method is used only by scenario runner
@@ -14191,8 +14227,10 @@ function Browser(window, document, $log, $sniffer) {
14191
14227
  }
14192
14228
  if (replace) {
14193
14229
  location.replace(url);
14194
- } else {
14230
+ } else if (!sameBase) {
14195
14231
  location.href = url;
14232
+ } else {
14233
+ location.hash = getHash(url);
14196
14234
  }
14197
14235
  }
14198
14236
  return self;
@@ -14971,7 +15009,7 @@ function $TemplateCacheProvider() {
14971
15009
  * #### `multiElement`
14972
15010
  * When this property is set to true, the HTML compiler will collect DOM nodes between
14973
15011
  * nodes with the attributes `directive-name-start` and `directive-name-end`, and group them
14974
- * together as the directive elements. It is recomended that this feature be used on directives
15012
+ * together as the directive elements. It is recommended that this feature be used on directives
14975
15013
  * which are not strictly behavioural (such as {@link ngClick}), and which
14976
15014
  * do not manipulate or replace child nodes (such as {@link ngInclude}).
14977
15015
  *
@@ -15659,7 +15697,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15659
15697
  * Retrieves or overrides the default regular expression that is used for whitelisting of safe
15660
15698
  * urls during a[href] sanitization.
15661
15699
  *
15662
- * The sanitization is a security measure aimed at prevent XSS attacks via html links.
15700
+ * The sanitization is a security measure aimed at preventing XSS attacks via html links.
15663
15701
  *
15664
15702
  * Any url about to be assigned to a[href] via data-binding is first normalized and turned into
15665
15703
  * an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`
@@ -15726,7 +15764,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15726
15764
  * * `ng-binding` CSS class
15727
15765
  * * `$binding` data property containing an array of the binding expressions
15728
15766
  *
15729
- * You may want to use this in production for a significant performance boost. See
15767
+ * You may want to disable this in production for a significant performance boost. See
15730
15768
  * {@link guide/production#disabling-debug-data Disabling Debug Data} for more.
15731
15769
  *
15732
15770
  * The default value is true.
@@ -15763,6 +15801,21 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15763
15801
  };
15764
15802
 
15765
15803
  Attributes.prototype = {
15804
+ /**
15805
+ * @ngdoc method
15806
+ * @name $compile.directive.Attributes#$normalize
15807
+ * @kind function
15808
+ *
15809
+ * @description
15810
+ * Converts an attribute name (e.g. dash/colon/underscore-delimited string, optionally prefixed with `x-` or
15811
+ * `data-`) to its normalized, camelCase form.
15812
+ *
15813
+ * Also there is special case for Moz prefix starting with upper case letter.
15814
+ *
15815
+ * For further information check out the guide on {@link guide/directive#matching-directives Matching Directives}
15816
+ *
15817
+ * @param {string} name Name to normalize
15818
+ */
15766
15819
  $normalize: directiveNormalize,
15767
15820
 
15768
15821
 
@@ -17341,13 +17394,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
17341
17394
  var PREFIX_REGEXP = /^((?:x|data)[\:\-_])/i;
17342
17395
  /**
17343
17396
  * Converts all accepted directives format into proper directive name.
17344
- * All of these will become 'myDirective':
17345
- * my:Directive
17346
- * my-directive
17347
- * x-my-directive
17348
- * data-my:directive
17349
- *
17350
- * Also there is special case for Moz prefix starting with upper case letter.
17351
17397
  * @param name Name to normalize
17352
17398
  */
17353
17399
  function directiveNormalize(name) {
@@ -18283,12 +18329,14 @@ function $HttpProvider() {
18283
18329
  * `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
18284
18330
  * transform function or an array of such functions. The transform function takes the http
18285
18331
  * request body and headers and returns its transformed (typically serialized) version.
18286
- * See {@link #overriding-the-default-transformations-per-request Overriding the Default Transformations}
18332
+ * See {@link ng.$http#overriding-the-default-transformations-per-request
18333
+ * Overriding the Default Transformations}
18287
18334
  * - **transformResponse** –
18288
18335
  * `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
18289
18336
  * transform function or an array of such functions. The transform function takes the http
18290
18337
  * response body and headers and returns its transformed (typically deserialized) version.
18291
- * See {@link #overriding-the-default-transformations-per-request Overriding the Default Transformations}
18338
+ * See {@link ng.$http#overriding-the-default-transformations-per-request
18339
+ * Overriding the Default Transformations}
18292
18340
  * - **cache** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
18293
18341
  * GET request, otherwise if a cache instance built with
18294
18342
  * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
@@ -18698,8 +18746,7 @@ function $HttpProvider() {
18698
18746
  if (isDefined(cachedResp)) {
18699
18747
  if (isPromiseLike(cachedResp)) {
18700
18748
  // cached request has already been sent, but there is no response yet
18701
- cachedResp.then(removePendingReq, removePendingReq);
18702
- return cachedResp;
18749
+ cachedResp.then(resolvePromiseWithResult, resolvePromiseWithResult);
18703
18750
  } else {
18704
18751
  // serving from cache
18705
18752
  if (isArray(cachedResp)) {
@@ -18777,6 +18824,9 @@ function $HttpProvider() {
18777
18824
  });
18778
18825
  }
18779
18826
 
18827
+ function resolvePromiseWithResult(result) {
18828
+ resolvePromise(result.data, result.status, shallowCopy(result.headers()), result.statusText);
18829
+ }
18780
18830
 
18781
18831
  function removePendingReq() {
18782
18832
  var idx = $http.pendingRequests.indexOf(config);
@@ -18938,7 +18988,9 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
18938
18988
 
18939
18989
  function completeRequest(callback, status, response, headersString, statusText) {
18940
18990
  // cancel timeout and subsequent timeout promise resolution
18941
- timeoutId && $browserDefer.cancel(timeoutId);
18991
+ if (timeoutId !== undefined) {
18992
+ $browserDefer.cancel(timeoutId);
18993
+ }
18942
18994
  jsonpDone = xhr = null;
18943
18995
 
18944
18996
  callback(status, response, headersString, statusText);
@@ -19386,33 +19438,33 @@ function $IntervalProvider() {
19386
19438
  * // Don't start a new fight if we are already fighting
19387
19439
  * if ( angular.isDefined(stop) ) return;
19388
19440
  *
19389
- * stop = $interval(function() {
19390
- * if ($scope.blood_1 > 0 && $scope.blood_2 > 0) {
19391
- * $scope.blood_1 = $scope.blood_1 - 3;
19392
- * $scope.blood_2 = $scope.blood_2 - 4;
19393
- * } else {
19394
- * $scope.stopFight();
19395
- * }
19396
- * }, 100);
19397
- * };
19441
+ * stop = $interval(function() {
19442
+ * if ($scope.blood_1 > 0 && $scope.blood_2 > 0) {
19443
+ * $scope.blood_1 = $scope.blood_1 - 3;
19444
+ * $scope.blood_2 = $scope.blood_2 - 4;
19445
+ * } else {
19446
+ * $scope.stopFight();
19447
+ * }
19448
+ * }, 100);
19449
+ * };
19398
19450
  *
19399
- * $scope.stopFight = function() {
19400
- * if (angular.isDefined(stop)) {
19401
- * $interval.cancel(stop);
19402
- * stop = undefined;
19403
- * }
19404
- * };
19451
+ * $scope.stopFight = function() {
19452
+ * if (angular.isDefined(stop)) {
19453
+ * $interval.cancel(stop);
19454
+ * stop = undefined;
19455
+ * }
19456
+ * };
19405
19457
  *
19406
- * $scope.resetFight = function() {
19407
- * $scope.blood_1 = 100;
19408
- * $scope.blood_2 = 120;
19409
- * };
19458
+ * $scope.resetFight = function() {
19459
+ * $scope.blood_1 = 100;
19460
+ * $scope.blood_2 = 120;
19461
+ * };
19410
19462
  *
19411
- * $scope.$on('$destroy', function() {
19412
- * // Make sure that the interval is destroyed too
19413
- * $scope.stopFight();
19414
- * });
19415
- * }])
19463
+ * $scope.$on('$destroy', function() {
19464
+ * // Make sure that the interval is destroyed too
19465
+ * $scope.stopFight();
19466
+ * });
19467
+ * }])
19416
19468
  * // Register the 'myCurrentTime' directive factory method.
19417
19469
  * // We inject $interval and dateFilter service since the factory method is DI.
19418
19470
  * .directive('myCurrentTime', ['$interval', 'dateFilter',
@@ -19655,6 +19707,10 @@ function stripHash(url) {
19655
19707
  return index == -1 ? url : url.substr(0, index);
19656
19708
  }
19657
19709
 
19710
+ function trimEmptyHash(url) {
19711
+ return url.replace(/(#.+)|#$/, '$1');
19712
+ }
19713
+
19658
19714
 
19659
19715
  function stripFile(url) {
19660
19716
  return url.substr(0, stripHash(url).lastIndexOf('/') + 1);
@@ -19766,16 +19822,25 @@ function LocationHashbangUrl(appBase, hashPrefix) {
19766
19822
  */
19767
19823
  this.$$parse = function(url) {
19768
19824
  var withoutBaseUrl = beginsWith(appBase, url) || beginsWith(appBaseNoFile, url);
19769
- var withoutHashUrl = withoutBaseUrl.charAt(0) == '#'
19770
- ? beginsWith(hashPrefix, withoutBaseUrl)
19771
- : (this.$$html5)
19772
- ? withoutBaseUrl
19773
- : '';
19825
+ var withoutHashUrl;
19826
+
19827
+ if (withoutBaseUrl.charAt(0) === '#') {
19774
19828
 
19775
- if (!isString(withoutHashUrl)) {
19776
- throw $locationMinErr('ihshprfx', 'Invalid url "{0}", missing hash prefix "{1}".', url,
19777
- hashPrefix);
19829
+ // The rest of the url starts with a hash so we have
19830
+ // got either a hashbang path or a plain hash fragment
19831
+ withoutHashUrl = beginsWith(hashPrefix, withoutBaseUrl);
19832
+ if (isUndefined(withoutHashUrl)) {
19833
+ // There was no hashbang prefix so we just have a hash fragment
19834
+ withoutHashUrl = withoutBaseUrl;
19835
+ }
19836
+
19837
+ } else {
19838
+ // There was no hashbang path nor hash fragment:
19839
+ // If we are in HTML5 mode we use what is left as the path;
19840
+ // Otherwise we ignore what is left
19841
+ withoutHashUrl = this.$$html5 ? withoutBaseUrl : '';
19778
19842
  }
19843
+
19779
19844
  parseAppUrl(withoutHashUrl, this);
19780
19845
 
19781
19846
  this.$$path = removeWindowsDriveName(this.$$path, withoutHashUrl, appBase);
@@ -20138,7 +20203,7 @@ var locationPrototype = {
20138
20203
  *
20139
20204
  *
20140
20205
  * ```js
20141
- * // given url http://example.com/some/path?foo=bar&baz=xoxo#hashValue
20206
+ * // given url http://example.com/#/some/path?foo=bar&baz=xoxo#hashValue
20142
20207
  * var hash = $location.hash();
20143
20208
  * // => "hashValue"
20144
20209
  * ```
@@ -20490,10 +20555,11 @@ function $LocationProvider() {
20490
20555
 
20491
20556
  // update browser
20492
20557
  $rootScope.$watch(function $locationWatch() {
20493
- var oldUrl = $browser.url();
20558
+ var oldUrl = trimEmptyHash($browser.url());
20559
+ var newUrl = trimEmptyHash($location.absUrl());
20494
20560
  var oldState = $browser.state();
20495
20561
  var currentReplace = $location.$$replace;
20496
- var urlOrStateChanged = oldUrl !== $location.absUrl() ||
20562
+ var urlOrStateChanged = oldUrl !== newUrl ||
20497
20563
  ($location.$$html5 && $sniffer.history && oldState !== $location.$$state);
20498
20564
 
20499
20565
  if (initializing || urlOrStateChanged) {
@@ -21296,8 +21362,8 @@ Parser.prototype = {
21296
21362
  logicalAND: function() {
21297
21363
  var left = this.equality();
21298
21364
  var token;
21299
- if ((token = this.expect('&&'))) {
21300
- left = this.binaryFn(left, token.text, this.logicalAND(), true);
21365
+ while ((token = this.expect('&&'))) {
21366
+ left = this.binaryFn(left, token.text, this.equality(), true);
21301
21367
  }
21302
21368
  return left;
21303
21369
  },
@@ -21305,8 +21371,8 @@ Parser.prototype = {
21305
21371
  equality: function() {
21306
21372
  var left = this.relational();
21307
21373
  var token;
21308
- if ((token = this.expect('==','!=','===','!=='))) {
21309
- left = this.binaryFn(left, token.text, this.equality());
21374
+ while ((token = this.expect('==','!=','===','!=='))) {
21375
+ left = this.binaryFn(left, token.text, this.relational());
21310
21376
  }
21311
21377
  return left;
21312
21378
  },
@@ -21314,8 +21380,8 @@ Parser.prototype = {
21314
21380
  relational: function() {
21315
21381
  var left = this.additive();
21316
21382
  var token;
21317
- if ((token = this.expect('<', '>', '<=', '>='))) {
21318
- left = this.binaryFn(left, token.text, this.relational());
21383
+ while ((token = this.expect('<', '>', '<=', '>='))) {
21384
+ left = this.binaryFn(left, token.text, this.additive());
21319
21385
  }
21320
21386
  return left;
21321
21387
  },
@@ -21407,7 +21473,7 @@ Parser.prototype = {
21407
21473
  var args = argsFn.length ? [] : null;
21408
21474
 
21409
21475
  return function $parseFunctionCall(scope, locals) {
21410
- var context = contextGetter ? contextGetter(scope, locals) : scope;
21476
+ var context = contextGetter ? contextGetter(scope, locals) : isDefined(contextGetter) ? undefined : scope;
21411
21477
  var fn = fnGetter(scope, locals, context) || noop;
21412
21478
 
21413
21479
  if (args) {
@@ -21420,13 +21486,13 @@ Parser.prototype = {
21420
21486
  ensureSafeObject(context, expressionText);
21421
21487
  ensureSafeFunction(fn, expressionText);
21422
21488
 
21423
- // IE stupidity! (IE doesn't have apply for some native functions)
21489
+ // IE doesn't have apply for some native functions
21424
21490
  var v = fn.apply
21425
21491
  ? fn.apply(context, args)
21426
21492
  : fn(args[0], args[1], args[2], args[3], args[4]);
21427
21493
 
21428
21494
  return ensureSafeObject(v, expressionText);
21429
- };
21495
+ };
21430
21496
  },
21431
21497
 
21432
21498
  // This is used with json array declaration
@@ -25062,7 +25128,9 @@ function $SnifferProvider() {
25062
25128
  // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
25063
25129
  // it. In particular the event is not fired when backspace or delete key are pressed or
25064
25130
  // when cut operation is performed.
25065
- if (event == 'input' && msie == 9) return false;
25131
+ // IE10+ implements 'input' event but it erroneously fires under various situations,
25132
+ // e.g. when placeholder changes, or a form is focused.
25133
+ if (event === 'input' && msie <= 11) return false;
25066
25134
 
25067
25135
  if (isUndefined(eventSupport[event])) {
25068
25136
  var divElm = document.createElement('div');
@@ -25108,14 +25176,9 @@ function $TemplateRequestProvider() {
25108
25176
  var transformResponse = $http.defaults && $http.defaults.transformResponse;
25109
25177
 
25110
25178
  if (isArray(transformResponse)) {
25111
- var original = transformResponse;
25112
- transformResponse = [];
25113
- for (var i = 0; i < original.length; ++i) {
25114
- var transformer = original[i];
25115
- if (transformer !== defaultHttpResponseTransform) {
25116
- transformResponse.push(transformer);
25117
- }
25118
- }
25179
+ transformResponse = transformResponse.filter(function(transformer) {
25180
+ return transformer !== defaultHttpResponseTransform;
25181
+ });
25119
25182
  } else if (transformResponse === defaultHttpResponseTransform) {
25120
25183
  transformResponse = null;
25121
25184
  }
@@ -25127,18 +25190,16 @@ function $TemplateRequestProvider() {
25127
25190
 
25128
25191
  return $http.get(tpl, httpOptions)
25129
25192
  .then(function(response) {
25130
- var html = response.data;
25131
25193
  self.totalPendingRequests--;
25132
- $templateCache.put(tpl, html);
25133
- return html;
25194
+ return response.data;
25134
25195
  }, handleError);
25135
25196
 
25136
- function handleError() {
25197
+ function handleError(resp) {
25137
25198
  self.totalPendingRequests--;
25138
25199
  if (!ignoreRequestError) {
25139
25200
  throw $compileMinErr('tpload', 'Failed to load template: {0}', tpl);
25140
25201
  }
25141
- return $q.reject();
25202
+ return $q.reject(resp);
25142
25203
  }
25143
25204
  }
25144
25205
 
@@ -25761,106 +25822,103 @@ function filterFilter() {
25761
25822
  return function(array, expression, comparator) {
25762
25823
  if (!isArray(array)) return array;
25763
25824
 
25764
- var comparatorType = typeof(comparator),
25765
- predicates = [];
25825
+ var predicateFn;
25826
+ var matchAgainstAnyProp;
25766
25827
 
25767
- predicates.check = function(value, index) {
25768
- for (var j = 0; j < predicates.length; j++) {
25769
- if (!predicates[j](value, index)) {
25770
- return false;
25771
- }
25772
- }
25773
- return true;
25774
- };
25775
-
25776
- if (comparatorType !== 'function') {
25777
- if (comparatorType === 'boolean' && comparator) {
25778
- comparator = function(obj, text) {
25779
- return angular.equals(obj, text);
25780
- };
25781
- } else {
25782
- comparator = function(obj, text) {
25783
- if (obj && text && typeof obj === 'object' && typeof text === 'object') {
25784
- for (var objKey in obj) {
25785
- if (objKey.charAt(0) !== '$' && hasOwnProperty.call(obj, objKey) &&
25786
- comparator(obj[objKey], text[objKey])) {
25787
- return true;
25788
- }
25789
- }
25790
- return false;
25791
- }
25792
- text = ('' + text).toLowerCase();
25793
- return ('' + obj).toLowerCase().indexOf(text) > -1;
25794
- };
25795
- }
25796
- }
25797
-
25798
- var search = function(obj, text) {
25799
- if (typeof text === 'string' && text.charAt(0) === '!') {
25800
- return !search(obj, text.substr(1));
25801
- }
25802
- switch (typeof obj) {
25803
- case 'boolean':
25804
- case 'number':
25805
- case 'string':
25806
- return comparator(obj, text);
25807
- case 'object':
25808
- switch (typeof text) {
25809
- case 'object':
25810
- return comparator(obj, text);
25811
- default:
25812
- for (var objKey in obj) {
25813
- if (objKey.charAt(0) !== '$' && search(obj[objKey], text)) {
25814
- return true;
25815
- }
25816
- }
25817
- break;
25818
- }
25819
- return false;
25820
- case 'array':
25821
- for (var i = 0; i < obj.length; i++) {
25822
- if (search(obj[i], text)) {
25823
- return true;
25824
- }
25825
- }
25826
- return false;
25827
- default:
25828
- return false;
25829
- }
25830
- };
25831
25828
  switch (typeof expression) {
25829
+ case 'function':
25830
+ predicateFn = expression;
25831
+ break;
25832
25832
  case 'boolean':
25833
25833
  case 'number':
25834
25834
  case 'string':
25835
- // Set up expression object and fall through
25836
- expression = {$:expression};
25837
- // jshint -W086
25835
+ matchAgainstAnyProp = true;
25836
+ //jshint -W086
25838
25837
  case 'object':
25839
- // jshint +W086
25840
- for (var key in expression) {
25841
- (function(path) {
25842
- if (typeof expression[path] === 'undefined') return;
25843
- predicates.push(function(value) {
25844
- return search(path == '$' ? value : (value && value[path]), expression[path]);
25845
- });
25846
- })(key);
25847
- }
25848
- break;
25849
- case 'function':
25850
- predicates.push(expression);
25838
+ //jshint +W086
25839
+ predicateFn = createPredicateFn(expression, comparator, matchAgainstAnyProp);
25851
25840
  break;
25852
25841
  default:
25853
25842
  return array;
25854
25843
  }
25855
- var filtered = [];
25856
- for (var j = 0; j < array.length; j++) {
25857
- var value = array[j];
25858
- if (predicates.check(value, j)) {
25859
- filtered.push(value);
25844
+
25845
+ return array.filter(predicateFn);
25846
+ };
25847
+ }
25848
+
25849
+ // Helper functions for `filterFilter`
25850
+ function createPredicateFn(expression, comparator, matchAgainstAnyProp) {
25851
+ var predicateFn;
25852
+
25853
+ if (comparator === true) {
25854
+ comparator = equals;
25855
+ } else if (!isFunction(comparator)) {
25856
+ comparator = function(actual, expected) {
25857
+ if (isObject(actual) || isObject(expected)) {
25858
+ // Prevent an object to be considered equal to a string like `'[object'`
25859
+ return false;
25860
25860
  }
25861
- }
25862
- return filtered;
25861
+
25862
+ actual = lowercase('' + actual);
25863
+ expected = lowercase('' + expected);
25864
+ return actual.indexOf(expected) !== -1;
25865
+ };
25866
+ }
25867
+
25868
+ predicateFn = function(item) {
25869
+ return deepCompare(item, expression, comparator, matchAgainstAnyProp);
25863
25870
  };
25871
+
25872
+ return predicateFn;
25873
+ }
25874
+
25875
+ function deepCompare(actual, expected, comparator, matchAgainstAnyProp) {
25876
+ var actualType = typeof actual;
25877
+ var expectedType = typeof expected;
25878
+
25879
+ if ((expectedType === 'string') && (expected.charAt(0) === '!')) {
25880
+ return !deepCompare(actual, expected.substring(1), comparator, matchAgainstAnyProp);
25881
+ } else if (actualType === 'array') {
25882
+ // In case `actual` is an array, consider it a match
25883
+ // if ANY of it's items matches `expected`
25884
+ return actual.some(function(item) {
25885
+ return deepCompare(item, expected, comparator, matchAgainstAnyProp);
25886
+ });
25887
+ }
25888
+
25889
+ switch (actualType) {
25890
+ case 'object':
25891
+ var key;
25892
+ if (matchAgainstAnyProp) {
25893
+ for (key in actual) {
25894
+ if ((key.charAt(0) !== '$') && deepCompare(actual[key], expected, comparator)) {
25895
+ return true;
25896
+ }
25897
+ }
25898
+ return false;
25899
+ } else if (expectedType === 'object') {
25900
+ for (key in expected) {
25901
+ var expectedVal = expected[key];
25902
+ if (isFunction(expectedVal)) {
25903
+ continue;
25904
+ }
25905
+
25906
+ var keyIsDollar = key === '$';
25907
+ var actualVal = keyIsDollar ? actual : actual[key];
25908
+ if (!deepCompare(actualVal, expectedVal, comparator, keyIsDollar)) {
25909
+ return false;
25910
+ }
25911
+ }
25912
+ return true;
25913
+ } else {
25914
+ return comparator(actual, expected);
25915
+ }
25916
+ break;
25917
+ case 'function':
25918
+ return false;
25919
+ default:
25920
+ return comparator(actual, expected);
25921
+ }
25864
25922
  }
25865
25923
 
25866
25924
  /**
@@ -26013,7 +26071,6 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
26013
26071
  if (numStr.indexOf('e') !== -1) {
26014
26072
  var match = numStr.match(/([\d\.]+)e(-?)(\d+)/);
26015
26073
  if (match && match[2] == '-' && match[3] > fractionSize + 1) {
26016
- numStr = '0';
26017
26074
  number = 0;
26018
26075
  } else {
26019
26076
  formatedText = numStr;
@@ -26034,10 +26091,6 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
26034
26091
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
26035
26092
  number = +(Math.round(+(number.toString() + 'e' + fractionSize)).toString() + 'e' + -fractionSize);
26036
26093
 
26037
- if (number === 0) {
26038
- isNegative = false;
26039
- }
26040
-
26041
26094
  var fraction = ('' + number).split(DECIMAL_SEP);
26042
26095
  var whole = fraction[0];
26043
26096
  fraction = fraction[1] || '';
@@ -26070,12 +26123,16 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
26070
26123
 
26071
26124
  if (fractionSize && fractionSize !== "0") formatedText += decimalSep + fraction.substr(0, fractionSize);
26072
26125
  } else {
26073
-
26074
- if (fractionSize > 0 && number > -1 && number < 1) {
26126
+ if (fractionSize > 0 && number < 1) {
26075
26127
  formatedText = number.toFixed(fractionSize);
26128
+ number = parseFloat(formatedText);
26076
26129
  }
26077
26130
  }
26078
26131
 
26132
+ if (number === 0) {
26133
+ isNegative = false;
26134
+ }
26135
+
26079
26136
  parts.push(isNegative ? pattern.negPre : pattern.posPre,
26080
26137
  formatedText,
26081
26138
  isNegative ? pattern.negSuf : pattern.posSuf);
@@ -26365,25 +26422,31 @@ function dateFilter($locale) {
26365
26422
  * the binding is automatically converted to JSON.
26366
26423
  *
26367
26424
  * @param {*} object Any JavaScript object (including arrays and primitive types) to filter.
26425
+ * @param {number=} spacing The number of spaces to use per indentation, defaults to 2.
26368
26426
  * @returns {string} JSON string.
26369
26427
  *
26370
26428
  *
26371
26429
  * @example
26372
26430
  <example>
26373
26431
  <file name="index.html">
26374
- <pre>{{ {'name':'value'} | json }}</pre>
26432
+ <pre id="default-spacing">{{ {'name':'value'} | json }}</pre>
26433
+ <pre id="custom-spacing">{{ {'name':'value'} | json:4 }}</pre>
26375
26434
  </file>
26376
26435
  <file name="protractor.js" type="protractor">
26377
26436
  it('should jsonify filtered objects', function() {
26378
- expect(element(by.binding("{'name':'value'}")).getText()).toMatch(/\{\n "name": ?"value"\n}/);
26437
+ expect(element(by.id('default-spacing')).getText()).toMatch(/\{\n "name": ?"value"\n}/);
26438
+ expect(element(by.id('custom-spacing')).getText()).toMatch(/\{\n "name": ?"value"\n}/);
26379
26439
  });
26380
26440
  </file>
26381
26441
  </example>
26382
26442
  *
26383
26443
  */
26384
26444
  function jsonFilter() {
26385
- return function(object) {
26386
- return toJson(object, true);
26445
+ return function(object, spacing) {
26446
+ if (isUndefined(spacing)) {
26447
+ spacing = 2;
26448
+ }
26449
+ return toJson(object, spacing);
26387
26450
  };
26388
26451
  }
26389
26452
 
@@ -26703,12 +26766,29 @@ function orderByFilter($parse) {
26703
26766
  function compare(v1, v2) {
26704
26767
  var t1 = typeof v1;
26705
26768
  var t2 = typeof v2;
26706
- if (t1 == t2) {
26707
- if (isDate(v1) && isDate(v2)) {
26708
- v1 = v1.valueOf();
26709
- v2 = v2.valueOf();
26710
- }
26711
- if (t1 == "string") {
26769
+ // Prepare values for Abstract Relational Comparison
26770
+ // (http://www.ecma-international.org/ecma-262/5.1/#sec-11.8.5):
26771
+ // If the resulting values are identical, return 0 to prevent
26772
+ // incorrect re-ordering.
26773
+ if (t1 === t2 && t1 === "object") {
26774
+ // If types are both numbers, emulate abstract ToPrimitive() operation
26775
+ // in order to get primitive values suitable for comparison
26776
+ t1 = typeof (v1.valueOf ? v1 = v1.valueOf() : v1);
26777
+ t2 = typeof (v2.valueOf ? v2 = v2.valueOf() : v2);
26778
+ if (t1 === t2 && t1 === "object") {
26779
+ // Object.prototype.valueOf will return the original object, by
26780
+ // default. If we do not receive a primitive value, use ToString()
26781
+ // instead.
26782
+ t1 = typeof (v1.toString ? v1 = v1.toString() : v1);
26783
+ t2 = typeof (v2.toString ? v2 = v2.toString() : v2);
26784
+
26785
+ // If the end result of toString() for each item is the same, do not
26786
+ // perform relational comparison, and do not re-order objects.
26787
+ if (t1 === t2 && v1 === v2 || t1 === "object") return 0;
26788
+ }
26789
+ }
26790
+ if (t1 === t2) {
26791
+ if (t1 === "string") {
26712
26792
  v1 = v1.toLowerCase();
26713
26793
  v2 = v2.toLowerCase();
26714
26794
  }
@@ -26774,9 +26854,8 @@ var htmlAnchorDirective = valueFn({
26774
26854
  * make the link go to the wrong URL if the user clicks it before
26775
26855
  * Angular has a chance to replace the `{{hash}}` markup with its
26776
26856
  * value. Until Angular replaces the markup the link will be broken
26777
- * and will most likely return a 404 error.
26778
- *
26779
- * The `ngHref` directive solves this problem.
26857
+ * and will most likely return a 404 error. The `ngHref` directive
26858
+ * solves this problem.
26780
26859
  *
26781
26860
  * The wrong way to write it:
26782
26861
  * ```html
@@ -28658,7 +28737,6 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
28658
28737
  }
28659
28738
 
28660
28739
  function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
28661
- var placeholder = element[0].placeholder, noevent = {};
28662
28740
  var type = lowercase(element[0].type);
28663
28741
 
28664
28742
  // In composition mode, users are still inputing intermediate text buffer,
@@ -28678,19 +28756,14 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
28678
28756
  }
28679
28757
 
28680
28758
  var listener = function(ev) {
28759
+ if (timeout) {
28760
+ $browser.defer.cancel(timeout);
28761
+ timeout = null;
28762
+ }
28681
28763
  if (composing) return;
28682
28764
  var value = element.val(),
28683
28765
  event = ev && ev.type;
28684
28766
 
28685
- // IE (11 and under) seem to emit an 'input' event if the placeholder value changes.
28686
- // We don't want to dirty the value when this happens, so we abort here. Unfortunately,
28687
- // IE also sends input events for other non-input-related things, (such as focusing on a
28688
- // form control), so this change is not entirely enough to solve this.
28689
- if (msie && (ev || noevent).type === 'input' && element[0].placeholder !== placeholder) {
28690
- placeholder = element[0].placeholder;
28691
- return;
28692
- }
28693
-
28694
28767
  // By default we will trim the value
28695
28768
  // If the attribute ng-trim exists we will avoid trimming
28696
28769
  // If input type is 'password', the value is never trimmed
@@ -28713,11 +28786,13 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
28713
28786
  } else {
28714
28787
  var timeout;
28715
28788
 
28716
- var deferListener = function(ev) {
28789
+ var deferListener = function(ev, input, origValue) {
28717
28790
  if (!timeout) {
28718
28791
  timeout = $browser.defer(function() {
28719
- listener(ev);
28720
28792
  timeout = null;
28793
+ if (!input || input.value !== origValue) {
28794
+ listener(ev);
28795
+ }
28721
28796
  });
28722
28797
  }
28723
28798
  };
@@ -28729,7 +28804,7 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
28729
28804
  // command modifiers arrows
28730
28805
  if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return;
28731
28806
 
28732
- deferListener(event);
28807
+ deferListener(event, this, this.value);
28733
28808
  });
28734
28809
 
28735
28810
  // if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it
@@ -29904,11 +29979,15 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
29904
29979
  var prevModelValue = ctrl.$modelValue;
29905
29980
  var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid;
29906
29981
  ctrl.$$rawModelValue = modelValue;
29982
+
29907
29983
  if (allowInvalid) {
29908
29984
  ctrl.$modelValue = modelValue;
29909
29985
  writeToModelIfNeeded();
29910
29986
  }
29911
- ctrl.$$runValidators(parserValid, modelValue, viewValue, function(allValid) {
29987
+
29988
+ // Pass the $$lastCommittedViewValue here, because the cached viewValue might be out of date.
29989
+ // This can happen if e.g. $setViewValue is called from inside a parser
29990
+ ctrl.$$runValidators(parserValid, modelValue, ctrl.$$lastCommittedViewValue, function(allValid) {
29912
29991
  if (!allowInvalid) {
29913
29992
  // Note: Don't check ctrl.$valid here, as we could have
29914
29993
  // external validators (e.g. calculated on the server),
@@ -34250,7 +34329,7 @@ var ngSwitchDefaultDirective = ngDirective({
34250
34329
  }]);
34251
34330
  </script>
34252
34331
  <div ng-controller="ExampleController">
34253
- <input ng-model="title"><br>
34332
+ <input ng-model="title"> <br/>
34254
34333
  <textarea ng-model="text"></textarea> <br/>
34255
34334
  <pane title="{{title}}">{{text}}</pane>
34256
34335
  </div>
@@ -34328,7 +34407,6 @@ var scriptDirective = ['$templateCache', function($templateCache) {
34328
34407
  compile: function(element, attr) {
34329
34408
  if (attr.type == 'text/ng-template') {
34330
34409
  var templateUrl = attr.id,
34331
- // IE is not consistent, in scripts we have to read .text but in other nodes we have to read .textContent
34332
34410
  text = element[0].text;
34333
34411
 
34334
34412
  $templateCache.put(templateUrl, text);
@@ -34379,9 +34457,9 @@ var ngOptionsMinErr = minErr('ngOptions');
34379
34457
  * or property name (for object data sources) of the value within the collection. If a `track by` expression
34380
34458
  * is used, the result of that expression will be set as the value of the `option` and `select` elements.
34381
34459
  *
34382
- * ### `select as` with `trackexpr`
34460
+ * ### `select as` with `track by`
34383
34461
  *
34384
- * Using `select as` together with `trackexpr` is not recommended. Reasoning:
34462
+ * Using `select as` together with `track by` is not recommended. Reasoning:
34385
34463
  *
34386
34464
  * - Example: &lt;select ng-options="item.subItem as item.label for item in values track by item.id" ng-model="selected"&gt;
34387
34465
  * values: [{id: 1, label: 'aLabel', subItem: {name: 'aSubItem'}}, {id: 2, label: 'bLabel', subItem: {name: 'bSubItem'}}],
@@ -34406,8 +34484,10 @@ var ngOptionsMinErr = minErr('ngOptions');
34406
34484
  * * for array data sources:
34407
34485
  * * `label` **`for`** `value` **`in`** `array`
34408
34486
  * * `select` **`as`** `label` **`for`** `value` **`in`** `array`
34409
- * * `label` **`group by`** `group` **`for`** `value` **`in`** `array`
34410
- * * `select` **`as`** `label` **`group by`** `group` **`for`** `value` **`in`** `array` **`track by`** `trackexpr`
34487
+ * * `label` **`group by`** `group` **`for`** `value` **`in`** `array`
34488
+ * * `label` **`group by`** `group` **`for`** `value` **`in`** `array` **`track by`** `trackexpr`
34489
+ * * `label` **`for`** `value` **`in`** `array` | orderBy:`orderexpr` **`track by`** `trackexpr`
34490
+ * (for including a filter with `track by`)
34411
34491
  * * for object data sources:
34412
34492
  * * `label` **`for (`**`key` **`,`** `value`**`) in`** `object`
34413
34493
  * * `select` **`as`** `label` **`for (`**`key` **`,`** `value`**`) in`** `object`
@@ -34549,7 +34629,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
34549
34629
  self.removeOption = function(value) {
34550
34630
  if (this.hasOption(value)) {
34551
34631
  delete optionsMap[value];
34552
- if (ngModelCtrl.$viewValue == value) {
34632
+ if (ngModelCtrl.$viewValue === value) {
34553
34633
  this.renderUnknownOption(value);
34554
34634
  }
34555
34635
  }
@@ -35016,18 +35096,23 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
35016
35096
  updateLabelMap(labelMap, option.label, false);
35017
35097
  option.element.remove();
35018
35098
  }
35019
- forEach(labelMap, function(count, label) {
35020
- if (count > 0) {
35021
- selectCtrl.addOption(label);
35022
- } else if (count < 0) {
35023
- selectCtrl.removeOption(label);
35024
- }
35025
- });
35026
35099
  }
35027
35100
  // remove any excessive OPTGROUPs from select
35028
35101
  while (optionGroupsCache.length > groupIndex) {
35029
- optionGroupsCache.pop()[0].element.remove();
35102
+ // remove all the labels in the option group
35103
+ optionGroup = optionGroupsCache.pop();
35104
+ for (index = 1; index < optionGroup.length; ++index) {
35105
+ updateLabelMap(labelMap, optionGroup[index].label, false);
35106
+ }
35107
+ optionGroup[0].element.remove();
35030
35108
  }
35109
+ forEach(labelMap, function(count, label) {
35110
+ if (count > 0) {
35111
+ selectCtrl.addOption(label);
35112
+ } else if (count < 0) {
35113
+ selectCtrl.removeOption(label);
35114
+ }
35115
+ });
35031
35116
  }
35032
35117
  }
35033
35118
  }
@@ -36688,7 +36773,7 @@ angular.scenario.dsl('binding', function() {
36688
36773
  */
36689
36774
  angular.scenario.dsl('input', function() {
36690
36775
  var chain = {};
36691
- var supportInputEvent = 'oninput' in document.createElement('div') && msie != 9;
36776
+ var supportInputEvent = 'oninput' in document.createElement('div') && !(msie && msie <= 11);
36692
36777
 
36693
36778
  chain.enter = function(value, event) {
36694
36779
  return this.addFutureAction("input '" + this.name + "' enter '" + value + "'",