rails-angularjs 1.3.12 → 1.3.14

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.
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
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.4.0-beta.3
2
+ * @license AngularJS v1.4.0-beta.5
3
3
  * (c) 2010-2015 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -57,7 +57,7 @@ function minErr(module, ErrorConstructor) {
57
57
  return match;
58
58
  });
59
59
 
60
- message += '\nhttp://errors.angularjs.org/1.4.0-beta.3/' +
60
+ message += '\nhttp://errors.angularjs.org/1.4.0-beta.5/' +
61
61
  (module ? module + '/' : '') + code;
62
62
 
63
63
  for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
@@ -127,6 +127,7 @@ function minErr(module, ErrorConstructor) {
127
127
  shallowCopy: true,
128
128
  equals: true,
129
129
  csp: true,
130
+ jq: true,
130
131
  concat: true,
131
132
  sliceArgs: true,
132
133
  bind: true,
@@ -970,7 +971,61 @@ var csp = function() {
970
971
  return (csp.isActive_ = active);
971
972
  };
972
973
 
974
+ /**
975
+ * @ngdoc directive
976
+ * @module ng
977
+ * @name ngJq
978
+ *
979
+ * @element ANY
980
+ * @param {string=} the name of the library available under `window`
981
+ * to be used for angular.element
982
+ * @description
983
+ * Use this directive to force the angular.element library. This should be
984
+ * used to force either jqLite by leaving ng-jq blank or setting the name of
985
+ * the jquery variable under window (eg. jQuery).
986
+ *
987
+ * Since this directive is global for the angular library, it is recommended
988
+ * that it's added to the same element as ng-app or the HTML element, but it is not mandatory.
989
+ * It needs to be noted that only the first instance of `ng-jq` will be used and all others
990
+ * ignored.
991
+ *
992
+ * @example
993
+ * This example shows how to force jqLite using the `ngJq` directive to the `html` tag.
994
+ ```html
995
+ <!doctype html>
996
+ <html ng-app ng-jq>
997
+ ...
998
+ ...
999
+ </html>
1000
+ ```
1001
+ * @example
1002
+ * This example shows how to use a jQuery based library of a different name.
1003
+ * The library name must be available at the top most 'window'.
1004
+ ```html
1005
+ <!doctype html>
1006
+ <html ng-app ng-jq="jQueryLib">
1007
+ ...
1008
+ ...
1009
+ </html>
1010
+ ```
1011
+ */
1012
+ var jq = function() {
1013
+ if (isDefined(jq.name_)) return jq.name_;
1014
+ var el;
1015
+ var i, ii = ngAttrPrefixes.length;
1016
+ for (i = 0; i < ii; ++i) {
1017
+ if (el = document.querySelector('[' + ngAttrPrefixes[i].replace(':', '\\:') + 'jq]')) {
1018
+ break;
1019
+ }
1020
+ }
973
1021
 
1022
+ var name;
1023
+ if (el) {
1024
+ name = getNgAttribute(el, "jq");
1025
+ }
1026
+
1027
+ return (jq.name_ = name);
1028
+ };
974
1029
 
975
1030
  function concat(array1, array2, index) {
976
1031
  return array1.concat(slice.call(array2, index));
@@ -1543,7 +1598,12 @@ function bindJQuery() {
1543
1598
  }
1544
1599
 
1545
1600
  // bind to jQuery if present;
1546
- jQuery = window.jQuery;
1601
+ var jqName = jq();
1602
+ jQuery = window.jQuery; // use default jQuery.
1603
+ if (isDefined(jqName)) { // `ngJq` present
1604
+ jQuery = jqName === null ? undefined : window[jqName]; // if empty; use jqLite. if not empty, use jQuery specified by `ngJq`.
1605
+ }
1606
+
1547
1607
  // Use jQuery if it exists with proper functionality, otherwise default to us.
1548
1608
  // Angular 1.2+ requires jQuery 1.7+ for on()/off() support.
1549
1609
  // Angular 1.3+ technically requires at least jQuery 2.1+ but it may work with older
@@ -2135,11 +2195,11 @@ function toDebugString(obj) {
2135
2195
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
2136
2196
  */
2137
2197
  var version = {
2138
- full: '1.4.0-beta.3', // all of these placeholder strings will be replaced by grunt's
2198
+ full: '1.4.0-beta.5', // all of these placeholder strings will be replaced by grunt's
2139
2199
  major: 1, // package task
2140
2200
  minor: 4,
2141
2201
  dot: 0,
2142
- codeName: 'substance-mimicry'
2202
+ codeName: 'karmic-stabilization'
2143
2203
  };
2144
2204
 
2145
2205
 
@@ -7347,7 +7407,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7347
7407
  var terminalPriority = -Number.MAX_VALUE,
7348
7408
  newScopeDirective,
7349
7409
  controllerDirectives = previousCompileContext.controllerDirectives,
7350
- controllers,
7351
7410
  newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective,
7352
7411
  templateDirective = previousCompileContext.templateDirective,
7353
7412
  nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective,
@@ -7405,7 +7464,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7405
7464
 
7406
7465
  if (!directive.templateUrl && directive.controller) {
7407
7466
  directiveValue = directive.controller;
7408
- controllerDirectives = controllerDirectives || {};
7467
+ controllerDirectives = controllerDirectives || createMap();
7409
7468
  assertNoDuplicate("'" + directiveName + "' controller",
7410
7469
  controllerDirectives[directiveName], directive, $compileNode);
7411
7470
  controllerDirectives[directiveName] = directive;
@@ -7573,51 +7632,74 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7573
7632
 
7574
7633
 
7575
7634
  function getControllers(directiveName, require, $element, elementControllers) {
7576
- var value, retrievalMethod = 'data', optional = false;
7577
- var $searchElement = $element;
7578
- var match;
7579
- if (isString(require)) {
7580
- match = require.match(REQUIRE_PREFIX_REGEXP);
7581
- require = require.substring(match[0].length);
7635
+ var value;
7582
7636
 
7583
- if (match[3]) {
7584
- if (match[1]) match[3] = null;
7585
- else match[1] = match[3];
7586
- }
7587
- if (match[1] === '^') {
7588
- retrievalMethod = 'inheritedData';
7589
- } else if (match[1] === '^^') {
7590
- retrievalMethod = 'inheritedData';
7591
- $searchElement = $element.parent();
7592
- }
7593
- if (match[2] === '?') {
7594
- optional = true;
7637
+ if (isString(require)) {
7638
+ var match = require.match(REQUIRE_PREFIX_REGEXP);
7639
+ var name = require.substring(match[0].length);
7640
+ var inheritType = match[1] || match[3];
7641
+ var optional = match[2] === '?';
7642
+
7643
+ //If only parents then start at the parent element
7644
+ if (inheritType === '^^') {
7645
+ $element = $element.parent();
7646
+ //Otherwise attempt getting the controller from elementControllers in case
7647
+ //the element is transcluded (and has no data) and to avoid .data if possible
7648
+ } else {
7649
+ value = elementControllers && elementControllers[name];
7650
+ value = value && value.instance;
7595
7651
  }
7596
7652
 
7597
- value = null;
7598
-
7599
- if (elementControllers && retrievalMethod === 'data') {
7600
- if (value = elementControllers[require]) {
7601
- value = value.instance;
7602
- }
7653
+ if (!value) {
7654
+ var dataName = '$' + name + 'Controller';
7655
+ value = inheritType ? $element.inheritedData(dataName) : $element.data(dataName);
7603
7656
  }
7604
- value = value || $searchElement[retrievalMethod]('$' + require + 'Controller');
7605
7657
 
7606
7658
  if (!value && !optional) {
7607
7659
  throw $compileMinErr('ctreq',
7608
7660
  "Controller '{0}', required by directive '{1}', can't be found!",
7609
- require, directiveName);
7661
+ name, directiveName);
7610
7662
  }
7611
- return value || null;
7612
7663
  } else if (isArray(require)) {
7613
7664
  value = [];
7614
- forEach(require, function(require) {
7615
- value.push(getControllers(directiveName, require, $element, elementControllers));
7616
- });
7665
+ for (var i = 0, ii = require.length; i < ii; i++) {
7666
+ value[i] = getControllers(directiveName, require[i], $element, elementControllers);
7667
+ }
7617
7668
  }
7618
- return value;
7669
+
7670
+ return value || null;
7619
7671
  }
7620
7672
 
7673
+ function setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope) {
7674
+ var elementControllers = createMap();
7675
+ for (var controllerKey in controllerDirectives) {
7676
+ var directive = controllerDirectives[controllerKey];
7677
+ var locals = {
7678
+ $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
7679
+ $element: $element,
7680
+ $attrs: attrs,
7681
+ $transclude: transcludeFn
7682
+ };
7683
+
7684
+ var controller = directive.controller;
7685
+ if (controller == '@') {
7686
+ controller = attrs[directive.name];
7687
+ }
7688
+
7689
+ var controllerInstance = $controller(controller, locals, true, directive.controllerAs);
7690
+
7691
+ // For directives with element transclusion the element is a comment,
7692
+ // but jQuery .data doesn't support attaching data to comment nodes as it's hard to
7693
+ // clean up (http://bugs.jquery.com/ticket/8335).
7694
+ // Instead, we save the controllers for the element in a local hash and attach to .data
7695
+ // later, once we have the actual element.
7696
+ elementControllers[directive.name] = controllerInstance;
7697
+ if (!hasElementTranscludeDirective) {
7698
+ $element.data('$' + directive.name + 'Controller', controllerInstance.instance);
7699
+ }
7700
+ }
7701
+ return elementControllers;
7702
+ }
7621
7703
 
7622
7704
  function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn,
7623
7705
  thisLinkFn) {
@@ -7644,36 +7726,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7644
7726
  }
7645
7727
 
7646
7728
  if (controllerDirectives) {
7647
- // TODO: merge `controllers` and `elementControllers` into single object.
7648
- controllers = {};
7649
- elementControllers = {};
7650
- forEach(controllerDirectives, function(directive) {
7651
- var locals = {
7652
- $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
7653
- $element: $element,
7654
- $attrs: attrs,
7655
- $transclude: transcludeFn
7656
- }, controllerInstance;
7657
-
7658
- controller = directive.controller;
7659
- if (controller == '@') {
7660
- controller = attrs[directive.name];
7661
- }
7662
-
7663
- controllerInstance = $controller(controller, locals, true, directive.controllerAs);
7664
-
7665
- // For directives with element transclusion the element is a comment,
7666
- // but jQuery .data doesn't support attaching data to comment nodes as it's hard to
7667
- // clean up (http://bugs.jquery.com/ticket/8335).
7668
- // Instead, we save the controllers for the element in a local hash and attach to .data
7669
- // later, once we have the actual element.
7670
- elementControllers[directive.name] = controllerInstance;
7671
- if (!hasElementTranscludeDirective) {
7672
- $element.data('$' + directive.name + 'Controller', controllerInstance.instance);
7673
- }
7674
-
7675
- controllers[directive.name] = controllerInstance;
7676
- });
7729
+ elementControllers = setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope);
7677
7730
  }
7678
7731
 
7679
7732
  if (newIsolateScopeDirective) {
@@ -7687,14 +7740,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7687
7740
  isolateScope.$$isolateBindings,
7688
7741
  newIsolateScopeDirective, isolateScope);
7689
7742
  }
7690
- if (controllers) {
7743
+ if (elementControllers) {
7691
7744
  // Initialize bindToController bindings for new/isolate scopes
7692
7745
  var scopeDirective = newIsolateScopeDirective || newScopeDirective;
7693
7746
  var bindings;
7694
7747
  var controllerForBindings;
7695
- if (scopeDirective && controllers[scopeDirective.name]) {
7748
+ if (scopeDirective && elementControllers[scopeDirective.name]) {
7696
7749
  bindings = scopeDirective.$$bindings.bindToController;
7697
- controller = controllers[scopeDirective.name];
7750
+ controller = elementControllers[scopeDirective.name];
7698
7751
 
7699
7752
  if (controller && controller.identifier && bindings) {
7700
7753
  controllerForBindings = controller;
@@ -7703,18 +7756,18 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7703
7756
  bindings, scopeDirective);
7704
7757
  }
7705
7758
  }
7706
- forEach(controllers, function(controller) {
7707
- var result = controller();
7708
- if (result !== controller.instance &&
7759
+ for (i in elementControllers) {
7760
+ controller = elementControllers[i];
7761
+ var controllerResult = controller();
7762
+ if (controllerResult !== controller.instance &&
7709
7763
  controller === controllerForBindings) {
7710
7764
  // Remove and re-install bindToController bindings
7711
7765
  thisLinkFn.$$destroyBindings();
7712
7766
  thisLinkFn.$$destroyBindings =
7713
- initializeDirectiveBindings(scope, attrs, result,
7767
+ initializeDirectiveBindings(scope, attrs, controllerResult,
7714
7768
  bindings, scopeDirective);
7715
7769
  }
7716
- });
7717
- controllers = null;
7770
+ }
7718
7771
  }
7719
7772
 
7720
7773
  // PRELINKING
@@ -8725,19 +8778,24 @@ function isJsonLike(str) {
8725
8778
  * @returns {Object} Parsed headers as key value object
8726
8779
  */
8727
8780
  function parseHeaders(headers) {
8728
- var parsed = createMap(), key, val, i;
8729
-
8730
- if (!headers) return parsed;
8731
-
8732
- forEach(headers.split('\n'), function(line) {
8733
- i = line.indexOf(':');
8734
- key = lowercase(trim(line.substr(0, i)));
8735
- val = trim(line.substr(i + 1));
8781
+ var parsed = createMap(), i;
8736
8782
 
8783
+ function fillInParsed(key, val) {
8737
8784
  if (key) {
8738
8785
  parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
8739
8786
  }
8740
- });
8787
+ }
8788
+
8789
+ if (isString(headers)) {
8790
+ forEach(headers.split('\n'), function(line) {
8791
+ i = line.indexOf(':');
8792
+ fillInParsed(lowercase(trim(line.substr(0, i))), trim(line.substr(i + 1)));
8793
+ });
8794
+ } else if (isObject(headers)) {
8795
+ forEach(headers, function(headerVal, headerKey) {
8796
+ fillInParsed(lowercase(headerKey), trim(headerVal));
8797
+ });
8798
+ }
8741
8799
 
8742
8800
  return parsed;
8743
8801
  }
@@ -8756,7 +8814,7 @@ function parseHeaders(headers) {
8756
8814
  * - if called with no arguments returns an object containing all headers.
8757
8815
  */
8758
8816
  function headersGetter(headers) {
8759
- var headersObj = isObject(headers) ? headers : undefined;
8817
+ var headersObj;
8760
8818
 
8761
8819
  return function(name) {
8762
8820
  if (!headersObj) headersObj = parseHeaders(headers);
@@ -11504,7 +11562,7 @@ function $LocationProvider() {
11504
11562
 
11505
11563
 
11506
11564
  // rewrite hashbang url <> html5 url
11507
- if ($location.absUrl() != initialUrl) {
11565
+ if (trimEmptyHash($location.absUrl()) != trimEmptyHash(initialUrl)) {
11508
11566
  $browser.url($location.absUrl(), true);
11509
11567
  }
11510
11568
 
@@ -12746,7 +12804,7 @@ ASTCompiler.prototype = {
12746
12804
  self.if(self.notNull(right), function() {
12747
12805
  self.addEnsureSafeFunction(right);
12748
12806
  forEach(ast.arguments, function(expr) {
12749
- self.recurse(expr, undefined, undefined, function(argument) {
12807
+ self.recurse(expr, self.nextId(), undefined, function(argument) {
12750
12808
  args.push(self.ensureSafeObject(argument));
12751
12809
  });
12752
12810
  });
@@ -12777,14 +12835,14 @@ ASTCompiler.prototype = {
12777
12835
  self.addEnsureSafeObject(self.member(left.context, left.name, left.computed));
12778
12836
  expression = self.member(left.context, left.name, left.computed) + ast.operator + right;
12779
12837
  self.assign(intoId, expression);
12780
- recursionFn(expression);
12838
+ recursionFn(intoId || expression);
12781
12839
  });
12782
12840
  }, 1);
12783
12841
  break;
12784
12842
  case AST.ArrayExpression:
12785
12843
  args = [];
12786
12844
  forEach(ast.elements, function(expr) {
12787
- self.recurse(expr, undefined, undefined, function(argument) {
12845
+ self.recurse(expr, self.nextId(), undefined, function(argument) {
12788
12846
  args.push(argument);
12789
12847
  });
12790
12848
  });
@@ -12795,7 +12853,7 @@ ASTCompiler.prototype = {
12795
12853
  case AST.ObjectExpression:
12796
12854
  args = [];
12797
12855
  forEach(ast.properties, function(property) {
12798
- self.recurse(property.value, undefined, undefined, function(expr) {
12856
+ self.recurse(property.value, self.nextId(), undefined, function(expr) {
12799
12857
  args.push(self.escape(
12800
12858
  property.key.type === AST.Identifier ? property.key.name :
12801
12859
  ('' + property.key.value)) +
@@ -16449,7 +16507,7 @@ function $SceProvider() {
16449
16507
  * escaping.
16450
16508
  *
16451
16509
  * @param {string} type The kind of context in which this value is safe for use. e.g. url,
16452
- * resource_url, html, js and css.
16510
+ * resourceUrl, html, js and css.
16453
16511
  * @param {*} value The value that that should be considered trusted/safe.
16454
16512
  * @returns {*} A value that can be used to stand in for the provided `value` in places
16455
16513
  * where Angular expects a $sce.trustAs() return value.
@@ -16827,7 +16885,7 @@ function $TemplateRequestProvider() {
16827
16885
  };
16828
16886
 
16829
16887
  return $http.get(tpl, httpOptions)
16830
- .finally(function() {
16888
+ ['finally'](function() {
16831
16889
  handleRequestFn.totalPendingRequests--;
16832
16890
  })
16833
16891
  .then(function(response) {
@@ -17982,7 +18040,9 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZEw']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d
17982
18040
  * specified in the string input, the time is considered to be in the local timezone.
17983
18041
  * @param {string=} format Formatting rules (see Description). If not specified,
17984
18042
  * `mediumDate` is used.
17985
- * @param {string=} timezone Timezone to be used for formatting. Right now, only `'UTC'` is supported.
18043
+ * @param {string=} timezone Timezone to be used for formatting. It understands UTC/GMT and the
18044
+ * continental US time zone abbreviations, but for general use, use a time zone offset, for
18045
+ * example, `'+0430'` (4 hours, 30 minutes east of the Greenwich meridian)
17986
18046
  * If not specified, the timezone of the browser will be used.
17987
18047
  * @returns {string} Formatted string or the input if input is not recognized as date/millis.
17988
18048
  *
@@ -18172,6 +18232,8 @@ var uppercaseFilter = valueFn(uppercase);
18172
18232
  * If the number is negative, `limit` number of items from the end of the source array/string
18173
18233
  * are copied. The `limit` will be trimmed if it exceeds `array.length`. If `limit` is undefined,
18174
18234
  * the input will be returned unchanged.
18235
+ * @param {(string|number)=} begin Index at which to begin limitation. As a negative index, `begin`
18236
+ * indicates an offset from the end of `input`. Defaults to `0`.
18175
18237
  * @returns {Array|string} A new sub-array or substring of length `limit` or less if input array
18176
18238
  * had less than `limit` elements.
18177
18239
  *
@@ -18243,7 +18305,7 @@ var uppercaseFilter = valueFn(uppercase);
18243
18305
  </example>
18244
18306
  */
18245
18307
  function limitToFilter() {
18246
- return function(input, limit) {
18308
+ return function(input, limit, begin) {
18247
18309
  if (Math.abs(Number(limit)) === Infinity) {
18248
18310
  limit = Number(limit);
18249
18311
  } else {
@@ -18254,7 +18316,18 @@ function limitToFilter() {
18254
18316
  if (isNumber(input)) input = input.toString();
18255
18317
  if (!isArray(input) && !isString(input)) return input;
18256
18318
 
18257
- return limit >= 0 ? input.slice(0, limit) : input.slice(limit);
18319
+ begin = (!begin || isNaN(begin)) ? 0 : toInt(begin);
18320
+ begin = (begin < 0 && begin >= -input.length) ? input.length + begin : begin;
18321
+
18322
+ if (limit >= 0) {
18323
+ return input.slice(begin, begin + limit);
18324
+ } else {
18325
+ if (begin === 0) {
18326
+ return input.slice(limit, input.length);
18327
+ } else {
18328
+ return input.slice(Math.max(0, begin + limit), begin);
18329
+ }
18330
+ }
18258
18331
  };
18259
18332
  }
18260
18333
 
@@ -18666,20 +18739,23 @@ var htmlAnchorDirective = valueFn({
18666
18739
  *
18667
18740
  * @description
18668
18741
  *
18669
- * We shouldn't do this, because it will make the button enabled on Chrome/Firefox but not on IE8 and older IEs:
18742
+ * This directive sets the `disabled` attribute on the element if the
18743
+ * {@link guide/expression expression} inside `ngDisabled` evaluates to truthy.
18744
+ *
18745
+ * A special directive is necessary because we cannot use interpolation inside the `disabled`
18746
+ * attribute. The following example would make the button enabled on Chrome/Firefox
18747
+ * but not on older IEs:
18748
+ *
18670
18749
  * ```html
18671
- * <div ng-init="scope = { isDisabled: false }">
18672
- * <button disabled="{{scope.isDisabled}}">Disabled</button>
18750
+ * <div ng-init="isDisabled = false">
18751
+ * <button disabled="{{isDisabled}}">Disabled</button>
18673
18752
  * </div>
18674
18753
  * ```
18675
18754
  *
18676
- * The HTML specification does not require browsers to preserve the values of boolean attributes
18677
- * such as disabled. (Their presence means true and their absence means false.)
18755
+ * This is because the HTML specification does not require browsers to preserve the values of
18756
+ * boolean attributes such as `disabled` (Their presence means true and their absence means false.)
18678
18757
  * If we put an Angular interpolation expression into such an attribute then the
18679
18758
  * binding information would be lost when the browser removes the attribute.
18680
- * The `ngDisabled` directive solves this problem for the `disabled` attribute.
18681
- * This complementary directive is not removed by the browser and so provides
18682
- * a permanent reliable place to store the binding information.
18683
18759
  *
18684
18760
  * @example
18685
18761
  <example>
@@ -18698,7 +18774,7 @@ var htmlAnchorDirective = valueFn({
18698
18774
  *
18699
18775
  * @element INPUT
18700
18776
  * @param {expression} ngDisabled If the {@link guide/expression expression} is truthy,
18701
- * then special attribute "disabled" will be set on the element
18777
+ * then the `disabled` attribute will be set on the element
18702
18778
  */
18703
18779
 
18704
18780
 
@@ -20712,7 +20788,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
20712
20788
  return value;
20713
20789
  });
20714
20790
 
20715
- if (attr.min || attr.ngMin) {
20791
+ if (isDefined(attr.min) || attr.ngMin) {
20716
20792
  var minVal;
20717
20793
  ctrl.$validators.min = function(value) {
20718
20794
  return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal;
@@ -20728,7 +20804,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
20728
20804
  });
20729
20805
  }
20730
20806
 
20731
- if (attr.max || attr.ngMax) {
20807
+ if (isDefined(attr.max) || attr.ngMax) {
20732
20808
  var maxVal;
20733
20809
  ctrl.$validators.max = function(value) {
20734
20810
  return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal;
@@ -23534,6 +23610,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
23534
23610
  ngModelGet = parsedNgModel,
23535
23611
  ngModelSet = parsedNgModelAssign,
23536
23612
  pendingDebounce = null,
23613
+ parserValid,
23537
23614
  ctrl = this;
23538
23615
 
23539
23616
  this.$$setOptions = function(options) {
@@ -23806,16 +23883,12 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
23806
23883
  // the model although neither viewValue nor the model on the scope changed
23807
23884
  var modelValue = ctrl.$$rawModelValue;
23808
23885
 
23809
- // Check if the there's a parse error, so we don't unset it accidentially
23810
- var parserName = ctrl.$$parserName || 'parse';
23811
- var parserValid = ctrl.$error[parserName] ? false : undefined;
23812
-
23813
23886
  var prevValid = ctrl.$valid;
23814
23887
  var prevModelValue = ctrl.$modelValue;
23815
23888
 
23816
23889
  var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid;
23817
23890
 
23818
- ctrl.$$runValidators(parserValid, modelValue, viewValue, function(allValid) {
23891
+ ctrl.$$runValidators(modelValue, viewValue, function(allValid) {
23819
23892
  // If there was no change in validity, don't update the model
23820
23893
  // This prevents changing an invalid modelValue to undefined
23821
23894
  if (!allowInvalid && prevValid !== allValid) {
@@ -23833,12 +23906,12 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
23833
23906
 
23834
23907
  };
23835
23908
 
23836
- this.$$runValidators = function(parseValid, modelValue, viewValue, doneCallback) {
23909
+ this.$$runValidators = function(modelValue, viewValue, doneCallback) {
23837
23910
  currentValidationRunId++;
23838
23911
  var localValidationRunId = currentValidationRunId;
23839
23912
 
23840
23913
  // check parser error
23841
- if (!processParseErrors(parseValid)) {
23914
+ if (!processParseErrors()) {
23842
23915
  validationDone(false);
23843
23916
  return;
23844
23917
  }
@@ -23848,21 +23921,22 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
23848
23921
  }
23849
23922
  processAsyncValidators();
23850
23923
 
23851
- function processParseErrors(parseValid) {
23924
+ function processParseErrors() {
23852
23925
  var errorKey = ctrl.$$parserName || 'parse';
23853
- if (parseValid === undefined) {
23926
+ if (parserValid === undefined) {
23854
23927
  setValidity(errorKey, null);
23855
23928
  } else {
23856
- setValidity(errorKey, parseValid);
23857
- if (!parseValid) {
23929
+ if (!parserValid) {
23858
23930
  forEach(ctrl.$validators, function(v, name) {
23859
23931
  setValidity(name, null);
23860
23932
  });
23861
23933
  forEach(ctrl.$asyncValidators, function(v, name) {
23862
23934
  setValidity(name, null);
23863
23935
  });
23864
- return false;
23865
23936
  }
23937
+ // Set the parse error last, to prevent unsetting it, should a $validators key == parserName
23938
+ setValidity(errorKey, parserValid);
23939
+ return parserValid;
23866
23940
  }
23867
23941
  return true;
23868
23942
  }
@@ -23957,7 +24031,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
23957
24031
  this.$$parseAndValidate = function() {
23958
24032
  var viewValue = ctrl.$$lastCommittedViewValue;
23959
24033
  var modelValue = viewValue;
23960
- var parserValid = isUndefined(modelValue) ? undefined : true;
24034
+ parserValid = isUndefined(modelValue) ? undefined : true;
23961
24035
 
23962
24036
  if (parserValid) {
23963
24037
  for (var i = 0; i < ctrl.$parsers.length; i++) {
@@ -23983,7 +24057,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
23983
24057
 
23984
24058
  // Pass the $$lastCommittedViewValue here, because the cached viewValue might be out of date.
23985
24059
  // This can happen if e.g. $setViewValue is called from inside a parser
23986
- ctrl.$$runValidators(parserValid, modelValue, ctrl.$$lastCommittedViewValue, function(allValid) {
24060
+ ctrl.$$runValidators(modelValue, ctrl.$$lastCommittedViewValue, function(allValid) {
23987
24061
  if (!allowInvalid) {
23988
24062
  // Note: Don't check ctrl.$valid here, as we could have
23989
24063
  // external validators (e.g. calculated on the server),
@@ -24104,6 +24178,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
24104
24178
  // TODO(perf): why not move this to the action fn?
24105
24179
  if (modelValue !== ctrl.$modelValue) {
24106
24180
  ctrl.$modelValue = ctrl.$$rawModelValue = modelValue;
24181
+ parserValid = undefined;
24107
24182
 
24108
24183
  var formatters = ctrl.$formatters,
24109
24184
  idx = formatters.length;
@@ -24116,7 +24191,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
24116
24191
  ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;
24117
24192
  ctrl.$render();
24118
24193
 
24119
- ctrl.$$runValidators(undefined, modelValue, viewValue, noop);
24194
+ ctrl.$$runValidators(modelValue, viewValue, noop);
24120
24195
  }
24121
24196
  }
24122
24197
 
@@ -24752,15 +24827,20 @@ var ngOptionsMinErr = minErr('ngOptions');
24752
24827
  * * `label` **`for`** `value` **`in`** `array`
24753
24828
  * * `select` **`as`** `label` **`for`** `value` **`in`** `array`
24754
24829
  * * `label` **`group by`** `group` **`for`** `value` **`in`** `array`
24830
+ * * `label` **`disable when`** `disable` **`for`** `value` **`in`** `array`
24755
24831
  * * `label` **`group by`** `group` **`for`** `value` **`in`** `array` **`track by`** `trackexpr`
24832
+ * * `label` **`disable when`** `disable` **`for`** `value` **`in`** `array` **`track by`** `trackexpr`
24756
24833
  * * `label` **`for`** `value` **`in`** `array` | orderBy:`orderexpr` **`track by`** `trackexpr`
24757
24834
  * (for including a filter with `track by`)
24758
24835
  * * for object data sources:
24759
24836
  * * `label` **`for (`**`key` **`,`** `value`**`) in`** `object`
24760
24837
  * * `select` **`as`** `label` **`for (`**`key` **`,`** `value`**`) in`** `object`
24761
24838
  * * `label` **`group by`** `group` **`for (`**`key`**`,`** `value`**`) in`** `object`
24839
+ * * `label` **`disable when`** `disable` **`for (`**`key`**`,`** `value`**`) in`** `object`
24762
24840
  * * `select` **`as`** `label` **`group by`** `group`
24763
24841
  * **`for` `(`**`key`**`,`** `value`**`) in`** `object`
24842
+ * * `select` **`as`** `label` **`disable when`** `disable`
24843
+ * **`for` `(`**`key`**`,`** `value`**`) in`** `object`
24764
24844
  *
24765
24845
  * Where:
24766
24846
  *
@@ -24774,6 +24854,8 @@ var ngOptionsMinErr = minErr('ngOptions');
24774
24854
  * element. If not specified, `select` expression will default to `value`.
24775
24855
  * * `group`: The result of this expression will be used to group options using the `<optgroup>`
24776
24856
  * DOM element.
24857
+ * * `disable`: The result of this expression will be used to disable the rendered `<option>`
24858
+ * element. Return `true` to disable.
24777
24859
  * * `trackexpr`: Used when working with an array of objects. The result of this expression will be
24778
24860
  * used to identify the objects in the array. The `trackexpr` will most likely refer to the
24779
24861
  * `value` variable (e.g. `value.propertyName`). With this the selection is preserved
@@ -24787,10 +24869,10 @@ var ngOptionsMinErr = minErr('ngOptions');
24787
24869
  .controller('ExampleController', ['$scope', function($scope) {
24788
24870
  $scope.colors = [
24789
24871
  {name:'black', shade:'dark'},
24790
- {name:'white', shade:'light'},
24872
+ {name:'white', shade:'light', notAnOption: true},
24791
24873
  {name:'red', shade:'dark'},
24792
- {name:'blue', shade:'dark'},
24793
- {name:'yellow', shade:'light'}
24874
+ {name:'blue', shade:'dark', notAnOption: true},
24875
+ {name:'yellow', shade:'light', notAnOption: false}
24794
24876
  ];
24795
24877
  $scope.myColor = $scope.colors[2]; // red
24796
24878
  }]);
@@ -24799,6 +24881,7 @@ var ngOptionsMinErr = minErr('ngOptions');
24799
24881
  <ul>
24800
24882
  <li ng-repeat="color in colors">
24801
24883
  Name: <input ng-model="color.name">
24884
+ <input type="checkbox" ng-model="color.notAnOption"> Disabled?
24802
24885
  [<a href ng-click="colors.splice($index, 1)">X</a>]
24803
24886
  </li>
24804
24887
  <li>
@@ -24820,6 +24903,12 @@ var ngOptionsMinErr = minErr('ngOptions');
24820
24903
  <select ng-model="myColor" ng-options="color.name group by color.shade for color in colors">
24821
24904
  </select><br/>
24822
24905
 
24906
+ Color grouped by shade, with some disabled:
24907
+ <select ng-model="myColor"
24908
+ ng-options="color.name group by color.shade disable when color.notAnOption for color in colors">
24909
+ </select><br/>
24910
+
24911
+
24823
24912
 
24824
24913
  Select <a href ng-click="myColor = { name:'not in list', shade: 'other' }">bogus</a>.<br>
24825
24914
  <hr/>
@@ -24844,16 +24933,17 @@ var ngOptionsMinErr = minErr('ngOptions');
24844
24933
  */
24845
24934
 
24846
24935
  // jshint maxlen: false
24847
- //000011111111110000000000022222222220000000000000000000003333333333000000000000004444444444444440000000005555555555555550000000666666666666666000000000000000777777777700000000000000000008888888888
24848
- 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]+?))?$/;
24936
+ // //00001111111111000000000002222222222000000000000000000000333333333300000000000000000000000004444444444400000000000005555555555555550000000006666666666666660000000777777777777777000000000000000888888888800000000000000000009999999999
24937
+ 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]+?))?$/;
24849
24938
  // 1: value expression (valueFn)
24850
24939
  // 2: label expression (displayFn)
24851
24940
  // 3: group by expression (groupByFn)
24852
- // 4: array item variable name
24853
- // 5: object item key variable name
24854
- // 6: object item value variable name
24855
- // 7: collection expression
24856
- // 8: track by expression
24941
+ // 4: disable when expression (disableWhenFn)
24942
+ // 5: array item variable name
24943
+ // 6: object item key variable name
24944
+ // 7: object item value variable name
24945
+ // 8: collection expression
24946
+ // 9: track by expression
24857
24947
  // jshint maxlen: 100
24858
24948
 
24859
24949
 
@@ -24873,14 +24963,14 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
24873
24963
  // Extract the parts from the ngOptions expression
24874
24964
 
24875
24965
  // The variable name for the value of the item in the collection
24876
- var valueName = match[4] || match[6];
24966
+ var valueName = match[5] || match[7];
24877
24967
  // The variable name for the key of the item in the collection
24878
- var keyName = match[5];
24968
+ var keyName = match[6];
24879
24969
 
24880
24970
  // An expression that generates the viewValue for an option if there is a label expression
24881
24971
  var selectAs = / as /.test(match[0]) && match[1];
24882
24972
  // An expression that is used to track the id of each object in the options collection
24883
- var trackBy = match[8];
24973
+ var trackBy = match[9];
24884
24974
  // An expression that generates the viewValue for an option if there is no label expression
24885
24975
  var valueFn = $parse(match[2] ? match[1] : valueName);
24886
24976
  var selectAsFn = selectAs && $parse(selectAs);
@@ -24895,7 +24985,8 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
24895
24985
  function getHashOfValue(viewValue) { return hashKey(viewValue); };
24896
24986
  var displayFn = $parse(match[2] || match[1]);
24897
24987
  var groupByFn = $parse(match[3] || '');
24898
- var valuesFn = $parse(match[7]);
24988
+ var disableWhenFn = $parse(match[4] || '');
24989
+ var valuesFn = $parse(match[8]);
24899
24990
 
24900
24991
  var locals = {};
24901
24992
  var getLocals = keyName ? function(value, key) {
@@ -24908,11 +24999,12 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
24908
24999
  };
24909
25000
 
24910
25001
 
24911
- function Option(selectValue, viewValue, label, group) {
25002
+ function Option(selectValue, viewValue, label, group, disabled) {
24912
25003
  this.selectValue = selectValue;
24913
25004
  this.viewValue = viewValue;
24914
25005
  this.label = label;
24915
25006
  this.group = group;
25007
+ this.disabled = disabled;
24916
25008
  }
24917
25009
 
24918
25010
  return {
@@ -24925,10 +25017,20 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
24925
25017
 
24926
25018
  Object.keys(values).forEach(function getWatchable(key) {
24927
25019
  var locals = getLocals(values[key], key);
24928
- var label = displayFn(scope, locals);
24929
25020
  var selectValue = getTrackByValue(values[key], locals);
24930
25021
  watchedArray.push(selectValue);
24931
- watchedArray.push(label);
25022
+
25023
+ // Only need to watch the displayFn if there is a specific label expression
25024
+ if (match[2]) {
25025
+ var label = displayFn(scope, locals);
25026
+ watchedArray.push(label);
25027
+ }
25028
+
25029
+ // Only need to watch the disableWhenFn if there is a specific disable expression
25030
+ if (match[4]) {
25031
+ var disableWhen = disableWhenFn(scope, locals);
25032
+ watchedArray.push(disableWhen);
25033
+ }
24932
25034
  });
24933
25035
  return watchedArray;
24934
25036
  }),
@@ -24954,7 +25056,8 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
24954
25056
  var selectValue = getTrackByValue(viewValue, locals);
24955
25057
  var label = displayFn(scope, locals);
24956
25058
  var group = groupByFn(scope, locals);
24957
- var optionItem = new Option(selectValue, viewValue, label, group);
25059
+ var disabled = disableWhenFn(scope, locals);
25060
+ var optionItem = new Option(selectValue, viewValue, label, group, disabled);
24958
25061
 
24959
25062
  optionItems.push(optionItem);
24960
25063
  selectValueMap[selectValue] = optionItem;
@@ -25031,7 +25134,7 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
25031
25134
  selectCtrl.writeValue = function writeNgOptionsValue(value) {
25032
25135
  var option = options.getOptionFromViewValue(value);
25033
25136
 
25034
- if (option) {
25137
+ if (option && !option.disabled) {
25035
25138
  if (selectElement[0].value !== option.selectValue) {
25036
25139
  removeUnknownOption();
25037
25140
  removeEmptyOption();
@@ -25055,7 +25158,7 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
25055
25158
 
25056
25159
  var selectedOption = options.selectValueMap[selectElement.val()];
25057
25160
 
25058
- if (selectedOption) {
25161
+ if (selectedOption && !selectedOption.disabled) {
25059
25162
  removeEmptyOption();
25060
25163
  removeUnknownOption();
25061
25164
  return selectedOption.viewValue;
@@ -25080,18 +25183,22 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
25080
25183
  if (value) {
25081
25184
  value.forEach(function(item) {
25082
25185
  var option = options.getOptionFromViewValue(item);
25083
- if (option) option.element.selected = true;
25186
+ if (option && !option.disabled) option.element.selected = true;
25084
25187
  });
25085
25188
  }
25086
25189
  };
25087
25190
 
25088
25191
 
25089
25192
  selectCtrl.readValue = function readNgOptionsMultiple() {
25090
- var selectedValues = selectElement.val() || [];
25091
- return selectedValues.map(function(selectedKey) {
25092
- var option = options.selectValueMap[selectedKey];
25093
- return option.viewValue;
25193
+ var selectedValues = selectElement.val() || [],
25194
+ selections = [];
25195
+
25196
+ forEach(selectedValues, function(value) {
25197
+ var option = options.selectValueMap[value];
25198
+ if (!option.disabled) selections.push(option.viewValue);
25094
25199
  });
25200
+
25201
+ return selections;
25095
25202
  };
25096
25203
  }
25097
25204
 
@@ -25124,6 +25231,7 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
25124
25231
 
25125
25232
  function updateOptionElement(option, element) {
25126
25233
  option.element = element;
25234
+ element.disabled = option.disabled;
25127
25235
  if (option.value !== element.value) element.value = option.selectValue;
25128
25236
  if (option.label !== element.label) {
25129
25237
  element.label = option.label;
@@ -25557,6 +25665,55 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
25557
25665
  * or implement a `$watch` on the object yourself.
25558
25666
  *
25559
25667
  *
25668
+ * # Tracking and Duplicates
25669
+ *
25670
+ * When the contents of the collection change, `ngRepeat` makes the corresponding changes to the DOM:
25671
+ *
25672
+ * * When an item is added, a new instance of the template is added to the DOM.
25673
+ * * When an item is removed, its template instance is removed from the DOM.
25674
+ * * When items are reordered, their respective templates are reordered in the DOM.
25675
+ *
25676
+ * By default, `ngRepeat` does not allow duplicate items in arrays. This is because when
25677
+ * there are duplicates, it is not possible to maintain a one-to-one mapping between collection
25678
+ * items and DOM elements.
25679
+ *
25680
+ * If you do need to repeat duplicate items, you can substitute the default tracking behavior
25681
+ * with your own using the `track by` expression.
25682
+ *
25683
+ * For example, you may track items by the index of each item in the collection, using the
25684
+ * special scope property `$index`:
25685
+ * ```html
25686
+ * <div ng-repeat="n in [42, 42, 43, 43] track by $index">
25687
+ * {{n}}
25688
+ * </div>
25689
+ * ```
25690
+ *
25691
+ * You may use arbitrary expressions in `track by`, including references to custom functions
25692
+ * on the scope:
25693
+ * ```html
25694
+ * <div ng-repeat="n in [42, 42, 43, 43] track by myTrackingFunction(n)">
25695
+ * {{n}}
25696
+ * </div>
25697
+ * ```
25698
+ *
25699
+ * If you are working with objects that have an identifier property, you can track
25700
+ * by the identifier instead of the whole object. Should you reload your data later, `ngRepeat`
25701
+ * will not have to rebuild the DOM elements for items it has already rendered, even if the
25702
+ * JavaScript objects in the collection have been substituted for new ones:
25703
+ * ```html
25704
+ * <div ng-repeat="model in collection track by model.id">
25705
+ * {{model.name}}
25706
+ * </div>
25707
+ * ```
25708
+ *
25709
+ * When no `track by` expression is provided, it is equivalent to tracking by the built-in
25710
+ * `$id` function, which tracks items by their identity:
25711
+ * ```html
25712
+ * <div ng-repeat="obj in collection track by $id(obj)">
25713
+ * {{obj.prop}}
25714
+ * </div>
25715
+ * ```
25716
+ *
25560
25717
  * # Special repeat start and end points
25561
25718
  * To repeat a series of elements instead of just one parent element, ngRepeat (as well as other ng directives) supports extending
25562
25719
  * the range of the repeater by defining explicit start and end points by using **ng-repeat-start** and **ng-repeat-end** respectively.
@@ -25624,12 +25781,12 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
25624
25781
  *
25625
25782
  * For example: `(name, age) in {'adam':10, 'amalie':12}`.
25626
25783
  *
25627
- * * `variable in expression track by tracking_expression` – You can also provide an optional tracking function
25628
- * which can be used to associate the objects in the collection with the DOM elements. If no tracking function
25629
- * is specified the ng-repeat associates elements by identity in the collection. It is an error to have
25630
- * more than one tracking function to resolve to the same key. (This would mean that two distinct objects are
25631
- * mapped to the same DOM element, which is not possible.) Filters should be applied to the expression,
25632
- * before specifying a tracking expression.
25784
+ * * `variable in expression track by tracking_expression` – You can also provide an optional tracking expression
25785
+ * which can be used to associate the objects in the collection with the DOM elements. If no tracking expression
25786
+ * is specified, ng-repeat associates elements by identity. It is an error to have
25787
+ * more than one tracking expression value resolve to the same key. (This would mean that two distinct objects are
25788
+ * mapped to the same DOM element, which is not possible.) If filters are used in the expression, they should be
25789
+ * applied before the tracking expression.
25633
25790
  *
25634
25791
  * For example: `item in items` is equivalent to `item in items track by $id(item)`. This implies that the DOM elements
25635
25792
  * will be associated by item identity in the array.
@@ -25653,6 +25810,11 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
25653
25810
  * For example: `item in items | filter:x as results` will store the fragment of the repeated items as `results`, but only after
25654
25811
  * the items have been processed through the filter.
25655
25812
  *
25813
+ * 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
25814
+ * (and not as operator, inside an expression).
25815
+ *
25816
+ * For example: `item in items | filter : x | orderBy : order | limitTo : limit as results` .
25817
+ *
25656
25818
  * @example
25657
25819
  * This example initializes the scope to a list of names and
25658
25820
  * then uses `ngRepeat` to display every person:
@@ -26492,7 +26654,6 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
26492
26654
  */
26493
26655
  var ngSwitchDirective = ['$animate', function($animate) {
26494
26656
  return {
26495
- restrict: 'EA',
26496
26657
  require: 'ngSwitch',
26497
26658
 
26498
26659
  // asks for $scope to fool the BC controller module
@@ -26760,6 +26921,7 @@ var SelectController =
26760
26921
  if (value === '') self.emptyOption.prop('selected', true); // to make IE9 happy
26761
26922
  } else {
26762
26923
  if (isUndefined(value) && self.emptyOption) {
26924
+ self.removeUnknownOption();
26763
26925
  $element.val('');
26764
26926
  } else {
26765
26927
  self.renderUnknownOption(value);