angular-gem 1.2.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.1
2
+ * @license AngularJS v1.2.2
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.1
2
+ * @license AngularJS v1.2.2
3
3
  * (c) 2010-2012 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.2.1/' +
71
+ message = message + '\nhttp://errors.angularjs.org/1.2.2/' +
72
72
  (module ? module + '/' : '') + code;
73
73
  for (i = 2; i < arguments.length; i++) {
74
74
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -159,7 +159,7 @@ function minErr(module) {
159
159
  -assertArgFn,
160
160
  -assertNotHasOwnProperty,
161
161
  -getter,
162
- -getBlockElements
162
+ -getBlockElements,
163
163
 
164
164
  */
165
165
 
@@ -1181,26 +1181,38 @@ function encodeUriQuery(val, pctEncodeSpaces) {
1181
1181
  *
1182
1182
  * @description
1183
1183
  *
1184
- * Use this directive to auto-bootstrap an application. Only
1185
- * one ngApp directive can be used per HTML document. The directive
1186
- * designates the root of the application and is typically placed
1187
- * at the root of the page.
1188
- *
1189
- * The first ngApp found in the document will be auto-bootstrapped. To use multiple applications in
1190
- * an HTML document you must manually bootstrap them using {@link angular.bootstrap}.
1191
- * Applications cannot be nested.
1192
- *
1193
- * In the example below if the `ngApp` directive were not placed
1194
- * on the `html` element then the document would not be compiled
1195
- * and the `{{ 1+2 }}` would not be resolved to `3`.
1196
- *
1197
- * `ngApp` is the easiest way to bootstrap an application.
1198
- *
1199
- <doc:example>
1200
- <doc:source>
1201
- I can add: 1 + 2 = {{ 1+2 }}
1202
- </doc:source>
1203
- </doc:example>
1184
+ * Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive
1185
+ * designates the **root element** of the application and is typically placed near the root element
1186
+ * of the page - e.g. on the `<body>` or `<html>` tags.
1187
+ *
1188
+ * Only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp`
1189
+ * found in the document will be used to define the root element to auto-bootstrap as an
1190
+ * application. To run multiple applications in an HTML document you must manually bootstrap them using
1191
+ * {@link angular.bootstrap} instead. AngularJS applications cannot be nested within each other.
1192
+ *
1193
+ * You can specify an **AngularJS module** to be used as the root module for the application. This
1194
+ * module will be loaded into the {@link AUTO.$injector} when the application is bootstrapped and
1195
+ * should contain the application code needed or have dependencies on other modules that will
1196
+ * contain the code. See {@link angular.module} for more information.
1197
+ *
1198
+ * In the example below if the `ngApp` directive were not placed on the `html` element then the
1199
+ * document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}`
1200
+ * would not be resolved to `3`.
1201
+ *
1202
+ * `ngApp` is the easiest, and most common, way to bootstrap an application.
1203
+ *
1204
+ <example module="ngAppDemo">
1205
+ <file name="index.html">
1206
+ <div ng-controller="ngAppDemoController">
1207
+ I can add: {{a}} + {{b}} = {{ a+b }}
1208
+ </file>
1209
+ <file name="script.js">
1210
+ angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) {
1211
+ $scope.a = 1;
1212
+ $scope.b = 2;
1213
+ });
1214
+ </file>
1215
+ </example>
1204
1216
  *
1205
1217
  */
1206
1218
  function angularInit(element, bootstrap) {
@@ -1435,7 +1447,12 @@ function setupModuleLoader(window) {
1435
1447
  return obj[name] || (obj[name] = factory());
1436
1448
  }
1437
1449
 
1438
- return ensure(ensure(window, 'angular', Object), 'module', function() {
1450
+ var angular = ensure(window, 'angular', Object);
1451
+
1452
+ // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
1453
+ angular.$$minErr = angular.$$minErr || minErr;
1454
+
1455
+ return ensure(angular, 'module', function() {
1439
1456
  /** @type {Object.<string, angular.Module>} */
1440
1457
  var modules = {};
1441
1458
 
@@ -1808,11 +1825,11 @@ function setupModuleLoader(window) {
1808
1825
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
1809
1826
  */
1810
1827
  var version = {
1811
- full: '1.2.1', // all of these placeholder strings will be replaced by grunt's
1828
+ full: '1.2.2', // all of these placeholder strings will be replaced by grunt's
1812
1829
  major: 1, // package task
1813
1830
  minor: 2,
1814
- dot: 1,
1815
- codeName: 'underscore-empathy'
1831
+ dot: 2,
1832
+ codeName: 'consciousness-inertia'
1816
1833
  };
1817
1834
 
1818
1835
 
@@ -3359,11 +3376,11 @@ function annotate(fn) {
3359
3376
  * @example
3360
3377
  * Here are some examples of creating value services.
3361
3378
  * <pre>
3362
- * $provide.constant('ADMIN_USER', 'admin');
3379
+ * $provide.value('ADMIN_USER', 'admin');
3363
3380
  *
3364
- * $provide.constant('RoleLookup', { admin: 0, writer: 1, reader: 2 });
3381
+ * $provide.value('RoleLookup', { admin: 0, writer: 1, reader: 2 });
3365
3382
  *
3366
- * $provide.constant('halfOf', function(value) {
3383
+ * $provide.value('halfOf', function(value) {
3367
3384
  * return value / 2;
3368
3385
  * });
3369
3386
  * </pre>
@@ -3849,13 +3866,14 @@ var $AnimateProvider = ['$provide', function($provide) {
3849
3866
  * inserted into the DOM
3850
3867
  */
3851
3868
  enter : function(element, parent, after, done) {
3852
- var afterNode = after && after[after.length - 1];
3853
- var parentNode = parent && parent[0] || afterNode && afterNode.parentNode;
3854
- // IE does not like undefined so we have to pass null.
3855
- var afterNextSibling = (afterNode && afterNode.nextSibling) || null;
3856
- forEach(element, function(node) {
3857
- parentNode.insertBefore(node, afterNextSibling);
3858
- });
3869
+ if (after) {
3870
+ after.after(element);
3871
+ } else {
3872
+ if (!parent || !parent[0]) {
3873
+ parent = after.parent();
3874
+ }
3875
+ parent.append(element);
3876
+ }
3859
3877
  done && $timeout(done, 0, false);
3860
3878
  },
3861
3879
 
@@ -5260,6 +5278,24 @@ function $CompileProvider($provide) {
5260
5278
  }
5261
5279
  },
5262
5280
 
5281
+ /**
5282
+ * @ngdoc function
5283
+ * @name ng.$compile.directive.Attributes#$updateClass
5284
+ * @methodOf ng.$compile.directive.Attributes
5285
+ * @function
5286
+ *
5287
+ * @description
5288
+ * Adds and removes the appropriate CSS class values to the element based on the difference
5289
+ * between the new and old CSS class values (specified as newClasses and oldClasses).
5290
+ *
5291
+ * @param {string} newClasses The current CSS className value
5292
+ * @param {string} oldClasses The former CSS className value
5293
+ */
5294
+ $updateClass : function(newClasses, oldClasses) {
5295
+ this.$removeClass(tokenDifference(oldClasses, newClasses));
5296
+ this.$addClass(tokenDifference(newClasses, oldClasses));
5297
+ },
5298
+
5263
5299
  /**
5264
5300
  * Set a normalized attribute on the element in a way such that all directives
5265
5301
  * can share the attribute. This function properly handles boolean attributes.
@@ -5270,59 +5306,53 @@ function $CompileProvider($provide) {
5270
5306
  * @param {string=} attrName Optional none normalized name. Defaults to key.
5271
5307
  */
5272
5308
  $set: function(key, value, writeAttr, attrName) {
5273
- //special case for class attribute addition + removal
5274
- //so that class changes can tap into the animation
5275
- //hooks provided by the $animate service
5276
- if(key == 'class') {
5277
- value = value || '';
5278
- var current = this.$$element.attr('class') || '';
5279
- this.$removeClass(tokenDifference(current, value).join(' '));
5280
- this.$addClass(tokenDifference(value, current).join(' '));
5281
- } else {
5282
- var booleanKey = getBooleanAttrName(this.$$element[0], key),
5283
- normalizedVal,
5284
- nodeName;
5309
+ // TODO: decide whether or not to throw an error if "class"
5310
+ //is set through this function since it may cause $updateClass to
5311
+ //become unstable.
5285
5312
 
5286
- if (booleanKey) {
5287
- this.$$element.prop(key, value);
5288
- attrName = booleanKey;
5289
- }
5313
+ var booleanKey = getBooleanAttrName(this.$$element[0], key),
5314
+ normalizedVal,
5315
+ nodeName;
5290
5316
 
5291
- this[key] = value;
5317
+ if (booleanKey) {
5318
+ this.$$element.prop(key, value);
5319
+ attrName = booleanKey;
5320
+ }
5292
5321
 
5293
- // translate normalized key to actual key
5294
- if (attrName) {
5295
- this.$attr[key] = attrName;
5296
- } else {
5297
- attrName = this.$attr[key];
5298
- if (!attrName) {
5299
- this.$attr[key] = attrName = snake_case(key, '-');
5300
- }
5322
+ this[key] = value;
5323
+
5324
+ // translate normalized key to actual key
5325
+ if (attrName) {
5326
+ this.$attr[key] = attrName;
5327
+ } else {
5328
+ attrName = this.$attr[key];
5329
+ if (!attrName) {
5330
+ this.$attr[key] = attrName = snake_case(key, '-');
5301
5331
  }
5332
+ }
5302
5333
 
5303
- nodeName = nodeName_(this.$$element);
5304
-
5305
- // sanitize a[href] and img[src] values
5306
- if ((nodeName === 'A' && key === 'href') ||
5307
- (nodeName === 'IMG' && key === 'src')) {
5308
- // NOTE: urlResolve() doesn't support IE < 8 so we don't sanitize for that case.
5309
- if (!msie || msie >= 8 ) {
5310
- normalizedVal = urlResolve(value).href;
5311
- if (normalizedVal !== '') {
5312
- if ((key === 'href' && !normalizedVal.match(aHrefSanitizationWhitelist)) ||
5313
- (key === 'src' && !normalizedVal.match(imgSrcSanitizationWhitelist))) {
5314
- this[key] = value = 'unsafe:' + normalizedVal;
5315
- }
5334
+ nodeName = nodeName_(this.$$element);
5335
+
5336
+ // sanitize a[href] and img[src] values
5337
+ if ((nodeName === 'A' && key === 'href') ||
5338
+ (nodeName === 'IMG' && key === 'src')) {
5339
+ // NOTE: urlResolve() doesn't support IE < 8 so we don't sanitize for that case.
5340
+ if (!msie || msie >= 8 ) {
5341
+ normalizedVal = urlResolve(value).href;
5342
+ if (normalizedVal !== '') {
5343
+ if ((key === 'href' && !normalizedVal.match(aHrefSanitizationWhitelist)) ||
5344
+ (key === 'src' && !normalizedVal.match(imgSrcSanitizationWhitelist))) {
5345
+ this[key] = value = 'unsafe:' + normalizedVal;
5316
5346
  }
5317
5347
  }
5318
5348
  }
5349
+ }
5319
5350
 
5320
- if (writeAttr !== false) {
5321
- if (value === null || value === undefined) {
5322
- this.$$element.removeAttr(attrName);
5323
- } else {
5324
- this.$$element.attr(attrName, value);
5325
- }
5351
+ if (writeAttr !== false) {
5352
+ if (value === null || value === undefined) {
5353
+ this.$$element.removeAttr(attrName);
5354
+ } else {
5355
+ this.$$element.attr(attrName, value);
5326
5356
  }
5327
5357
  }
5328
5358
 
@@ -5335,22 +5365,6 @@ function $CompileProvider($provide) {
5335
5365
  $exceptionHandler(e);
5336
5366
  }
5337
5367
  });
5338
-
5339
- function tokenDifference(str1, str2) {
5340
- var values = [],
5341
- tokens1 = str1.split(/\s+/),
5342
- tokens2 = str2.split(/\s+/);
5343
-
5344
- outer:
5345
- for(var i=0;i<tokens1.length;i++) {
5346
- var token = tokens1[i];
5347
- for(var j=0;j<tokens2.length;j++) {
5348
- if(token == tokens2[j]) continue outer;
5349
- }
5350
- values.push(token);
5351
- }
5352
- return values;
5353
- }
5354
5368
  },
5355
5369
 
5356
5370
 
@@ -6372,10 +6386,15 @@ function $CompileProvider($provide) {
6372
6386
 
6373
6387
 
6374
6388
  function getTrustedContext(node, attrNormalizedName) {
6389
+ if (attrNormalizedName == "srcdoc") {
6390
+ return $sce.HTML;
6391
+ }
6392
+ var tag = nodeName_(node);
6375
6393
  // maction[xlink:href] can source SVG. It's not limited to <maction>.
6376
6394
  if (attrNormalizedName == "xlinkHref" ||
6377
- (nodeName_(node) != "IMG" && (attrNormalizedName == "src" ||
6378
- attrNormalizedName == "ngSrc"))) {
6395
+ (tag == "FORM" && attrNormalizedName == "action") ||
6396
+ (tag != "IMG" && (attrNormalizedName == "src" ||
6397
+ attrNormalizedName == "ngSrc"))) {
6379
6398
  return $sce.RESOURCE_URL;
6380
6399
  }
6381
6400
  }
@@ -6420,9 +6439,19 @@ function $CompileProvider($provide) {
6420
6439
  attr[name] = interpolateFn(scope);
6421
6440
  ($$observers[name] || ($$observers[name] = [])).$$inter = true;
6422
6441
  (attr.$$observers && attr.$$observers[name].$$scope || scope).
6423
- $watch(interpolateFn, function interpolateFnWatchAction(value) {
6424
- attr.$set(name, value);
6425
- });
6442
+ $watch(interpolateFn, function interpolateFnWatchAction(newValue, oldValue) {
6443
+ //special case for class attribute addition + removal
6444
+ //so that class changes can tap into the animation
6445
+ //hooks provided by the $animate service. Be sure to
6446
+ //skip animations when the first digest occurs (when
6447
+ //both the new and the old values are the same) since
6448
+ //the CSS classes are the non-interpolated values
6449
+ if(name === 'class' && newValue != oldValue) {
6450
+ attr.$updateClass(newValue, oldValue);
6451
+ } else {
6452
+ attr.$set(name, newValue);
6453
+ }
6454
+ });
6426
6455
  }
6427
6456
  };
6428
6457
  }
@@ -6563,6 +6592,22 @@ function directiveLinkingFn(
6563
6592
  /* function(Function) */ boundTranscludeFn
6564
6593
  ){}
6565
6594
 
6595
+ function tokenDifference(str1, str2) {
6596
+ var values = '',
6597
+ tokens1 = str1.split(/\s+/),
6598
+ tokens2 = str2.split(/\s+/);
6599
+
6600
+ outer:
6601
+ for(var i = 0; i < tokens1.length; i++) {
6602
+ var token = tokens1[i];
6603
+ for(var j = 0; j < tokens2.length; j++) {
6604
+ if(token == tokens2[j]) continue outer;
6605
+ }
6606
+ values += (values.length > 0 ? ' ' : '') + token;
6607
+ }
6608
+ return values;
6609
+ }
6610
+
6566
6611
  /**
6567
6612
  * @ngdoc object
6568
6613
  * @name ng.$controllerProvider
@@ -7779,6 +7824,8 @@ function $HttpBackendProvider() {
7779
7824
  }
7780
7825
 
7781
7826
  function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument, locationProtocol) {
7827
+ var ABORTED = -1;
7828
+
7782
7829
  // TODO(vojta): fix the signature
7783
7830
  return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
7784
7831
  var status;
@@ -7814,13 +7861,19 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
7814
7861
  // always async
7815
7862
  xhr.onreadystatechange = function() {
7816
7863
  if (xhr.readyState == 4) {
7817
- var responseHeaders = xhr.getAllResponseHeaders();
7864
+ var responseHeaders = null,
7865
+ response = null;
7866
+
7867
+ if(status !== ABORTED) {
7868
+ responseHeaders = xhr.getAllResponseHeaders();
7869
+ response = xhr.responseType ? xhr.response : xhr.responseText;
7870
+ }
7818
7871
 
7819
7872
  // responseText is the old-school way of retrieving response (supported by IE8 & 9)
7820
7873
  // response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
7821
7874
  completeRequest(callback,
7822
7875
  status || xhr.status,
7823
- (xhr.responseType ? xhr.response : xhr.responseText),
7876
+ response,
7824
7877
  responseHeaders);
7825
7878
  }
7826
7879
  };
@@ -7844,7 +7897,7 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
7844
7897
 
7845
7898
 
7846
7899
  function timeoutRequest() {
7847
- status = -1;
7900
+ status = ABORTED;
7848
7901
  jsonpDone && jsonpDone();
7849
7902
  xhr && xhr.abort();
7850
7903
  }
@@ -7873,6 +7926,7 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
7873
7926
  // - adds and immediately removes script elements from the document
7874
7927
  var script = rawDocument.createElement('script'),
7875
7928
  doneWrapper = function() {
7929
+ script.onreadystatechange = script.onload = script.onerror = null;
7876
7930
  rawDocument.body.removeChild(script);
7877
7931
  if (done) done();
7878
7932
  };
@@ -7880,12 +7934,16 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
7880
7934
  script.type = 'text/javascript';
7881
7935
  script.src = url;
7882
7936
 
7883
- if (msie) {
7937
+ if (msie && msie <= 8) {
7884
7938
  script.onreadystatechange = function() {
7885
- if (/loaded|complete/.test(script.readyState)) doneWrapper();
7939
+ if (/loaded|complete/.test(script.readyState)) {
7940
+ doneWrapper();
7941
+ }
7886
7942
  };
7887
7943
  } else {
7888
- script.onload = script.onerror = doneWrapper;
7944
+ script.onload = script.onerror = function() {
7945
+ doneWrapper();
7946
+ };
7889
7947
  }
7890
7948
 
7891
7949
  rawDocument.body.appendChild(script);
@@ -8962,7 +9020,7 @@ function $LocationProvider(){
8962
9020
  *
8963
9021
  * The main purpose of this service is to simplify debugging and troubleshooting.
8964
9022
  *
8965
- * The default is not to log `debug` messages. You can use
9023
+ * The default is to log `debug` messages. You can use
8966
9024
  * {@link ng.$logProvider ng.$logProvider#debugEnabled} to change this.
8967
9025
  *
8968
9026
  * @example
@@ -10128,7 +10186,7 @@ function getterFn(path, options, fullExp) {
10128
10186
  : '((k&&k.hasOwnProperty("' + key + '"))?k:s)') + '["' + key + '"]' + ';\n' +
10129
10187
  (options.unwrapPromises
10130
10188
  ? 'if (s && s.then) {\n' +
10131
- ' pw("' + fullExp.replace(/\"/g, '\\"') + '");\n' +
10189
+ ' pw("' + fullExp.replace(/(["\r\n])/g, '\\$1') + '");\n' +
10132
10190
  ' if (!("$$v" in s)) {\n' +
10133
10191
  ' p=s;\n' +
10134
10192
  ' p.$$v = undefined;\n' +
@@ -12098,8 +12156,7 @@ function $SceDelegateProvider() {
12098
12156
  return resourceUrlBlacklist;
12099
12157
  };
12100
12158
 
12101
- this.$get = ['$log', '$document', '$injector', function(
12102
- $log, $document, $injector) {
12159
+ this.$get = ['$injector', function($injector) {
12103
12160
 
12104
12161
  var htmlSanitizer = function htmlSanitizer(html) {
12105
12162
  throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');
@@ -12630,18 +12687,15 @@ function $SceProvider() {
12630
12687
  * sce.js and sceSpecs.js would need to be aware of this detail.
12631
12688
  */
12632
12689
 
12633
- this.$get = ['$parse', '$document', '$sceDelegate', function(
12634
- $parse, $document, $sceDelegate) {
12690
+ this.$get = ['$parse', '$sniffer', '$sceDelegate', function(
12691
+ $parse, $sniffer, $sceDelegate) {
12635
12692
  // Prereq: Ensure that we're not running in IE8 quirks mode. In that mode, IE allows
12636
12693
  // the "expression(javascript expression)" syntax which is insecure.
12637
- if (enabled && msie) {
12638
- var documentMode = $document[0].documentMode;
12639
- if (documentMode !== undefined && documentMode < 8) {
12640
- throw $sceMinErr('iequirks',
12641
- 'Strict Contextual Escaping does not support Internet Explorer version < 9 in quirks ' +
12642
- 'mode. You can fix this by adding the text <!doctype html> to the top of your HTML ' +
12643
- 'document. See http://docs.angularjs.org/api/ng.$sce for more information.');
12644
- }
12694
+ if (enabled && $sniffer.msie && $sniffer.msieDocumentMode < 8) {
12695
+ throw $sceMinErr('iequirks',
12696
+ 'Strict Contextual Escaping does not support Internet Explorer version < 9 in quirks ' +
12697
+ 'mode. You can fix this by adding the text <!doctype html> to the top of your HTML ' +
12698
+ 'document. See http://docs.angularjs.org/api/ng.$sce for more information.');
12645
12699
  }
12646
12700
 
12647
12701
  var sce = copy(SCE_CONTEXTS);
@@ -13003,6 +13057,7 @@ function $SnifferProvider() {
13003
13057
  int((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),
13004
13058
  boxee = /Boxee/i.test(($window.navigator || {}).userAgent),
13005
13059
  document = $document[0] || {},
13060
+ documentMode = document.documentMode,
13006
13061
  vendorPrefix,
13007
13062
  vendorRegex = /^(Moz|webkit|O|ms)(?=[A-Z])/,
13008
13063
  bodyStyle = document.body && document.body.style,
@@ -13047,7 +13102,7 @@ function $SnifferProvider() {
13047
13102
  // jshint +W018
13048
13103
  hashchange: 'onhashchange' in $window &&
13049
13104
  // IE8 compatible mode lies
13050
- (!document.documentMode || document.documentMode > 7),
13105
+ (!documentMode || documentMode > 7),
13051
13106
  hasEvent: function(event) {
13052
13107
  // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
13053
13108
  // it. In particular the event is not fired when backspace or delete key are pressed or
@@ -13065,7 +13120,8 @@ function $SnifferProvider() {
13065
13120
  vendorPrefix: vendorPrefix,
13066
13121
  transitions : transitions,
13067
13122
  animations : animations,
13068
- msie : msie
13123
+ msie : msie,
13124
+ msieDocumentMode: documentMode
13069
13125
  };
13070
13126
  }];
13071
13127
  }
@@ -14680,8 +14736,11 @@ var htmlAnchorDirective = valueFn({
14680
14736
  *
14681
14737
  * The HTML specification does not require browsers to preserve the values of boolean attributes
14682
14738
  * such as disabled. (Their presence means true and their absence means false.)
14683
- * This prevents the Angular compiler from retrieving the binding expression.
14739
+ * If we put an Angular interpolation expression into such an attribute then the
14740
+ * binding information would be lost when the browser removes the attribute.
14684
14741
  * The `ngDisabled` directive solves this problem for the `disabled` attribute.
14742
+ * This complementary directive is not removed by the browser and so provides
14743
+ * a permanent reliable place to store the binding information.
14685
14744
  *
14686
14745
  * @example
14687
14746
  <doc:example>
@@ -14712,8 +14771,11 @@ var htmlAnchorDirective = valueFn({
14712
14771
  * @description
14713
14772
  * The HTML specification does not require browsers to preserve the values of boolean attributes
14714
14773
  * such as checked. (Their presence means true and their absence means false.)
14715
- * This prevents the Angular compiler from retrieving the binding expression.
14774
+ * If we put an Angular interpolation expression into such an attribute then the
14775
+ * binding information would be lost when the browser removes the attribute.
14716
14776
  * The `ngChecked` directive solves this problem for the `checked` attribute.
14777
+ * This complementary directive is not removed by the browser and so provides
14778
+ * a permanent reliable place to store the binding information.
14717
14779
  * @example
14718
14780
  <doc:example>
14719
14781
  <doc:source>
@@ -14743,8 +14805,12 @@ var htmlAnchorDirective = valueFn({
14743
14805
  * @description
14744
14806
  * The HTML specification does not require browsers to preserve the values of boolean attributes
14745
14807
  * such as readonly. (Their presence means true and their absence means false.)
14746
- * This prevents the Angular compiler from retrieving the binding expression.
14808
+ * If we put an Angular interpolation expression into such an attribute then the
14809
+ * binding information would be lost when the browser removes the attribute.
14747
14810
  * The `ngReadonly` directive solves this problem for the `readonly` attribute.
14811
+ * This complementary directive is not removed by the browser and so provides
14812
+ * a permanent reliable place to store the binding information.
14813
+
14748
14814
  * @example
14749
14815
  <doc:example>
14750
14816
  <doc:source>
@@ -14774,8 +14840,11 @@ var htmlAnchorDirective = valueFn({
14774
14840
  * @description
14775
14841
  * The HTML specification does not require browsers to preserve the values of boolean attributes
14776
14842
  * such as selected. (Their presence means true and their absence means false.)
14777
- * This prevents the Angular compiler from retrieving the binding expression.
14843
+ * If we put an Angular interpolation expression into such an attribute then the
14844
+ * binding information would be lost when the browser removes the attribute.
14778
14845
  * The `ngSelected` directive solves this problem for the `selected` atttribute.
14846
+ * This complementary directive is not removed by the browser and so provides
14847
+ * a permanent reliable place to store the binding information.
14779
14848
  * @example
14780
14849
  <doc:example>
14781
14850
  <doc:source>
@@ -14807,8 +14876,12 @@ var htmlAnchorDirective = valueFn({
14807
14876
  * @description
14808
14877
  * The HTML specification does not require browsers to preserve the values of boolean attributes
14809
14878
  * such as open. (Their presence means true and their absence means false.)
14810
- * This prevents the Angular compiler from retrieving the binding expression.
14879
+ * If we put an Angular interpolation expression into such an attribute then the
14880
+ * binding information would be lost when the browser removes the attribute.
14811
14881
  * The `ngOpen` directive solves this problem for the `open` attribute.
14882
+ * This complementary directive is not removed by the browser and so provides
14883
+ * a permanent reliable place to store the binding information.
14884
+
14812
14885
  *
14813
14886
  * @example
14814
14887
  <doc:example>
@@ -15638,8 +15711,21 @@ var inputType = {
15638
15711
 
15639
15712
 
15640
15713
  function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
15714
+ // In composition mode, users are still inputing intermediate text buffer,
15715
+ // hold the listener until composition is done.
15716
+ // More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
15717
+ var composing = false;
15718
+
15719
+ element.on('compositionstart', function() {
15720
+ composing = true;
15721
+ });
15722
+
15723
+ element.on('compositionend', function() {
15724
+ composing = false;
15725
+ });
15641
15726
 
15642
15727
  var listener = function() {
15728
+ if (composing) return;
15643
15729
  var value = element.val();
15644
15730
 
15645
15731
  // By default we will trim the value
@@ -16929,11 +17015,10 @@ function classDirective(name, selector) {
16929
17015
  // jshint bitwise: false
16930
17016
  var mod = $index & 1;
16931
17017
  if (mod !== old$index & 1) {
16932
- if (mod === selector) {
16933
- addClass(scope.$eval(attr[name]));
16934
- } else {
16935
- removeClass(scope.$eval(attr[name]));
16936
- }
17018
+ var classes = flattenClasses(scope.$eval(attr[name]));
17019
+ mod === selector ?
17020
+ attr.$addClass(classes) :
17021
+ attr.$removeClass(classes);
16937
17022
  }
16938
17023
  });
16939
17024
  }
@@ -16941,24 +17026,17 @@ function classDirective(name, selector) {
16941
17026
 
16942
17027
  function ngClassWatchAction(newVal) {
16943
17028
  if (selector === true || scope.$index % 2 === selector) {
16944
- if (oldVal && !equals(newVal,oldVal)) {
16945
- removeClass(oldVal);
17029
+ var newClasses = flattenClasses(newVal || '');
17030
+ if(!oldVal) {
17031
+ attr.$addClass(newClasses);
17032
+ } else if(!equals(newVal,oldVal)) {
17033
+ attr.$updateClass(newClasses, flattenClasses(oldVal));
16946
17034
  }
16947
- addClass(newVal);
16948
17035
  }
16949
17036
  oldVal = copy(newVal);
16950
17037
  }
16951
17038
 
16952
17039
 
16953
- function removeClass(classVal) {
16954
- attr.$removeClass(flattenClasses(classVal));
16955
- }
16956
-
16957
-
16958
- function addClass(classVal) {
16959
- attr.$addClass(flattenClasses(classVal));
16960
- }
16961
-
16962
17040
  function flattenClasses(classVal) {
16963
17041
  if(isArray(classVal)) {
16964
17042
  return classVal.join(' ');
@@ -17436,7 +17514,8 @@ var ngCloakDirective = ngDirective({
17436
17514
  var ngControllerDirective = [function() {
17437
17515
  return {
17438
17516
  scope: true,
17439
- controller: '@'
17517
+ controller: '@',
17518
+ priority: 500
17440
17519
  };
17441
17520
  }];
17442
17521
 
@@ -18132,18 +18211,23 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
18132
18211
  if (thisChangeId !== changeCounter) return;
18133
18212
  var newScope = scope.$new();
18134
18213
 
18135
- $transclude(newScope, function(clone) {
18136
- cleanupLastIncludeContent();
18137
-
18138
- currentScope = newScope;
18139
- currentElement = clone;
18140
-
18141
- currentElement.html(response);
18142
- $animate.enter(currentElement, null, $element, afterAnimation);
18143
- $compile(currentElement.contents())(currentScope);
18144
- currentScope.$emit('$includeContentLoaded');
18145
- scope.$eval(onloadExp);
18146
- });
18214
+ // Note: This will also link all children of ng-include that were contained in the original
18215
+ // html. If that content contains controllers, ... they could pollute/change the scope.
18216
+ // However, using ng-include on an element with additional content does not make sense...
18217
+ // Note: We can't remove them in the cloneAttchFn of $transclude as that
18218
+ // function is called before linking the content, which would apply child
18219
+ // directives to non existing elements.
18220
+ var clone = $transclude(newScope, noop);
18221
+ cleanupLastIncludeContent();
18222
+
18223
+ currentScope = newScope;
18224
+ currentElement = clone;
18225
+
18226
+ currentElement.html(response);
18227
+ $animate.enter(currentElement, null, $element, afterAnimation);
18228
+ $compile(currentElement.contents())(currentScope);
18229
+ currentScope.$emit('$includeContentLoaded');
18230
+ scope.$eval(onloadExp);
18147
18231
  }).error(function() {
18148
18232
  if (thisChangeId === changeCounter) cleanupLastIncludeContent();
18149
18233
  });
@@ -18298,7 +18382,7 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
18298
18382
  * other numbers, for example 12, so that instead of showing "12 people are viewing", you can
18299
18383
  * show "a dozen people are viewing".
18300
18384
  *
18301
- * You can use a set of closed braces(`{}`) as a placeholder for the number that you want substituted
18385
+ * You can use a set of closed braces (`{}`) as a placeholder for the number that you want substituted
18302
18386
  * into pluralized strings. In the previous example, Angular will replace `{}` with
18303
18387
  * <span ng-non-bindable>`{{personCount}}`</span>. The closed braces `{}` is a placeholder
18304
18388
  * for <span ng-non-bindable>{{numberExpression}}</span>.
@@ -18559,7 +18643,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
18559
18643
  * For example: `item in items track by $id(item)`. A built in `$id()` function can be used to assign a unique
18560
18644
  * `$$hashKey` property to each item in the array. This property is then used as a key to associated DOM elements
18561
18645
  * with the corresponding item in the array by identity. Moving the same object in array would move the DOM
18562
- * element in the same way ian the DOM.
18646
+ * element in the same way in the DOM.
18563
18647
  *
18564
18648
  * For example: `item in items track by item.id` is a typical pattern when the items come from the database. In this
18565
18649
  * case the object identity does not matter. Two objects are considered equivalent as long as their `id`
@@ -20128,4 +20212,4 @@ var styleDirective = valueFn({
20128
20212
 
20129
20213
  })(window, document);
20130
20214
 
20131
- !angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-start{clip:rect(0,auto,auto,0);-ms-zoom:1.0001;}.ng-animate-active{clip:rect(-1px,auto,auto,0);-ms-zoom:1;}</style>');
20215
+ !angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-start{border-spacing:1px 1px;-ms-zoom:1.0001;}.ng-animate-active{border-spacing:0px 0px;-ms-zoom:1;}</style>');