angularjs-rails 1.2.21 → 1.2.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.3.0-beta.17
2
+ * @license AngularJS v1.3.0-beta.18
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.0-beta.17
2
+ * @license AngularJS v1.3.0-beta.18
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -68,7 +68,7 @@ function minErr(module) {
68
68
  return match;
69
69
  });
70
70
 
71
- message = message + '\nhttp://errors.angularjs.org/1.3.0-beta.17/' +
71
+ message = message + '\nhttp://errors.angularjs.org/1.3.0-beta.18/' +
72
72
  (module ? module + '/' : '') + code;
73
73
  for (i = 2; i < arguments.length; i++) {
74
74
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -1255,6 +1255,7 @@ function encodeUriQuery(val, pctEncodeSpaces) {
1255
1255
  replace(/%3A/gi, ':').
1256
1256
  replace(/%24/g, '$').
1257
1257
  replace(/%2C/gi, ',').
1258
+ replace(/%3B/gi, ';').
1258
1259
  replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
1259
1260
  }
1260
1261
 
@@ -1537,7 +1538,9 @@ function bindJQuery() {
1537
1538
  // bind to jQuery if present;
1538
1539
  jQuery = window.jQuery;
1539
1540
  // Use jQuery if it exists with proper functionality, otherwise default to us.
1540
- // Angular 1.2+ requires jQuery 1.7.1+ for on()/off() support.
1541
+ // Angular 1.2+ requires jQuery 1.7+ for on()/off() support.
1542
+ // Angular 1.3+ technically requires at least jQuery 2.1+ but it may work with older
1543
+ // versions. It will not work for sure with jQuery <1.7, though.
1541
1544
  if (jQuery && jQuery.fn.on) {
1542
1545
  jqLite = jQuery;
1543
1546
  extend(jQuery.fn, {
@@ -2067,11 +2070,11 @@ function setupModuleLoader(window) {
2067
2070
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
2068
2071
  */
2069
2072
  var version = {
2070
- full: '1.3.0-beta.17', // all of these placeholder strings will be replaced by grunt's
2073
+ full: '1.3.0-beta.18', // all of these placeholder strings will be replaced by grunt's
2071
2074
  major: 1, // package task
2072
2075
  minor: 3,
2073
2076
  dot: 0,
2074
- codeName: 'turing-autocompletion'
2077
+ codeName: 'spontaneous-combustion'
2075
2078
  };
2076
2079
 
2077
2080
 
@@ -2084,11 +2087,11 @@ function publishExternalAPI(angular){
2084
2087
  'element': jqLite,
2085
2088
  'forEach': forEach,
2086
2089
  'injector': createInjector,
2087
- 'noop':noop,
2088
- 'bind':bind,
2090
+ 'noop': noop,
2091
+ 'bind': bind,
2089
2092
  'toJson': toJson,
2090
2093
  'fromJson': fromJson,
2091
- 'identity':identity,
2094
+ 'identity': identity,
2092
2095
  'isUndefined': isUndefined,
2093
2096
  'isDefined': isDefined,
2094
2097
  'isString': isString,
@@ -2451,7 +2454,7 @@ function jqLiteDealoc(element, onlyDescendants){
2451
2454
 
2452
2455
  if (element.childNodes && element.childNodes.length) {
2453
2456
  // we use querySelectorAll because documentFragments don't have getElementsByTagName
2454
- var descendants = element.getElementsByTagName ? element.getElementsByTagName('*') :
2457
+ var descendants = element.getElementsByTagName ? sliceArgs(element.getElementsByTagName('*')) :
2455
2458
  element.querySelectorAll ? element.querySelectorAll('*') : [];
2456
2459
  for (var i = 0, l = descendants.length; i < l; i++) {
2457
2460
  jqLiteRemoveData(descendants[i]);
@@ -3150,26 +3153,37 @@ forEach({
3150
3153
 
3151
3154
  clone: jqLiteClone,
3152
3155
 
3153
- triggerHandler: function(element, eventName, eventData) {
3154
- // Copy event handlers in case event handlers array is modified during execution.
3155
- var eventFns = (jqLiteExpandoStore(element, 'events') || {})[eventName],
3156
- eventFnsCopy = shallowCopy(eventFns || []);
3156
+ triggerHandler: function(element, event, extraParameters) {
3157
3157
 
3158
- eventData = eventData || [];
3158
+ var dummyEvent, eventFnsCopy, handlerArgs;
3159
+ var eventName = event.type || event;
3160
+ var eventFns = (jqLiteExpandoStore(element, 'events') || {})[eventName];
3159
3161
 
3160
- var event = [{
3161
- preventDefault: function() {
3162
- this.defaultPrevented = true;
3163
- },
3164
- isDefaultPrevented: function() {
3165
- return this.defaultPrevented === true;
3166
- },
3167
- stopPropagation: noop
3168
- }];
3162
+ if (eventFns) {
3169
3163
 
3170
- forEach(eventFnsCopy, function(fn) {
3171
- fn.apply(element, event.concat(eventData));
3172
- });
3164
+ // Create a dummy event to pass to the handlers
3165
+ dummyEvent = {
3166
+ preventDefault: function() { this.defaultPrevented = true; },
3167
+ isDefaultPrevented: function() { return this.defaultPrevented === true; },
3168
+ stopPropagation: noop,
3169
+ type: eventName,
3170
+ target: element
3171
+ };
3172
+
3173
+ // If a custom event was provided then extend our dummy event with it
3174
+ if (event.type) {
3175
+ dummyEvent = extend(dummyEvent, event);
3176
+ }
3177
+
3178
+ // Copy event handlers in case event handlers array is modified during execution.
3179
+ eventFnsCopy = shallowCopy(eventFns);
3180
+ handlerArgs = extraParameters ? [dummyEvent].concat(extraParameters) : [dummyEvent];
3181
+
3182
+ forEach(eventFnsCopy, function(fn) {
3183
+ fn.apply(element, handlerArgs);
3184
+ });
3185
+
3186
+ }
3173
3187
  }
3174
3188
  }, function(fn, name){
3175
3189
  /**
@@ -5345,7 +5359,7 @@ function $TemplateCacheProvider() {
5345
5359
  * The directive definition object provides instructions to the {@link ng.$compile
5346
5360
  * compiler}. The attributes are:
5347
5361
  *
5348
- * ### `multiElement`
5362
+ * #### `multiElement`
5349
5363
  * When this property is set to true, the HTML compiler will collect DOM nodes between
5350
5364
  * nodes with the attributes `directive-name-start` and `directive-name-end`, and group them
5351
5365
  * together as the directive elements. It is recomended that this feature be used on directives
@@ -5468,7 +5482,7 @@ function $TemplateCacheProvider() {
5468
5482
  *
5469
5483
  * #### `template`
5470
5484
  * HTML markup that may:
5471
- * * Replace the contents of the directive's element (defualt).
5485
+ * * Replace the contents of the directive's element (default).
5472
5486
  * * Replace the directive's element itself (if `replace` is true - DEPRECATED).
5473
5487
  * * Wrap the contents of the directive's element (if `transclude` is true).
5474
5488
  *
@@ -6741,7 +6755,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6741
6755
  if (parentGet.literal) {
6742
6756
  compare = equals;
6743
6757
  } else {
6744
- compare = function(a,b) { return a === b; };
6758
+ compare = function(a,b) { return a === b || (a !== a && b !== b); };
6745
6759
  }
6746
6760
  parentSet = parentGet.assign || function() {
6747
6761
  // reset the change, or we will throw this exception on every $digest
@@ -7265,7 +7279,25 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7265
7279
  }
7266
7280
  var fragment = document.createDocumentFragment();
7267
7281
  fragment.appendChild(firstElementToRemove);
7268
- newNode[jqLite.expando] = firstElementToRemove[jqLite.expando];
7282
+
7283
+ // Copy over user data (that includes Angular's $scope etc.). Don't copy private
7284
+ // data here because there's no public interface in jQuery to do that and copying over
7285
+ // event listeners (which is the main use of private data) wouldn't work anyway.
7286
+ jqLite(newNode).data(jqLite(firstElementToRemove).data());
7287
+
7288
+ // Remove data of the replaced element. We cannot just call .remove()
7289
+ // on the element it since that would deallocate scope that is needed
7290
+ // for the new node. Instead, remove the data "manually".
7291
+ if (!jQuery) {
7292
+ delete jqLite.cache[firstElementToRemove[jqLite.expando]];
7293
+ } else {
7294
+ // jQuery 2.x doesn't expose the data storage. Use jQuery.cleanData to clean up after the replaced
7295
+ // element. Note that we need to use the original method here and not the one monkey-patched by Angular
7296
+ // since the patched method emits the $destroy event causing the scope to be trashed and we do need
7297
+ // the very same scope to work with the new element.
7298
+ jQuery.cleanData.$$original([firstElementToRemove]);
7299
+ }
7300
+
7269
7301
  for (var k = 1, kk = elementsToRemove.length; k < kk; k++) {
7270
7302
  var element = elementsToRemove[k];
7271
7303
  jqLite(element).remove(); // must do this way to clean up expando
@@ -7793,6 +7825,7 @@ function $HttpProvider() {
7793
7825
  * - {@link ng.$http#put $http.put}
7794
7826
  * - {@link ng.$http#delete $http.delete}
7795
7827
  * - {@link ng.$http#jsonp $http.jsonp}
7828
+ * - {@link ng.$http#patch $http.patch}
7796
7829
  *
7797
7830
  *
7798
7831
  * # Setting HTTP Headers
@@ -8049,7 +8082,7 @@ function $HttpProvider() {
8049
8082
  * - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise}
8050
8083
  * that should abort the request when resolved.
8051
8084
  * - **withCredentials** - `{boolean}` - whether to set the `withCredentials` flag on the
8052
- * XHR object. See [requests with credentials]https://developer.mozilla.org/en/http_access_control#section_5
8085
+ * XHR object. See [requests with credentials](https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials)
8053
8086
  * for more information.
8054
8087
  * - **responseType** - `{string}` - see
8055
8088
  * [requestType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType).
@@ -8431,7 +8464,8 @@ function $HttpProvider() {
8431
8464
  promise.then(removePendingReq, removePendingReq);
8432
8465
 
8433
8466
 
8434
- if ((config.cache || defaults.cache) && config.cache !== false && config.method == 'GET') {
8467
+ if ((config.cache || defaults.cache) && config.cache !== false &&
8468
+ (config.method === 'GET' || config.method === 'JSONP')) {
8435
8469
  cache = isObject(config.cache) ? config.cache
8436
8470
  : isObject(defaults.cache) ? defaults.cache
8437
8471
  : defaultCache;
@@ -10002,6 +10036,8 @@ function $LocationProvider(){
10002
10036
  $location = new LocationMode(appBase, '#' + hashPrefix);
10003
10037
  $location.$$parse($location.$$rewrite(initialUrl));
10004
10038
 
10039
+ var IGNORE_URI_REGEXP = /^\s*(javascript|mailto):/i;
10040
+
10005
10041
  $rootElement.on('click', function(event) {
10006
10042
  // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)
10007
10043
  // currently we open nice url link and redirect then
@@ -10024,6 +10060,9 @@ function $LocationProvider(){
10024
10060
  absHref = urlResolve(absHref.animVal).href;
10025
10061
  }
10026
10062
 
10063
+ // Ignore when url is started with javascript: or mailto:
10064
+ if (IGNORE_URI_REGEXP.test(absHref)) return;
10065
+
10027
10066
  // Make relative links work in HTML5 mode for legacy browsers (or at least IE8 & 9)
10028
10067
  // The href should be a regular url e.g. /link/somewhere or link/somewhere or ../somewhere or
10029
10068
  // somewhere#anchor or http://example.com/somewhere
@@ -10878,9 +10917,9 @@ Parser.prototype = {
10878
10917
  var middle;
10879
10918
  var token;
10880
10919
  if ((token = this.expect('?'))) {
10881
- middle = this.ternary();
10920
+ middle = this.assignment();
10882
10921
  if ((token = this.expect(':'))) {
10883
- return this.ternaryFn(left, middle, this.ternary());
10922
+ return this.ternaryFn(left, middle, this.assignment());
10884
10923
  } else {
10885
10924
  this.throwError('expected :', token);
10886
10925
  }
@@ -10968,7 +11007,9 @@ Parser.prototype = {
10968
11007
  return getter(self || object(scope, locals));
10969
11008
  }, {
10970
11009
  assign: function(scope, value, locals) {
10971
- return setter(object(scope, locals), field, value, parser.text);
11010
+ var o = object(scope, locals);
11011
+ if (!o) object.assign(scope, o = {});
11012
+ return setter(o, field, value, parser.text);
10972
11013
  }
10973
11014
  });
10974
11015
  },
@@ -10990,10 +11031,11 @@ Parser.prototype = {
10990
11031
  return v;
10991
11032
  }, {
10992
11033
  assign: function(self, value, locals) {
10993
- var key = indexFn(self, locals);
11034
+ var key = ensureSafeMemberName(indexFn(self, locals), parser.text);
10994
11035
  // prevent overwriting of Function.constructor which would break ensureSafeObject check
10995
- var safe = ensureSafeObject(obj(self, locals), parser.text);
10996
- return safe[key] = value;
11036
+ var o = ensureSafeObject(obj(self, locals), parser.text);
11037
+ if (!o) obj.assign(self, o = {});
11038
+ return o[key] = value;
10997
11039
  }
10998
11040
  });
10999
11041
  },
@@ -11298,8 +11340,12 @@ function $ParseProvider() {
11298
11340
  var parser = new Parser(lexer, $filter, $parseOptions);
11299
11341
  parsedExpression = parser.parse(exp);
11300
11342
 
11301
- if (parsedExpression.constant) parsedExpression.$$watchDelegate = constantWatch;
11302
- else if (oneTime) parsedExpression.$$watchDelegate = oneTimeWatch;
11343
+ if (parsedExpression.constant) {
11344
+ parsedExpression.$$watchDelegate = constantWatch;
11345
+ } else if (oneTime) {
11346
+ parsedExpression.$$watchDelegate = parsedExpression.literal ?
11347
+ oneTimeLiteralWatch : oneTimeWatch;
11348
+ }
11303
11349
 
11304
11350
  if (cacheKey !== 'hasOwnProperty') {
11305
11351
  // Only cache the value if it's not going to mess up the cache object
@@ -11336,6 +11382,30 @@ function $ParseProvider() {
11336
11382
  }, objectEquality, deregisterNotifier);
11337
11383
  }
11338
11384
 
11385
+ function oneTimeLiteralWatch(scope, listener, objectEquality, deregisterNotifier, parsedExpression) {
11386
+ var unwatch;
11387
+ return unwatch = scope.$watch(function oneTimeWatch(scope) {
11388
+ return parsedExpression(scope);
11389
+ }, function oneTimeListener(value, old, scope) {
11390
+ if (isFunction(listener)) {
11391
+ listener.call(this, value, old, scope);
11392
+ }
11393
+ if (isAllDefined(value)) {
11394
+ scope.$$postDigest(function () {
11395
+ if(isAllDefined(value)) unwatch();
11396
+ });
11397
+ }
11398
+ }, objectEquality);
11399
+
11400
+ function isAllDefined(value) {
11401
+ var allDefined = true;
11402
+ forEach(value, function (val) {
11403
+ if (!isDefined(val)) allDefined = false;
11404
+ });
11405
+ return allDefined;
11406
+ }
11407
+ }
11408
+
11339
11409
  function constantWatch(scope, listener, objectEquality, deregisterNotifier, parsedExpression) {
11340
11410
  var unwatch;
11341
11411
  return unwatch = scope.$watch(function constantWatch(scope) {
@@ -11613,143 +11683,122 @@ function qFactory(nextTick, exceptionHandler) {
11613
11683
  * @returns {Deferred} Returns a new instance of deferred.
11614
11684
  */
11615
11685
  var defer = function() {
11616
- var pending = [],
11617
- value, deferred;
11618
-
11619
- deferred = {
11620
-
11621
- resolve: function(val) {
11622
- if (pending) {
11623
- var callbacks = pending;
11624
- pending = undefined;
11625
- value = ref(val);
11626
-
11627
- if (callbacks.length) {
11628
- nextTick(function() {
11629
- var callback;
11630
- for (var i = 0, ii = callbacks.length; i < ii; i++) {
11631
- callback = callbacks[i];
11632
- value.then(callback[0], callback[1], callback[2]);
11633
- }
11634
- });
11635
- }
11636
- }
11637
- },
11638
-
11639
-
11640
- reject: function(reason) {
11641
- deferred.resolve(createInternalRejectedPromise(reason));
11642
- },
11686
+ return new Deferred();
11687
+ };
11643
11688
 
11689
+ function Promise () {
11690
+ this.$$pending = [];
11691
+ }
11644
11692
 
11645
- notify: function(progress) {
11646
- if (pending) {
11647
- var callbacks = pending;
11693
+ Promise.prototype = {
11694
+ then: function(callback, errback, progressback) {
11695
+ var result = new Deferred();
11648
11696
 
11649
- if (pending.length) {
11650
- nextTick(function() {
11651
- var callback;
11652
- for (var i = 0, ii = callbacks.length; i < ii; i++) {
11653
- callback = callbacks[i];
11654
- callback[2](progress);
11655
- }
11656
- });
11657
- }
11697
+ var wrappedCallback = function(value) {
11698
+ try {
11699
+ result.resolve((isFunction(callback) ? callback : defaultCallback)(value));
11700
+ } catch(e) {
11701
+ result.reject(e);
11702
+ exceptionHandler(e);
11658
11703
  }
11659
- },
11660
-
11661
-
11662
- promise: {
11663
- then: function(callback, errback, progressback) {
11664
- var result = defer();
11665
-
11666
- var wrappedCallback = function(value) {
11667
- try {
11668
- result.resolve((isFunction(callback) ? callback : defaultCallback)(value));
11669
- } catch(e) {
11670
- result.reject(e);
11671
- exceptionHandler(e);
11672
- }
11673
- };
11704
+ };
11674
11705
 
11675
- var wrappedErrback = function(reason) {
11676
- try {
11677
- result.resolve((isFunction(errback) ? errback : defaultErrback)(reason));
11678
- } catch(e) {
11679
- result.reject(e);
11680
- exceptionHandler(e);
11681
- }
11682
- };
11706
+ var wrappedErrback = function(reason) {
11707
+ try {
11708
+ result.resolve((isFunction(errback) ? errback : defaultErrback)(reason));
11709
+ } catch(e) {
11710
+ result.reject(e);
11711
+ exceptionHandler(e);
11712
+ }
11713
+ };
11683
11714
 
11684
- var wrappedProgressback = function(progress) {
11685
- try {
11686
- result.notify((isFunction(progressback) ? progressback : defaultCallback)(progress));
11687
- } catch(e) {
11688
- exceptionHandler(e);
11689
- }
11690
- };
11715
+ var wrappedProgressback = function(progress) {
11716
+ try {
11717
+ result.notify((isFunction(progressback) ? progressback : defaultCallback)(progress));
11718
+ } catch(e) {
11719
+ exceptionHandler(e);
11720
+ }
11721
+ };
11691
11722
 
11692
- if (pending) {
11693
- pending.push([wrappedCallback, wrappedErrback, wrappedProgressback]);
11694
- } else {
11695
- value.then(wrappedCallback, wrappedErrback, wrappedProgressback);
11696
- }
11723
+ if (this.$$pending) {
11724
+ this.$$pending.push([wrappedCallback, wrappedErrback, wrappedProgressback]);
11725
+ } else {
11726
+ this.$$value.then(wrappedCallback, wrappedErrback, wrappedProgressback);
11727
+ }
11697
11728
 
11698
- return result.promise;
11699
- },
11729
+ return result.promise;
11730
+ },
11700
11731
 
11701
- "catch": function(callback) {
11702
- return this.then(null, callback);
11703
- },
11732
+ "catch": function(callback) {
11733
+ return this.then(null, callback);
11734
+ },
11735
+ "finally": function(callback) {
11736
+ return this.then(function(value) {
11737
+ return handleCallback(value, true, callback);
11738
+ }, function(error) {
11739
+ return handleCallback(error, false, callback);
11740
+ });
11741
+ }
11742
+ };
11704
11743
 
11705
- "finally": function(callback) {
11744
+ //Faster, more basic than angular.bind http://jsperf.com/angular-bind-vs-custom-vs-native
11745
+ function simpleBind(context, fn) {
11746
+ return function(value) {
11747
+ fn.call(context, value);
11748
+ };
11749
+ }
11706
11750
 
11707
- function makePromise(value, resolved) {
11708
- var result = defer();
11709
- if (resolved) {
11710
- result.resolve(value);
11711
- } else {
11712
- result.reject(value);
11713
- }
11714
- return result.promise;
11715
- }
11751
+ function Deferred () {
11752
+ this.promise = new Promise();
11753
+ //Necessary to support unbound execution :/
11754
+ this.resolve = simpleBind(this, this.resolve);
11755
+ this.reject = simpleBind(this, this.reject);
11756
+ this.notify = simpleBind(this, this.notify);
11757
+ }
11716
11758
 
11717
- function handleCallback(value, isResolved) {
11718
- var callbackOutput = null;
11719
- try {
11720
- callbackOutput = (callback ||defaultCallback)();
11721
- } catch(e) {
11722
- return makePromise(e, false);
11759
+ Deferred.prototype = {
11760
+ resolve: function(val) {
11761
+ if (this.promise.$$pending) {
11762
+ var callbacks = this.promise.$$pending;
11763
+ this.promise.$$pending = undefined;
11764
+ this.promise.$$value = ref(val);
11765
+
11766
+ if (callbacks.length) {
11767
+ nextTick(simpleBind(this, function() {
11768
+ var callback;
11769
+ for (var i = 0, ii = callbacks.length; i < ii; i++) {
11770
+ callback = callbacks[i];
11771
+ this.promise.$$value.then(callback[0], callback[1], callback[2]);
11723
11772
  }
11724
- if (isPromiseLike(callbackOutput)) {
11725
- return callbackOutput.then(function() {
11726
- return makePromise(value, isResolved);
11727
- }, function(error) {
11728
- return makePromise(error, false);
11729
- });
11730
- } else {
11731
- return makePromise(value, isResolved);
11773
+ }));
11774
+ }
11775
+ }
11776
+ },
11777
+ reject: function(reason) {
11778
+ this.resolve(createInternalRejectedPromise(reason));
11779
+ },
11780
+ notify: function(progress) {
11781
+ if (this.promise.$$pending) {
11782
+ var callbacks = this.promise.$$pending;
11783
+
11784
+ if (this.promise.$$pending.length) {
11785
+ nextTick(function() {
11786
+ var callback;
11787
+ for (var i = 0, ii = callbacks.length; i < ii; i++) {
11788
+ callback = callbacks[i];
11789
+ callback[2](progress);
11732
11790
  }
11733
- }
11734
-
11735
- return this.then(function(value) {
11736
- return handleCallback(value, true);
11737
- }, function(error) {
11738
- return handleCallback(error, false);
11739
11791
  });
11740
11792
  }
11741
11793
  }
11742
- };
11743
-
11744
- return deferred;
11794
+ }
11745
11795
  };
11746
11796
 
11747
-
11748
11797
  var ref = function(value) {
11749
11798
  if (isPromiseLike(value)) return value;
11750
11799
  return {
11751
11800
  then: function(callback) {
11752
- var result = defer();
11801
+ var result = new Deferred();
11753
11802
  nextTick(function() {
11754
11803
  result.resolve(callback(value));
11755
11804
  });
@@ -11796,15 +11845,43 @@ function qFactory(nextTick, exceptionHandler) {
11796
11845
  * @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`.
11797
11846
  */
11798
11847
  var reject = function(reason) {
11799
- var result = defer();
11848
+ var result = new Deferred();
11800
11849
  result.reject(reason);
11801
11850
  return result.promise;
11802
11851
  };
11803
11852
 
11853
+ var makePromise = function makePromise(value, resolved) {
11854
+ var result = new Deferred();
11855
+ if (resolved) {
11856
+ result.resolve(value);
11857
+ } else {
11858
+ result.reject(value);
11859
+ }
11860
+ return result.promise;
11861
+ };
11862
+
11863
+ var handleCallback = function handleCallback(value, isResolved, callback) {
11864
+ var callbackOutput = null;
11865
+ try {
11866
+ callbackOutput = (callback ||defaultCallback)();
11867
+ } catch(e) {
11868
+ return makePromise(e, false);
11869
+ }
11870
+ if (isPromiseLike(callbackOutput)) {
11871
+ return callbackOutput.then(function() {
11872
+ return makePromise(value, isResolved);
11873
+ }, function(error) {
11874
+ return makePromise(error, false);
11875
+ });
11876
+ } else {
11877
+ return makePromise(value, isResolved);
11878
+ }
11879
+ };
11880
+
11804
11881
  var createInternalRejectedPromise = function(reason) {
11805
11882
  return {
11806
11883
  then: function(callback, errback) {
11807
- var result = defer();
11884
+ var result = new Deferred();
11808
11885
  nextTick(function() {
11809
11886
  try {
11810
11887
  result.resolve((isFunction(errback) ? errback : defaultErrback)(reason));
@@ -11833,7 +11910,7 @@ function qFactory(nextTick, exceptionHandler) {
11833
11910
  * @returns {Promise} Returns a promise of the passed value or promise
11834
11911
  */
11835
11912
  var when = function(value, callback, errback, progressback) {
11836
- var result = defer(),
11913
+ var result = new Deferred(),
11837
11914
  done;
11838
11915
 
11839
11916
  var wrappedCallback = function(value) {
@@ -11907,7 +11984,7 @@ function qFactory(nextTick, exceptionHandler) {
11907
11984
  * with the same rejection value.
11908
11985
  */
11909
11986
  function all(promises) {
11910
- var deferred = defer(),
11987
+ var deferred = new Deferred(),
11911
11988
  counter = 0,
11912
11989
  results = isArray(promises) ? [] : {};
11913
11990
 
@@ -11941,7 +12018,7 @@ function qFactory(nextTick, exceptionHandler) {
11941
12018
  return new Q(resolver);
11942
12019
  }
11943
12020
 
11944
- var deferred = defer();
12021
+ var deferred = new Deferred();
11945
12022
 
11946
12023
  function resolveFn(value) {
11947
12024
  deferred.resolve(value);
@@ -12244,7 +12321,6 @@ function $RootScopeProvider(){
12244
12321
  * can compare the `newVal` and `oldVal`. If these two values are identical (`===`) then the
12245
12322
  * listener was called due to initialization.
12246
12323
  *
12247
- * The example below contains an illustration of using a function as your $watch listener
12248
12324
  *
12249
12325
  *
12250
12326
  * # Example
@@ -12274,14 +12350,14 @@ function $RootScopeProvider(){
12274
12350
 
12275
12351
 
12276
12352
 
12277
- // Using a listener function
12353
+ // Using a function as a watchExpression
12278
12354
  var food;
12279
12355
  scope.foodCounter = 0;
12280
12356
  expect(scope.foodCounter).toEqual(0);
12281
12357
  scope.$watch(
12282
- // This is the listener function
12358
+ // This function returns the value being watched. It is called for each turn of the $digest loop
12283
12359
  function() { return food; },
12284
- // This is the change handler
12360
+ // This is the change listener, called when the value returned from the above function changes
12285
12361
  function(newValue, oldValue) {
12286
12362
  if ( newValue !== oldValue ) {
12287
12363
  // Only increment the counter if the value changed
@@ -15407,7 +15483,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZEw']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d
15407
15483
  * (e.g. `"h 'o''clock'"`).
15408
15484
  *
15409
15485
  * @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or
15410
- * number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.SSSZ and its
15486
+ * number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.sssZ and its
15411
15487
  * shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is
15412
15488
  * specified in the string input, the time is considered to be in the local timezone.
15413
15489
  * @param {string=} format Formatting rules (see Description). If not specified,
@@ -15923,12 +15999,12 @@ var htmlAnchorDirective = valueFn({
15923
15999
  *
15924
16000
  * The wrong way to write it:
15925
16001
  * ```html
15926
- * <a href="http://www.gravatar.com/avatar/{{hash}}"/>
16002
+ * <a href="http://www.gravatar.com/avatar/{{hash}}">link1</a>
15927
16003
  * ```
15928
16004
  *
15929
16005
  * The correct way to write it:
15930
16006
  * ```html
15931
- * <a ng-href="http://www.gravatar.com/avatar/{{hash}}"/>
16007
+ * <a ng-href="http://www.gravatar.com/avatar/{{hash}}">link1</a>
15932
16008
  * ```
15933
16009
  *
15934
16010
  * @element A
@@ -16330,14 +16406,16 @@ forEach(['src', 'srcset', 'href'], function(attrName) {
16330
16406
  };
16331
16407
  });
16332
16408
 
16333
- /* global -nullFormCtrl */
16409
+ /* global -nullFormCtrl, -SUBMITTED_CLASS */
16334
16410
  var nullFormCtrl = {
16335
16411
  $addControl: noop,
16336
16412
  $removeControl: noop,
16337
16413
  $setValidity: noop,
16338
16414
  $setDirty: noop,
16339
- $setPristine: noop
16340
- };
16415
+ $setPristine: noop,
16416
+ $setSubmitted: noop
16417
+ },
16418
+ SUBMITTED_CLASS = 'ng-submitted';
16341
16419
 
16342
16420
  /**
16343
16421
  * @ngdoc type
@@ -16390,6 +16468,7 @@ function FormController(element, attrs, $scope, $animate) {
16390
16468
  form.$pristine = true;
16391
16469
  form.$valid = true;
16392
16470
  form.$invalid = false;
16471
+ form.$submitted = false;
16393
16472
 
16394
16473
  parentForm.$addControl(form);
16395
16474
 
@@ -16558,16 +16637,28 @@ function FormController(element, attrs, $scope, $animate) {
16558
16637
  * saving or resetting it.
16559
16638
  */
16560
16639
  form.$setPristine = function () {
16561
- $animate.removeClass(element, DIRTY_CLASS);
16562
- $animate.addClass(element, PRISTINE_CLASS);
16640
+ $animate.setClass(element, PRISTINE_CLASS, DIRTY_CLASS + ' ' + SUBMITTED_CLASS);
16563
16641
  form.$dirty = false;
16564
16642
  form.$pristine = true;
16643
+ form.$submitted = false;
16565
16644
  forEach(controls, function(control) {
16566
16645
  control.$setPristine();
16567
16646
  });
16568
16647
  };
16569
- }
16570
16648
 
16649
+ /**
16650
+ * @ngdoc method
16651
+ * @name form.FormController#setSubmitted
16652
+ *
16653
+ * @description
16654
+ * Sets the form to its submitted state.
16655
+ */
16656
+ form.$setSubmitted = function () {
16657
+ $animate.addClass(element, SUBMITTED_CLASS);
16658
+ form.$submitted = true;
16659
+ parentForm.$setSubmitted();
16660
+ };
16661
+ }
16571
16662
 
16572
16663
  /**
16573
16664
  * @ngdoc directive
@@ -16617,6 +16708,7 @@ function FormController(element, attrs, $scope, $animate) {
16617
16708
  * - `ng-invalid` is set if the form is invalid.
16618
16709
  * - `ng-pristine` is set if the form is pristine.
16619
16710
  * - `ng-dirty` is set if the form is dirty.
16711
+ * - `ng-submitted` is set if the form was submitted.
16620
16712
  *
16621
16713
  * Keep in mind that ngAnimate can detect each of these classes when added and removed.
16622
16714
  *
@@ -16753,6 +16845,7 @@ var formDirectiveFactory = function(isNgForm) {
16753
16845
  var handleFormSubmission = function(event) {
16754
16846
  scope.$apply(function() {
16755
16847
  controller.$commitViewValue();
16848
+ controller.$setSubmitted();
16756
16849
  });
16757
16850
 
16758
16851
  event.preventDefault
@@ -16930,7 +17023,7 @@ var inputType = {
16930
17023
  }]);
16931
17024
  </script>
16932
17025
  <form name="myForm" ng-controller="DateController as dateCtrl">
16933
- Pick a date between in 2013:
17026
+ Pick a date in 2013:
16934
17027
  <input type="date" id="exampleInput" name="input" ng-model="value"
16935
17028
  placeholder="yyyy-MM-dd" min="2013-01-01" max="2013-12-31" required />
16936
17029
  <span class="error" ng-show="myForm.input.$error.required">
@@ -18980,6 +19073,8 @@ var ngModelDirective = function() {
18980
19073
  }
18981
19074
 
18982
19075
  element.on('blur', function(ev) {
19076
+ if (modelCtrl.$touched) return;
19077
+
18983
19078
  scope.$apply(function() {
18984
19079
  modelCtrl.$setTouched();
18985
19080
  });
@@ -18999,7 +19094,15 @@ var ngModelDirective = function() {
18999
19094
  * The expression is evaluated immediately, unlike the JavaScript onchange event
19000
19095
  * which only triggers at the end of a change (usually, when the user leaves the
19001
19096
  * form element or presses the return key).
19002
- * The expression is not evaluated when the value change is coming from the model.
19097
+ *
19098
+ * The `ngChange` expression is only evaluated when a change in the input value causes
19099
+ * a new value to be committed to the model.
19100
+ *
19101
+ * It will not be evaluated:
19102
+ * * if the value returned from the `$parsers` transformation pipeline has not changed
19103
+ * * if the input has continued to be invalid since the model will stay `null`
19104
+ * * if the model is changed programmatically and not by a change to the input value
19105
+ *
19003
19106
  *
19004
19107
  * Note, this directive requires `ngModel` to be present.
19005
19108
  *
@@ -20156,10 +20259,16 @@ var ngCloakDirective = ngDirective({
20156
20259
  *
20157
20260
  * @element ANY
20158
20261
  * @scope
20159
- * @param {expression} ngController Name of a globally accessible constructor function or an
20160
- * {@link guide/expression expression} that on the current scope evaluates to a
20161
- * constructor function. The controller instance can be published into a scope property
20162
- * by specifying `as propertyName`.
20262
+ * @param {expression} ngController Name of a constructor function registered with the current
20263
+ * {@link ng.$controllerProvider $controllerProvider} or an {@link guide/expression expression}
20264
+ * that on the current scope evaluates to a constructor function.
20265
+ *
20266
+ * The controller instance can be published into a scope property by specifying
20267
+ * `ng-controller="as propertyName"`.
20268
+ *
20269
+ * If the current `$controllerProvider` is configured to use globals (via
20270
+ * {@link ng.$controllerProvider#allowGlobals `$controllerProvider.allowGlobals()` }), this may
20271
+ * also be the name of a globally accessible constructor function (not recommended).
20163
20272
  *
20164
20273
  * @example
20165
20274
  * Here is a simple form for editing user contact information. Adding, removing, clearing, and
@@ -20724,6 +20833,13 @@ forEach(
20724
20833
  * server and reloading the current page), but only if the form does not contain `action`,
20725
20834
  * `data-action`, or `x-action` attributes.
20726
20835
  *
20836
+ * <div class="alert alert-warning">
20837
+ * **Warning:** Be careful not to cause "double-submission" by using both the `ngClick` and
20838
+ * `ngSubmit` handlers together. See the
20839
+ * {@link form#submitting-a-form-and-preventing-the-default-action `form` directive documentation}
20840
+ * for a detailed discussion of when `ngSubmit` may be triggered.
20841
+ * </div>
20842
+ *
20727
20843
  * @element form
20728
20844
  * @priority 0
20729
20845
  * @param {expression} ngSubmit {@link guide/expression Expression} to eval.
@@ -23091,21 +23207,37 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
23091
23207
  value = valueFn(scope, locals);
23092
23208
  }
23093
23209
  }
23094
- // Update the null option's selected property here so $render cleans it up correctly
23095
- if (optionGroupsCache[0].length > 1) {
23096
- if (optionGroupsCache[0][1].id !== key) {
23097
- optionGroupsCache[0][1].selected = false;
23098
- }
23099
- }
23100
23210
  }
23101
23211
  ctrl.$setViewValue(value);
23212
+ render();
23102
23213
  });
23103
23214
  });
23104
23215
 
23105
23216
  ctrl.$render = render;
23106
23217
 
23107
- // TODO(vojta): can't we optimize this ?
23108
- scope.$watch(render);
23218
+ scope.$watchCollection(valuesFn, render);
23219
+ if ( multiple ) {
23220
+ scope.$watchCollection(function() { return ctrl.$modelValue; }, render);
23221
+ }
23222
+
23223
+ function getSelectedSet() {
23224
+ var selectedSet = false;
23225
+ if (multiple) {
23226
+ var modelValue = ctrl.$modelValue;
23227
+ if (trackFn && isArray(modelValue)) {
23228
+ selectedSet = new HashMap([]);
23229
+ var locals = {};
23230
+ for (var trackIndex = 0; trackIndex < modelValue.length; trackIndex++) {
23231
+ locals[valueName] = modelValue[trackIndex];
23232
+ selectedSet.put(trackFn(scope, locals), modelValue[trackIndex]);
23233
+ }
23234
+ } else {
23235
+ selectedSet = new HashMap(modelValue);
23236
+ }
23237
+ }
23238
+ return selectedSet;
23239
+ }
23240
+
23109
23241
 
23110
23242
  function render() {
23111
23243
  // Temporary location for the option groups before we render them
@@ -23123,22 +23255,11 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
23123
23255
  groupIndex, index,
23124
23256
  locals = {},
23125
23257
  selected,
23126
- selectedSet = false, // nothing is selected yet
23258
+ selectedSet = getSelectedSet(),
23127
23259
  lastElement,
23128
23260
  element,
23129
23261
  label;
23130
23262
 
23131
- if (multiple) {
23132
- if (trackFn && isArray(modelValue)) {
23133
- selectedSet = new HashMap([]);
23134
- for (var trackIndex = 0; trackIndex < modelValue.length; trackIndex++) {
23135
- locals[valueName] = modelValue[trackIndex];
23136
- selectedSet.put(trackFn(scope, locals), modelValue[trackIndex]);
23137
- }
23138
- } else {
23139
- selectedSet = new HashMap(modelValue);
23140
- }
23141
- }
23142
23263
 
23143
23264
  // We now build up the list of options we need (we merge later)
23144
23265
  for (index = 0; length = keys.length, index < length; index++) {
@@ -23234,7 +23355,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
23234
23355
  lastElement.val(existingOption.id = option.id);
23235
23356
  }
23236
23357
  // lastElement.prop('selected') provided by jQuery has side-effects
23237
- if (existingOption.selected !== option.selected) {
23358
+ if (lastElement[0].selected !== option.selected) {
23238
23359
  lastElement.prop('selected', (existingOption.selected = option.selected));
23239
23360
  if (msie) {
23240
23361
  // See #7692
@@ -23257,6 +23378,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
23257
23378
  (element = optionTemplate.clone())
23258
23379
  .val(option.id)
23259
23380
  .prop('selected', option.selected)
23381
+ .attr('selected', option.selected)
23260
23382
  .text(option.label);
23261
23383
  }
23262
23384