angularjs-rails 1.2.18 → 1.2.19

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.2.18
2
+ * @license AngularJS v1.2.19
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.2.18
2
+ * @license AngularJS v1.2.19
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.2.18/' +
71
+ message = message + '\nhttp://errors.angularjs.org/1.2.19/' +
72
72
  (module ? module + '/' : '') + code;
73
73
  for (i = 2; i < arguments.length; i++) {
74
74
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -92,6 +92,7 @@ function minErr(module) {
92
92
  -angularModule,
93
93
  -nodeName_,
94
94
  -uid,
95
+ -VALIDITY_STATE_PROPERTY,
95
96
 
96
97
  -lowercase,
97
98
  -uppercase,
@@ -181,6 +182,10 @@ function minErr(module) {
181
182
  * <div doc-module-components="ng"></div>
182
183
  */
183
184
 
185
+ // The name of a form control's ValidityState property.
186
+ // This is used so that it's possible for internal tests to create mock ValidityStates.
187
+ var VALIDITY_STATE_PROPERTY = 'validity';
188
+
184
189
  /**
185
190
  * @ngdoc function
186
191
  * @name angular.lowercase
@@ -1353,7 +1358,7 @@ function angularInit(element, bootstrap) {
1353
1358
  *
1354
1359
  * Angular will detect if it has been loaded into the browser more than once and only allow the
1355
1360
  * first loaded script to be bootstrapped and will report a warning to the browser console for
1356
- * each of the subsequent scripts. This prevents strange results in applications, where otherwise
1361
+ * each of the subsequent scripts. This prevents strange results in applications, where otherwise
1357
1362
  * multiple instances of Angular try to work on the DOM.
1358
1363
  *
1359
1364
  * <example name="multi-bootstrap" module="multi-bootstrap">
@@ -1483,7 +1488,7 @@ function assertArgFn(arg, name, acceptArrayAnnotation) {
1483
1488
  }
1484
1489
 
1485
1490
  assertArg(isFunction(arg), name, 'not a function, got ' +
1486
- (arg && typeof arg == 'object' ? arg.constructor.name || 'Object' : typeof arg));
1491
+ (arg && typeof arg === 'object' ? arg.constructor.name || 'Object' : typeof arg));
1487
1492
  return arg;
1488
1493
  }
1489
1494
 
@@ -1953,11 +1958,11 @@ function setupModuleLoader(window) {
1953
1958
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
1954
1959
  */
1955
1960
  var version = {
1956
- full: '1.2.18', // all of these placeholder strings will be replaced by grunt's
1961
+ full: '1.2.19', // all of these placeholder strings will be replaced by grunt's
1957
1962
  major: 1, // package task
1958
1963
  minor: 2,
1959
- dot: 18,
1960
- codeName: 'ear-extendability'
1964
+ dot: 19,
1965
+ codeName: 'precognitive-flashbacks'
1961
1966
  };
1962
1967
 
1963
1968
 
@@ -2179,8 +2184,9 @@ function publishExternalAPI(angular){
2179
2184
  * @returns {Object} jQuery object.
2180
2185
  */
2181
2186
 
2187
+ JQLite.expando = 'ng339';
2188
+
2182
2189
  var jqCache = JQLite.cache = {},
2183
- jqName = JQLite.expando = 'ng' + new Date().getTime(),
2184
2190
  jqId = 1,
2185
2191
  addEventListenerFn = (window.document.addEventListener
2186
2192
  ? function(element, type, fn) {element.addEventListener(type, fn, false);}
@@ -2390,7 +2396,7 @@ function jqLiteOff(element, type, fn, unsupported) {
2390
2396
  }
2391
2397
 
2392
2398
  function jqLiteRemoveData(element, name) {
2393
- var expandoId = element[jqName],
2399
+ var expandoId = element.ng339,
2394
2400
  expandoStore = jqCache[expandoId];
2395
2401
 
2396
2402
  if (expandoStore) {
@@ -2404,17 +2410,17 @@ function jqLiteRemoveData(element, name) {
2404
2410
  jqLiteOff(element);
2405
2411
  }
2406
2412
  delete jqCache[expandoId];
2407
- element[jqName] = undefined; // ie does not allow deletion of attributes on elements.
2413
+ element.ng339 = undefined; // don't delete DOM expandos. IE and Chrome don't like it
2408
2414
  }
2409
2415
  }
2410
2416
 
2411
2417
  function jqLiteExpandoStore(element, key, value) {
2412
- var expandoId = element[jqName],
2418
+ var expandoId = element.ng339,
2413
2419
  expandoStore = jqCache[expandoId || -1];
2414
2420
 
2415
2421
  if (isDefined(value)) {
2416
2422
  if (!expandoStore) {
2417
- element[jqName] = expandoId = jqNextId();
2423
+ element.ng339 = expandoId = jqNextId();
2418
2424
  expandoStore = jqCache[expandoId] = {};
2419
2425
  }
2420
2426
  expandoStore[key] = value;
@@ -3081,16 +3087,16 @@ forEach({
3081
3087
  * @returns {string} hash string such that the same input will have the same hash string.
3082
3088
  * The resulting string key is in 'type:hashKey' format.
3083
3089
  */
3084
- function hashKey(obj) {
3090
+ function hashKey(obj, nextUidFn) {
3085
3091
  var objType = typeof obj,
3086
3092
  key;
3087
3093
 
3088
- if (objType == 'object' && obj !== null) {
3094
+ if (objType == 'function' || (objType == 'object' && obj !== null)) {
3089
3095
  if (typeof (key = obj.$$hashKey) == 'function') {
3090
3096
  // must invoke on object to keep the right this
3091
3097
  key = obj.$$hashKey();
3092
3098
  } else if (key === undefined) {
3093
- key = obj.$$hashKey = nextUid();
3099
+ key = obj.$$hashKey = (nextUidFn || nextUid)();
3094
3100
  }
3095
3101
  } else {
3096
3102
  key = obj;
@@ -3102,7 +3108,13 @@ function hashKey(obj) {
3102
3108
  /**
3103
3109
  * HashMap which can use objects as keys
3104
3110
  */
3105
- function HashMap(array){
3111
+ function HashMap(array, isolatedUid) {
3112
+ if (isolatedUid) {
3113
+ var uid = 0;
3114
+ this.nextUid = function() {
3115
+ return ++uid;
3116
+ };
3117
+ }
3106
3118
  forEach(array, this.put, this);
3107
3119
  }
3108
3120
  HashMap.prototype = {
@@ -3112,7 +3124,7 @@ HashMap.prototype = {
3112
3124
  * @param value value to store can be any type
3113
3125
  */
3114
3126
  put: function(key, value) {
3115
- this[hashKey(key)] = value;
3127
+ this[hashKey(key, this.nextUid)] = value;
3116
3128
  },
3117
3129
 
3118
3130
  /**
@@ -3120,7 +3132,7 @@ HashMap.prototype = {
3120
3132
  * @returns {Object} the value for the key
3121
3133
  */
3122
3134
  get: function(key) {
3123
- return this[hashKey(key)];
3135
+ return this[hashKey(key, this.nextUid)];
3124
3136
  },
3125
3137
 
3126
3138
  /**
@@ -3128,7 +3140,7 @@ HashMap.prototype = {
3128
3140
  * @param key
3129
3141
  */
3130
3142
  remove: function(key) {
3131
- var value = this[key = hashKey(key)];
3143
+ var value = this[key = hashKey(key, this.nextUid)];
3132
3144
  delete this[key];
3133
3145
  return value;
3134
3146
  }
@@ -3206,7 +3218,7 @@ function annotate(fn) {
3206
3218
  argDecl,
3207
3219
  last;
3208
3220
 
3209
- if (typeof fn == 'function') {
3221
+ if (typeof fn === 'function') {
3210
3222
  if (!($inject = fn.$inject)) {
3211
3223
  $inject = [];
3212
3224
  if (fn.length) {
@@ -3419,7 +3431,7 @@ function annotate(fn) {
3419
3431
 
3420
3432
 
3421
3433
  /**
3422
- * @ngdoc object
3434
+ * @ngdoc service
3423
3435
  * @name $provide
3424
3436
  *
3425
3437
  * @description
@@ -3725,7 +3737,7 @@ function createInjector(modulesToLoad) {
3725
3737
  var INSTANTIATING = {},
3726
3738
  providerSuffix = 'Provider',
3727
3739
  path = [],
3728
- loadedModules = new HashMap(),
3740
+ loadedModules = new HashMap([], true),
3729
3741
  providerCache = {
3730
3742
  $provide: {
3731
3743
  provider: supportObject(provider),
@@ -3896,8 +3908,7 @@ function createInjector(modulesToLoad) {
3896
3908
  : getService(key)
3897
3909
  );
3898
3910
  }
3899
- if (!fn.$inject) {
3900
- // this means that we must be an array.
3911
+ if (isArray(fn)) {
3901
3912
  fn = fn[length];
3902
3913
  }
3903
3914
 
@@ -6078,7 +6089,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6078
6089
  directiveNormalize(nodeName_(node).toLowerCase()), 'E', maxPriority, ignoreDirective);
6079
6090
 
6080
6091
  // iterate over the attributes
6081
- for (var attr, name, nName, ngAttrName, value, nAttrs = node.attributes,
6092
+ for (var attr, name, nName, ngAttrName, value, isNgAttr, nAttrs = node.attributes,
6082
6093
  j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) {
6083
6094
  var attrStartName = false;
6084
6095
  var attrEndName = false;
@@ -6086,9 +6097,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6086
6097
  attr = nAttrs[j];
6087
6098
  if (!msie || msie >= 8 || attr.specified) {
6088
6099
  name = attr.name;
6100
+ value = trim(attr.value);
6101
+
6089
6102
  // support ngAttr attribute binding
6090
6103
  ngAttrName = directiveNormalize(name);
6091
- if (NG_ATTR_BINDING.test(ngAttrName)) {
6104
+ if (isNgAttr = NG_ATTR_BINDING.test(ngAttrName)) {
6092
6105
  name = snake_case(ngAttrName.substr(6), '-');
6093
6106
  }
6094
6107
 
@@ -6101,9 +6114,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
6101
6114
 
6102
6115
  nName = directiveNormalize(name.toLowerCase());
6103
6116
  attrsMap[nName] = name;
6104
- attrs[nName] = value = trim(attr.value);
6105
- if (getBooleanAttrName(node, nName)) {
6106
- attrs[nName] = true; // presence means true
6117
+ if (isNgAttr || !attrs.hasOwnProperty(nName)) {
6118
+ attrs[nName] = value;
6119
+ if (getBooleanAttrName(node, nName)) {
6120
+ attrs[nName] = true; // presence means true
6121
+ }
6107
6122
  }
6108
6123
  addAttrInterpolateDirective(node, directives, value, nName);
6109
6124
  addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName,
@@ -7201,7 +7216,7 @@ function $ControllerProvider() {
7201
7216
  instance = $injector.instantiate(expression, locals);
7202
7217
 
7203
7218
  if (identifier) {
7204
- if (!(locals && typeof locals.$scope == 'object')) {
7219
+ if (!(locals && typeof locals.$scope === 'object')) {
7205
7220
  throw minErr('$controller')('noscp',
7206
7221
  "Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`.",
7207
7222
  constructor || expression.name, identifier);
@@ -8403,7 +8418,8 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
8403
8418
  // Safari respectively.
8404
8419
  if (xhr && xhr.readyState == 4) {
8405
8420
  var responseHeaders = null,
8406
- response = null;
8421
+ response = null,
8422
+ statusText = '';
8407
8423
 
8408
8424
  if(status !== ABORTED) {
8409
8425
  responseHeaders = xhr.getAllResponseHeaders();
@@ -8413,11 +8429,17 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
8413
8429
  response = ('response' in xhr) ? xhr.response : xhr.responseText;
8414
8430
  }
8415
8431
 
8432
+ // Accessing statusText on an aborted xhr object will
8433
+ // throw an 'c00c023f error' in IE9 and lower, don't touch it.
8434
+ if (!(status === ABORTED && msie < 10)) {
8435
+ statusText = xhr.statusText;
8436
+ }
8437
+
8416
8438
  completeRequest(callback,
8417
8439
  status || xhr.status,
8418
8440
  response,
8419
8441
  responseHeaders,
8420
- xhr.statusText || '');
8442
+ statusText);
8421
8443
  }
8422
8444
  };
8423
8445
 
@@ -8951,7 +8973,7 @@ function $IntervalProvider() {
8951
8973
  interval.cancel = function(promise) {
8952
8974
  if (promise && promise.$$intervalId in intervals) {
8953
8975
  intervals[promise.$$intervalId].reject('canceled');
8954
- clearInterval(promise.$$intervalId);
8976
+ $window.clearInterval(promise.$$intervalId);
8955
8977
  delete intervals[promise.$$intervalId];
8956
8978
  return true;
8957
8979
  }
@@ -9585,7 +9607,7 @@ function $LocationProvider(){
9585
9607
  html5Mode = false;
9586
9608
 
9587
9609
  /**
9588
- * @ngdoc property
9610
+ * @ngdoc method
9589
9611
  * @name $locationProvider#hashPrefix
9590
9612
  * @description
9591
9613
  * @param {string=} prefix Prefix for hash part (containing path and search)
@@ -9601,7 +9623,7 @@ function $LocationProvider(){
9601
9623
  };
9602
9624
 
9603
9625
  /**
9604
- * @ngdoc property
9626
+ * @ngdoc method
9605
9627
  * @name $locationProvider#html5Mode
9606
9628
  * @description
9607
9629
  * @param {boolean=} mode Use HTML5 strategy if available.
@@ -9959,14 +9981,7 @@ var promiseWarning;
9959
9981
  //
9960
9982
  // As an example, consider the following Angular expression:
9961
9983
  //
9962
- // {}.toString.constructor(alert("evil JS code"))
9963
- //
9964
- // We want to prevent this type of access. For the sake of performance, during the lexing phase we
9965
- // disallow any "dotted" access to any member named "constructor".
9966
- //
9967
- // For reflective calls (a[b]) we check that the value of the lookup is not the Function constructor
9968
- // while evaluating the expression, which is a stronger but more expensive test. Since reflective
9969
- // calls are expensive anyway, this is not such a big deal compared to static dereferencing.
9984
+ // {}.toString.constructor('alert("evil JS code")')
9970
9985
  //
9971
9986
  // This sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits
9972
9987
  // against the expression language, but not to prevent exploits that were enabled by exposing
@@ -9974,17 +9989,19 @@ var promiseWarning;
9974
9989
  // practice and therefore we are not even trying to protect against interaction with an object
9975
9990
  // explicitly exposed in this way.
9976
9991
  //
9977
- // A developer could foil the name check by aliasing the Function constructor under a different
9978
- // name on the scope.
9979
- //
9980
9992
  // In general, it is not possible to access a Window object from an angular expression unless a
9981
9993
  // window or some DOM object that has a reference to window is published onto a Scope.
9994
+ // Similarly we prevent invocations of function known to be dangerous, as well as assignments to
9995
+ // native objects.
9996
+
9982
9997
 
9983
9998
  function ensureSafeMemberName(name, fullExpression) {
9984
- if (name === "constructor") {
9999
+ if (name === "__defineGetter__" || name === "__defineSetter__"
10000
+ || name === "__lookupGetter__" || name === "__lookupSetter__"
10001
+ || name === "__proto__") {
9985
10002
  throw $parseMinErr('isecfld',
9986
- 'Referencing "constructor" field in Angular expressions is disallowed! Expression: {0}',
9987
- fullExpression);
10003
+ 'Attempting to access a disallowed field in Angular expressions! '
10004
+ +'Expression: {0}', fullExpression);
9988
10005
  }
9989
10006
  return name;
9990
10007
  }
@@ -10006,11 +10023,34 @@ function ensureSafeObject(obj, fullExpression) {
10006
10023
  throw $parseMinErr('isecdom',
10007
10024
  'Referencing DOM nodes in Angular expressions is disallowed! Expression: {0}',
10008
10025
  fullExpression);
10026
+ } else if (// block Object so that we can't get hold of dangerous Object.* methods
10027
+ obj === Object) {
10028
+ throw $parseMinErr('isecobj',
10029
+ 'Referencing Object in Angular expressions is disallowed! Expression: {0}',
10030
+ fullExpression);
10009
10031
  }
10010
10032
  }
10011
10033
  return obj;
10012
10034
  }
10013
10035
 
10036
+ var CALL = Function.prototype.call;
10037
+ var APPLY = Function.prototype.apply;
10038
+ var BIND = Function.prototype.bind;
10039
+
10040
+ function ensureSafeFunction(obj, fullExpression) {
10041
+ if (obj) {
10042
+ if (obj.constructor === obj) {
10043
+ throw $parseMinErr('isecfn',
10044
+ 'Referencing Function in Angular expressions is disallowed! Expression: {0}',
10045
+ fullExpression);
10046
+ } else if (obj === CALL || obj === APPLY || (BIND && obj === BIND)) {
10047
+ throw $parseMinErr('isecff',
10048
+ 'Referencing call, apply or bind in Angular expressions is disallowed! Expression: {0}',
10049
+ fullExpression);
10050
+ }
10051
+ }
10052
+ }
10053
+
10014
10054
  var OPERATORS = {
10015
10055
  /* jshint bitwise : false */
10016
10056
  'null':function(){return null;},
@@ -10645,6 +10685,7 @@ Parser.prototype = {
10645
10685
  i = indexFn(self, locals),
10646
10686
  v, p;
10647
10687
 
10688
+ ensureSafeMemberName(i, parser.text);
10648
10689
  if (!o) return undefined;
10649
10690
  v = ensureSafeObject(o[i], parser.text);
10650
10691
  if (v && v.then && parser.options.unwrapPromises) {
@@ -10687,7 +10728,7 @@ Parser.prototype = {
10687
10728
  var fnPtr = fn(scope, locals, context) || noop;
10688
10729
 
10689
10730
  ensureSafeObject(context, parser.text);
10690
- ensureSafeObject(fnPtr, parser.text);
10731
+ ensureSafeFunction(fnPtr, parser.text);
10691
10732
 
10692
10733
  // IE stupidity! (IE doesn't have apply for some native functions)
10693
10734
  var v = fnPtr.apply
@@ -10796,6 +10837,8 @@ function setter(obj, path, setValue, fullExp, options) {
10796
10837
  }
10797
10838
  }
10798
10839
  key = ensureSafeMemberName(element.shift(), fullExp);
10840
+ ensureSafeObject(obj, fullExp);
10841
+ ensureSafeObject(obj[key], fullExp);
10799
10842
  obj[key] = setValue;
10800
10843
  return setValue;
10801
10844
  }
@@ -11215,17 +11258,13 @@ function $ParseProvider() {
11215
11258
  * var deferred = $q.defer();
11216
11259
  *
11217
11260
  * setTimeout(function() {
11218
- * // since this fn executes async in a future turn of the event loop, we need to wrap
11219
- * // our code into an $apply call so that the model changes are properly observed.
11220
- * scope.$apply(function() {
11221
- * deferred.notify('About to greet ' + name + '.');
11222
- *
11223
- * if (okToGreet(name)) {
11224
- * deferred.resolve('Hello, ' + name + '!');
11225
- * } else {
11226
- * deferred.reject('Greeting ' + name + ' is not allowed.');
11227
- * }
11228
- * });
11261
+ * deferred.notify('About to greet ' + name + '.');
11262
+ *
11263
+ * if (okToGreet(name)) {
11264
+ * deferred.resolve('Hello, ' + name + '!');
11265
+ * } else {
11266
+ * deferred.reject('Greeting ' + name + ' is not allowed.');
11267
+ * }
11229
11268
  * }, 1000);
11230
11269
  *
11231
11270
  * return deferred.promise;
@@ -12387,7 +12426,7 @@ function $RootScopeProvider(){
12387
12426
  if ((value = watch.get(current)) !== (last = watch.last) &&
12388
12427
  !(watch.eq
12389
12428
  ? equals(value, last)
12390
- : (typeof value == 'number' && typeof last == 'number'
12429
+ : (typeof value === 'number' && typeof last === 'number'
12391
12430
  && isNaN(value) && isNaN(last)))) {
12392
12431
  dirty = true;
12393
12432
  lastDirtyWatch = watch;
@@ -13732,7 +13771,7 @@ function $SceProvider() {
13732
13771
 
13733
13772
  /**
13734
13773
  * @ngdoc method
13735
- * @name $sce#parse
13774
+ * @name $sce#parseAs
13736
13775
  *
13737
13776
  * @description
13738
13777
  * Converts Angular {@link guide/expression expression} into a function. This is like {@link
@@ -14688,7 +14727,7 @@ function filterFilter() {
14688
14727
  // jshint +W086
14689
14728
  for (var key in expression) {
14690
14729
  (function(path) {
14691
- if (typeof expression[path] == 'undefined') return;
14730
+ if (typeof expression[path] === 'undefined') return;
14692
14731
  predicates.push(function(value) {
14693
14732
  return search(path == '$' ? value : (value && value[path]), expression[path]);
14694
14733
  });
@@ -14843,6 +14882,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
14843
14882
  var match = numStr.match(/([\d\.]+)e(-?)(\d+)/);
14844
14883
  if (match && match[2] == '-' && match[3] > fractionSize + 1) {
14845
14884
  numStr = '0';
14885
+ number = 0;
14846
14886
  } else {
14847
14887
  formatedText = numStr;
14848
14888
  hasExponent = true;
@@ -14857,8 +14897,11 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
14857
14897
  fractionSize = Math.min(Math.max(pattern.minFrac, fractionLen), pattern.maxFrac);
14858
14898
  }
14859
14899
 
14860
- var pow = Math.pow(10, fractionSize + 1);
14861
- number = Math.floor(number * pow + 5) / pow;
14900
+ // safely round numbers in JS without hitting imprecisions of floating-point arithmetics
14901
+ // inspired by:
14902
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
14903
+ number = +(Math.round(+(number.toString() + 'e' + fractionSize)).toString() + 'e' + -fractionSize);
14904
+
14862
14905
  var fraction = ('' + number).split(DECIMAL_SEP);
14863
14906
  var whole = fraction[0];
14864
14907
  fraction = fraction[1] || '';
@@ -16360,7 +16403,7 @@ var ngFormDirective = formDirectiveFactory(true);
16360
16403
  */
16361
16404
 
16362
16405
  var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;
16363
- var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*$/i;
16406
+ var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*$/i;
16364
16407
  var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;
16365
16408
 
16366
16409
  var inputType = {
@@ -16786,15 +16829,29 @@ function validate(ctrl, validatorName, validity, value){
16786
16829
  return validity ? value : undefined;
16787
16830
  }
16788
16831
 
16832
+ function testFlags(validity, flags) {
16833
+ var i, flag;
16834
+ if (flags) {
16835
+ for (i=0; i<flags.length; ++i) {
16836
+ flag = flags[i];
16837
+ if (validity[flag]) {
16838
+ return true;
16839
+ }
16840
+ }
16841
+ }
16842
+ return false;
16843
+ }
16789
16844
 
16790
- function addNativeHtml5Validators(ctrl, validatorName, element) {
16791
- var validity = element.prop('validity');
16845
+ // Pass validity so that behaviour can be mocked easier.
16846
+ function addNativeHtml5Validators(ctrl, validatorName, badFlags, ignoreFlags, validity) {
16792
16847
  if (isObject(validity)) {
16848
+ ctrl.$$hasNativeValidators = true;
16793
16849
  var validator = function(value) {
16794
16850
  // Don't overwrite previous validation, don't consider valueMissing to apply (ng-required can
16795
16851
  // perform the required validation)
16796
- if (!ctrl.$error[validatorName] && (validity.badInput || validity.customError ||
16797
- validity.typeMismatch) && !validity.valueMissing) {
16852
+ if (!ctrl.$error[validatorName] &&
16853
+ !testFlags(validity, ignoreFlags) &&
16854
+ testFlags(validity, badFlags)) {
16798
16855
  ctrl.$setValidity(validatorName, false);
16799
16856
  return;
16800
16857
  }
@@ -16805,8 +16862,9 @@ function addNativeHtml5Validators(ctrl, validatorName, element) {
16805
16862
  }
16806
16863
 
16807
16864
  function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
16808
- var validity = element.prop('validity');
16865
+ var validity = element.prop(VALIDITY_STATE_PROPERTY);
16809
16866
  var placeholder = element[0].placeholder, noevent = {};
16867
+ ctrl.$$validityState = validity;
16810
16868
 
16811
16869
  // In composition mode, users are still inputing intermediate text buffer,
16812
16870
  // hold the listener until composition is done.
@@ -16844,11 +16902,11 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
16844
16902
  value = trim(value);
16845
16903
  }
16846
16904
 
16847
- if (ctrl.$viewValue !== value ||
16848
- // If the value is still empty/falsy, and there is no `required` error, run validators
16849
- // again. This enables HTML5 constraint validation errors to affect Angular validation
16850
- // even when the first character entered causes an error.
16851
- (validity && value === '' && !validity.valueMissing)) {
16905
+ // If a control is suffering from bad input, browsers discard its value, so it may be
16906
+ // necessary to revalidate even if the control's value is the same empty value twice in
16907
+ // a row.
16908
+ var revalidate = validity && ctrl.$$hasNativeValidators;
16909
+ if (ctrl.$viewValue !== value || (value === '' && revalidate)) {
16852
16910
  if (scope.$$phase) {
16853
16911
  ctrl.$setViewValue(value);
16854
16912
  } else {
@@ -16954,6 +17012,8 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
16954
17012
  }
16955
17013
  }
16956
17014
 
17015
+ var numberBadFlags = ['badInput'];
17016
+
16957
17017
  function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
16958
17018
  textInputType(scope, element, attr, ctrl, $sniffer, $browser);
16959
17019
 
@@ -16968,7 +17028,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
16968
17028
  }
16969
17029
  });
16970
17030
 
16971
- addNativeHtml5Validators(ctrl, 'number', element);
17031
+ addNativeHtml5Validators(ctrl, 'number', numberBadFlags, null, ctrl.$$validityState);
16972
17032
 
16973
17033
  ctrl.$formatters.push(function(value) {
16974
17034
  return ctrl.$isEmpty(value) ? '' : '' + value;
@@ -17450,7 +17510,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
17450
17510
  * This method should be called by validators - i.e. the parser or formatter functions.
17451
17511
  *
17452
17512
  * @param {string} validationErrorKey Name of the validator. the `validationErrorKey` will assign
17453
- * to `$error[validationErrorKey]=isValid` so that it is available for data-binding.
17513
+ * to `$error[validationErrorKey]=!isValid` so that it is available for data-binding.
17454
17514
  * The `validationErrorKey` should be in camelCase and will get converted into dash-case
17455
17515
  * for class name. Example: `myError` will result in `ng-valid-my-error` and `ng-invalid-my-error`
17456
17516
  * class and can be bound to as `{{someForm.someControl.$error.myError}}` .
@@ -19834,7 +19894,7 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
19834
19894
  * When one person, perhaps John, views the document, "John is viewing" will be shown.
19835
19895
  * When three people view the document, no explicit number rule is found, so
19836
19896
  * an offset of 2 is taken off 3, and Angular uses 1 to decide the plural category.
19837
- * In this case, plural category 'one' is matched and "John, Marry and one other person are viewing"
19897
+ * In this case, plural category 'one' is matched and "John, Mary and one other person are viewing"
19838
19898
  * is shown.
19839
19899
  *
19840
19900
  * Note that when you specify offsets, you must provide explicit number rules for
@@ -20716,7 +20776,7 @@ var ngHideDirective = ['$animate', function($animate) {
20716
20776
  <file name="protractor.js" type="protractor">
20717
20777
  var colorSpan = element(by.css('span'));
20718
20778
 
20719
- iit('should check ng-style', function() {
20779
+ it('should check ng-style', function() {
20720
20780
  expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
20721
20781
  element(by.css('input[value=\'set color\']')).click();
20722
20782
  expect(colorSpan.getCssValue('color')).toBe('rgba(255, 0, 0, 1)');
@@ -21609,7 +21669,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
21609
21669
  // rather then the element.
21610
21670
  (element = optionTemplate.clone())
21611
21671
  .val(option.id)
21612
- .attr('selected', option.selected)
21672
+ .prop('selected', option.selected)
21613
21673
  .text(option.label);
21614
21674
  }
21615
21675