rails-angularjs 1.3.12 → 1.3.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/lib/rails-angularjs/version.rb +2 -2
  4. data/vendor/assets/javascripts/{angularjs/angular-animate.js → angular-animate.js} +1 -1
  5. data/vendor/assets/javascripts/{angularjs/angular-animate.min.js → angular-animate.min.js} +1 -1
  6. data/vendor/assets/javascripts/{angularjs/angular-aria.js → angular-aria.js} +16 -6
  7. data/vendor/assets/javascripts/angular-aria.min.js +12 -0
  8. data/vendor/assets/javascripts/{angularjs/angular-cookies.js → angular-cookies.js} +1 -1
  9. data/vendor/assets/javascripts/{angularjs/angular-cookies.min.js → angular-cookies.min.js} +1 -1
  10. data/vendor/assets/javascripts/{angularjs/angular-loader.js → angular-loader.js} +2 -2
  11. data/vendor/assets/javascripts/{angularjs/angular-loader.min.js → angular-loader.min.js} +2 -2
  12. data/vendor/assets/javascripts/{angularjs/angular-messages.js → angular-messages.js} +1 -1
  13. data/vendor/assets/javascripts/{angularjs/angular-messages.min.js → angular-messages.min.js} +1 -1
  14. data/vendor/assets/javascripts/{angularjs/angular-mocks.js → angular-mocks.js} +2 -2
  15. data/vendor/assets/javascripts/{angularjs/angular-resource.js → angular-resource.js} +2 -1
  16. data/vendor/assets/javascripts/{angularjs/angular-resource.min.js → angular-resource.min.js} +1 -1
  17. data/vendor/assets/javascripts/{angularjs/angular-route.js → angular-route.js} +1 -1
  18. data/vendor/assets/javascripts/{angularjs/angular-route.min.js → angular-route.min.js} +1 -1
  19. data/vendor/assets/javascripts/{angularjs/angular-sanitize.js → angular-sanitize.js} +7 -19
  20. data/vendor/assets/javascripts/angular-sanitize.min.js +16 -0
  21. data/vendor/assets/javascripts/{angularjs/angular-scenario.js → angular-scenario.js} +89 -38
  22. data/vendor/assets/javascripts/{angularjs/angular-touch.js → angular-touch.js} +1 -1
  23. data/vendor/assets/javascripts/{angularjs/angular-touch.min.js → angular-touch.min.js} +1 -1
  24. data/vendor/assets/javascripts/{angularjs/angular.js → angular.js} +89 -38
  25. data/vendor/assets/javascripts/angular.min.js +250 -0
  26. data/vendor/assets/javascripts/{angularjs/unstable → unstable}/angular-animate.js +1 -1
  27. data/vendor/assets/javascripts/{angularjs/unstable → unstable}/angular-animate.min.js +1 -1
  28. data/vendor/assets/javascripts/{angularjs/unstable → unstable}/angular-aria.js +16 -6
  29. data/vendor/assets/javascripts/unstable/angular-aria.min.js +12 -0
  30. data/vendor/assets/javascripts/{angularjs/unstable → unstable}/angular-cookies.js +1 -1
  31. data/vendor/assets/javascripts/{angularjs/unstable → unstable}/angular-cookies.min.js +1 -1
  32. data/vendor/assets/javascripts/{angularjs/unstable → unstable}/angular-loader.js +2 -2
  33. data/vendor/assets/javascripts/{angularjs/unstable → unstable}/angular-loader.min.js +2 -2
  34. data/vendor/assets/javascripts/unstable/angular-messages.js +644 -0
  35. data/vendor/assets/javascripts/unstable/angular-messages.min.js +12 -0
  36. data/vendor/assets/javascripts/{angularjs/unstable → unstable}/angular-mocks.js +2 -2
  37. data/vendor/assets/javascripts/{angularjs/unstable → unstable}/angular-resource.js +3 -2
  38. data/vendor/assets/javascripts/{angularjs/unstable → unstable}/angular-resource.min.js +1 -1
  39. data/vendor/assets/javascripts/{angularjs/unstable → unstable}/angular-route.js +1 -1
  40. data/vendor/assets/javascripts/{angularjs/unstable → unstable}/angular-route.min.js +1 -1
  41. data/vendor/assets/javascripts/{angularjs/unstable → unstable}/angular-sanitize.js +12 -22
  42. data/vendor/assets/javascripts/unstable/angular-sanitize.min.js +16 -0
  43. data/vendor/assets/javascripts/{angularjs/unstable → unstable}/angular-scenario.js +317 -155
  44. data/vendor/assets/javascripts/{angularjs/unstable → unstable}/angular-touch.js +1 -1
  45. data/vendor/assets/javascripts/{angularjs/unstable → unstable}/angular-touch.min.js +1 -1
  46. data/vendor/assets/javascripts/{angularjs/unstable → unstable}/angular.js +317 -155
  47. data/vendor/assets/javascripts/unstable/angular.min.js +282 -0
  48. metadata +46 -46
  49. data/vendor/assets/javascripts/angularjs/angular-aria.min.js +0 -12
  50. data/vendor/assets/javascripts/angularjs/angular-sanitize.min.js +0 -16
  51. data/vendor/assets/javascripts/angularjs/angular.min.js +0 -250
  52. data/vendor/assets/javascripts/angularjs/unstable/angular-aria.min.js +0 -12
  53. data/vendor/assets/javascripts/angularjs/unstable/angular-messages.js +0 -400
  54. data/vendor/assets/javascripts/angularjs/unstable/angular-messages.min.js +0 -10
  55. data/vendor/assets/javascripts/angularjs/unstable/angular-sanitize.min.js +0 -16
  56. data/vendor/assets/javascripts/angularjs/unstable/angular.min.js +0 -281
@@ -9190,7 +9190,7 @@ return jQuery;
9190
9190
  }));
9191
9191
 
9192
9192
  /**
9193
- * @license AngularJS v1.4.0-beta.3
9193
+ * @license AngularJS v1.4.0-beta.5
9194
9194
  * (c) 2010-2015 Google, Inc. http://angularjs.org
9195
9195
  * License: MIT
9196
9196
  */
@@ -9249,7 +9249,7 @@ function minErr(module, ErrorConstructor) {
9249
9249
  return match;
9250
9250
  });
9251
9251
 
9252
- message += '\nhttp://errors.angularjs.org/1.4.0-beta.3/' +
9252
+ message += '\nhttp://errors.angularjs.org/1.4.0-beta.5/' +
9253
9253
  (module ? module + '/' : '') + code;
9254
9254
 
9255
9255
  for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
@@ -9319,6 +9319,7 @@ function minErr(module, ErrorConstructor) {
9319
9319
  shallowCopy: true,
9320
9320
  equals: true,
9321
9321
  csp: true,
9322
+ jq: true,
9322
9323
  concat: true,
9323
9324
  sliceArgs: true,
9324
9325
  bind: true,
@@ -10162,7 +10163,61 @@ var csp = function() {
10162
10163
  return (csp.isActive_ = active);
10163
10164
  };
10164
10165
 
10166
+ /**
10167
+ * @ngdoc directive
10168
+ * @module ng
10169
+ * @name ngJq
10170
+ *
10171
+ * @element ANY
10172
+ * @param {string=} the name of the library available under `window`
10173
+ * to be used for angular.element
10174
+ * @description
10175
+ * Use this directive to force the angular.element library. This should be
10176
+ * used to force either jqLite by leaving ng-jq blank or setting the name of
10177
+ * the jquery variable under window (eg. jQuery).
10178
+ *
10179
+ * Since this directive is global for the angular library, it is recommended
10180
+ * that it's added to the same element as ng-app or the HTML element, but it is not mandatory.
10181
+ * It needs to be noted that only the first instance of `ng-jq` will be used and all others
10182
+ * ignored.
10183
+ *
10184
+ * @example
10185
+ * This example shows how to force jqLite using the `ngJq` directive to the `html` tag.
10186
+ ```html
10187
+ <!doctype html>
10188
+ <html ng-app ng-jq>
10189
+ ...
10190
+ ...
10191
+ </html>
10192
+ ```
10193
+ * @example
10194
+ * This example shows how to use a jQuery based library of a different name.
10195
+ * The library name must be available at the top most 'window'.
10196
+ ```html
10197
+ <!doctype html>
10198
+ <html ng-app ng-jq="jQueryLib">
10199
+ ...
10200
+ ...
10201
+ </html>
10202
+ ```
10203
+ */
10204
+ var jq = function() {
10205
+ if (isDefined(jq.name_)) return jq.name_;
10206
+ var el;
10207
+ var i, ii = ngAttrPrefixes.length;
10208
+ for (i = 0; i < ii; ++i) {
10209
+ if (el = document.querySelector('[' + ngAttrPrefixes[i].replace(':', '\\:') + 'jq]')) {
10210
+ break;
10211
+ }
10212
+ }
10213
+
10214
+ var name;
10215
+ if (el) {
10216
+ name = getNgAttribute(el, "jq");
10217
+ }
10165
10218
 
10219
+ return (jq.name_ = name);
10220
+ };
10166
10221
 
10167
10222
  function concat(array1, array2, index) {
10168
10223
  return array1.concat(slice.call(array2, index));
@@ -10735,7 +10790,12 @@ function bindJQuery() {
10735
10790
  }
10736
10791
 
10737
10792
  // bind to jQuery if present;
10738
- jQuery = window.jQuery;
10793
+ var jqName = jq();
10794
+ jQuery = window.jQuery; // use default jQuery.
10795
+ if (isDefined(jqName)) { // `ngJq` present
10796
+ jQuery = jqName === null ? undefined : window[jqName]; // if empty; use jqLite. if not empty, use jQuery specified by `ngJq`.
10797
+ }
10798
+
10739
10799
  // Use jQuery if it exists with proper functionality, otherwise default to us.
10740
10800
  // Angular 1.2+ requires jQuery 1.7+ for on()/off() support.
10741
10801
  // Angular 1.3+ technically requires at least jQuery 2.1+ but it may work with older
@@ -11327,11 +11387,11 @@ function toDebugString(obj) {
11327
11387
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
11328
11388
  */
11329
11389
  var version = {
11330
- full: '1.4.0-beta.3', // all of these placeholder strings will be replaced by grunt's
11390
+ full: '1.4.0-beta.5', // all of these placeholder strings will be replaced by grunt's
11331
11391
  major: 1, // package task
11332
11392
  minor: 4,
11333
11393
  dot: 0,
11334
- codeName: 'substance-mimicry'
11394
+ codeName: 'karmic-stabilization'
11335
11395
  };
11336
11396
 
11337
11397
 
@@ -16539,7 +16599,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16539
16599
  var terminalPriority = -Number.MAX_VALUE,
16540
16600
  newScopeDirective,
16541
16601
  controllerDirectives = previousCompileContext.controllerDirectives,
16542
- controllers,
16543
16602
  newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective,
16544
16603
  templateDirective = previousCompileContext.templateDirective,
16545
16604
  nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective,
@@ -16597,7 +16656,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16597
16656
 
16598
16657
  if (!directive.templateUrl && directive.controller) {
16599
16658
  directiveValue = directive.controller;
16600
- controllerDirectives = controllerDirectives || {};
16659
+ controllerDirectives = controllerDirectives || createMap();
16601
16660
  assertNoDuplicate("'" + directiveName + "' controller",
16602
16661
  controllerDirectives[directiveName], directive, $compileNode);
16603
16662
  controllerDirectives[directiveName] = directive;
@@ -16765,51 +16824,74 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16765
16824
 
16766
16825
 
16767
16826
  function getControllers(directiveName, require, $element, elementControllers) {
16768
- var value, retrievalMethod = 'data', optional = false;
16769
- var $searchElement = $element;
16770
- var match;
16771
- if (isString(require)) {
16772
- match = require.match(REQUIRE_PREFIX_REGEXP);
16773
- require = require.substring(match[0].length);
16827
+ var value;
16774
16828
 
16775
- if (match[3]) {
16776
- if (match[1]) match[3] = null;
16777
- else match[1] = match[3];
16778
- }
16779
- if (match[1] === '^') {
16780
- retrievalMethod = 'inheritedData';
16781
- } else if (match[1] === '^^') {
16782
- retrievalMethod = 'inheritedData';
16783
- $searchElement = $element.parent();
16784
- }
16785
- if (match[2] === '?') {
16786
- optional = true;
16829
+ if (isString(require)) {
16830
+ var match = require.match(REQUIRE_PREFIX_REGEXP);
16831
+ var name = require.substring(match[0].length);
16832
+ var inheritType = match[1] || match[3];
16833
+ var optional = match[2] === '?';
16834
+
16835
+ //If only parents then start at the parent element
16836
+ if (inheritType === '^^') {
16837
+ $element = $element.parent();
16838
+ //Otherwise attempt getting the controller from elementControllers in case
16839
+ //the element is transcluded (and has no data) and to avoid .data if possible
16840
+ } else {
16841
+ value = elementControllers && elementControllers[name];
16842
+ value = value && value.instance;
16787
16843
  }
16788
16844
 
16789
- value = null;
16790
-
16791
- if (elementControllers && retrievalMethod === 'data') {
16792
- if (value = elementControllers[require]) {
16793
- value = value.instance;
16794
- }
16845
+ if (!value) {
16846
+ var dataName = '$' + name + 'Controller';
16847
+ value = inheritType ? $element.inheritedData(dataName) : $element.data(dataName);
16795
16848
  }
16796
- value = value || $searchElement[retrievalMethod]('$' + require + 'Controller');
16797
16849
 
16798
16850
  if (!value && !optional) {
16799
16851
  throw $compileMinErr('ctreq',
16800
16852
  "Controller '{0}', required by directive '{1}', can't be found!",
16801
- require, directiveName);
16853
+ name, directiveName);
16802
16854
  }
16803
- return value || null;
16804
16855
  } else if (isArray(require)) {
16805
16856
  value = [];
16806
- forEach(require, function(require) {
16807
- value.push(getControllers(directiveName, require, $element, elementControllers));
16808
- });
16857
+ for (var i = 0, ii = require.length; i < ii; i++) {
16858
+ value[i] = getControllers(directiveName, require[i], $element, elementControllers);
16859
+ }
16809
16860
  }
16810
- return value;
16861
+
16862
+ return value || null;
16811
16863
  }
16812
16864
 
16865
+ function setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope) {
16866
+ var elementControllers = createMap();
16867
+ for (var controllerKey in controllerDirectives) {
16868
+ var directive = controllerDirectives[controllerKey];
16869
+ var locals = {
16870
+ $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
16871
+ $element: $element,
16872
+ $attrs: attrs,
16873
+ $transclude: transcludeFn
16874
+ };
16875
+
16876
+ var controller = directive.controller;
16877
+ if (controller == '@') {
16878
+ controller = attrs[directive.name];
16879
+ }
16880
+
16881
+ var controllerInstance = $controller(controller, locals, true, directive.controllerAs);
16882
+
16883
+ // For directives with element transclusion the element is a comment,
16884
+ // but jQuery .data doesn't support attaching data to comment nodes as it's hard to
16885
+ // clean up (http://bugs.jquery.com/ticket/8335).
16886
+ // Instead, we save the controllers for the element in a local hash and attach to .data
16887
+ // later, once we have the actual element.
16888
+ elementControllers[directive.name] = controllerInstance;
16889
+ if (!hasElementTranscludeDirective) {
16890
+ $element.data('$' + directive.name + 'Controller', controllerInstance.instance);
16891
+ }
16892
+ }
16893
+ return elementControllers;
16894
+ }
16813
16895
 
16814
16896
  function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn,
16815
16897
  thisLinkFn) {
@@ -16836,36 +16918,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16836
16918
  }
16837
16919
 
16838
16920
  if (controllerDirectives) {
16839
- // TODO: merge `controllers` and `elementControllers` into single object.
16840
- controllers = {};
16841
- elementControllers = {};
16842
- forEach(controllerDirectives, function(directive) {
16843
- var locals = {
16844
- $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
16845
- $element: $element,
16846
- $attrs: attrs,
16847
- $transclude: transcludeFn
16848
- }, controllerInstance;
16849
-
16850
- controller = directive.controller;
16851
- if (controller == '@') {
16852
- controller = attrs[directive.name];
16853
- }
16854
-
16855
- controllerInstance = $controller(controller, locals, true, directive.controllerAs);
16856
-
16857
- // For directives with element transclusion the element is a comment,
16858
- // but jQuery .data doesn't support attaching data to comment nodes as it's hard to
16859
- // clean up (http://bugs.jquery.com/ticket/8335).
16860
- // Instead, we save the controllers for the element in a local hash and attach to .data
16861
- // later, once we have the actual element.
16862
- elementControllers[directive.name] = controllerInstance;
16863
- if (!hasElementTranscludeDirective) {
16864
- $element.data('$' + directive.name + 'Controller', controllerInstance.instance);
16865
- }
16866
-
16867
- controllers[directive.name] = controllerInstance;
16868
- });
16921
+ elementControllers = setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope);
16869
16922
  }
16870
16923
 
16871
16924
  if (newIsolateScopeDirective) {
@@ -16879,14 +16932,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16879
16932
  isolateScope.$$isolateBindings,
16880
16933
  newIsolateScopeDirective, isolateScope);
16881
16934
  }
16882
- if (controllers) {
16935
+ if (elementControllers) {
16883
16936
  // Initialize bindToController bindings for new/isolate scopes
16884
16937
  var scopeDirective = newIsolateScopeDirective || newScopeDirective;
16885
16938
  var bindings;
16886
16939
  var controllerForBindings;
16887
- if (scopeDirective && controllers[scopeDirective.name]) {
16940
+ if (scopeDirective && elementControllers[scopeDirective.name]) {
16888
16941
  bindings = scopeDirective.$$bindings.bindToController;
16889
- controller = controllers[scopeDirective.name];
16942
+ controller = elementControllers[scopeDirective.name];
16890
16943
 
16891
16944
  if (controller && controller.identifier && bindings) {
16892
16945
  controllerForBindings = controller;
@@ -16895,18 +16948,18 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16895
16948
  bindings, scopeDirective);
16896
16949
  }
16897
16950
  }
16898
- forEach(controllers, function(controller) {
16899
- var result = controller();
16900
- if (result !== controller.instance &&
16951
+ for (i in elementControllers) {
16952
+ controller = elementControllers[i];
16953
+ var controllerResult = controller();
16954
+ if (controllerResult !== controller.instance &&
16901
16955
  controller === controllerForBindings) {
16902
16956
  // Remove and re-install bindToController bindings
16903
16957
  thisLinkFn.$$destroyBindings();
16904
16958
  thisLinkFn.$$destroyBindings =
16905
- initializeDirectiveBindings(scope, attrs, result,
16959
+ initializeDirectiveBindings(scope, attrs, controllerResult,
16906
16960
  bindings, scopeDirective);
16907
16961
  }
16908
- });
16909
- controllers = null;
16962
+ }
16910
16963
  }
16911
16964
 
16912
16965
  // PRELINKING
@@ -17917,19 +17970,24 @@ function isJsonLike(str) {
17917
17970
  * @returns {Object} Parsed headers as key value object
17918
17971
  */
17919
17972
  function parseHeaders(headers) {
17920
- var parsed = createMap(), key, val, i;
17921
-
17922
- if (!headers) return parsed;
17923
-
17924
- forEach(headers.split('\n'), function(line) {
17925
- i = line.indexOf(':');
17926
- key = lowercase(trim(line.substr(0, i)));
17927
- val = trim(line.substr(i + 1));
17973
+ var parsed = createMap(), i;
17928
17974
 
17975
+ function fillInParsed(key, val) {
17929
17976
  if (key) {
17930
17977
  parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
17931
17978
  }
17932
- });
17979
+ }
17980
+
17981
+ if (isString(headers)) {
17982
+ forEach(headers.split('\n'), function(line) {
17983
+ i = line.indexOf(':');
17984
+ fillInParsed(lowercase(trim(line.substr(0, i))), trim(line.substr(i + 1)));
17985
+ });
17986
+ } else if (isObject(headers)) {
17987
+ forEach(headers, function(headerVal, headerKey) {
17988
+ fillInParsed(lowercase(headerKey), trim(headerVal));
17989
+ });
17990
+ }
17933
17991
 
17934
17992
  return parsed;
17935
17993
  }
@@ -17948,7 +18006,7 @@ function parseHeaders(headers) {
17948
18006
  * - if called with no arguments returns an object containing all headers.
17949
18007
  */
17950
18008
  function headersGetter(headers) {
17951
- var headersObj = isObject(headers) ? headers : undefined;
18009
+ var headersObj;
17952
18010
 
17953
18011
  return function(name) {
17954
18012
  if (!headersObj) headersObj = parseHeaders(headers);
@@ -20696,7 +20754,7 @@ function $LocationProvider() {
20696
20754
 
20697
20755
 
20698
20756
  // rewrite hashbang url <> html5 url
20699
- if ($location.absUrl() != initialUrl) {
20757
+ if (trimEmptyHash($location.absUrl()) != trimEmptyHash(initialUrl)) {
20700
20758
  $browser.url($location.absUrl(), true);
20701
20759
  }
20702
20760
 
@@ -21938,7 +21996,7 @@ ASTCompiler.prototype = {
21938
21996
  self.if(self.notNull(right), function() {
21939
21997
  self.addEnsureSafeFunction(right);
21940
21998
  forEach(ast.arguments, function(expr) {
21941
- self.recurse(expr, undefined, undefined, function(argument) {
21999
+ self.recurse(expr, self.nextId(), undefined, function(argument) {
21942
22000
  args.push(self.ensureSafeObject(argument));
21943
22001
  });
21944
22002
  });
@@ -21969,14 +22027,14 @@ ASTCompiler.prototype = {
21969
22027
  self.addEnsureSafeObject(self.member(left.context, left.name, left.computed));
21970
22028
  expression = self.member(left.context, left.name, left.computed) + ast.operator + right;
21971
22029
  self.assign(intoId, expression);
21972
- recursionFn(expression);
22030
+ recursionFn(intoId || expression);
21973
22031
  });
21974
22032
  }, 1);
21975
22033
  break;
21976
22034
  case AST.ArrayExpression:
21977
22035
  args = [];
21978
22036
  forEach(ast.elements, function(expr) {
21979
- self.recurse(expr, undefined, undefined, function(argument) {
22037
+ self.recurse(expr, self.nextId(), undefined, function(argument) {
21980
22038
  args.push(argument);
21981
22039
  });
21982
22040
  });
@@ -21987,7 +22045,7 @@ ASTCompiler.prototype = {
21987
22045
  case AST.ObjectExpression:
21988
22046
  args = [];
21989
22047
  forEach(ast.properties, function(property) {
21990
- self.recurse(property.value, undefined, undefined, function(expr) {
22048
+ self.recurse(property.value, self.nextId(), undefined, function(expr) {
21991
22049
  args.push(self.escape(
21992
22050
  property.key.type === AST.Identifier ? property.key.name :
21993
22051
  ('' + property.key.value)) +
@@ -25641,7 +25699,7 @@ function $SceProvider() {
25641
25699
  * escaping.
25642
25700
  *
25643
25701
  * @param {string} type The kind of context in which this value is safe for use. e.g. url,
25644
- * resource_url, html, js and css.
25702
+ * resourceUrl, html, js and css.
25645
25703
  * @param {*} value The value that that should be considered trusted/safe.
25646
25704
  * @returns {*} A value that can be used to stand in for the provided `value` in places
25647
25705
  * where Angular expects a $sce.trustAs() return value.
@@ -26019,7 +26077,7 @@ function $TemplateRequestProvider() {
26019
26077
  };
26020
26078
 
26021
26079
  return $http.get(tpl, httpOptions)
26022
- .finally(function() {
26080
+ ['finally'](function() {
26023
26081
  handleRequestFn.totalPendingRequests--;
26024
26082
  })
26025
26083
  .then(function(response) {
@@ -27174,7 +27232,9 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZEw']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d
27174
27232
  * specified in the string input, the time is considered to be in the local timezone.
27175
27233
  * @param {string=} format Formatting rules (see Description). If not specified,
27176
27234
  * `mediumDate` is used.
27177
- * @param {string=} timezone Timezone to be used for formatting. Right now, only `'UTC'` is supported.
27235
+ * @param {string=} timezone Timezone to be used for formatting. It understands UTC/GMT and the
27236
+ * continental US time zone abbreviations, but for general use, use a time zone offset, for
27237
+ * example, `'+0430'` (4 hours, 30 minutes east of the Greenwich meridian)
27178
27238
  * If not specified, the timezone of the browser will be used.
27179
27239
  * @returns {string} Formatted string or the input if input is not recognized as date/millis.
27180
27240
  *
@@ -27364,6 +27424,8 @@ var uppercaseFilter = valueFn(uppercase);
27364
27424
  * If the number is negative, `limit` number of items from the end of the source array/string
27365
27425
  * are copied. The `limit` will be trimmed if it exceeds `array.length`. If `limit` is undefined,
27366
27426
  * the input will be returned unchanged.
27427
+ * @param {(string|number)=} begin Index at which to begin limitation. As a negative index, `begin`
27428
+ * indicates an offset from the end of `input`. Defaults to `0`.
27367
27429
  * @returns {Array|string} A new sub-array or substring of length `limit` or less if input array
27368
27430
  * had less than `limit` elements.
27369
27431
  *
@@ -27435,7 +27497,7 @@ var uppercaseFilter = valueFn(uppercase);
27435
27497
  </example>
27436
27498
  */
27437
27499
  function limitToFilter() {
27438
- return function(input, limit) {
27500
+ return function(input, limit, begin) {
27439
27501
  if (Math.abs(Number(limit)) === Infinity) {
27440
27502
  limit = Number(limit);
27441
27503
  } else {
@@ -27446,7 +27508,18 @@ function limitToFilter() {
27446
27508
  if (isNumber(input)) input = input.toString();
27447
27509
  if (!isArray(input) && !isString(input)) return input;
27448
27510
 
27449
- return limit >= 0 ? input.slice(0, limit) : input.slice(limit);
27511
+ begin = (!begin || isNaN(begin)) ? 0 : toInt(begin);
27512
+ begin = (begin < 0 && begin >= -input.length) ? input.length + begin : begin;
27513
+
27514
+ if (limit >= 0) {
27515
+ return input.slice(begin, begin + limit);
27516
+ } else {
27517
+ if (begin === 0) {
27518
+ return input.slice(limit, input.length);
27519
+ } else {
27520
+ return input.slice(Math.max(0, begin + limit), begin);
27521
+ }
27522
+ }
27450
27523
  };
27451
27524
  }
27452
27525
 
@@ -27858,20 +27931,23 @@ var htmlAnchorDirective = valueFn({
27858
27931
  *
27859
27932
  * @description
27860
27933
  *
27861
- * We shouldn't do this, because it will make the button enabled on Chrome/Firefox but not on IE8 and older IEs:
27934
+ * This directive sets the `disabled` attribute on the element if the
27935
+ * {@link guide/expression expression} inside `ngDisabled` evaluates to truthy.
27936
+ *
27937
+ * A special directive is necessary because we cannot use interpolation inside the `disabled`
27938
+ * attribute. The following example would make the button enabled on Chrome/Firefox
27939
+ * but not on older IEs:
27940
+ *
27862
27941
  * ```html
27863
- * <div ng-init="scope = { isDisabled: false }">
27864
- * <button disabled="{{scope.isDisabled}}">Disabled</button>
27942
+ * <div ng-init="isDisabled = false">
27943
+ * <button disabled="{{isDisabled}}">Disabled</button>
27865
27944
  * </div>
27866
27945
  * ```
27867
27946
  *
27868
- * The HTML specification does not require browsers to preserve the values of boolean attributes
27869
- * such as disabled. (Their presence means true and their absence means false.)
27947
+ * This is because the HTML specification does not require browsers to preserve the values of
27948
+ * boolean attributes such as `disabled` (Their presence means true and their absence means false.)
27870
27949
  * If we put an Angular interpolation expression into such an attribute then the
27871
27950
  * binding information would be lost when the browser removes the attribute.
27872
- * The `ngDisabled` directive solves this problem for the `disabled` attribute.
27873
- * This complementary directive is not removed by the browser and so provides
27874
- * a permanent reliable place to store the binding information.
27875
27951
  *
27876
27952
  * @example
27877
27953
  <example>
@@ -27890,7 +27966,7 @@ var htmlAnchorDirective = valueFn({
27890
27966
  *
27891
27967
  * @element INPUT
27892
27968
  * @param {expression} ngDisabled If the {@link guide/expression expression} is truthy,
27893
- * then special attribute "disabled" will be set on the element
27969
+ * then the `disabled` attribute will be set on the element
27894
27970
  */
27895
27971
 
27896
27972
 
@@ -29904,7 +29980,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
29904
29980
  return value;
29905
29981
  });
29906
29982
 
29907
- if (attr.min || attr.ngMin) {
29983
+ if (isDefined(attr.min) || attr.ngMin) {
29908
29984
  var minVal;
29909
29985
  ctrl.$validators.min = function(value) {
29910
29986
  return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal;
@@ -29920,7 +29996,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
29920
29996
  });
29921
29997
  }
29922
29998
 
29923
- if (attr.max || attr.ngMax) {
29999
+ if (isDefined(attr.max) || attr.ngMax) {
29924
30000
  var maxVal;
29925
30001
  ctrl.$validators.max = function(value) {
29926
30002
  return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal;
@@ -32726,6 +32802,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
32726
32802
  ngModelGet = parsedNgModel,
32727
32803
  ngModelSet = parsedNgModelAssign,
32728
32804
  pendingDebounce = null,
32805
+ parserValid,
32729
32806
  ctrl = this;
32730
32807
 
32731
32808
  this.$$setOptions = function(options) {
@@ -32998,16 +33075,12 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
32998
33075
  // the model although neither viewValue nor the model on the scope changed
32999
33076
  var modelValue = ctrl.$$rawModelValue;
33000
33077
 
33001
- // Check if the there's a parse error, so we don't unset it accidentially
33002
- var parserName = ctrl.$$parserName || 'parse';
33003
- var parserValid = ctrl.$error[parserName] ? false : undefined;
33004
-
33005
33078
  var prevValid = ctrl.$valid;
33006
33079
  var prevModelValue = ctrl.$modelValue;
33007
33080
 
33008
33081
  var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid;
33009
33082
 
33010
- ctrl.$$runValidators(parserValid, modelValue, viewValue, function(allValid) {
33083
+ ctrl.$$runValidators(modelValue, viewValue, function(allValid) {
33011
33084
  // If there was no change in validity, don't update the model
33012
33085
  // This prevents changing an invalid modelValue to undefined
33013
33086
  if (!allowInvalid && prevValid !== allValid) {
@@ -33025,12 +33098,12 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
33025
33098
 
33026
33099
  };
33027
33100
 
33028
- this.$$runValidators = function(parseValid, modelValue, viewValue, doneCallback) {
33101
+ this.$$runValidators = function(modelValue, viewValue, doneCallback) {
33029
33102
  currentValidationRunId++;
33030
33103
  var localValidationRunId = currentValidationRunId;
33031
33104
 
33032
33105
  // check parser error
33033
- if (!processParseErrors(parseValid)) {
33106
+ if (!processParseErrors()) {
33034
33107
  validationDone(false);
33035
33108
  return;
33036
33109
  }
@@ -33040,21 +33113,22 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
33040
33113
  }
33041
33114
  processAsyncValidators();
33042
33115
 
33043
- function processParseErrors(parseValid) {
33116
+ function processParseErrors() {
33044
33117
  var errorKey = ctrl.$$parserName || 'parse';
33045
- if (parseValid === undefined) {
33118
+ if (parserValid === undefined) {
33046
33119
  setValidity(errorKey, null);
33047
33120
  } else {
33048
- setValidity(errorKey, parseValid);
33049
- if (!parseValid) {
33121
+ if (!parserValid) {
33050
33122
  forEach(ctrl.$validators, function(v, name) {
33051
33123
  setValidity(name, null);
33052
33124
  });
33053
33125
  forEach(ctrl.$asyncValidators, function(v, name) {
33054
33126
  setValidity(name, null);
33055
33127
  });
33056
- return false;
33057
33128
  }
33129
+ // Set the parse error last, to prevent unsetting it, should a $validators key == parserName
33130
+ setValidity(errorKey, parserValid);
33131
+ return parserValid;
33058
33132
  }
33059
33133
  return true;
33060
33134
  }
@@ -33149,7 +33223,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
33149
33223
  this.$$parseAndValidate = function() {
33150
33224
  var viewValue = ctrl.$$lastCommittedViewValue;
33151
33225
  var modelValue = viewValue;
33152
- var parserValid = isUndefined(modelValue) ? undefined : true;
33226
+ parserValid = isUndefined(modelValue) ? undefined : true;
33153
33227
 
33154
33228
  if (parserValid) {
33155
33229
  for (var i = 0; i < ctrl.$parsers.length; i++) {
@@ -33175,7 +33249,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
33175
33249
 
33176
33250
  // Pass the $$lastCommittedViewValue here, because the cached viewValue might be out of date.
33177
33251
  // This can happen if e.g. $setViewValue is called from inside a parser
33178
- ctrl.$$runValidators(parserValid, modelValue, ctrl.$$lastCommittedViewValue, function(allValid) {
33252
+ ctrl.$$runValidators(modelValue, ctrl.$$lastCommittedViewValue, function(allValid) {
33179
33253
  if (!allowInvalid) {
33180
33254
  // Note: Don't check ctrl.$valid here, as we could have
33181
33255
  // external validators (e.g. calculated on the server),
@@ -33296,6 +33370,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
33296
33370
  // TODO(perf): why not move this to the action fn?
33297
33371
  if (modelValue !== ctrl.$modelValue) {
33298
33372
  ctrl.$modelValue = ctrl.$$rawModelValue = modelValue;
33373
+ parserValid = undefined;
33299
33374
 
33300
33375
  var formatters = ctrl.$formatters,
33301
33376
  idx = formatters.length;
@@ -33308,7 +33383,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
33308
33383
  ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;
33309
33384
  ctrl.$render();
33310
33385
 
33311
- ctrl.$$runValidators(undefined, modelValue, viewValue, noop);
33386
+ ctrl.$$runValidators(modelValue, viewValue, noop);
33312
33387
  }
33313
33388
  }
33314
33389
 
@@ -33944,15 +34019,20 @@ var ngOptionsMinErr = minErr('ngOptions');
33944
34019
  * * `label` **`for`** `value` **`in`** `array`
33945
34020
  * * `select` **`as`** `label` **`for`** `value` **`in`** `array`
33946
34021
  * * `label` **`group by`** `group` **`for`** `value` **`in`** `array`
34022
+ * * `label` **`disable when`** `disable` **`for`** `value` **`in`** `array`
33947
34023
  * * `label` **`group by`** `group` **`for`** `value` **`in`** `array` **`track by`** `trackexpr`
34024
+ * * `label` **`disable when`** `disable` **`for`** `value` **`in`** `array` **`track by`** `trackexpr`
33948
34025
  * * `label` **`for`** `value` **`in`** `array` | orderBy:`orderexpr` **`track by`** `trackexpr`
33949
34026
  * (for including a filter with `track by`)
33950
34027
  * * for object data sources:
33951
34028
  * * `label` **`for (`**`key` **`,`** `value`**`) in`** `object`
33952
34029
  * * `select` **`as`** `label` **`for (`**`key` **`,`** `value`**`) in`** `object`
33953
34030
  * * `label` **`group by`** `group` **`for (`**`key`**`,`** `value`**`) in`** `object`
34031
+ * * `label` **`disable when`** `disable` **`for (`**`key`**`,`** `value`**`) in`** `object`
33954
34032
  * * `select` **`as`** `label` **`group by`** `group`
33955
34033
  * **`for` `(`**`key`**`,`** `value`**`) in`** `object`
34034
+ * * `select` **`as`** `label` **`disable when`** `disable`
34035
+ * **`for` `(`**`key`**`,`** `value`**`) in`** `object`
33956
34036
  *
33957
34037
  * Where:
33958
34038
  *
@@ -33966,6 +34046,8 @@ var ngOptionsMinErr = minErr('ngOptions');
33966
34046
  * element. If not specified, `select` expression will default to `value`.
33967
34047
  * * `group`: The result of this expression will be used to group options using the `<optgroup>`
33968
34048
  * DOM element.
34049
+ * * `disable`: The result of this expression will be used to disable the rendered `<option>`
34050
+ * element. Return `true` to disable.
33969
34051
  * * `trackexpr`: Used when working with an array of objects. The result of this expression will be
33970
34052
  * used to identify the objects in the array. The `trackexpr` will most likely refer to the
33971
34053
  * `value` variable (e.g. `value.propertyName`). With this the selection is preserved
@@ -33979,10 +34061,10 @@ var ngOptionsMinErr = minErr('ngOptions');
33979
34061
  .controller('ExampleController', ['$scope', function($scope) {
33980
34062
  $scope.colors = [
33981
34063
  {name:'black', shade:'dark'},
33982
- {name:'white', shade:'light'},
34064
+ {name:'white', shade:'light', notAnOption: true},
33983
34065
  {name:'red', shade:'dark'},
33984
- {name:'blue', shade:'dark'},
33985
- {name:'yellow', shade:'light'}
34066
+ {name:'blue', shade:'dark', notAnOption: true},
34067
+ {name:'yellow', shade:'light', notAnOption: false}
33986
34068
  ];
33987
34069
  $scope.myColor = $scope.colors[2]; // red
33988
34070
  }]);
@@ -33991,6 +34073,7 @@ var ngOptionsMinErr = minErr('ngOptions');
33991
34073
  <ul>
33992
34074
  <li ng-repeat="color in colors">
33993
34075
  Name: <input ng-model="color.name">
34076
+ <input type="checkbox" ng-model="color.notAnOption"> Disabled?
33994
34077
  [<a href ng-click="colors.splice($index, 1)">X</a>]
33995
34078
  </li>
33996
34079
  <li>
@@ -34012,6 +34095,12 @@ var ngOptionsMinErr = minErr('ngOptions');
34012
34095
  <select ng-model="myColor" ng-options="color.name group by color.shade for color in colors">
34013
34096
  </select><br/>
34014
34097
 
34098
+ Color grouped by shade, with some disabled:
34099
+ <select ng-model="myColor"
34100
+ ng-options="color.name group by color.shade disable when color.notAnOption for color in colors">
34101
+ </select><br/>
34102
+
34103
+
34015
34104
 
34016
34105
  Select <a href ng-click="myColor = { name:'not in list', shade: 'other' }">bogus</a>.<br>
34017
34106
  <hr/>
@@ -34036,16 +34125,17 @@ var ngOptionsMinErr = minErr('ngOptions');
34036
34125
  */
34037
34126
 
34038
34127
  // jshint maxlen: false
34039
- //000011111111110000000000022222222220000000000000000000003333333333000000000000004444444444444440000000005555555555555550000000666666666666666000000000000000777777777700000000000000000008888888888
34040
- var NG_OPTIONS_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/;
34128
+ // //00001111111111000000000002222222222000000000000000000000333333333300000000000000000000000004444444444400000000000005555555555555550000000006666666666666660000000777777777777777000000000000000888888888800000000000000000009999999999
34129
+ var NG_OPTIONS_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?(?:\s+disable\s+when\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/;
34041
34130
  // 1: value expression (valueFn)
34042
34131
  // 2: label expression (displayFn)
34043
34132
  // 3: group by expression (groupByFn)
34044
- // 4: array item variable name
34045
- // 5: object item key variable name
34046
- // 6: object item value variable name
34047
- // 7: collection expression
34048
- // 8: track by expression
34133
+ // 4: disable when expression (disableWhenFn)
34134
+ // 5: array item variable name
34135
+ // 6: object item key variable name
34136
+ // 7: object item value variable name
34137
+ // 8: collection expression
34138
+ // 9: track by expression
34049
34139
  // jshint maxlen: 100
34050
34140
 
34051
34141
 
@@ -34065,14 +34155,14 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
34065
34155
  // Extract the parts from the ngOptions expression
34066
34156
 
34067
34157
  // The variable name for the value of the item in the collection
34068
- var valueName = match[4] || match[6];
34158
+ var valueName = match[5] || match[7];
34069
34159
  // The variable name for the key of the item in the collection
34070
- var keyName = match[5];
34160
+ var keyName = match[6];
34071
34161
 
34072
34162
  // An expression that generates the viewValue for an option if there is a label expression
34073
34163
  var selectAs = / as /.test(match[0]) && match[1];
34074
34164
  // An expression that is used to track the id of each object in the options collection
34075
- var trackBy = match[8];
34165
+ var trackBy = match[9];
34076
34166
  // An expression that generates the viewValue for an option if there is no label expression
34077
34167
  var valueFn = $parse(match[2] ? match[1] : valueName);
34078
34168
  var selectAsFn = selectAs && $parse(selectAs);
@@ -34087,7 +34177,8 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
34087
34177
  function getHashOfValue(viewValue) { return hashKey(viewValue); };
34088
34178
  var displayFn = $parse(match[2] || match[1]);
34089
34179
  var groupByFn = $parse(match[3] || '');
34090
- var valuesFn = $parse(match[7]);
34180
+ var disableWhenFn = $parse(match[4] || '');
34181
+ var valuesFn = $parse(match[8]);
34091
34182
 
34092
34183
  var locals = {};
34093
34184
  var getLocals = keyName ? function(value, key) {
@@ -34100,11 +34191,12 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
34100
34191
  };
34101
34192
 
34102
34193
 
34103
- function Option(selectValue, viewValue, label, group) {
34194
+ function Option(selectValue, viewValue, label, group, disabled) {
34104
34195
  this.selectValue = selectValue;
34105
34196
  this.viewValue = viewValue;
34106
34197
  this.label = label;
34107
34198
  this.group = group;
34199
+ this.disabled = disabled;
34108
34200
  }
34109
34201
 
34110
34202
  return {
@@ -34117,10 +34209,20 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
34117
34209
 
34118
34210
  Object.keys(values).forEach(function getWatchable(key) {
34119
34211
  var locals = getLocals(values[key], key);
34120
- var label = displayFn(scope, locals);
34121
34212
  var selectValue = getTrackByValue(values[key], locals);
34122
34213
  watchedArray.push(selectValue);
34123
- watchedArray.push(label);
34214
+
34215
+ // Only need to watch the displayFn if there is a specific label expression
34216
+ if (match[2]) {
34217
+ var label = displayFn(scope, locals);
34218
+ watchedArray.push(label);
34219
+ }
34220
+
34221
+ // Only need to watch the disableWhenFn if there is a specific disable expression
34222
+ if (match[4]) {
34223
+ var disableWhen = disableWhenFn(scope, locals);
34224
+ watchedArray.push(disableWhen);
34225
+ }
34124
34226
  });
34125
34227
  return watchedArray;
34126
34228
  }),
@@ -34146,7 +34248,8 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
34146
34248
  var selectValue = getTrackByValue(viewValue, locals);
34147
34249
  var label = displayFn(scope, locals);
34148
34250
  var group = groupByFn(scope, locals);
34149
- var optionItem = new Option(selectValue, viewValue, label, group);
34251
+ var disabled = disableWhenFn(scope, locals);
34252
+ var optionItem = new Option(selectValue, viewValue, label, group, disabled);
34150
34253
 
34151
34254
  optionItems.push(optionItem);
34152
34255
  selectValueMap[selectValue] = optionItem;
@@ -34223,7 +34326,7 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
34223
34326
  selectCtrl.writeValue = function writeNgOptionsValue(value) {
34224
34327
  var option = options.getOptionFromViewValue(value);
34225
34328
 
34226
- if (option) {
34329
+ if (option && !option.disabled) {
34227
34330
  if (selectElement[0].value !== option.selectValue) {
34228
34331
  removeUnknownOption();
34229
34332
  removeEmptyOption();
@@ -34247,7 +34350,7 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
34247
34350
 
34248
34351
  var selectedOption = options.selectValueMap[selectElement.val()];
34249
34352
 
34250
- if (selectedOption) {
34353
+ if (selectedOption && !selectedOption.disabled) {
34251
34354
  removeEmptyOption();
34252
34355
  removeUnknownOption();
34253
34356
  return selectedOption.viewValue;
@@ -34272,18 +34375,22 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
34272
34375
  if (value) {
34273
34376
  value.forEach(function(item) {
34274
34377
  var option = options.getOptionFromViewValue(item);
34275
- if (option) option.element.selected = true;
34378
+ if (option && !option.disabled) option.element.selected = true;
34276
34379
  });
34277
34380
  }
34278
34381
  };
34279
34382
 
34280
34383
 
34281
34384
  selectCtrl.readValue = function readNgOptionsMultiple() {
34282
- var selectedValues = selectElement.val() || [];
34283
- return selectedValues.map(function(selectedKey) {
34284
- var option = options.selectValueMap[selectedKey];
34285
- return option.viewValue;
34385
+ var selectedValues = selectElement.val() || [],
34386
+ selections = [];
34387
+
34388
+ forEach(selectedValues, function(value) {
34389
+ var option = options.selectValueMap[value];
34390
+ if (!option.disabled) selections.push(option.viewValue);
34286
34391
  });
34392
+
34393
+ return selections;
34287
34394
  };
34288
34395
  }
34289
34396
 
@@ -34316,6 +34423,7 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
34316
34423
 
34317
34424
  function updateOptionElement(option, element) {
34318
34425
  option.element = element;
34426
+ element.disabled = option.disabled;
34319
34427
  if (option.value !== element.value) element.value = option.selectValue;
34320
34428
  if (option.label !== element.label) {
34321
34429
  element.label = option.label;
@@ -34749,6 +34857,55 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
34749
34857
  * or implement a `$watch` on the object yourself.
34750
34858
  *
34751
34859
  *
34860
+ * # Tracking and Duplicates
34861
+ *
34862
+ * When the contents of the collection change, `ngRepeat` makes the corresponding changes to the DOM:
34863
+ *
34864
+ * * When an item is added, a new instance of the template is added to the DOM.
34865
+ * * When an item is removed, its template instance is removed from the DOM.
34866
+ * * When items are reordered, their respective templates are reordered in the DOM.
34867
+ *
34868
+ * By default, `ngRepeat` does not allow duplicate items in arrays. This is because when
34869
+ * there are duplicates, it is not possible to maintain a one-to-one mapping between collection
34870
+ * items and DOM elements.
34871
+ *
34872
+ * If you do need to repeat duplicate items, you can substitute the default tracking behavior
34873
+ * with your own using the `track by` expression.
34874
+ *
34875
+ * For example, you may track items by the index of each item in the collection, using the
34876
+ * special scope property `$index`:
34877
+ * ```html
34878
+ * <div ng-repeat="n in [42, 42, 43, 43] track by $index">
34879
+ * {{n}}
34880
+ * </div>
34881
+ * ```
34882
+ *
34883
+ * You may use arbitrary expressions in `track by`, including references to custom functions
34884
+ * on the scope:
34885
+ * ```html
34886
+ * <div ng-repeat="n in [42, 42, 43, 43] track by myTrackingFunction(n)">
34887
+ * {{n}}
34888
+ * </div>
34889
+ * ```
34890
+ *
34891
+ * If you are working with objects that have an identifier property, you can track
34892
+ * by the identifier instead of the whole object. Should you reload your data later, `ngRepeat`
34893
+ * will not have to rebuild the DOM elements for items it has already rendered, even if the
34894
+ * JavaScript objects in the collection have been substituted for new ones:
34895
+ * ```html
34896
+ * <div ng-repeat="model in collection track by model.id">
34897
+ * {{model.name}}
34898
+ * </div>
34899
+ * ```
34900
+ *
34901
+ * When no `track by` expression is provided, it is equivalent to tracking by the built-in
34902
+ * `$id` function, which tracks items by their identity:
34903
+ * ```html
34904
+ * <div ng-repeat="obj in collection track by $id(obj)">
34905
+ * {{obj.prop}}
34906
+ * </div>
34907
+ * ```
34908
+ *
34752
34909
  * # Special repeat start and end points
34753
34910
  * To repeat a series of elements instead of just one parent element, ngRepeat (as well as other ng directives) supports extending
34754
34911
  * the range of the repeater by defining explicit start and end points by using **ng-repeat-start** and **ng-repeat-end** respectively.
@@ -34816,12 +34973,12 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
34816
34973
  *
34817
34974
  * For example: `(name, age) in {'adam':10, 'amalie':12}`.
34818
34975
  *
34819
- * * `variable in expression track by tracking_expression` – You can also provide an optional tracking function
34820
- * which can be used to associate the objects in the collection with the DOM elements. If no tracking function
34821
- * is specified the ng-repeat associates elements by identity in the collection. It is an error to have
34822
- * more than one tracking function to resolve to the same key. (This would mean that two distinct objects are
34823
- * mapped to the same DOM element, which is not possible.) Filters should be applied to the expression,
34824
- * before specifying a tracking expression.
34976
+ * * `variable in expression track by tracking_expression` – You can also provide an optional tracking expression
34977
+ * which can be used to associate the objects in the collection with the DOM elements. If no tracking expression
34978
+ * is specified, ng-repeat associates elements by identity. It is an error to have
34979
+ * more than one tracking expression value resolve to the same key. (This would mean that two distinct objects are
34980
+ * mapped to the same DOM element, which is not possible.) If filters are used in the expression, they should be
34981
+ * applied before the tracking expression.
34825
34982
  *
34826
34983
  * For example: `item in items` is equivalent to `item in items track by $id(item)`. This implies that the DOM elements
34827
34984
  * will be associated by item identity in the array.
@@ -34845,6 +35002,11 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
34845
35002
  * For example: `item in items | filter:x as results` will store the fragment of the repeated items as `results`, but only after
34846
35003
  * the items have been processed through the filter.
34847
35004
  *
35005
+ * Please note that `as [variable name] is not an operator but rather a part of ngRepeat micro-syntax so it can be used only at the end
35006
+ * (and not as operator, inside an expression).
35007
+ *
35008
+ * For example: `item in items | filter : x | orderBy : order | limitTo : limit as results` .
35009
+ *
34848
35010
  * @example
34849
35011
  * This example initializes the scope to a list of names and
34850
35012
  * then uses `ngRepeat` to display every person:
@@ -35684,7 +35846,6 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
35684
35846
  */
35685
35847
  var ngSwitchDirective = ['$animate', function($animate) {
35686
35848
  return {
35687
- restrict: 'EA',
35688
35849
  require: 'ngSwitch',
35689
35850
 
35690
35851
  // asks for $scope to fool the BC controller module
@@ -35952,6 +36113,7 @@ var SelectController =
35952
36113
  if (value === '') self.emptyOption.prop('selected', true); // to make IE9 happy
35953
36114
  } else {
35954
36115
  if (isUndefined(value) && self.emptyOption) {
36116
+ self.removeUnknownOption();
35955
36117
  $element.val('');
35956
36118
  } else {
35957
36119
  self.renderUnknownOption(value);