rails-angularjs 1.4.9 → 1.5.0

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/rails-angularjs/version.rb +1 -1
  4. data/vendor/assets/javascripts/angular-animate.js +296 -48
  5. data/vendor/assets/javascripts/angular-animate.min.js +52 -51
  6. data/vendor/assets/javascripts/angular-animate.min.js.map +3 -3
  7. data/vendor/assets/javascripts/angular-aria.js +51 -51
  8. data/vendor/assets/javascripts/angular-aria.min.js +10 -10
  9. data/vendor/assets/javascripts/angular-aria.min.js.map +2 -2
  10. data/vendor/assets/javascripts/angular-cookies.js +9 -8
  11. data/vendor/assets/javascripts/angular-cookies.min.js +2 -2
  12. data/vendor/assets/javascripts/angular-cookies.min.js.map +1 -1
  13. data/vendor/assets/javascripts/angular-loader.js +16 -3
  14. data/vendor/assets/javascripts/angular-loader.min.js +5 -5
  15. data/vendor/assets/javascripts/angular-loader.min.js.map +2 -2
  16. data/vendor/assets/javascripts/angular-message-format.js +2 -2
  17. data/vendor/assets/javascripts/angular-message-format.min.js +2 -2
  18. data/vendor/assets/javascripts/angular-messages.js +7 -5
  19. data/vendor/assets/javascripts/angular-messages.min.js +8 -8
  20. data/vendor/assets/javascripts/angular-messages.min.js.map +2 -2
  21. data/vendor/assets/javascripts/angular-mocks.js +323 -30
  22. data/vendor/assets/javascripts/angular-resource.js +116 -42
  23. data/vendor/assets/javascripts/angular-resource.min.js +11 -10
  24. data/vendor/assets/javascripts/angular-resource.min.js.map +3 -3
  25. data/vendor/assets/javascripts/angular-route.js +36 -11
  26. data/vendor/assets/javascripts/angular-route.min.js +11 -11
  27. data/vendor/assets/javascripts/angular-route.min.js.map +2 -2
  28. data/vendor/assets/javascripts/angular-sanitize.js +280 -246
  29. data/vendor/assets/javascripts/angular-sanitize.min.js +11 -12
  30. data/vendor/assets/javascripts/angular-sanitize.min.js.map +3 -3
  31. data/vendor/assets/javascripts/angular-scenario.js +1227 -456
  32. data/vendor/assets/javascripts/angular-touch.js +114 -12
  33. data/vendor/assets/javascripts/angular-touch.min.js +10 -9
  34. data/vendor/assets/javascripts/angular-touch.min.js.map +3 -3
  35. data/vendor/assets/javascripts/angular.js +1227 -456
  36. data/vendor/assets/javascripts/angular.min.js +302 -293
  37. data/vendor/assets/javascripts/angular.min.js.map +3 -3
  38. metadata +1 -1
@@ -1,10 +1,13 @@
1
1
  /**
2
- * @license AngularJS v1.4.9
3
- * (c) 2010-2015 Google, Inc. http://angularjs.org
2
+ * @license AngularJS v1.5.0
3
+ * (c) 2010-2016 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
6
6
  (function(window, angular, undefined) {'use strict';
7
7
 
8
+ /* global ngTouchClickDirectiveFactory: false,
9
+ */
10
+
8
11
  /**
9
12
  * @ngdoc module
10
13
  * @name ngTouch
@@ -27,10 +30,108 @@
27
30
  /* global -ngTouch */
28
31
  var ngTouch = angular.module('ngTouch', []);
29
32
 
33
+ ngTouch.provider('$touch', $TouchProvider);
34
+
30
35
  function nodeName_(element) {
31
36
  return angular.lowercase(element.nodeName || (element[0] && element[0].nodeName));
32
37
  }
33
38
 
39
+ /**
40
+ * @ngdoc provider
41
+ * @name $touchProvider
42
+ *
43
+ * @description
44
+ * The `$touchProvider` allows enabling / disabling {@link ngTouch.ngClick ngTouch's ngClick directive}.
45
+ */
46
+ $TouchProvider.$inject = ['$provide', '$compileProvider'];
47
+ function $TouchProvider($provide, $compileProvider) {
48
+
49
+ /**
50
+ * @ngdoc method
51
+ * @name $touchProvider#ngClickOverrideEnabled
52
+ *
53
+ * @param {boolean=} enabled update the ngClickOverrideEnabled state if provided, otherwise just return the
54
+ * current ngClickOverrideEnabled state
55
+ * @returns {*} current value if used as getter or itself (chaining) if used as setter
56
+ *
57
+ * @kind function
58
+ *
59
+ * @description
60
+ * Call this method to enable/disable {@link ngTouch.ngClick ngTouch's ngClick directive}. If enabled,
61
+ * the default ngClick directive will be replaced by a version that eliminates the 300ms delay for
62
+ * click events on browser for touch-devices.
63
+ *
64
+ * The default is `false`.
65
+ *
66
+ */
67
+ var ngClickOverrideEnabled = false;
68
+ var ngClickDirectiveAdded = false;
69
+ this.ngClickOverrideEnabled = function(enabled) {
70
+ if (angular.isDefined(enabled)) {
71
+
72
+ if (enabled && !ngClickDirectiveAdded) {
73
+ ngClickDirectiveAdded = true;
74
+
75
+ // Use this to identify the correct directive in the delegate
76
+ ngTouchClickDirectiveFactory.$$moduleName = 'ngTouch';
77
+ $compileProvider.directive('ngClick', ngTouchClickDirectiveFactory);
78
+
79
+ $provide.decorator('ngClickDirective', ['$delegate', function($delegate) {
80
+ if (ngClickOverrideEnabled) {
81
+ // drop the default ngClick directive
82
+ $delegate.shift();
83
+ } else {
84
+ // drop the ngTouch ngClick directive if the override has been re-disabled (because
85
+ // we cannot de-register added directives)
86
+ var i = $delegate.length - 1;
87
+ while (i >= 0) {
88
+ if ($delegate[i].$$moduleName === 'ngTouch') {
89
+ $delegate.splice(i, 1);
90
+ break;
91
+ }
92
+ i--;
93
+ }
94
+ }
95
+
96
+ return $delegate;
97
+ }]);
98
+ }
99
+
100
+ ngClickOverrideEnabled = enabled;
101
+ return this;
102
+ }
103
+
104
+ return ngClickOverrideEnabled;
105
+ };
106
+
107
+ /**
108
+ * @ngdoc service
109
+ * @name $touch
110
+ * @kind object
111
+ *
112
+ * @description
113
+ * Provides the {@link ngTouch.$touch#ngClickOverrideEnabled `ngClickOverrideEnabled`} method.
114
+ *
115
+ */
116
+ this.$get = function() {
117
+ return {
118
+ /**
119
+ * @ngdoc method
120
+ * @name $touch#ngClickOverrideEnabled
121
+ *
122
+ * @returns {*} current value of `ngClickOverrideEnabled` set in the {@link ngTouch.$touchProvider $touchProvider},
123
+ * i.e. if {@link ngTouch.ngClick ngTouch's ngClick} directive is enabled.
124
+ *
125
+ * @kind function
126
+ */
127
+ ngClickOverrideEnabled: function() {
128
+ return ngClickOverrideEnabled;
129
+ }
130
+ };
131
+ };
132
+
133
+ }
134
+
34
135
  /* global ngTouch: false */
35
136
 
36
137
  /**
@@ -202,8 +303,17 @@ ngTouch.factory('$swipe', [function() {
202
303
  /**
203
304
  * @ngdoc directive
204
305
  * @name ngClick
306
+ * @deprecated
205
307
  *
206
308
  * @description
309
+ * <div class="alert alert-danger">
310
+ * **DEPRECATION NOTICE**: Beginning with Angular 1.5, this directive is deprecated and by default **disabled**.
311
+ * The directive will receive no further support and might be removed from future releases.
312
+ * If you need the directive, you can enable it with the {@link ngTouch.$touchProvider $touchProvider#ngClickOverrideEnabled}
313
+ * function. We also recommend that you migrate to [FastClick](https://github.com/ftlabs/fastclick).
314
+ * To learn more about the 300ms delay, this [Telerik article](http://developer.telerik.com/featured/300-ms-click-delay-ios-8/)
315
+ * gives a good overview.
316
+ * </div>
207
317
  * A more powerful replacement for the default ngClick designed to be used on touchscreen
208
318
  * devices. Most mobile browsers wait about 300ms after a tap-and-release before sending
209
319
  * the click event. This version handles them immediately, and then prevents the
@@ -235,15 +345,7 @@ ngTouch.factory('$swipe', [function() {
235
345
  </example>
236
346
  */
237
347
 
238
- ngTouch.config(['$provide', function($provide) {
239
- $provide.decorator('ngClickDirective', ['$delegate', function($delegate) {
240
- // drop the default ngClick directive
241
- $delegate.shift();
242
- return $delegate;
243
- }]);
244
- }]);
245
-
246
- ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
348
+ var ngTouchClickDirectiveFactory = ['$parse', '$timeout', '$rootElement',
247
349
  function($parse, $timeout, $rootElement) {
248
350
  var TAP_DURATION = 750; // Shorter than 750ms is a tap, longer is a taphold or drag.
249
351
  var MOVE_TOLERANCE = 12; // 12px seems to work in most mobile browsers.
@@ -487,7 +589,7 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
487
589
  });
488
590
 
489
591
  };
490
- }]);
592
+ }];
491
593
 
492
594
  /* global ngTouch: false */
493
595
 
@@ -1,13 +1,14 @@
1
1
  /*
2
- AngularJS v1.4.9
3
- (c) 2010-2015 Google, Inc. http://angularjs.org
2
+ AngularJS v1.5.0
3
+ (c) 2010-2016 Google, Inc. http://angularjs.org
4
4
  License: MIT
5
5
  */
6
- (function(x,s,y){'use strict';function t(f,k,p){n.directive(f,["$parse","$swipe",function(c,e){return function(l,m,g){function h(a){if(!b)return!1;var d=Math.abs(a.y-b.y);a=(a.x-b.x)*k;return r&&75>d&&0<a&&30<a&&.3>d/a}var d=c(g[f]),b,r,a=["touch"];s.isDefined(g.ngSwipeDisableMouse)||a.push("mouse");e.bind(m,{start:function(a,d){b=a;r=!0},cancel:function(a){r=!1},end:function(a,b){h(a)&&l.$apply(function(){m.triggerHandler(p);d(l,{$event:b})})}},a)}}])}var n=s.module("ngTouch",[]);n.factory("$swipe",
7
- [function(){function f(c){c=c.originalEvent||c;var e=c.touches&&c.touches.length?c.touches:[c];c=c.changedTouches&&c.changedTouches[0]||e[0];return{x:c.clientX,y:c.clientY}}function k(c,e){var l=[];s.forEach(c,function(c){(c=p[c][e])&&l.push(c)});return l.join(" ")}var p={mouse:{start:"mousedown",move:"mousemove",end:"mouseup"},touch:{start:"touchstart",move:"touchmove",end:"touchend",cancel:"touchcancel"}};return{bind:function(c,e,l){var m,g,h,d,b=!1;l=l||["mouse","touch"];c.on(k(l,"start"),function(a){h=
8
- f(a);b=!0;g=m=0;d=h;e.start&&e.start(h,a)});var r=k(l,"cancel");if(r)c.on(r,function(a){b=!1;e.cancel&&e.cancel(a)});c.on(k(l,"move"),function(a){if(b&&h){var c=f(a);m+=Math.abs(c.x-d.x);g+=Math.abs(c.y-d.y);d=c;10>m&&10>g||(g>m?(b=!1,e.cancel&&e.cancel(a)):(a.preventDefault(),e.move&&e.move(c,a)))}});c.on(k(l,"end"),function(a){b&&(b=!1,e.end&&e.end(f(a),a))})}}}]);n.config(["$provide",function(f){f.decorator("ngClickDirective",["$delegate",function(k){k.shift();return k}])}]);n.directive("ngClick",
9
- ["$parse","$timeout","$rootElement",function(f,k,p){function c(d,b,c){for(var a=0;a<d.length;a+=2){var e=d[a+1],g=c;if(25>Math.abs(d[a]-b)&&25>Math.abs(e-g))return d.splice(a,a+2),!0}return!1}function e(d){if(!(2500<Date.now()-m)){var b=d.touches&&d.touches.length?d.touches:[d],e=b[0].clientX,b=b[0].clientY;if(!(1>e&&1>b||h&&h[0]===e&&h[1]===b)){h&&(h=null);var a=d.target;"label"===s.lowercase(a.nodeName||a[0]&&a[0].nodeName)&&(h=[e,b]);c(g,e,b)||(d.stopPropagation(),d.preventDefault(),d.target&&
10
- d.target.blur&&d.target.blur())}}}function l(d){d=d.touches&&d.touches.length?d.touches:[d];var b=d[0].clientX,c=d[0].clientY;g.push(b,c);k(function(){for(var a=0;a<g.length;a+=2)if(g[a]==b&&g[a+1]==c){g.splice(a,a+2);break}},2500,!1)}var m,g,h;return function(d,b,h){var a=f(h.ngClick),k=!1,q,n,t,v;b.on("touchstart",function(a){k=!0;q=a.target?a.target:a.srcElement;3==q.nodeType&&(q=q.parentNode);b.addClass("ng-click-active");n=Date.now();a=a.originalEvent||a;a=(a.touches&&a.touches.length?a.touches:
11
- [a])[0];t=a.clientX;v=a.clientY});b.on("touchcancel",function(a){k=!1;b.removeClass("ng-click-active")});b.on("touchend",function(a){var d=Date.now()-n,f=a.originalEvent||a,u=(f.changedTouches&&f.changedTouches.length?f.changedTouches:f.touches&&f.touches.length?f.touches:[f])[0],f=u.clientX,u=u.clientY,w=Math.sqrt(Math.pow(f-t,2)+Math.pow(u-v,2));k&&750>d&&12>w&&(g||(p[0].addEventListener("click",e,!0),p[0].addEventListener("touchstart",l,!0),g=[]),m=Date.now(),c(g,f,u),q&&q.blur(),s.isDefined(h.disabled)&&
12
- !1!==h.disabled||b.triggerHandler("click",[a]));k=!1;b.removeClass("ng-click-active")});b.onclick=function(a){};b.on("click",function(b,c){d.$apply(function(){a(d,{$event:c||b})})});b.on("mousedown",function(a){b.addClass("ng-click-active")});b.on("mousemove mouseup",function(a){b.removeClass("ng-click-active")})}}]);t("ngSwipeLeft",-1,"swipeleft");t("ngSwipeRight",1,"swiperight")})(window,window.angular);
6
+ (function(x,n,y){'use strict';function s(f,k){var e=!1,a=!1;this.ngClickOverrideEnabled=function(b){return n.isDefined(b)?(b&&!a&&(a=!0,t.$$moduleName="ngTouch",k.directive("ngClick",t),f.decorator("ngClickDirective",["$delegate",function(a){if(e)a.shift();else for(var b=a.length-1;0<=b;){if("ngTouch"===a[b].$$moduleName){a.splice(b,1);break}b--}return a}])),e=b,this):e};this.$get=function(){return{ngClickOverrideEnabled:function(){return e}}}}function v(f,k,e){p.directive(f,["$parse","$swipe",function(a,
7
+ b){return function(l,u,g){function h(c){if(!d)return!1;var a=Math.abs(c.y-d.y);c=(c.x-d.x)*k;return r&&75>a&&0<c&&30<c&&.3>a/c}var m=a(g[f]),d,r,c=["touch"];n.isDefined(g.ngSwipeDisableMouse)||c.push("mouse");b.bind(u,{start:function(c,a){d=c;r=!0},cancel:function(c){r=!1},end:function(c,d){h(c)&&l.$apply(function(){u.triggerHandler(e);m(l,{$event:d})})}},c)}}])}var p=n.module("ngTouch",[]);p.provider("$touch",s);s.$inject=["$provide","$compileProvider"];p.factory("$swipe",[function(){function f(a){a=
8
+ a.originalEvent||a;var b=a.touches&&a.touches.length?a.touches:[a];a=a.changedTouches&&a.changedTouches[0]||b[0];return{x:a.clientX,y:a.clientY}}function k(a,b){var l=[];n.forEach(a,function(a){(a=e[a][b])&&l.push(a)});return l.join(" ")}var e={mouse:{start:"mousedown",move:"mousemove",end:"mouseup"},touch:{start:"touchstart",move:"touchmove",end:"touchend",cancel:"touchcancel"}};return{bind:function(a,b,l){var e,g,h,m,d=!1;l=l||["mouse","touch"];a.on(k(l,"start"),function(c){h=f(c);d=!0;g=e=0;m=
9
+ h;b.start&&b.start(h,c)});var r=k(l,"cancel");if(r)a.on(r,function(c){d=!1;b.cancel&&b.cancel(c)});a.on(k(l,"move"),function(c){if(d&&h){var a=f(c);e+=Math.abs(a.x-m.x);g+=Math.abs(a.y-m.y);m=a;10>e&&10>g||(g>e?(d=!1,b.cancel&&b.cancel(c)):(c.preventDefault(),b.move&&b.move(a,c)))}});a.on(k(l,"end"),function(c){d&&(d=!1,b.end&&b.end(f(c),c))})}}}]);var t=["$parse","$timeout","$rootElement",function(f,k,e){function a(a,d,b){for(var c=0;c<a.length;c+=2){var g=a[c+1],e=b;if(25>Math.abs(a[c]-d)&&25>Math.abs(g-
10
+ e))return a.splice(c,c+2),!0}return!1}function b(b){if(!(2500<Date.now()-u)){var d=b.touches&&b.touches.length?b.touches:[b],e=d[0].clientX,d=d[0].clientY;if(!(1>e&&1>d||h&&h[0]===e&&h[1]===d)){h&&(h=null);var c=b.target;"label"===n.lowercase(c.nodeName||c[0]&&c[0].nodeName)&&(h=[e,d]);a(g,e,d)||(b.stopPropagation(),b.preventDefault(),b.target&&b.target.blur&&b.target.blur())}}}function l(a){a=a.touches&&a.touches.length?a.touches:[a];var b=a[0].clientX,e=a[0].clientY;g.push(b,e);k(function(){for(var a=
11
+ 0;a<g.length;a+=2)if(g[a]==b&&g[a+1]==e){g.splice(a,a+2);break}},2500,!1)}var u,g,h;return function(h,d,k){var c=f(k.ngClick),w=!1,q,p,s,t;d.on("touchstart",function(a){w=!0;q=a.target?a.target:a.srcElement;3==q.nodeType&&(q=q.parentNode);d.addClass("ng-click-active");p=Date.now();a=a.originalEvent||a;a=(a.touches&&a.touches.length?a.touches:[a])[0];s=a.clientX;t=a.clientY});d.on("touchcancel",function(a){w=!1;d.removeClass("ng-click-active")});d.on("touchend",function(c){var h=Date.now()-p,f=c.originalEvent||
12
+ c,m=(f.changedTouches&&f.changedTouches.length?f.changedTouches:f.touches&&f.touches.length?f.touches:[f])[0],f=m.clientX,m=m.clientY,v=Math.sqrt(Math.pow(f-s,2)+Math.pow(m-t,2));w&&750>h&&12>v&&(g||(e[0].addEventListener("click",b,!0),e[0].addEventListener("touchstart",l,!0),g=[]),u=Date.now(),a(g,f,m),q&&q.blur(),n.isDefined(k.disabled)&&!1!==k.disabled||d.triggerHandler("click",[c]));w=!1;d.removeClass("ng-click-active")});d.onclick=function(a){};d.on("click",function(a,b){h.$apply(function(){c(h,
13
+ {$event:b||a})})});d.on("mousedown",function(a){d.addClass("ng-click-active")});d.on("mousemove mouseup",function(a){d.removeClass("ng-click-active")})}}];v("ngSwipeLeft",-1,"swipeleft");v("ngSwipeRight",1,"swiperight")})(window,window.angular);
13
14
  //# sourceMappingURL=angular-touch.min.js.map
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "version":3,
3
3
  "file":"angular-touch.min.js",
4
- "lineCount":12,
5
- "mappings":"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",
4
+ "lineCount":13,
5
+ "mappings":"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",
6
6
  "sources":["angular-touch.js"],
7
- "names":["window","angular","undefined","makeSwipeDirective","directiveName","direction","eventName","ngTouch","directive","$parse","$swipe","scope","element","attr","validSwipe","coords","startCoords","deltaY","Math","abs","y","deltaX","x","valid","MAX_VERTICAL_DISTANCE","MIN_HORIZONTAL_DISTANCE","MAX_VERTICAL_RATIO","swipeHandler","pointerTypes","isDefined","push","bind","start","event","cancel","end","$apply","triggerHandler","$event","module","factory","getCoordinates","originalEvent","touches","length","e","changedTouches","clientX","clientY","getEvents","eventType","res","forEach","pointerType","POINTER_EVENTS","join","move","eventHandlers","totalX","totalY","lastPos","active","on","events","MOVE_BUFFER_RADIUS","preventDefault","config","$provide","decorator","$delegate","shift","$timeout","$rootElement","checkAllowableRegions","touchCoordinates","i","CLICKBUSTER_THRESHOLD","x1","y1","y2","splice","onClick","PREVENT_DURATION","Date","now","lastPreventedTime","lastLabelClickCoordinates","target","lowercase","nodeName","stopPropagation","blur","onTouchStart","clickHandler","ngClick","tapping","tapElement","startTime","touchStartX","touchStartY","srcElement","nodeType","parentNode","addClass","ACTIVE_CLASS_NAME","removeClass","diff","dist","sqrt","pow","TAP_DURATION","MOVE_TOLERANCE","addEventListener","disabled","onclick","element.onclick","touchend"]
7
+ "names":["window","angular","undefined","$TouchProvider","$provide","$compileProvider","ngClickOverrideEnabled","ngClickDirectiveAdded","this.ngClickOverrideEnabled","enabled","isDefined","ngTouchClickDirectiveFactory","$$moduleName","directive","decorator","$delegate","shift","i","length","splice","$get","this.$get","makeSwipeDirective","directiveName","direction","eventName","ngTouch","$parse","$swipe","scope","element","attr","validSwipe","coords","startCoords","deltaY","Math","abs","y","deltaX","x","valid","MAX_VERTICAL_DISTANCE","MIN_HORIZONTAL_DISTANCE","MAX_VERTICAL_RATIO","swipeHandler","pointerTypes","push","bind","start","event","cancel","end","$apply","triggerHandler","$event","module","provider","$inject","factory","getCoordinates","originalEvent","touches","e","changedTouches","clientX","clientY","getEvents","eventType","res","forEach","pointerType","POINTER_EVENTS","join","move","eventHandlers","totalX","totalY","lastPos","active","on","events","MOVE_BUFFER_RADIUS","preventDefault","$timeout","$rootElement","checkAllowableRegions","touchCoordinates","CLICKBUSTER_THRESHOLD","x1","y1","y2","onClick","PREVENT_DURATION","Date","now","lastPreventedTime","lastLabelClickCoordinates","target","lowercase","nodeName","stopPropagation","blur","onTouchStart","clickHandler","ngClick","tapping","tapElement","startTime","touchStartX","touchStartY","srcElement","nodeType","parentNode","addClass","ACTIVE_CLASS_NAME","removeClass","diff","dist","sqrt","pow","TAP_DURATION","MOVE_TOLERANCE","addEventListener","disabled","onclick","element.onclick","touchend"]
8
8
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @license AngularJS v1.4.9
3
- * (c) 2010-2015 Google, Inc. http://angularjs.org
2
+ * @license AngularJS v1.5.0
3
+ * (c) 2010-2016 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
6
6
  (function(window, document, undefined) {'use strict';
@@ -57,7 +57,7 @@ function minErr(module, ErrorConstructor) {
57
57
  return match;
58
58
  });
59
59
 
60
- message += '\nhttp://errors.angularjs.org/1.4.9/' +
60
+ message += '\nhttp://errors.angularjs.org/1.5.0/' +
61
61
  (module ? module + '/' : '') + code;
62
62
 
63
63
  for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
@@ -188,29 +188,9 @@ var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/;
188
188
  // This is used so that it's possible for internal tests to create mock ValidityStates.
189
189
  var VALIDITY_STATE_PROPERTY = 'validity';
190
190
 
191
- /**
192
- * @ngdoc function
193
- * @name angular.lowercase
194
- * @module ng
195
- * @kind function
196
- *
197
- * @description Converts the specified string to lowercase.
198
- * @param {string} string String to be converted to lowercase.
199
- * @returns {string} Lowercased string.
200
- */
201
- var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};
202
191
  var hasOwnProperty = Object.prototype.hasOwnProperty;
203
192
 
204
- /**
205
- * @ngdoc function
206
- * @name angular.uppercase
207
- * @module ng
208
- * @kind function
209
- *
210
- * @description Converts the specified string to uppercase.
211
- * @param {string} string String to be converted to uppercase.
212
- * @returns {string} Uppercased string.
213
- */
193
+ var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};
214
194
  var uppercase = function(string) {return isString(string) ? string.toUpperCase() : string;};
215
195
 
216
196
 
@@ -230,7 +210,7 @@ var manualUppercase = function(s) {
230
210
 
231
211
  // String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish
232
212
  // locale, for this reason we need to detect this case and redefine lowercase/uppercase methods
233
- // with correct but slower alternatives.
213
+ // with correct but slower alternatives. See https://github.com/angular/angular.js/issues/11387
234
214
  if ('i' !== 'I'.toLowerCase()) {
235
215
  lowercase = manualLowercase;
236
216
  uppercase = manualUppercase;
@@ -273,7 +253,7 @@ function isArrayLike(obj) {
273
253
 
274
254
  // arrays, strings and jQuery/jqLite objects are array like
275
255
  // * jqLite is either the jQuery or jqLite constructor function
276
- // * we have to check the existance of jqLite first as this method is called
256
+ // * we have to check the existence of jqLite first as this method is called
277
257
  // via the forEach method when constructing the jqLite object in the first place
278
258
  if (isArray(obj) || isString(obj) || (jqLite && obj instanceof jqLite)) return true;
279
259
 
@@ -382,7 +362,7 @@ function forEachSorted(obj, iterator, context) {
382
362
  * @returns {function(*, string)}
383
363
  */
384
364
  function reverseParams(iteratorFn) {
385
- return function(value, key) { iteratorFn(key, value); };
365
+ return function(value, key) {iteratorFn(key, value);};
386
366
  }
387
367
 
388
368
  /**
@@ -753,6 +733,10 @@ function isTypedArray(value) {
753
733
  return value && isNumber(value.length) && TYPED_ARRAY_REGEXP.test(toString.call(value));
754
734
  }
755
735
 
736
+ function isArrayBuffer(obj) {
737
+ return toString.call(obj) === '[object ArrayBuffer]';
738
+ }
739
+
756
740
 
757
741
  var trim = function(value) {
758
742
  return isString(value) ? value.trim() : value;
@@ -790,7 +774,7 @@ function isElement(node) {
790
774
  * @returns {object} in the form of {key1:true, key2:true, ...}
791
775
  */
792
776
  function makeMap(str) {
793
- var obj = {}, items = str.split(","), i;
777
+ var obj = {}, items = str.split(','), i;
794
778
  for (i = 0; i < items.length; i++) {
795
779
  obj[items[i]] = true;
796
780
  }
@@ -877,7 +861,7 @@ function copy(source, destination) {
877
861
  var stackDest = [];
878
862
 
879
863
  if (destination) {
880
- if (isTypedArray(destination)) {
864
+ if (isTypedArray(destination) || isArrayBuffer(destination)) {
881
865
  throw ngMinErr('cpta', "Can't copy! TypedArray destination cannot be mutated.");
882
866
  }
883
867
  if (source === destination) {
@@ -951,22 +935,10 @@ function copy(source, destination) {
951
935
  }
952
936
 
953
937
  var needsRecurse = false;
954
- var destination;
938
+ var destination = copyType(source);
955
939
 
956
- if (isArray(source)) {
957
- destination = [];
958
- needsRecurse = true;
959
- } else if (isTypedArray(source)) {
960
- destination = new source.constructor(source);
961
- } else if (isDate(source)) {
962
- destination = new Date(source.getTime());
963
- } else if (isRegExp(source)) {
964
- destination = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]);
965
- destination.lastIndex = source.lastIndex;
966
- } else if (isFunction(source.cloneNode)) {
967
- destination = source.cloneNode(true);
968
- } else {
969
- destination = Object.create(getPrototypeOf(source));
940
+ if (destination === undefined) {
941
+ destination = isArray(source) ? [] : Object.create(getPrototypeOf(source));
970
942
  needsRecurse = true;
971
943
  }
972
944
 
@@ -977,6 +949,45 @@ function copy(source, destination) {
977
949
  ? copyRecurse(source, destination)
978
950
  : destination;
979
951
  }
952
+
953
+ function copyType(source) {
954
+ switch (toString.call(source)) {
955
+ case '[object Int8Array]':
956
+ case '[object Int16Array]':
957
+ case '[object Int32Array]':
958
+ case '[object Float32Array]':
959
+ case '[object Float64Array]':
960
+ case '[object Uint8Array]':
961
+ case '[object Uint8ClampedArray]':
962
+ case '[object Uint16Array]':
963
+ case '[object Uint32Array]':
964
+ return new source.constructor(copyElement(source.buffer));
965
+
966
+ case '[object ArrayBuffer]':
967
+ //Support: IE10
968
+ if (!source.slice) {
969
+ var copied = new ArrayBuffer(source.byteLength);
970
+ new Uint8Array(copied).set(new Uint8Array(source));
971
+ return copied;
972
+ }
973
+ return source.slice(0);
974
+
975
+ case '[object Boolean]':
976
+ case '[object Number]':
977
+ case '[object String]':
978
+ case '[object Date]':
979
+ return new source.constructor(source.valueOf());
980
+
981
+ case '[object RegExp]':
982
+ var re = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]);
983
+ re.lastIndex = source.lastIndex;
984
+ return re;
985
+ }
986
+
987
+ if (isFunction(source.cloneNode)) {
988
+ return source.cloneNode(true);
989
+ }
990
+ }
980
991
  }
981
992
 
982
993
  /**
@@ -1039,38 +1050,37 @@ function equals(o1, o2) {
1039
1050
  if (o1 === null || o2 === null) return false;
1040
1051
  if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN
1041
1052
  var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
1042
- if (t1 == t2) {
1043
- if (t1 == 'object') {
1044
- if (isArray(o1)) {
1045
- if (!isArray(o2)) return false;
1046
- if ((length = o1.length) == o2.length) {
1047
- for (key = 0; key < length; key++) {
1048
- if (!equals(o1[key], o2[key])) return false;
1049
- }
1050
- return true;
1051
- }
1052
- } else if (isDate(o1)) {
1053
- if (!isDate(o2)) return false;
1054
- return equals(o1.getTime(), o2.getTime());
1055
- } else if (isRegExp(o1)) {
1056
- return isRegExp(o2) ? o1.toString() == o2.toString() : false;
1057
- } else {
1058
- if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) ||
1059
- isArray(o2) || isDate(o2) || isRegExp(o2)) return false;
1060
- keySet = createMap();
1061
- for (key in o1) {
1062
- if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
1053
+ if (t1 == t2 && t1 == 'object') {
1054
+ if (isArray(o1)) {
1055
+ if (!isArray(o2)) return false;
1056
+ if ((length = o1.length) == o2.length) {
1057
+ for (key = 0; key < length; key++) {
1063
1058
  if (!equals(o1[key], o2[key])) return false;
1064
- keySet[key] = true;
1065
- }
1066
- for (key in o2) {
1067
- if (!(key in keySet) &&
1068
- key.charAt(0) !== '$' &&
1069
- isDefined(o2[key]) &&
1070
- !isFunction(o2[key])) return false;
1071
1059
  }
1072
1060
  return true;
1073
1061
  }
1062
+ } else if (isDate(o1)) {
1063
+ if (!isDate(o2)) return false;
1064
+ return equals(o1.getTime(), o2.getTime());
1065
+ } else if (isRegExp(o1)) {
1066
+ if (!isRegExp(o2)) return false;
1067
+ return o1.toString() == o2.toString();
1068
+ } else {
1069
+ if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) ||
1070
+ isArray(o2) || isDate(o2) || isRegExp(o2)) return false;
1071
+ keySet = createMap();
1072
+ for (key in o1) {
1073
+ if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
1074
+ if (!equals(o1[key], o2[key])) return false;
1075
+ keySet[key] = true;
1076
+ }
1077
+ for (key in o2) {
1078
+ if (!(key in keySet) &&
1079
+ key.charAt(0) !== '$' &&
1080
+ isDefined(o2[key]) &&
1081
+ !isFunction(o2[key])) return false;
1082
+ }
1083
+ return true;
1074
1084
  }
1075
1085
  }
1076
1086
  return false;
@@ -1247,7 +1257,7 @@ function toJsonReplacer(key, value) {
1247
1257
  * @returns {string|undefined} JSON-ified string representing `obj`.
1248
1258
  */
1249
1259
  function toJson(obj, pretty) {
1250
- if (typeof obj === 'undefined') return undefined;
1260
+ if (isUndefined(obj)) return undefined;
1251
1261
  if (!isNumber(pretty)) {
1252
1262
  pretty = pretty ? 2 : null;
1253
1263
  }
@@ -1274,7 +1284,10 @@ function fromJson(json) {
1274
1284
  }
1275
1285
 
1276
1286
 
1287
+ var ALL_COLONS = /:/g;
1277
1288
  function timezoneToOffset(timezone, fallback) {
1289
+ // IE/Edge do not "understand" colon (`:`) in timezone
1290
+ timezone = timezone.replace(ALL_COLONS, '');
1278
1291
  var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;
1279
1292
  return isNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;
1280
1293
  }
@@ -1289,8 +1302,9 @@ function addDateMinutes(date, minutes) {
1289
1302
 
1290
1303
  function convertTimezoneToLocal(date, timezone, reverse) {
1291
1304
  reverse = reverse ? -1 : 1;
1292
- var timezoneOffset = timezoneToOffset(timezone, date.getTimezoneOffset());
1293
- return addDateMinutes(date, reverse * (timezoneOffset - date.getTimezoneOffset()));
1305
+ var dateTimezoneOffset = date.getTimezoneOffset();
1306
+ var timezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
1307
+ return addDateMinutes(date, reverse * (timezoneOffset - dateTimezoneOffset));
1294
1308
  }
1295
1309
 
1296
1310
 
@@ -1309,7 +1323,7 @@ function startingTag(element) {
1309
1323
  return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) :
1310
1324
  elemHtml.
1311
1325
  match(/^(<[^>]+>)/)[1].
1312
- replace(/^<([\w\-]+)/, function(match, nodeName) { return '<' + lowercase(nodeName); });
1326
+ replace(/^<([\w\-]+)/, function(match, nodeName) {return '<' + lowercase(nodeName);});
1313
1327
  } catch (e) {
1314
1328
  return lowercase(elemHtml);
1315
1329
  }
@@ -1752,7 +1766,6 @@ function snake_case(name, separator) {
1752
1766
  }
1753
1767
 
1754
1768
  var bindJQueryFired = false;
1755
- var skipDestroyOnNextJQueryCleanData;
1756
1769
  function bindJQuery() {
1757
1770
  var originalCleanData;
1758
1771
 
@@ -1786,15 +1799,11 @@ function bindJQuery() {
1786
1799
  originalCleanData = jQuery.cleanData;
1787
1800
  jQuery.cleanData = function(elems) {
1788
1801
  var events;
1789
- if (!skipDestroyOnNextJQueryCleanData) {
1790
- for (var i = 0, elem; (elem = elems[i]) != null; i++) {
1791
- events = jQuery._data(elem, "events");
1792
- if (events && events.$destroy) {
1793
- jQuery(elem).triggerHandler('$destroy');
1794
- }
1802
+ for (var i = 0, elem; (elem = elems[i]) != null; i++) {
1803
+ events = jQuery._data(elem, "events");
1804
+ if (events && events.$destroy) {
1805
+ jQuery(elem).triggerHandler('$destroy');
1795
1806
  }
1796
- } else {
1797
- skipDestroyOnNextJQueryCleanData = false;
1798
1807
  }
1799
1808
  originalCleanData(elems);
1800
1809
  };
@@ -2194,6 +2203,19 @@ function setupModuleLoader(window) {
2194
2203
  */
2195
2204
  directive: invokeLaterAndSetModuleName('$compileProvider', 'directive'),
2196
2205
 
2206
+ /**
2207
+ * @ngdoc method
2208
+ * @name angular.Module#component
2209
+ * @module ng
2210
+ * @param {string} name Name of the component in camel-case (i.e. myComp which will match as my-comp)
2211
+ * @param {Object} options Component definition object (a simplified
2212
+ * {@link ng.$compile#directive-definition-object directive definition object})
2213
+ *
2214
+ * @description
2215
+ * See {@link ng.$compileProvider#component $compileProvider.component()}.
2216
+ */
2217
+ component: invokeLaterAndSetModuleName('$compileProvider', 'component'),
2218
+
2197
2219
  /**
2198
2220
  * @ngdoc method
2199
2221
  * @name angular.Module#config
@@ -2352,6 +2374,7 @@ function toDebugString(obj) {
2352
2374
  $BrowserProvider,
2353
2375
  $CacheFactoryProvider,
2354
2376
  $ControllerProvider,
2377
+ $DateProvider,
2355
2378
  $DocumentProvider,
2356
2379
  $ExceptionHandlerProvider,
2357
2380
  $FilterProvider,
@@ -2401,11 +2424,11 @@ function toDebugString(obj) {
2401
2424
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
2402
2425
  */
2403
2426
  var version = {
2404
- full: '1.4.9', // all of these placeholder strings will be replaced by grunt's
2427
+ full: '1.5.0', // all of these placeholder strings will be replaced by grunt's
2405
2428
  major: 1, // package task
2406
- minor: 4,
2407
- dot: 9,
2408
- codeName: 'implicit-superannuation'
2429
+ minor: 5,
2430
+ dot: 0,
2431
+ codeName: 'ennoblement-facilitation'
2409
2432
  };
2410
2433
 
2411
2434
 
@@ -2744,6 +2767,12 @@ function jqLiteHasData(node) {
2744
2767
  return false;
2745
2768
  }
2746
2769
 
2770
+ function jqLiteCleanData(nodes) {
2771
+ for (var i = 0, ii = nodes.length; i < ii; i++) {
2772
+ jqLiteRemoveData(nodes[i]);
2773
+ }
2774
+ }
2775
+
2747
2776
  function jqLiteBuildFragment(html, context) {
2748
2777
  var tmp, tag, wrap,
2749
2778
  fragment = context.createDocumentFragment(),
@@ -2796,6 +2825,16 @@ function jqLiteParseHTML(html, context) {
2796
2825
  return [];
2797
2826
  }
2798
2827
 
2828
+ function jqLiteWrapNode(node, wrapper) {
2829
+ var parent = node.parentNode;
2830
+
2831
+ if (parent) {
2832
+ parent.replaceChild(wrapper, node);
2833
+ }
2834
+
2835
+ wrapper.appendChild(node);
2836
+ }
2837
+
2799
2838
 
2800
2839
  // IE9-11 has no method "contains" in SVG element and in Node.prototype. Bug #10259.
2801
2840
  var jqLiteContains = Node.prototype.contains || function(arg) {
@@ -3046,7 +3085,7 @@ function jqLiteRemove(element, keepData) {
3046
3085
  function jqLiteDocumentLoaded(action, win) {
3047
3086
  win = win || window;
3048
3087
  if (win.document.readyState === 'complete') {
3049
- // Force the action to be run async for consistent behaviour
3088
+ // Force the action to be run async for consistent behavior
3050
3089
  // from the action's point of view
3051
3090
  // i.e. it will definitely not be in a $apply
3052
3091
  win.setTimeout(action);
@@ -3132,7 +3171,8 @@ function getAliasedAttrName(name) {
3132
3171
  forEach({
3133
3172
  data: jqLiteData,
3134
3173
  removeData: jqLiteRemoveData,
3135
- hasData: jqLiteHasData
3174
+ hasData: jqLiteHasData,
3175
+ cleanData: jqLiteCleanData
3136
3176
  }, function(fn, name) {
3137
3177
  JQLite[name] = fn;
3138
3178
  });
@@ -3487,12 +3527,7 @@ forEach({
3487
3527
  },
3488
3528
 
3489
3529
  wrap: function(element, wrapNode) {
3490
- wrapNode = jqLite(wrapNode).eq(0).clone()[0];
3491
- var parent = element.parentNode;
3492
- if (parent) {
3493
- parent.replaceChild(wrapNode, element);
3494
- }
3495
- wrapNode.appendChild(element);
3530
+ jqLiteWrapNode(element, jqLite(wrapNode).eq(0).clone()[0]);
3496
3531
  },
3497
3532
 
3498
3533
  remove: jqLiteRemove,
@@ -3770,17 +3805,23 @@ var $$HashMapProvider = [function() {
3770
3805
  * Implicit module which gets automatically added to each {@link auto.$injector $injector}.
3771
3806
  */
3772
3807
 
3808
+ var ARROW_ARG = /^([^\(]+?)=>/;
3773
3809
  var FN_ARGS = /^[^\(]*\(\s*([^\)]*)\)/m;
3774
3810
  var FN_ARG_SPLIT = /,/;
3775
3811
  var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
3776
3812
  var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
3777
3813
  var $injectorMinErr = minErr('$injector');
3778
3814
 
3815
+ function extractArgs(fn) {
3816
+ var fnText = fn.toString().replace(STRIP_COMMENTS, ''),
3817
+ args = fnText.match(ARROW_ARG) || fnText.match(FN_ARGS);
3818
+ return args;
3819
+ }
3820
+
3779
3821
  function anonFn(fn) {
3780
3822
  // For anonymous functions, showing at the very least the function signature can help in
3781
3823
  // debugging.
3782
- var fnText = fn.toString().replace(STRIP_COMMENTS, ''),
3783
- args = fnText.match(FN_ARGS);
3824
+ var args = extractArgs(fn);
3784
3825
  if (args) {
3785
3826
  return 'function(' + (args[1] || '').replace(/[\s\r\n]+/, ' ') + ')';
3786
3827
  }
@@ -3789,7 +3830,6 @@ function anonFn(fn) {
3789
3830
 
3790
3831
  function annotate(fn, strictDi, name) {
3791
3832
  var $inject,
3792
- fnText,
3793
3833
  argDecl,
3794
3834
  last;
3795
3835
 
@@ -3804,8 +3844,7 @@ function annotate(fn, strictDi, name) {
3804
3844
  throw $injectorMinErr('strictdi',
3805
3845
  '{0} is not using explicit annotation and cannot be invoked in strict mode', name);
3806
3846
  }
3807
- fnText = fn.toString().replace(STRIP_COMMENTS, '');
3808
- argDecl = fnText.match(FN_ARGS);
3847
+ argDecl = extractArgs(fn);
3809
3848
  forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) {
3810
3849
  arg.replace(FN_ARG, function(all, underscore, name) {
3811
3850
  $inject.push(name);
@@ -4195,8 +4234,20 @@ function annotate(fn, strictDi, name) {
4195
4234
  *
4196
4235
  * Register a **service constructor**, which will be invoked with `new` to create the service
4197
4236
  * instance.
4198
- * This is short for registering a service where its provider's `$get` property is the service
4199
- * constructor function that will be used to instantiate the service instance.
4237
+ * This is short for registering a service where its provider's `$get` property is a factory
4238
+ * function that returns an instance instantiated by the injector from the service constructor
4239
+ * function.
4240
+ *
4241
+ * Internally it looks a bit like this:
4242
+ *
4243
+ * ```
4244
+ * {
4245
+ * $get: function() {
4246
+ * return $injector.instantiate(constructor);
4247
+ * }
4248
+ * }
4249
+ * ```
4250
+ *
4200
4251
  *
4201
4252
  * You should use {@link auto.$provide#service $provide.service(class)} if you define your service
4202
4253
  * as a type/class.
@@ -4346,14 +4397,19 @@ function createInjector(modulesToLoad, strictDi) {
4346
4397
  throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- '));
4347
4398
  })),
4348
4399
  instanceCache = {},
4349
- instanceInjector = (instanceCache.$injector =
4400
+ protoInstanceInjector =
4350
4401
  createInternalInjector(instanceCache, function(serviceName, caller) {
4351
4402
  var provider = providerInjector.get(serviceName + providerSuffix, caller);
4352
- return instanceInjector.invoke(provider.$get, provider, undefined, serviceName);
4353
- }));
4354
-
4403
+ return instanceInjector.invoke(
4404
+ provider.$get, provider, undefined, serviceName);
4405
+ }),
4406
+ instanceInjector = protoInstanceInjector;
4355
4407
 
4356
- forEach(loadModules(modulesToLoad), function(fn) { if (fn) instanceInjector.invoke(fn); });
4408
+ providerCache['$injector' + providerSuffix] = { $get: valueFn(protoInstanceInjector) };
4409
+ var runBlocks = loadModules(modulesToLoad);
4410
+ instanceInjector = protoInstanceInjector.get('$injector');
4411
+ instanceInjector.strictDi = strictDi;
4412
+ forEach(runBlocks, function(fn) { if (fn) instanceInjector.invoke(fn); });
4357
4413
 
4358
4414
  return instanceInjector;
4359
4415
 
@@ -4503,48 +4559,67 @@ function createInjector(modulesToLoad, strictDi) {
4503
4559
  }
4504
4560
  }
4505
4561
 
4506
- function invoke(fn, self, locals, serviceName) {
4507
- if (typeof locals === 'string') {
4508
- serviceName = locals;
4509
- locals = null;
4510
- }
4511
4562
 
4563
+ function injectionArgs(fn, locals, serviceName) {
4512
4564
  var args = [],
4513
- $inject = createInjector.$$annotate(fn, strictDi, serviceName),
4514
- length, i,
4515
- key;
4565
+ $inject = createInjector.$$annotate(fn, strictDi, serviceName);
4516
4566
 
4517
- for (i = 0, length = $inject.length; i < length; i++) {
4518
- key = $inject[i];
4567
+ for (var i = 0, length = $inject.length; i < length; i++) {
4568
+ var key = $inject[i];
4519
4569
  if (typeof key !== 'string') {
4520
4570
  throw $injectorMinErr('itkn',
4521
4571
  'Incorrect injection token! Expected service name as string, got {0}', key);
4522
4572
  }
4523
- args.push(
4524
- locals && locals.hasOwnProperty(key)
4525
- ? locals[key]
4526
- : getService(key, serviceName)
4527
- );
4573
+ args.push(locals && locals.hasOwnProperty(key) ? locals[key] :
4574
+ getService(key, serviceName));
4575
+ }
4576
+ return args;
4577
+ }
4578
+
4579
+ function isClass(func) {
4580
+ // IE 9-11 do not support classes and IE9 leaks with the code below.
4581
+ if (msie <= 11) {
4582
+ return false;
4583
+ }
4584
+ // Workaround for MS Edge.
4585
+ // Check https://connect.microsoft.com/IE/Feedback/Details/2211653
4586
+ return typeof func === 'function'
4587
+ && /^(?:class\s|constructor\()/.test(Function.prototype.toString.call(func));
4588
+ }
4589
+
4590
+ function invoke(fn, self, locals, serviceName) {
4591
+ if (typeof locals === 'string') {
4592
+ serviceName = locals;
4593
+ locals = null;
4528
4594
  }
4595
+
4596
+ var args = injectionArgs(fn, locals, serviceName);
4529
4597
  if (isArray(fn)) {
4530
- fn = fn[length];
4598
+ fn = fn[fn.length - 1];
4531
4599
  }
4532
4600
 
4533
- // http://jsperf.com/angularjs-invoke-apply-vs-switch
4534
- // #5388
4535
- return fn.apply(self, args);
4601
+ if (!isClass(fn)) {
4602
+ // http://jsperf.com/angularjs-invoke-apply-vs-switch
4603
+ // #5388
4604
+ return fn.apply(self, args);
4605
+ } else {
4606
+ args.unshift(null);
4607
+ return new (Function.prototype.bind.apply(fn, args))();
4608
+ }
4536
4609
  }
4537
4610
 
4611
+
4538
4612
  function instantiate(Type, locals, serviceName) {
4539
4613
  // Check if Type is annotated and use just the given function at n-1 as parameter
4540
4614
  // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);
4541
- // Object creation: http://jsperf.com/create-constructor/2
4542
- var instance = Object.create((isArray(Type) ? Type[Type.length - 1] : Type).prototype || null);
4543
- var returnedValue = invoke(Type, instance, locals, serviceName);
4544
-
4545
- return isObject(returnedValue) || isFunction(returnedValue) ? returnedValue : instance;
4615
+ var ctor = (isArray(Type) ? Type[Type.length - 1] : Type);
4616
+ var args = injectionArgs(Type, locals, serviceName);
4617
+ // Empty object at position 0 is ignored for invocation with `new`, but required.
4618
+ args.unshift(null);
4619
+ return new (Function.prototype.bind.apply(ctor, args))();
4546
4620
  }
4547
4621
 
4622
+
4548
4623
  return {
4549
4624
  invoke: invoke,
4550
4625
  instantiate: instantiate,
@@ -5159,8 +5234,8 @@ var $AnimateProvider = ['$provide', function($provide) {
5159
5234
  * // remove all the animation event listeners listening for `enter` on the given element and its children
5160
5235
  * $animate.off('enter', container);
5161
5236
  *
5162
- * // remove the event listener function provided by `listenerFn` that is set
5163
- * // to listen for `enter` on the given `element` as well as its children
5237
+ * // remove the event listener function provided by `callback` that is set
5238
+ * // to listen for `enter` on the given `container` as well as its children
5164
5239
  * $animate.off('enter', container, callback);
5165
5240
  * ```
5166
5241
  *
@@ -5383,7 +5458,7 @@ var $AnimateProvider = ['$provide', function($provide) {
5383
5458
  *
5384
5459
  * @description Performs an inline animation on the element which applies the provided to and from CSS styles to the element.
5385
5460
  * If any detected CSS transition, keyframe or JavaScript matches the provided className value, then the animation will take
5386
- * on the provided styles. For example, if a transition animation is set for the given className, then the provided `from` and
5461
+ * on the provided styles. For example, if a transition animation is set for the given classNamem, then the provided `from` and
5387
5462
  * `to` styles will be applied alongside the given transition. If the CSS style provided in `from` does not have a corresponding
5388
5463
  * style in `to`, the style in `from` is applied immediately, and no animation is run.
5389
5464
  * If a JavaScript animation is detected then the provided styles will be given in as function parameters into the `animate`
@@ -5405,7 +5480,7 @@ var $AnimateProvider = ['$provide', function($provide) {
5405
5480
  * @param {object} to the to (destination) CSS styles that will be applied to the element and across the animation.
5406
5481
  * @param {string=} className an optional CSS class that will be applied to the element for the duration of the animation. If
5407
5482
  * this value is left as empty then a CSS class of `ng-inline-animate` will be applied to the element.
5408
- * (Note that if no animation is detected then this value will not be appplied to the element.)
5483
+ * (Note that if no animation is detected then this value will not be applied to the element.)
5409
5484
  * @param {object=} options an optional collection of options/styles that will be applied to the element
5410
5485
  *
5411
5486
  * @return {Promise} the animation callback promise
@@ -5643,7 +5718,7 @@ var $CoreAnimateCssProvider = function() {
5643
5718
  options.from = null;
5644
5719
  }
5645
5720
 
5646
- /* jshint newcap: false*/
5721
+ /* jshint newcap: false */
5647
5722
  var closed, runner = new $$AnimateRunner();
5648
5723
  return {
5649
5724
  start: run,
@@ -6569,7 +6644,7 @@ function $TemplateCacheProvider() {
6569
6644
  * When this property is set to true, the HTML compiler will collect DOM nodes between
6570
6645
  * nodes with the attributes `directive-name-start` and `directive-name-end`, and group them
6571
6646
  * together as the directive elements. It is recommended that this feature be used on directives
6572
- * which are not strictly behavioural (such as {@link ngClick}), and which
6647
+ * which are not strictly behavioral (such as {@link ngClick}), and which
6573
6648
  * do not manipulate or replace child nodes (such as {@link ngInclude}).
6574
6649
  *
6575
6650
  * #### `priority`
@@ -6607,35 +6682,62 @@ function $TemplateCacheProvider() {
6607
6682
  * is bound to the parent scope, via matching attributes on the directive's element:
6608
6683
  *
6609
6684
  * * `@` or `@attr` - bind a local scope property to the value of DOM attribute. The result is
6610
- * always a string since DOM attributes are strings. If no `attr` name is specified then the
6611
- * attribute name is assumed to be the same as the local name.
6612
- * Given `<widget my-attr="hello {{name}}">` and widget definition
6613
- * of `scope: { localName:'@myAttr' }`, then widget scope property `localName` will reflect
6614
- * the interpolated value of `hello {{name}}`. As the `name` attribute changes so will the
6615
- * `localName` property on the widget scope. The `name` is read from the parent scope (not
6616
- * component scope).
6617
- *
6618
- * * `=` or `=attr` - set up bi-directional binding between a local scope property and the
6619
- * parent scope property of name defined via the value of the `attr` attribute. If no `attr`
6620
- * name is specified then the attribute name is assumed to be the same as the local name.
6621
- * Given `<widget my-attr="parentModel">` and widget definition of
6622
- * `scope: { localModel:'=myAttr' }`, then widget scope property `localModel` will reflect the
6685
+ * always a string since DOM attributes are strings. If no `attr` name is specified then the
6686
+ * attribute name is assumed to be the same as the local name. Given `<my-component
6687
+ * my-attr="hello {{name}}">` and the isolate scope definition `scope: { localName:'@myAttr' }`,
6688
+ * the directive's scope property `localName` will reflect the interpolated value of `hello
6689
+ * {{name}}`. As the `name` attribute changes so will the `localName` property on the directive's
6690
+ * scope. The `name` is read from the parent scope (not the directive's scope).
6691
+ *
6692
+ * * `=` or `=attr` - set up a bidirectional binding between a local scope property and an expression
6693
+ * passed via the attribute `attr`. The expression is evaluated in the context of the parent scope.
6694
+ * If no `attr` name is specified then the attribute name is assumed to be the same as the local
6695
+ * name. Given `<my-component my-attr="parentModel">` and the isolate scope definition `scope: {
6696
+ * localModel: '=myAttr' }`, the property `localModel` on the directive's scope will reflect the
6697
+ * value of `parentModel` on the parent scope. Changes to `parentModel` will be reflected in
6698
+ * `localModel` and vice versa. Optional attributes should be marked as such with a question mark:
6699
+ * `=?` or `=?attr`. If the binding expression is non-assignable, or if the attribute isn't
6700
+ * optional and doesn't exist, an exception ({@link error/$compile/nonassign `$compile:nonassign`})
6701
+ * will be thrown upon discovering changes to the local value, since it will be impossible to sync
6702
+ * them back to the parent scope. By default, the {@link ng.$rootScope.Scope#$watch `$watch`}
6703
+ * method is used for tracking changes, and the equality check is based on object identity.
6704
+ * However, if an object literal or an array literal is passed as the binding expression, the
6705
+ * equality check is done by value (using the {@link angular.equals} function). It's also possible
6706
+ * to watch the evaluated value shallowly with {@link ng.$rootScope.Scope#$watchCollection
6707
+ * `$watchCollection`}: use `=*` or `=*attr` (`=*?` or `=*?attr` if the attribute is optional).
6708
+ *
6709
+ * * `<` or `<attr` - set up a one-way (one-directional) binding between a local scope property and an
6710
+ * expression passed via the attribute `attr`. The expression is evaluated in the context of the
6711
+ * parent scope. If no `attr` name is specified then the attribute name is assumed to be the same as the
6712
+ * local name. You can also make the binding optional by adding `?`: `<?` or `<?attr`.
6713
+ *
6714
+ * For example, given `<my-component my-attr="parentModel">` and directive definition of
6715
+ * `scope: { localModel:'<myAttr' }`, then the isolated scope property `localModel` will reflect the
6623
6716
  * value of `parentModel` on the parent scope. Any changes to `parentModel` will be reflected
6624
- * in `localModel` and any changes in `localModel` will reflect in `parentModel`. If the parent
6625
- * scope property doesn't exist, it will throw a NON_ASSIGNABLE_MODEL_EXPRESSION exception. You
6626
- * can avoid this behavior using `=?` or `=?attr` in order to flag the property as optional. If
6627
- * you want to shallow watch for changes (i.e. $watchCollection instead of $watch) you can use
6628
- * `=*` or `=*attr` (`=*?` or `=*?attr` if the property is optional).
6629
- *
6630
- * * `&` or `&attr` - provides a way to execute an expression in the context of the parent scope.
6631
- * If no `attr` name is specified then the attribute name is assumed to be the same as the
6632
- * local name. Given `<widget my-attr="count = count + value">` and widget definition of
6633
- * `scope: { localFn:'&myAttr' }`, then isolate scope property `localFn` will point to
6634
- * a function wrapper for the `count = count + value` expression. Often it's desirable to
6635
- * pass data from the isolated scope via an expression to the parent scope, this can be
6636
- * done by passing a map of local variable names and values into the expression wrapper fn.
6637
- * For example, if the expression is `increment(amount)` then we can specify the amount value
6638
- * by calling the `localFn` as `localFn({amount: 22})`.
6717
+ * in `localModel`, but changes in `localModel` will not reflect in `parentModel`. There are however
6718
+ * two caveats:
6719
+ * 1. one-way binding does not copy the value from the parent to the isolate scope, it simply
6720
+ * sets the same value. That means if your bound value is an object, changes to its properties
6721
+ * in the isolated scope will be reflected in the parent scope (because both reference the same object).
6722
+ * 2. one-way binding watches changes to the **identity** of the parent value. That means the
6723
+ * {@link ng.$rootScope.Scope#$watch `$watch`} on the parent value only fires if the reference
6724
+ * to the value has changed. In most cases, this should not be of concern, but can be important
6725
+ * to know if you one-way bind to an object, and then replace that object in the isolated scope.
6726
+ * If you now change a property of the object in your parent scope, the change will not be
6727
+ * propagated to the isolated scope, because the identity of the object on the parent scope
6728
+ * has not changed. Instead you must assign a new object.
6729
+ *
6730
+ * One-way binding is useful if you do not plan to propagate changes to your isolated scope bindings
6731
+ * back to the parent. However, it does not make this completely impossible.
6732
+ *
6733
+ * * `&` or `&attr` - provides a way to execute an expression in the context of the parent scope. If
6734
+ * no `attr` name is specified then the attribute name is assumed to be the same as the local name.
6735
+ * Given `<my-component my-attr="count = count + value">` and the isolate scope definition `scope: {
6736
+ * localFn:'&myAttr' }`, the isolate scope property `localFn` will point to a function wrapper for
6737
+ * the `count = count + value` expression. Often it's desirable to pass data from the isolated scope
6738
+ * via an expression to the parent scope. This can be done by passing a map of local variable names
6739
+ * and values into the expression wrapper fn. For example, if the expression is `increment(amount)`
6740
+ * then we can specify the amount value by calling the `localFn` as `localFn({amount: 22})`.
6639
6741
  *
6640
6742
  * In general it's possible to apply more than one directive to one element, but there might be limitations
6641
6743
  * depending on the type of scope required by the directives. The following points will help explain these limitations.
@@ -6659,8 +6761,18 @@ function $TemplateCacheProvider() {
6659
6761
  * definition: `controller: 'myCtrl as myAlias'`.
6660
6762
  *
6661
6763
  * When an isolate scope is used for a directive (see above), `bindToController: true` will
6662
- * allow a component to have its properties bound to the controller, rather than to scope. When the controller
6663
- * is instantiated, the initial values of the isolate scope bindings are already available.
6764
+ * allow a component to have its properties bound to the controller, rather than to scope.
6765
+ *
6766
+ * After the controller is instantiated, the initial values of the isolate scope bindings will be bound to the controller
6767
+ * properties. You can access these bindings once they have been initialized by providing a controller method called
6768
+ * `$onInit`, which is called after all the controllers on an element have been constructed and had their bindings
6769
+ * initialized.
6770
+ *
6771
+ * <div class="alert alert-warning">
6772
+ * **Deprecation warning:** although bindings for non-ES6 class controllers are currently
6773
+ * bound to `this` before the controller constructor is called, this use is now deprecated. Please place initialization
6774
+ * code that relies upon bindings inside a `$onInit` method on the controller, instead.
6775
+ * </div>
6664
6776
  *
6665
6777
  * It is also possible to set `bindToController` to an object hash with the same format as the `scope` property.
6666
6778
  * This will set up the scope bindings to the controller directly. Note that `scope` can still be used
@@ -6680,10 +6792,10 @@ function $TemplateCacheProvider() {
6680
6792
  * * `$element` - Current element
6681
6793
  * * `$attrs` - Current attributes object for the element
6682
6794
  * * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope:
6683
- * `function([scope], cloneLinkingFn, futureParentElement)`.
6684
- * * `scope`: optional argument to override the scope.
6685
- * * `cloneLinkingFn`: optional argument to create clones of the original transcluded content.
6686
- * * `futureParentElement`:
6795
+ * `function([scope], cloneLinkingFn, futureParentElement, slotName)`:
6796
+ * * `scope`: (optional) override the scope.
6797
+ * * `cloneLinkingFn`: (optional) argument to create clones of the original transcluded content.
6798
+ * * `futureParentElement` (optional):
6687
6799
  * * defines the parent to which the `cloneLinkingFn` will add the cloned elements.
6688
6800
  * * default: `$element.parent()` resp. `$element` for `transclude:'element'` resp. `transclude:true`.
6689
6801
  * * only needed for transcludes that are allowed to contain non html elements (e.g. SVG elements)
@@ -6691,14 +6803,34 @@ function $TemplateCacheProvider() {
6691
6803
  * as those elements need to created and cloned in a special way when they are defined outside their
6692
6804
  * usual containers (e.g. like `<svg>`).
6693
6805
  * * See also the `directive.templateNamespace` property.
6806
+ * * `slotName`: (optional) the name of the slot to transclude. If falsy (e.g. `null`, `undefined` or `''`)
6807
+ * then the default translusion is provided.
6808
+ * The `$transclude` function also has a method on it, `$transclude.isSlotFilled(slotName)`, which returns
6809
+ * `true` if the specified slot contains content (i.e. one or more DOM nodes).
6694
6810
  *
6811
+ * The controller can provide the following methods that act as life-cycle hooks:
6812
+ * * `$onInit` - Called on each controller after all the controllers on an element have been constructed and
6813
+ * had their bindings initialized (and before the pre &amp; post linking functions for the directives on
6814
+ * this element). This is a good place to put initialization code for your controller.
6695
6815
  *
6696
6816
  * #### `require`
6697
6817
  * Require another directive and inject its controller as the fourth argument to the linking function. The
6698
- * `require` takes a string name (or array of strings) of the directive(s) to pass in. If an array is used, the
6699
- * injected argument will be an array in corresponding order. If no such directive can be
6700
- * found, or if the directive does not have a controller, then an error is raised (unless no link function
6701
- * is specified, in which case error checking is skipped). The name can be prefixed with:
6818
+ * `require` property can be a string, an array or an object:
6819
+ * * a **string** containing the name of the directive to pass to the linking function
6820
+ * * an **array** containing the names of directives to pass to the linking function. The argument passed to the
6821
+ * linking function will be an array of controllers in the same order as the names in the `require` property
6822
+ * * an **object** whose property values are the names of the directives to pass to the linking function. The argument
6823
+ * passed to the linking function will also be an object with matching keys, whose values will hold the corresponding
6824
+ * controllers.
6825
+ *
6826
+ * If the `require` property is an object and `bindToController` is truthy, then the required controllers are
6827
+ * bound to the controller using the keys of the `require` property. This binding occurs after all the controllers
6828
+ * have been constructed but before `$onInit` is called.
6829
+ * See the {@link $compileProvider#component} helper for an example of how this can be used.
6830
+ *
6831
+ * If no such required directive(s) can be found, or if the directive does not have a controller, then an error is
6832
+ * raised (unless no link function is specified and the required controllers are not being bound to the directive
6833
+ * controller, in which case error checking is skipped). The name can be prefixed with:
6702
6834
  *
6703
6835
  * * (no prefix) - Locate the required controller on the current element. Throw an error if not found.
6704
6836
  * * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found.
@@ -6791,14 +6923,6 @@ function $TemplateCacheProvider() {
6791
6923
  * The contents are compiled and provided to the directive as a **transclusion function**. See the
6792
6924
  * {@link $compile#transclusion Transclusion} section below.
6793
6925
  *
6794
- * There are two kinds of transclusion depending upon whether you want to transclude just the contents of the
6795
- * directive's element or the entire element:
6796
- *
6797
- * * `true` - transclude the content (i.e. the child nodes) of the directive's element.
6798
- * * `'element'` - transclude the whole of the directive's element including any directives on this
6799
- * element that defined at a lower priority than this directive. When used, the `template`
6800
- * property is ignored.
6801
- *
6802
6926
  *
6803
6927
  * #### `compile`
6804
6928
  *
@@ -6826,7 +6950,7 @@ function $TemplateCacheProvider() {
6826
6950
 
6827
6951
  * <div class="alert alert-warning">
6828
6952
  * **Note:** The compile function cannot handle directives that recursively use themselves in their
6829
- * own templates or compile functions. Compiling these directives results in an infinite loop and a
6953
+ * own templates or compile functions. Compiling these directives results in an infinite loop and
6830
6954
  * stack overflow errors.
6831
6955
  *
6832
6956
  * This can be avoided by manually using $compile in the postLink function to imperatively compile
@@ -6928,6 +7052,34 @@ function $TemplateCacheProvider() {
6928
7052
  * Testing Transclusion Directives}.
6929
7053
  * </div>
6930
7054
  *
7055
+ * There are three kinds of transclusion depending upon whether you want to transclude just the contents of the
7056
+ * directive's element, the entire element or multiple parts of the element contents:
7057
+ *
7058
+ * * `true` - transclude the content (i.e. the child nodes) of the directive's element.
7059
+ * * `'element'` - transclude the whole of the directive's element including any directives on this
7060
+ * element that defined at a lower priority than this directive. When used, the `template`
7061
+ * property is ignored.
7062
+ * * **`{...}` (an object hash):** - map elements of the content onto transclusion "slots" in the template.
7063
+ *
7064
+ * **Mult-slot transclusion** is declared by providing an object for the `transclude` property.
7065
+ *
7066
+ * This object is a map where the keys are the name of the slot to fill and the value is an element selector
7067
+ * used to match the HTML to the slot. The element selector should be in normalized form (e.g. `myElement`)
7068
+ * and will match the standard element variants (e.g. `my-element`, `my:element`, `data-my-element`, etc).
7069
+ *
7070
+ * For further information check out the guide on {@link guide/directive#matching-directives Matching Directives}
7071
+ *
7072
+ * If the element selector is prefixed with a `?` then that slot is optional.
7073
+ *
7074
+ * For example, the transclude object `{ slotA: '?myCustomElement' }` maps `<my-custom-element>` elements to
7075
+ * the `slotA` slot, which can be accessed via the `$transclude` function or via the {@link ngTransclude} directive.
7076
+ *
7077
+ * Slots that are not marked as optional (`?`) will trigger a compile time error if there are no matching elements
7078
+ * in the transclude content. If you wish to know if an optional slot was filled with content, then you can call
7079
+ * `$transclude.isSlotFilled(slotName)` on the transclude function passed to the directive's link function and
7080
+ * injectable into the directive's controller.
7081
+ *
7082
+ *
6931
7083
  * #### Transclusion Functions
6932
7084
  *
6933
7085
  * When a directive requests transclusion, the compiler extracts its contents and provides a **transclusion
@@ -6948,7 +7100,7 @@ function $TemplateCacheProvider() {
6948
7100
  * content and the `scope` is the newly created transclusion scope, to which the clone is bound.
6949
7101
  *
6950
7102
  * <div class="alert alert-info">
6951
- * **Best Practice**: Always provide a `cloneFn` (clone attach function) when you call a translude function
7103
+ * **Best Practice**: Always provide a `cloneFn` (clone attach function) when you call a transclude function
6952
7104
  * since you then get a fresh clone of the original DOM and also have access to the new transclusion scope.
6953
7105
  * </div>
6954
7106
  *
@@ -6980,7 +7132,7 @@ function $TemplateCacheProvider() {
6980
7132
  * </div>
6981
7133
  *
6982
7134
  * The built-in DOM manipulation directives, such as {@link ngIf}, {@link ngSwitch} and {@link ngRepeat}
6983
- * automatically destroy their transluded clones as necessary so you do not need to worry about this if
7135
+ * automatically destroy their transcluded clones as necessary so you do not need to worry about this if
6984
7136
  * you are simply using {@link ngTransclude} to inject the transclusion into your directive.
6985
7137
  *
6986
7138
  *
@@ -7025,10 +7177,9 @@ function $TemplateCacheProvider() {
7025
7177
  * The {@link ng.$compile.directive.Attributes Attributes} object - passed as a parameter in the
7026
7178
  * `link()` or `compile()` functions. It has a variety of uses.
7027
7179
  *
7028
- * accessing *Normalized attribute names:*
7029
- * Directives like 'ngBind' can be expressed in many ways: 'ng:bind', `data-ng-bind`, or 'x-ng-bind'.
7030
- * the attributes object allows for normalized access to
7031
- * the attributes.
7180
+ * * *Accessing normalized attribute names:* Directives like 'ngBind' can be expressed in many ways:
7181
+ * 'ng:bind', `data-ng-bind`, or 'x-ng-bind'. The attributes object allows for normalized access
7182
+ * to the attributes.
7032
7183
  *
7033
7184
  * * *Directive inter-communication:* All directives share the same instance of the attributes
7034
7185
  * object which allows the directives to use the attributes object as inter directive
@@ -7218,7 +7369,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7218
7369
  var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
7219
7370
 
7220
7371
  function parseIsolateBindings(scope, directiveName, isController) {
7221
- var LOCAL_REGEXP = /^\s*([@&]|=(\*?))(\??)\s*(\w*)\s*$/;
7372
+ var LOCAL_REGEXP = /^\s*([@&<]|=(\*?))(\??)\s*(\w*)\s*$/;
7222
7373
 
7223
7374
  var bindings = {};
7224
7375
 
@@ -7305,8 +7456,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7305
7456
  * @param {string|Object} name Name of the directive in camel-case (i.e. <code>ngBind</code> which
7306
7457
  * will match as <code>ng-bind</code>), or an object map of directives where the keys are the
7307
7458
  * names and the values are the factories.
7308
- * @param {Function|Array} directiveFactory An injectable directive factory function. See
7309
- * {@link guide/directive} for more info.
7459
+ * @param {Function|Array} directiveFactory An injectable directive factory function. See the
7460
+ * {@link guide/directive directive guide} and the {@link $compile compile API} for more info.
7310
7461
  * @returns {ng.$compileProvider} Self for chaining.
7311
7462
  */
7312
7463
  this.directive = function registerDirective(name, directiveFactory) {
@@ -7353,6 +7504,128 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7353
7504
  return this;
7354
7505
  };
7355
7506
 
7507
+ /**
7508
+ * @ngdoc method
7509
+ * @name $compileProvider#component
7510
+ * @module ng
7511
+ * @param {string} name Name of the component in camelCase (i.e. `myComp` which will match `<my-comp>`)
7512
+ * @param {Object} options Component definition object (a simplified
7513
+ * {@link ng.$compile#directive-definition-object directive definition object}),
7514
+ * with the following properties (all optional):
7515
+ *
7516
+ * - `controller` – `{(string|function()=}` – controller constructor function that should be
7517
+ * associated with newly created scope or the name of a {@link ng.$compile#-controller-
7518
+ * registered controller} if passed as a string. An empty `noop` function by default.
7519
+ * - `controllerAs` – `{string=}` – identifier name for to reference the controller in the component's scope.
7520
+ * If present, the controller will be published to scope under the `controllerAs` name.
7521
+ * If not present, this will default to be `$ctrl`.
7522
+ * - `template` – `{string=|function()=}` – html template as a string or a function that
7523
+ * returns an html template as a string which should be used as the contents of this component.
7524
+ * Empty string by default.
7525
+ *
7526
+ * If `template` is a function, then it is {@link auto.$injector#invoke injected} with
7527
+ * the following locals:
7528
+ *
7529
+ * - `$element` - Current element
7530
+ * - `$attrs` - Current attributes object for the element
7531
+ *
7532
+ * - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html
7533
+ * template that should be used as the contents of this component.
7534
+ *
7535
+ * If `templateUrl` is a function, then it is {@link auto.$injector#invoke injected} with
7536
+ * the following locals:
7537
+ *
7538
+ * - `$element` - Current element
7539
+ * - `$attrs` - Current attributes object for the element
7540
+ *
7541
+ * - `bindings` – `{object=}` – defines bindings between DOM attributes and component properties.
7542
+ * Component properties are always bound to the component controller and not to the scope.
7543
+ * See {@link ng.$compile#-bindtocontroller- `bindToController`}.
7544
+ * - `transclude` – `{boolean=}` – whether {@link $compile#transclusion content transclusion} is enabled.
7545
+ * Disabled by default.
7546
+ * - `$...` – `{function()=}` – additional annotations to provide to the directive factory function.
7547
+ *
7548
+ * @returns {ng.$compileProvider} the compile provider itself, for chaining of function calls.
7549
+ * @description
7550
+ * Register a **component definition** with the compiler. This is a shorthand for registering a special
7551
+ * type of directive, which represents a self-contained UI component in your application. Such components
7552
+ * are always isolated (i.e. `scope: {}`) and are always restricted to elements (i.e. `restrict: 'E'`).
7553
+ *
7554
+ * Component definitions are very simple and do not require as much configuration as defining general
7555
+ * directives. Component definitions usually consist only of a template and a controller backing it.
7556
+ *
7557
+ * In order to make the definition easier, components enforce best practices like use of `controllerAs`,
7558
+ * `bindToController`. They always have **isolate scope** and are restricted to elements.
7559
+ *
7560
+ * Here are a few examples of how you would usually define components:
7561
+ *
7562
+ * ```js
7563
+ * var myMod = angular.module(...);
7564
+ * myMod.component('myComp', {
7565
+ * template: '<div>My name is {{$ctrl.name}}</div>',
7566
+ * controller: function() {
7567
+ * this.name = 'shahar';
7568
+ * }
7569
+ * });
7570
+ *
7571
+ * myMod.component('myComp', {
7572
+ * template: '<div>My name is {{$ctrl.name}}</div>',
7573
+ * bindings: {name: '@'}
7574
+ * });
7575
+ *
7576
+ * myMod.component('myComp', {
7577
+ * templateUrl: 'views/my-comp.html',
7578
+ * controller: 'MyCtrl as ctrl',
7579
+ * bindings: {name: '@'}
7580
+ * });
7581
+ *
7582
+ * ```
7583
+ * For more examples, and an in-depth guide, see the {@link guide/component component guide}.
7584
+ *
7585
+ * <br />
7586
+ * See also {@link ng.$compileProvider#directive $compileProvider.directive()}.
7587
+ */
7588
+ this.component = function registerComponent(name, options) {
7589
+ var controller = options.controller || function() {};
7590
+
7591
+ function factory($injector) {
7592
+ function makeInjectable(fn) {
7593
+ if (isFunction(fn) || isArray(fn)) {
7594
+ return function(tElement, tAttrs) {
7595
+ return $injector.invoke(fn, this, {$element: tElement, $attrs: tAttrs});
7596
+ };
7597
+ } else {
7598
+ return fn;
7599
+ }
7600
+ }
7601
+
7602
+ var template = (!options.template && !options.templateUrl ? '' : options.template);
7603
+ return {
7604
+ controller: controller,
7605
+ controllerAs: identifierForController(options.controller) || options.controllerAs || '$ctrl',
7606
+ template: makeInjectable(template),
7607
+ templateUrl: makeInjectable(options.templateUrl),
7608
+ transclude: options.transclude,
7609
+ scope: {},
7610
+ bindToController: options.bindings || {},
7611
+ restrict: 'E',
7612
+ require: options.require
7613
+ };
7614
+ }
7615
+
7616
+ // Copy any annotation properties (starting with $) over to the factory function
7617
+ // These could be used by libraries such as the new component router
7618
+ forEach(options, function(val, key) {
7619
+ if (key.charAt(0) === '$') {
7620
+ factory[key] = val;
7621
+ }
7622
+ });
7623
+
7624
+ factory.$inject = ['$injector'];
7625
+
7626
+ return this.directive(name, factory);
7627
+ };
7628
+
7356
7629
 
7357
7630
  /**
7358
7631
  * @ngdoc method
@@ -7450,6 +7723,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7450
7723
  function($injector, $interpolate, $exceptionHandler, $templateRequest, $parse,
7451
7724
  $controller, $rootScope, $sce, $animate, $$sanitizeUri) {
7452
7725
 
7726
+ var SIMPLE_ATTR_NAME = /^\w/;
7727
+ var specialAttrHolder = document.createElement('div');
7453
7728
  var Attributes = function(element, attributesToCopy) {
7454
7729
  if (attributesToCopy) {
7455
7730
  var keys = Object.keys(attributesToCopy);
@@ -7585,7 +7860,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7585
7860
 
7586
7861
  nodeName = nodeName_(this.$$element);
7587
7862
 
7588
- if ((nodeName === 'a' && key === 'href') ||
7863
+ if ((nodeName === 'a' && (key === 'href' || key === 'xlinkHref')) ||
7589
7864
  (nodeName === 'img' && key === 'src')) {
7590
7865
  // sanitize a[href] and img[src] values
7591
7866
  this[key] = value = $$sanitizeUri(value, key === 'src');
@@ -7629,7 +7904,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7629
7904
  if (value === null || isUndefined(value)) {
7630
7905
  this.$$element.removeAttr(attrName);
7631
7906
  } else {
7632
- this.$$element.attr(attrName, value);
7907
+ if (SIMPLE_ATTR_NAME.test(attrName)) {
7908
+ this.$$element.attr(attrName, value);
7909
+ } else {
7910
+ setSpecialAttr(this.$$element[0], attrName, value);
7911
+ }
7633
7912
  }
7634
7913
  }
7635
7914
 
@@ -7683,6 +7962,18 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7683
7962
  }
7684
7963
  };
7685
7964
 
7965
+ function setSpecialAttr(element, attrName, value) {
7966
+ // Attributes names that do not start with letters (such as `(click)`) cannot be set using `setAttribute`
7967
+ // so we have to jump through some hoops to get such an attribute
7968
+ // https://github.com/angular/angular.js/pull/13318
7969
+ specialAttrHolder.innerHTML = "<span " + attrName + ">";
7970
+ var attributes = specialAttrHolder.firstChild.attributes;
7971
+ var attribute = attributes[0];
7972
+ // We have to remove the attribute from its container element before we can add it to the destination element
7973
+ attributes.removeNamedItem(attribute.name);
7974
+ attribute.value = value;
7975
+ element.attributes.setNamedItem(attribute);
7976
+ }
7686
7977
 
7687
7978
  function safeAddClass($element, className) {
7688
7979
  try {
@@ -7696,7 +7987,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7696
7987
 
7697
7988
  var startSymbol = $interpolate.startSymbol(),
7698
7989
  endSymbol = $interpolate.endSymbol(),
7699
- denormalizeTemplate = (startSymbol == '{{' || endSymbol == '}}')
7990
+ denormalizeTemplate = (startSymbol == '{{' && endSymbol == '}}')
7700
7991
  ? identity
7701
7992
  : function denormalizeTemplate(template) {
7702
7993
  return template.replace(/\{\{/g, startSymbol).replace(/}}/g, endSymbol);
@@ -7740,13 +8031,19 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7740
8031
  // modify it.
7741
8032
  $compileNodes = jqLite($compileNodes);
7742
8033
  }
8034
+
8035
+ var NOT_EMPTY = /\S+/;
8036
+
7743
8037
  // We can not compile top level text elements since text nodes can be merged and we will
7744
8038
  // not be able to attach scope data to them, so we will wrap them in <span>
7745
- forEach($compileNodes, function(node, index) {
7746
- if (node.nodeType == NODE_TYPE_TEXT && node.nodeValue.match(/\S+/) /* non-empty */ ) {
7747
- $compileNodes[index] = jqLite(node).wrap('<span></span>').parent()[0];
8039
+ for (var i = 0, len = $compileNodes.length; i < len; i++) {
8040
+ var domNode = $compileNodes[i];
8041
+
8042
+ if (domNode.nodeType === NODE_TYPE_TEXT && domNode.nodeValue.match(NOT_EMPTY) /* non-empty */) {
8043
+ jqLiteWrapNode(domNode, $compileNodes[i] = document.createElement('span'));
7748
8044
  }
7749
- });
8045
+ }
8046
+
7750
8047
  var compositeLinkFn =
7751
8048
  compileNodes($compileNodes, transcludeFn, $compileNodes,
7752
8049
  maxPriority, ignoreDirective, previousCompileContext);
@@ -7817,7 +8114,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7817
8114
  if (!node) {
7818
8115
  return 'html';
7819
8116
  } else {
7820
- return nodeName_(node) !== 'foreignobject' && node.toString().match(/SVG/) ? 'svg' : 'html';
8117
+ return nodeName_(node) !== 'foreignobject' && toString.call(node).match(/SVG/) ? 'svg' : 'html';
7821
8118
  }
7822
8119
  }
7823
8120
 
@@ -7951,6 +8248,17 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
7951
8248
  });
7952
8249
  };
7953
8250
 
8251
+ // We need to attach the transclusion slots onto the `boundTranscludeFn`
8252
+ // so that they are available inside the `controllersBoundTransclude` function
8253
+ var boundSlots = boundTranscludeFn.$$slots = createMap();
8254
+ for (var slotName in transcludeFn.$$slots) {
8255
+ if (transcludeFn.$$slots[slotName]) {
8256
+ boundSlots[slotName] = createBoundTranscludeFn(scope, transcludeFn.$$slots[slotName], previousBoundTranscludeFn);
8257
+ } else {
8258
+ boundSlots[slotName] = null;
8259
+ }
8260
+ }
8261
+
7954
8262
  return boundTranscludeFn;
7955
8263
  }
7956
8264
 
@@ -8109,6 +8417,37 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
8109
8417
  };
8110
8418
  }
8111
8419
 
8420
+ /**
8421
+ * A function generator that is used to support both eager and lazy compilation
8422
+ * linking function.
8423
+ * @param eager
8424
+ * @param $compileNodes
8425
+ * @param transcludeFn
8426
+ * @param maxPriority
8427
+ * @param ignoreDirective
8428
+ * @param previousCompileContext
8429
+ * @returns {Function}
8430
+ */
8431
+ function compilationGenerator(eager, $compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext) {
8432
+ if (eager) {
8433
+ return compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);
8434
+ }
8435
+
8436
+ var compiled;
8437
+
8438
+ return function() {
8439
+ if (!compiled) {
8440
+ compiled = compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);
8441
+
8442
+ // Null out all of these references in order to make them eligible for garbage collection
8443
+ // since this is a potentially long lived closure
8444
+ $compileNodes = transcludeFn = previousCompileContext = null;
8445
+ }
8446
+
8447
+ return compiled.apply(this, arguments);
8448
+ };
8449
+ }
8450
+
8112
8451
  /**
8113
8452
  * Once the directives have been collected, their compile functions are executed. This method
8114
8453
  * is responsible for inlining directive templates as well as terminating the application
@@ -8153,6 +8492,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
8153
8492
  replaceDirective = originalReplaceDirective,
8154
8493
  childTranscludeFn = transcludeFn,
8155
8494
  linkFn,
8495
+ didScanForMultipleTransclusion = false,
8496
+ mightHaveMultipleTransclusionError = false,
8156
8497
  directiveValue;
8157
8498
 
8158
8499
  // executes all directives on the current element
@@ -8195,6 +8536,27 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
8195
8536
 
8196
8537
  directiveName = directive.name;
8197
8538
 
8539
+ // If we encounter a condition that can result in transclusion on the directive,
8540
+ // then scan ahead in the remaining directives for others that may cause a multiple
8541
+ // transclusion error to be thrown during the compilation process. If a matching directive
8542
+ // is found, then we know that when we encounter a transcluded directive, we need to eagerly
8543
+ // compile the `transclude` function rather than doing it lazily in order to throw
8544
+ // exceptions at the correct time
8545
+ if (!didScanForMultipleTransclusion && ((directive.replace && (directive.templateUrl || directive.template))
8546
+ || (directive.transclude && !directive.$$tlb))) {
8547
+ var candidateDirective;
8548
+
8549
+ for (var scanningIndex = i + 1; candidateDirective = directives[scanningIndex++];) {
8550
+ if ((candidateDirective.transclude && !candidateDirective.$$tlb)
8551
+ || (candidateDirective.replace && (candidateDirective.templateUrl || candidateDirective.template))) {
8552
+ mightHaveMultipleTransclusionError = true;
8553
+ break;
8554
+ }
8555
+ }
8556
+
8557
+ didScanForMultipleTransclusion = true;
8558
+ }
8559
+
8198
8560
  if (!directive.templateUrl && directive.controller) {
8199
8561
  directiveValue = directive.controller;
8200
8562
  controllerDirectives = controllerDirectives || createMap();
@@ -8224,7 +8586,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
8224
8586
  compileNode = $compileNode[0];
8225
8587
  replaceWith(jqCollection, sliceArgs($template), compileNode);
8226
8588
 
8227
- childTranscludeFn = compile($template, transcludeFn, terminalPriority,
8589
+ childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn, terminalPriority,
8228
8590
  replaceDirective && replaceDirective.name, {
8229
8591
  // Don't pass in:
8230
8592
  // - controllerDirectives - otherwise we'll create duplicates controllers
@@ -8236,10 +8598,69 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
8236
8598
  nonTlbTranscludeDirective: nonTlbTranscludeDirective
8237
8599
  });
8238
8600
  } else {
8601
+
8602
+ var slots = createMap();
8603
+
8239
8604
  $template = jqLite(jqLiteClone(compileNode)).contents();
8605
+
8606
+ if (isObject(directiveValue)) {
8607
+
8608
+ // We have transclusion slots,
8609
+ // collect them up, compile them and store their transclusion functions
8610
+ $template = [];
8611
+
8612
+ var slotMap = createMap();
8613
+ var filledSlots = createMap();
8614
+
8615
+ // Parse the element selectors
8616
+ forEach(directiveValue, function(elementSelector, slotName) {
8617
+ // If an element selector starts with a ? then it is optional
8618
+ var optional = (elementSelector.charAt(0) === '?');
8619
+ elementSelector = optional ? elementSelector.substring(1) : elementSelector;
8620
+
8621
+ slotMap[elementSelector] = slotName;
8622
+
8623
+ // We explicitly assign `null` since this implies that a slot was defined but not filled.
8624
+ // Later when calling boundTransclusion functions with a slot name we only error if the
8625
+ // slot is `undefined`
8626
+ slots[slotName] = null;
8627
+
8628
+ // filledSlots contains `true` for all slots that are either optional or have been
8629
+ // filled. This is used to check that we have not missed any required slots
8630
+ filledSlots[slotName] = optional;
8631
+ });
8632
+
8633
+ // Add the matching elements into their slot
8634
+ forEach($compileNode.contents(), function(node) {
8635
+ var slotName = slotMap[directiveNormalize(nodeName_(node))];
8636
+ if (slotName) {
8637
+ filledSlots[slotName] = true;
8638
+ slots[slotName] = slots[slotName] || [];
8639
+ slots[slotName].push(node);
8640
+ } else {
8641
+ $template.push(node);
8642
+ }
8643
+ });
8644
+
8645
+ // Check for required slots that were not filled
8646
+ forEach(filledSlots, function(filled, slotName) {
8647
+ if (!filled) {
8648
+ throw $compileMinErr('reqslot', 'Required transclusion slot `{0}` was not filled.', slotName);
8649
+ }
8650
+ });
8651
+
8652
+ for (var slotName in slots) {
8653
+ if (slots[slotName]) {
8654
+ // Only define a transclusion function if the slot was filled
8655
+ slots[slotName] = compilationGenerator(mightHaveMultipleTransclusionError, slots[slotName], transcludeFn);
8656
+ }
8657
+ }
8658
+ }
8659
+
8240
8660
  $compileNode.empty(); // clear contents
8241
- childTranscludeFn = compile($template, transcludeFn, undefined,
8661
+ childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn, undefined,
8242
8662
  undefined, { needsNewScope: directive.$$isolateScope || directive.$$newScope});
8663
+ childTranscludeFn.$$slots = slots;
8243
8664
  }
8244
8665
  }
8245
8666
 
@@ -8402,6 +8823,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
8402
8823
  for (var i = 0, ii = require.length; i < ii; i++) {
8403
8824
  value[i] = getControllers(directiveName, require[i], $element, elementControllers);
8404
8825
  }
8826
+ } else if (isObject(require)) {
8827
+ value = {};
8828
+ forEach(require, function(controller, property) {
8829
+ value[property] = getControllers(directiveName, controller, $element, elementControllers);
8830
+ });
8405
8831
  }
8406
8832
 
8407
8833
  return value || null;
@@ -8439,7 +8865,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
8439
8865
  }
8440
8866
 
8441
8867
  function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {
8442
- var linkFn, isolateScope, controllerScope, elementControllers, transcludeFn, $element,
8868
+ var i, ii, linkFn, isolateScope, controllerScope, elementControllers, transcludeFn, $element,
8443
8869
  attrs, removeScopeBindingWatches, removeControllerBindingWatches;
8444
8870
 
8445
8871
  if (compileNode === linkNode) {
@@ -8462,6 +8888,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
8462
8888
  // is later passed as `parentBoundTranscludeFn` to `publicLinkFn`
8463
8889
  transcludeFn = controllersBoundTransclude;
8464
8890
  transcludeFn.$$boundTransclude = boundTranscludeFn;
8891
+ // expose the slots on the `$transclude` function
8892
+ transcludeFn.isSlotFilled = function(slotName) {
8893
+ return !!boundTranscludeFn.$$slots[slotName];
8894
+ };
8465
8895
  }
8466
8896
 
8467
8897
  if (controllerDirectives) {
@@ -8506,6 +8936,21 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
8506
8936
  }
8507
8937
  }
8508
8938
 
8939
+ // Bind the required controllers to the controller, if `require` is an object and `bindToController` is truthy
8940
+ forEach(controllerDirectives, function(controllerDirective, name) {
8941
+ var require = controllerDirective.require;
8942
+ if (controllerDirective.bindToController && !isArray(require) && isObject(require)) {
8943
+ extend(elementControllers[name].instance, getControllers(name, require, $element, elementControllers));
8944
+ }
8945
+ });
8946
+
8947
+ // Trigger the `$onInit` method on all controllers that have one
8948
+ forEach(elementControllers, function(controller) {
8949
+ if (isFunction(controller.instance.$onInit)) {
8950
+ controller.instance.$onInit();
8951
+ }
8952
+ });
8953
+
8509
8954
  // PRELINKING
8510
8955
  for (i = 0, ii = preLinkFns.length; i < ii; i++) {
8511
8956
  linkFn = preLinkFns[i];
@@ -8541,11 +8986,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
8541
8986
 
8542
8987
  // This is the function that is injected as `$transclude`.
8543
8988
  // Note: all arguments are optional!
8544
- function controllersBoundTransclude(scope, cloneAttachFn, futureParentElement) {
8989
+ function controllersBoundTransclude(scope, cloneAttachFn, futureParentElement, slotName) {
8545
8990
  var transcludeControllers;
8546
-
8547
8991
  // No scope passed in:
8548
8992
  if (!isScope(scope)) {
8993
+ slotName = futureParentElement;
8549
8994
  futureParentElement = cloneAttachFn;
8550
8995
  cloneAttachFn = scope;
8551
8996
  scope = undefined;
@@ -8557,7 +9002,23 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
8557
9002
  if (!futureParentElement) {
8558
9003
  futureParentElement = hasElementTranscludeDirective ? $element.parent() : $element;
8559
9004
  }
8560
- return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);
9005
+ if (slotName) {
9006
+ // slotTranscludeFn can be one of three things:
9007
+ // * a transclude function - a filled slot
9008
+ // * `null` - an optional slot that was not filled
9009
+ // * `undefined` - a slot that was not declared (i.e. invalid)
9010
+ var slotTranscludeFn = boundTranscludeFn.$$slots[slotName];
9011
+ if (slotTranscludeFn) {
9012
+ return slotTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);
9013
+ } else if (isUndefined(slotTranscludeFn)) {
9014
+ throw $compileMinErr('noslot',
9015
+ 'No parent directive that requires a transclusion with slot name "{0}". ' +
9016
+ 'Element: {1}',
9017
+ slotName, startingTag($element));
9018
+ }
9019
+ } else {
9020
+ return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);
9021
+ }
8561
9022
  }
8562
9023
  }
8563
9024
  }
@@ -8989,9 +9450,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
8989
9450
  parent.replaceChild(newNode, firstElementToRemove);
8990
9451
  }
8991
9452
 
8992
- // TODO(perf): what's this document fragment for? is it needed? can we at least reuse it?
9453
+ // Append all the `elementsToRemove` to a fragment. This will...
9454
+ // - remove them from the DOM
9455
+ // - allow them to still be traversed with .nextSibling
9456
+ // - allow a single fragment.qSA to fetch all elements being removed
8993
9457
  var fragment = document.createDocumentFragment();
8994
- fragment.appendChild(firstElementToRemove);
9458
+ for (i = 0; i < removeCount; i++) {
9459
+ fragment.appendChild(elementsToRemove[i]);
9460
+ }
8995
9461
 
8996
9462
  if (jqLite.hasData(firstElementToRemove)) {
8997
9463
  // Copy over user data (that includes Angular's $scope etc.). Don't copy private
@@ -8999,31 +9465,18 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
8999
9465
  // event listeners (which is the main use of private data) wouldn't work anyway.
9000
9466
  jqLite.data(newNode, jqLite.data(firstElementToRemove));
9001
9467
 
9002
- // Remove data of the replaced element. We cannot just call .remove()
9003
- // on the element it since that would deallocate scope that is needed
9004
- // for the new node. Instead, remove the data "manually".
9005
- if (!jQuery) {
9006
- delete jqLite.cache[firstElementToRemove[jqLite.expando]];
9007
- } else {
9008
- // jQuery 2.x doesn't expose the data storage. Use jQuery.cleanData to clean up after
9009
- // the replaced element. The cleanData version monkey-patched by Angular would cause
9010
- // the scope to be trashed and we do need the very same scope to work with the new
9011
- // element. However, we cannot just cache the non-patched version and use it here as
9012
- // that would break if another library patches the method after Angular does (one
9013
- // example is jQuery UI). Instead, set a flag indicating scope destroying should be
9014
- // skipped this one time.
9015
- skipDestroyOnNextJQueryCleanData = true;
9016
- jQuery.cleanData([firstElementToRemove]);
9017
- }
9468
+ // Remove $destroy event listeners from `firstElementToRemove`
9469
+ jqLite(firstElementToRemove).off('$destroy');
9018
9470
  }
9019
9471
 
9020
- for (var k = 1, kk = elementsToRemove.length; k < kk; k++) {
9021
- var element = elementsToRemove[k];
9022
- jqLite(element).remove(); // must do this way to clean up expando
9023
- fragment.appendChild(element);
9024
- delete elementsToRemove[k];
9025
- }
9472
+ // Cleanup any data/listeners on the elements and children.
9473
+ // This includes invoking the $destroy event on any elements with listeners.
9474
+ jqLite.cleanData(fragment.querySelectorAll('*'));
9026
9475
 
9476
+ // Update the jqLite collection to only contain the `newNode`
9477
+ for (i = 1; i < removeCount; i++) {
9478
+ delete elementsToRemove[i];
9479
+ }
9027
9480
  elementsToRemove[0] = newNode;
9028
9481
  elementsToRemove.length = 1;
9029
9482
  }
@@ -9052,7 +9505,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
9052
9505
  optional = definition.optional,
9053
9506
  mode = definition.mode, // @, =, or &
9054
9507
  lastValue,
9055
- parentGet, parentSet, compare;
9508
+ parentGet, parentSet, compare, removeWatch;
9056
9509
 
9057
9510
  switch (mode) {
9058
9511
 
@@ -9066,10 +9519,15 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
9066
9519
  }
9067
9520
  });
9068
9521
  attrs.$$observers[attrName].$$scope = scope;
9069
- if (isString(attrs[attrName])) {
9522
+ lastValue = attrs[attrName];
9523
+ if (isString(lastValue)) {
9070
9524
  // If the attribute has been provided then we trigger an interpolation to ensure
9071
9525
  // the value is there for use in the link fn
9072
- destination[scopeName] = $interpolate(attrs[attrName])(scope);
9526
+ destination[scopeName] = $interpolate(lastValue)(scope);
9527
+ } else if (isBoolean(lastValue)) {
9528
+ // If the attributes is one of the BOOLEAN_ATTR then Angular will have converted
9529
+ // the value to boolean rather than a string, so we special case this situation
9530
+ destination[scopeName] = lastValue;
9073
9531
  }
9074
9532
  break;
9075
9533
 
@@ -9090,8 +9548,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
9090
9548
  // reset the change, or we will throw this exception on every $digest
9091
9549
  lastValue = destination[scopeName] = parentGet(scope);
9092
9550
  throw $compileMinErr('nonassign',
9093
- "Expression '{0}' used with directive '{1}' is non-assignable!",
9094
- attrs[attrName], directive.name);
9551
+ "Expression '{0}' in attribute '{1}' used with directive '{2}' is non-assignable!",
9552
+ attrs[attrName], attrName, directive.name);
9095
9553
  };
9096
9554
  lastValue = destination[scopeName] = parentGet(scope);
9097
9555
  var parentValueWatch = function parentValueWatch(parentValue) {
@@ -9108,7 +9566,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
9108
9566
  return lastValue = parentValue;
9109
9567
  };
9110
9568
  parentValueWatch.$stateful = true;
9111
- var removeWatch;
9112
9569
  if (definition.collection) {
9113
9570
  removeWatch = scope.$watchCollection(attrs[attrName], parentValueWatch);
9114
9571
  } else {
@@ -9117,6 +9574,24 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
9117
9574
  removeWatchCollection.push(removeWatch);
9118
9575
  break;
9119
9576
 
9577
+ case '<':
9578
+ if (!hasOwnProperty.call(attrs, attrName)) {
9579
+ if (optional) break;
9580
+ attrs[attrName] = void 0;
9581
+ }
9582
+ if (optional && !attrs[attrName]) break;
9583
+
9584
+ parentGet = $parse(attrs[attrName]);
9585
+
9586
+ destination[scopeName] = parentGet(scope);
9587
+
9588
+ removeWatch = scope.$watch(parentGet, function parentValueWatchAction(newParentValue) {
9589
+ destination[scopeName] = newParentValue;
9590
+ }, parentGet.literal);
9591
+
9592
+ removeWatchCollection.push(removeWatch);
9593
+ break;
9594
+
9120
9595
  case '&':
9121
9596
  // Don't assign Object.prototype method to scope
9122
9597
  parentGet = attrs.hasOwnProperty(attrName) ? $parse(attrs[attrName]) : noop;
@@ -10036,7 +10511,7 @@ function $HttpProvider() {
10036
10511
  *
10037
10512
  * ```
10038
10513
  * module.run(function($http) {
10039
- * $http.defaults.headers.common.Authorization = 'Basic YmVlcDpib29w'
10514
+ * $http.defaults.headers.common.Authorization = 'Basic YmVlcDpib29w';
10040
10515
  * });
10041
10516
  * ```
10042
10517
  *
@@ -10264,13 +10739,13 @@ function $HttpProvider() {
10264
10739
  *
10265
10740
  * ### Cross Site Request Forgery (XSRF) Protection
10266
10741
  *
10267
- * [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery) is a technique by which
10268
- * an unauthorized site can gain your user's private data. Angular provides a mechanism
10269
- * to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie
10270
- * (by default, `XSRF-TOKEN`) and sets it as an HTTP header (`X-XSRF-TOKEN`). Since only
10271
- * JavaScript that runs on your domain could read the cookie, your server can be assured that
10272
- * the XHR came from JavaScript running on your domain. The header will not be set for
10273
- * cross-domain requests.
10742
+ * [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery) is an attack technique by
10743
+ * which the attacker can trick an authenticated user into unknowingly executing actions on your
10744
+ * website. Angular provides a mechanism to counter XSRF. When performing XHR requests, the
10745
+ * $http service reads a token from a cookie (by default, `XSRF-TOKEN`) and sets it as an HTTP
10746
+ * header (`X-XSRF-TOKEN`). Since only JavaScript that runs on your domain could read the
10747
+ * cookie, your server can be assured that the XHR came from JavaScript running on your domain.
10748
+ * The header will not be set for cross-domain requests.
10274
10749
  *
10275
10750
  * To take advantage of this, your server needs to set a token in a JavaScript readable session
10276
10751
  * cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the
@@ -10429,7 +10904,7 @@ function $HttpProvider() {
10429
10904
  */
10430
10905
  function $http(requestConfig) {
10431
10906
 
10432
- if (!angular.isObject(requestConfig)) {
10907
+ if (!isObject(requestConfig)) {
10433
10908
  throw minErr('$http')('badreq', 'Http request configuration must be an object. Received: {0}', requestConfig);
10434
10909
  }
10435
10910
 
@@ -10549,7 +11024,7 @@ function $HttpProvider() {
10549
11024
 
10550
11025
  defHeaders = extend({}, defHeaders.common, defHeaders[lowercase(config.method)]);
10551
11026
 
10552
- // using for-in instead of forEach to avoid unecessary iteration after header has been found
11027
+ // using for-in instead of forEach to avoid unnecessary iteration after header has been found
10553
11028
  defaultHeadersIteration:
10554
11029
  for (defHeaderName in defHeaders) {
10555
11030
  lowercaseDefHeaderName = lowercase(defHeaderName);
@@ -11048,6 +11523,14 @@ $interpolateMinErr.interr = function(text, err) {
11048
11523
  *
11049
11524
  * Used for configuring the interpolation markup. Defaults to `{{` and `}}`.
11050
11525
  *
11526
+ * <div class="alert alert-danger">
11527
+ * This feature is sometimes used to mix different markup languages, e.g. to wrap an Angular
11528
+ * template within a Python Jinja template (or any other template language). Mixing templating
11529
+ * languages is **very dangerous**. The embedding template language will not safely escape Angular
11530
+ * expressions, so any user-controlled values in the template will cause Cross Site Scripting (XSS)
11531
+ * security bugs!
11532
+ * </div>
11533
+ *
11051
11534
  * @example
11052
11535
  <example name="custom-interpolation-markup" module="customInterpolationApp">
11053
11536
  <file name="index.html">
@@ -11148,6 +11631,15 @@ function $InterpolateProvider() {
11148
11631
  return value;
11149
11632
  }
11150
11633
 
11634
+ //TODO: this is the same as the constantWatchDelegate in parse.js
11635
+ function constantWatchDelegate(scope, listener, objectEquality, constantInterp) {
11636
+ var unwatch;
11637
+ return unwatch = scope.$watch(function constantInterpolateWatch(scope) {
11638
+ unwatch();
11639
+ return constantInterp(scope);
11640
+ }, listener, objectEquality);
11641
+ }
11642
+
11151
11643
  /**
11152
11644
  * @ngdoc service
11153
11645
  * @name $interpolate
@@ -11243,6 +11735,19 @@ function $InterpolateProvider() {
11243
11735
  * - `context`: evaluation context for all expressions embedded in the interpolated text
11244
11736
  */
11245
11737
  function $interpolate(text, mustHaveExpression, trustedContext, allOrNothing) {
11738
+ // Provide a quick exit and simplified result function for text with no interpolation
11739
+ if (!text.length || text.indexOf(startSymbol) === -1) {
11740
+ var constantInterp;
11741
+ if (!mustHaveExpression) {
11742
+ var unescapedText = unescapeText(text);
11743
+ constantInterp = valueFn(unescapedText);
11744
+ constantInterp.exp = text;
11745
+ constantInterp.expressions = [];
11746
+ constantInterp.$$watchDelegate = constantWatchDelegate;
11747
+ }
11748
+ return constantInterp;
11749
+ }
11750
+
11246
11751
  allOrNothing = !!allOrNothing;
11247
11752
  var startIndex,
11248
11753
  endIndex,
@@ -11379,8 +11884,8 @@ function $InterpolateProvider() {
11379
11884
  }
11380
11885
 
11381
11886
  function $IntervalProvider() {
11382
- this.$get = ['$rootScope', '$window', '$q', '$$q',
11383
- function($rootScope, $window, $q, $$q) {
11887
+ this.$get = ['$rootScope', '$window', '$q', '$$q', '$browser',
11888
+ function($rootScope, $window, $q, $$q, $browser) {
11384
11889
  var intervals = {};
11385
11890
 
11386
11891
 
@@ -11521,11 +12026,12 @@ function $IntervalProvider() {
11521
12026
 
11522
12027
  count = isDefined(count) ? count : 0;
11523
12028
 
11524
- promise.then(null, null, (!hasParams) ? fn : function() {
11525
- fn.apply(null, args);
11526
- });
11527
-
11528
12029
  promise.$$intervalId = setInterval(function tick() {
12030
+ if (skipApply) {
12031
+ $browser.defer(callback);
12032
+ } else {
12033
+ $rootScope.$evalAsync(callback);
12034
+ }
11529
12035
  deferred.notify(iteration++);
11530
12036
 
11531
12037
  if (count > 0 && iteration >= count) {
@@ -11541,6 +12047,14 @@ function $IntervalProvider() {
11541
12047
  intervals[promise.$$intervalId] = deferred;
11542
12048
 
11543
12049
  return promise;
12050
+
12051
+ function callback() {
12052
+ if (!hasParams) {
12053
+ fn(iteration);
12054
+ } else {
12055
+ fn.apply(null, args);
12056
+ }
12057
+ }
11544
12058
  }
11545
12059
 
11546
12060
 
@@ -12780,23 +13294,22 @@ function ensureSafeMemberName(name, fullExpression) {
12780
13294
  return name;
12781
13295
  }
12782
13296
 
12783
- function getStringValue(name, fullExpression) {
12784
- // From the JavaScript docs:
13297
+ function getStringValue(name) {
12785
13298
  // Property names must be strings. This means that non-string objects cannot be used
12786
13299
  // as keys in an object. Any non-string object, including a number, is typecasted
12787
13300
  // into a string via the toString method.
13301
+ // -- MDN, https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Property_accessors#Property_names
12788
13302
  //
12789
- // So, to ensure that we are checking the same `name` that JavaScript would use,
12790
- // we cast it to a string, if possible.
12791
- // Doing `name + ''` can cause a repl error if the result to `toString` is not a string,
12792
- // this is, this will handle objects that misbehave.
12793
- name = name + '';
12794
- if (!isString(name)) {
12795
- throw $parseMinErr('iseccst',
12796
- 'Cannot convert object to primitive value! '
12797
- + 'Expression: {0}', fullExpression);
12798
- }
12799
- return name;
13303
+ // So, to ensure that we are checking the same `name` that JavaScript would use, we cast it
13304
+ // to a string. It's not always possible. If `name` is an object and its `toString` method is
13305
+ // 'broken' (doesn't return a string, isn't a function, etc.), an error will be thrown:
13306
+ //
13307
+ // TypeError: Cannot convert object to primitive value
13308
+ //
13309
+ // For performance reasons, we don't catch this error here and allow it to propagate up the call
13310
+ // stack. Note that you'll get the same error in JavaScript if you try to access a property using
13311
+ // such a 'broken' object as a key.
13312
+ return name + '';
12800
13313
  }
12801
13314
 
12802
13315
  function ensureSafeObject(obj, fullExpression) {
@@ -13057,6 +13570,7 @@ AST.ArrayExpression = 'ArrayExpression';
13057
13570
  AST.Property = 'Property';
13058
13571
  AST.ObjectExpression = 'ObjectExpression';
13059
13572
  AST.ThisExpression = 'ThisExpression';
13573
+ AST.LocalsExpression = 'LocalsExpression';
13060
13574
 
13061
13575
  // Internal use only
13062
13576
  AST.NGValueParameter = 'NGValueParameter';
@@ -13357,7 +13871,8 @@ AST.prototype = {
13357
13871
  'false': { type: AST.Literal, value: false },
13358
13872
  'null': { type: AST.Literal, value: null },
13359
13873
  'undefined': {type: AST.Literal, value: undefined },
13360
- 'this': {type: AST.ThisExpression }
13874
+ 'this': {type: AST.ThisExpression },
13875
+ '$locals': {type: AST.LocalsExpression }
13361
13876
  }
13362
13877
  };
13363
13878
 
@@ -13477,6 +13992,10 @@ function findConstantAndWatchExpressions(ast, $filter) {
13477
13992
  ast.constant = false;
13478
13993
  ast.toWatch = [];
13479
13994
  break;
13995
+ case AST.LocalsExpression:
13996
+ ast.constant = false;
13997
+ ast.toWatch = [];
13998
+ break;
13480
13999
  }
13481
14000
  }
13482
14001
 
@@ -13720,6 +14239,9 @@ ASTCompiler.prototype = {
13720
14239
  intoId = intoId || this.nextId();
13721
14240
  self.recurse(ast.object, left, undefined, function() {
13722
14241
  self.if_(self.notNull(left), function() {
14242
+ if (create && create !== 1) {
14243
+ self.addEnsureSafeAssignContext(left);
14244
+ }
13723
14245
  if (ast.computed) {
13724
14246
  right = self.nextId();
13725
14247
  self.recurse(ast.property, right);
@@ -13843,6 +14365,10 @@ ASTCompiler.prototype = {
13843
14365
  this.assign(intoId, 's');
13844
14366
  recursionFn('s');
13845
14367
  break;
14368
+ case AST.LocalsExpression:
14369
+ this.assign(intoId, 'l');
14370
+ recursionFn('l');
14371
+ break;
13846
14372
  case AST.NGValueParameter:
13847
14373
  this.assign(intoId, 'v');
13848
14374
  recursionFn('v');
@@ -13950,7 +14476,7 @@ ASTCompiler.prototype = {
13950
14476
  },
13951
14477
 
13952
14478
  getStringValue: function(item) {
13953
- this.assign(item, 'getStringValue(' + item + ',text)');
14479
+ this.assign(item, 'getStringValue(' + item + ')');
13954
14480
  },
13955
14481
 
13956
14482
  ensureSafeAssignContext: function(item) {
@@ -14170,6 +14696,10 @@ ASTInterpreter.prototype = {
14170
14696
  return function(scope) {
14171
14697
  return context ? {value: scope} : scope;
14172
14698
  };
14699
+ case AST.LocalsExpression:
14700
+ return function(scope, locals) {
14701
+ return context ? {value: locals} : locals;
14702
+ };
14173
14703
  case AST.NGValueParameter:
14174
14704
  return function(scope, locals, assign, inputs) {
14175
14705
  return context ? {value: assign} : assign;
@@ -14334,8 +14864,11 @@ ASTInterpreter.prototype = {
14334
14864
  rhs = right(scope, locals, assign, inputs);
14335
14865
  rhs = getStringValue(rhs);
14336
14866
  ensureSafeMemberName(rhs, expression);
14337
- if (create && create !== 1 && lhs && !(lhs[rhs])) {
14338
- lhs[rhs] = {};
14867
+ if (create && create !== 1) {
14868
+ ensureSafeAssignContext(lhs);
14869
+ if (lhs && !(lhs[rhs])) {
14870
+ lhs[rhs] = {};
14871
+ }
14339
14872
  }
14340
14873
  value = lhs[rhs];
14341
14874
  ensureSafeObject(value, expression);
@@ -14350,8 +14883,11 @@ ASTInterpreter.prototype = {
14350
14883
  nonComputedMember: function(left, right, expensiveChecks, context, create, expression) {
14351
14884
  return function(scope, locals, assign, inputs) {
14352
14885
  var lhs = left(scope, locals, assign, inputs);
14353
- if (create && create !== 1 && lhs && !(lhs[right])) {
14354
- lhs[right] = {};
14886
+ if (create && create !== 1) {
14887
+ ensureSafeAssignContext(lhs);
14888
+ if (lhs && !(lhs[right])) {
14889
+ lhs[right] = {};
14890
+ }
14355
14891
  }
14356
14892
  var value = lhs != null ? lhs[right] : undefined;
14357
14893
  if (expensiveChecks || isPossiblyDangerousMemberName(right)) {
@@ -14467,10 +15003,19 @@ function $ParseProvider() {
14467
15003
  csp: noUnsafeEval,
14468
15004
  expensiveChecks: true
14469
15005
  };
15006
+ var runningChecksEnabled = false;
15007
+
15008
+ $parse.$$runningExpensiveChecks = function() {
15009
+ return runningChecksEnabled;
15010
+ };
15011
+
15012
+ return $parse;
14470
15013
 
14471
- return function $parse(exp, interceptorFn, expensiveChecks) {
15014
+ function $parse(exp, interceptorFn, expensiveChecks) {
14472
15015
  var parsedExpression, oneTime, cacheKey;
14473
15016
 
15017
+ expensiveChecks = expensiveChecks || runningChecksEnabled;
15018
+
14474
15019
  switch (typeof exp) {
14475
15020
  case 'string':
14476
15021
  exp = exp.trim();
@@ -14496,6 +15041,9 @@ function $ParseProvider() {
14496
15041
  } else if (parsedExpression.inputs) {
14497
15042
  parsedExpression.$$watchDelegate = inputsWatchDelegate;
14498
15043
  }
15044
+ if (expensiveChecks) {
15045
+ parsedExpression = expensiveChecksInterceptor(parsedExpression);
15046
+ }
14499
15047
  cache[cacheKey] = parsedExpression;
14500
15048
  }
14501
15049
  return addInterceptor(parsedExpression, interceptorFn);
@@ -14506,7 +15054,31 @@ function $ParseProvider() {
14506
15054
  default:
14507
15055
  return addInterceptor(noop, interceptorFn);
14508
15056
  }
14509
- };
15057
+ }
15058
+
15059
+ function expensiveChecksInterceptor(fn) {
15060
+ if (!fn) return fn;
15061
+ expensiveCheckFn.$$watchDelegate = fn.$$watchDelegate;
15062
+ expensiveCheckFn.assign = expensiveChecksInterceptor(fn.assign);
15063
+ expensiveCheckFn.constant = fn.constant;
15064
+ expensiveCheckFn.literal = fn.literal;
15065
+ for (var i = 0; fn.inputs && i < fn.inputs.length; ++i) {
15066
+ fn.inputs[i] = expensiveChecksInterceptor(fn.inputs[i]);
15067
+ }
15068
+ expensiveCheckFn.inputs = fn.inputs;
15069
+
15070
+ return expensiveCheckFn;
15071
+
15072
+ function expensiveCheckFn(scope, locals, assign, inputs) {
15073
+ var expensiveCheckOldValue = runningChecksEnabled;
15074
+ runningChecksEnabled = true;
15075
+ try {
15076
+ return fn(scope, locals, assign, inputs);
15077
+ } finally {
15078
+ runningChecksEnabled = expensiveCheckOldValue;
15079
+ }
15080
+ }
15081
+ }
14510
15082
 
14511
15083
  function expressionInputDirtyCheck(newValue, oldValueOfValue) {
14512
15084
 
@@ -14623,13 +15195,9 @@ function $ParseProvider() {
14623
15195
  function constantWatchDelegate(scope, listener, objectEquality, parsedExpression) {
14624
15196
  var unwatch;
14625
15197
  return unwatch = scope.$watch(function constantWatch(scope) {
14626
- return parsedExpression(scope);
14627
- }, function constantListener(value, old, scope) {
14628
- if (isFunction(listener)) {
14629
- listener.apply(this, arguments);
14630
- }
14631
15198
  unwatch();
14632
- }, objectEquality);
15199
+ return parsedExpression(scope);
15200
+ }, listener, objectEquality);
14633
15201
  }
14634
15202
 
14635
15203
  function addInterceptor(parsedExpression, interceptorFn) {
@@ -14722,7 +15290,7 @@ function $ParseProvider() {
14722
15290
  *
14723
15291
  * Note: progress/notify callbacks are not currently supported via the ES6-style interface.
14724
15292
  *
14725
- * Note: unlike ES6 behaviour, an exception thrown in the constructor function will NOT implicitly reject the promise.
15293
+ * Note: unlike ES6 behavior, an exception thrown in the constructor function will NOT implicitly reject the promise.
14726
15294
  *
14727
15295
  * However, the more traditional CommonJS-style usage is still available, and documented below.
14728
15296
  *
@@ -14912,18 +15480,6 @@ function $$QProvider() {
14912
15480
  */
14913
15481
  function qFactory(nextTick, exceptionHandler) {
14914
15482
  var $qMinErr = minErr('$q', TypeError);
14915
- function callOnce(self, resolveFn, rejectFn) {
14916
- var called = false;
14917
- function wrap(fn) {
14918
- return function(value) {
14919
- if (called) return;
14920
- called = true;
14921
- fn.call(self, value);
14922
- };
14923
- }
14924
-
14925
- return [wrap(resolveFn), wrap(rejectFn)];
14926
- }
14927
15483
 
14928
15484
  /**
14929
15485
  * @ngdoc method
@@ -14936,7 +15492,12 @@ function qFactory(nextTick, exceptionHandler) {
14936
15492
  * @returns {Deferred} Returns a new instance of deferred.
14937
15493
  */
14938
15494
  var defer = function() {
14939
- return new Deferred();
15495
+ var d = new Deferred();
15496
+ //Necessary to support unbound execution :/
15497
+ d.resolve = simpleBind(d, d.resolve);
15498
+ d.reject = simpleBind(d, d.reject);
15499
+ d.notify = simpleBind(d, d.notify);
15500
+ return d;
14940
15501
  };
14941
15502
 
14942
15503
  function Promise() {
@@ -15009,10 +15570,6 @@ function qFactory(nextTick, exceptionHandler) {
15009
15570
 
15010
15571
  function Deferred() {
15011
15572
  this.promise = new Promise();
15012
- //Necessary to support unbound execution :/
15013
- this.resolve = simpleBind(this, this.resolve);
15014
- this.reject = simpleBind(this, this.reject);
15015
- this.notify = simpleBind(this, this.notify);
15016
15573
  }
15017
15574
 
15018
15575
  extend(Deferred.prototype, {
@@ -15030,23 +15587,34 @@ function qFactory(nextTick, exceptionHandler) {
15030
15587
  },
15031
15588
 
15032
15589
  $$resolve: function(val) {
15033
- var then, fns;
15034
-
15035
- fns = callOnce(this, this.$$resolve, this.$$reject);
15590
+ var then;
15591
+ var that = this;
15592
+ var done = false;
15036
15593
  try {
15037
15594
  if ((isObject(val) || isFunction(val))) then = val && val.then;
15038
15595
  if (isFunction(then)) {
15039
15596
  this.promise.$$state.status = -1;
15040
- then.call(val, fns[0], fns[1], this.notify);
15597
+ then.call(val, resolvePromise, rejectPromise, simpleBind(this, this.notify));
15041
15598
  } else {
15042
15599
  this.promise.$$state.value = val;
15043
15600
  this.promise.$$state.status = 1;
15044
15601
  scheduleProcessQueue(this.promise.$$state);
15045
15602
  }
15046
15603
  } catch (e) {
15047
- fns[1](e);
15604
+ rejectPromise(e);
15048
15605
  exceptionHandler(e);
15049
15606
  }
15607
+
15608
+ function resolvePromise(val) {
15609
+ if (done) return;
15610
+ done = true;
15611
+ that.$$resolve(val);
15612
+ }
15613
+ function rejectPromise(val) {
15614
+ if (done) return;
15615
+ done = true;
15616
+ that.$$reject(val);
15617
+ }
15050
15618
  },
15051
15619
 
15052
15620
  reject: function(reason) {
@@ -15235,11 +15803,6 @@ function qFactory(nextTick, exceptionHandler) {
15235
15803
  throw $qMinErr('norslvr', "Expected resolverFn, got '{0}'", resolver);
15236
15804
  }
15237
15805
 
15238
- if (!(this instanceof Q)) {
15239
- // More useful when $Q is the Promise itself.
15240
- return new Q(resolver);
15241
- }
15242
-
15243
15806
  var deferred = new Deferred();
15244
15807
 
15245
15808
  function resolveFn(value) {
@@ -15255,6 +15818,10 @@ function qFactory(nextTick, exceptionHandler) {
15255
15818
  return deferred.promise;
15256
15819
  };
15257
15820
 
15821
+ // Let's make the instanceof operator work for promises, so that
15822
+ // `new $q(fn) instanceof $q` would evaluate to true.
15823
+ $Q.prototype = Promise.prototype;
15824
+
15258
15825
  $Q.defer = defer;
15259
15826
  $Q.reject = reject;
15260
15827
  $Q.when = when;
@@ -15388,8 +15955,8 @@ function $RootScopeProvider() {
15388
15955
  return ChildScope;
15389
15956
  }
15390
15957
 
15391
- this.$get = ['$injector', '$exceptionHandler', '$parse', '$browser',
15392
- function($injector, $exceptionHandler, $parse, $browser) {
15958
+ this.$get = ['$exceptionHandler', '$parse', '$browser',
15959
+ function($exceptionHandler, $parse, $browser) {
15393
15960
 
15394
15961
  function destroyChildScope($event) {
15395
15962
  $event.currentScope.$$destroyed = true;
@@ -15673,7 +16240,7 @@ function $RootScopeProvider() {
15673
16240
  * - `newVal` contains the current value of the `watchExpression`
15674
16241
  * - `oldVal` contains the previous value of the `watchExpression`
15675
16242
  * - `scope` refers to the current scope
15676
- * @param {boolean=} objectEquality Compare for object equality using {@link angular.equals} instead of
16243
+ * @param {boolean=} [objectEquality=false] Compare for object equality using {@link angular.equals} instead of
15677
16244
  * comparing for reference equality.
15678
16245
  * @returns {function()} Returns a deregistration function for this listener.
15679
16246
  */
@@ -16038,7 +16605,7 @@ function $RootScopeProvider() {
16038
16605
  *
16039
16606
  */
16040
16607
  $digest: function() {
16041
- var watch, value, last,
16608
+ var watch, value, last, fn, get,
16042
16609
  watchers,
16043
16610
  length,
16044
16611
  dirty, ttl = TTL,
@@ -16084,7 +16651,8 @@ function $RootScopeProvider() {
16084
16651
  // Most common watches are on primitives, in which case we can short
16085
16652
  // circuit it with === operator, only when === fails do we use .equals
16086
16653
  if (watch) {
16087
- if ((value = watch.get(current)) !== (last = watch.last) &&
16654
+ get = watch.get;
16655
+ if ((value = get(current)) !== (last = watch.last) &&
16088
16656
  !(watch.eq
16089
16657
  ? equals(value, last)
16090
16658
  : (typeof value === 'number' && typeof last === 'number'
@@ -16092,7 +16660,8 @@ function $RootScopeProvider() {
16092
16660
  dirty = true;
16093
16661
  lastDirtyWatch = watch;
16094
16662
  watch.last = watch.eq ? copy(value, null) : value;
16095
- watch.fn(value, ((last === initWatchVal) ? value : last), current);
16663
+ fn = watch.fn;
16664
+ fn(value, ((last === initWatchVal) ? value : last), current);
16096
16665
  if (ttl < 5) {
16097
16666
  logIdx = 4 - ttl;
16098
16667
  if (!watchLog[logIdx]) watchLog[logIdx] = [];
@@ -16292,7 +16861,7 @@ function $RootScopeProvider() {
16292
16861
  });
16293
16862
  }
16294
16863
 
16295
- asyncQueue.push({scope: this, expression: expr, locals: locals});
16864
+ asyncQueue.push({scope: this, expression: $parse(expr), locals: locals});
16296
16865
  },
16297
16866
 
16298
16867
  $$postDigest: function(fn) {
@@ -16384,6 +16953,7 @@ function $RootScopeProvider() {
16384
16953
  $applyAsync: function(expr) {
16385
16954
  var scope = this;
16386
16955
  expr && applyAsyncQueue.push($applyAsyncExpression);
16956
+ expr = $parse(expr);
16387
16957
  scheduleApplyAsync();
16388
16958
 
16389
16959
  function $applyAsyncExpression() {
@@ -16887,13 +17457,15 @@ function $SceDelegateProvider() {
16887
17457
  * @kind function
16888
17458
  *
16889
17459
  * @param {Array=} whitelist When provided, replaces the resourceUrlWhitelist with the value
16890
- * provided. This must be an array or null. A snapshot of this array is used so further
16891
- * changes to the array are ignored.
17460
+ * provided. This must be an array or null. A snapshot of this array is used so further
17461
+ * changes to the array are ignored.
16892
17462
  *
16893
- * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
16894
- * allowed in this array.
17463
+ * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
17464
+ * allowed in this array.
16895
17465
  *
16896
- * Note: **an empty whitelist array will block all URLs**!
17466
+ * <div class="alert alert-warning">
17467
+ * **Note:** an empty whitelist array will block all URLs!
17468
+ * </div>
16897
17469
  *
16898
17470
  * @return {Array} the currently set whitelist array.
16899
17471
  *
@@ -16916,17 +17488,17 @@ function $SceDelegateProvider() {
16916
17488
  * @kind function
16917
17489
  *
16918
17490
  * @param {Array=} blacklist When provided, replaces the resourceUrlBlacklist with the value
16919
- * provided. This must be an array or null. A snapshot of this array is used so further
16920
- * changes to the array are ignored.
17491
+ * provided. This must be an array or null. A snapshot of this array is used so further
17492
+ * changes to the array are ignored.
16921
17493
  *
16922
- * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
16923
- * allowed in this array.
17494
+ * Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
17495
+ * allowed in this array.
16924
17496
  *
16925
- * The typical usage for the blacklist is to **block
16926
- * [open redirects](http://cwe.mitre.org/data/definitions/601.html)** served by your domain as
16927
- * these would otherwise be trusted but actually return content from the redirected domain.
17497
+ * The typical usage for the blacklist is to **block
17498
+ * [open redirects](http://cwe.mitre.org/data/definitions/601.html)** served by your domain as
17499
+ * these would otherwise be trusted but actually return content from the redirected domain.
16928
17500
  *
16929
- * Finally, **the blacklist overrides the whitelist** and has the final say.
17501
+ * Finally, **the blacklist overrides the whitelist** and has the final say.
16930
17502
  *
16931
17503
  * @return {Array} the currently set blacklist array.
16932
17504
  *
@@ -17085,6 +17657,11 @@ function $SceDelegateProvider() {
17085
17657
  * returns the originally supplied value if the queried context type is a supertype of the
17086
17658
  * created type. If this condition isn't satisfied, throws an exception.
17087
17659
  *
17660
+ * <div class="alert alert-danger">
17661
+ * Disabling auto-escaping is extremely dangerous, it usually creates a Cross Site Scripting
17662
+ * (XSS) vulnerability in your application.
17663
+ * </div>
17664
+ *
17088
17665
  * @param {string} type The kind of context in which this value is to be used.
17089
17666
  * @param {*} maybeTrusted The result of a prior {@link ng.$sceDelegate#trustAs
17090
17667
  * `$sceDelegate.trustAs`} call.
@@ -17892,26 +18469,63 @@ function $SnifferProvider() {
17892
18469
  var $compileMinErr = minErr('$compile');
17893
18470
 
17894
18471
  /**
17895
- * @ngdoc service
17896
- * @name $templateRequest
17897
- *
18472
+ * @ngdoc provider
18473
+ * @name $templateRequestProvider
17898
18474
  * @description
17899
- * The `$templateRequest` service runs security checks then downloads the provided template using
17900
- * `$http` and, upon success, stores the contents inside of `$templateCache`. If the HTTP request
17901
- * fails or the response data of the HTTP request is empty, a `$compile` error will be thrown (the
17902
- * exception can be thwarted by setting the 2nd parameter of the function to true). Note that the
17903
- * contents of `$templateCache` are trusted, so the call to `$sce.getTrustedUrl(tpl)` is omitted
17904
- * when `tpl` is of type string and `$templateCache` has the matching entry.
17905
- *
17906
- * @param {string|TrustedResourceUrl} tpl The HTTP request template URL
17907
- * @param {boolean=} ignoreRequestError Whether or not to ignore the exception when the request fails or the template is empty
18475
+ * Used to configure the options passed to the {@link $http} service when making a template request.
17908
18476
  *
17909
- * @return {Promise} a promise for the HTTP response data of the given URL.
17910
- *
17911
- * @property {number} totalPendingRequests total amount of pending template requests being downloaded.
18477
+ * For example, it can be used for specifying the "Accept" header that is sent to the server, when
18478
+ * requesting a template.
17912
18479
  */
17913
18480
  function $TemplateRequestProvider() {
18481
+
18482
+ var httpOptions;
18483
+
18484
+ /**
18485
+ * @ngdoc method
18486
+ * @name $templateRequestProvider#httpOptions
18487
+ * @description
18488
+ * The options to be passed to the {@link $http} service when making the request.
18489
+ * You can use this to override options such as the "Accept" header for template requests.
18490
+ *
18491
+ * The {@link $templateRequest} will set the `cache` and the `transformResponse` properties of the
18492
+ * options if not overridden here.
18493
+ *
18494
+ * @param {string=} value new value for the {@link $http} options.
18495
+ * @returns {string|self} Returns the {@link $http} options when used as getter and self if used as setter.
18496
+ */
18497
+ this.httpOptions = function(val) {
18498
+ if (val) {
18499
+ httpOptions = val;
18500
+ return this;
18501
+ }
18502
+ return httpOptions;
18503
+ };
18504
+
18505
+ /**
18506
+ * @ngdoc service
18507
+ * @name $templateRequest
18508
+ *
18509
+ * @description
18510
+ * The `$templateRequest` service runs security checks then downloads the provided template using
18511
+ * `$http` and, upon success, stores the contents inside of `$templateCache`. If the HTTP request
18512
+ * fails or the response data of the HTTP request is empty, a `$compile` error will be thrown (the
18513
+ * exception can be thwarted by setting the 2nd parameter of the function to true). Note that the
18514
+ * contents of `$templateCache` are trusted, so the call to `$sce.getTrustedUrl(tpl)` is omitted
18515
+ * when `tpl` is of type string and `$templateCache` has the matching entry.
18516
+ *
18517
+ * If you want to pass custom options to the `$http` service, such as setting the Accept header you
18518
+ * can configure this via {@link $templateRequestProvider#httpOptions}.
18519
+ *
18520
+ * @param {string|TrustedResourceUrl} tpl The HTTP request template URL
18521
+ * @param {boolean=} ignoreRequestError Whether or not to ignore the exception when the request fails or the template is empty
18522
+ *
18523
+ * @return {Promise} a promise for the HTTP response data of the given URL.
18524
+ *
18525
+ * @property {number} totalPendingRequests total amount of pending template requests being downloaded.
18526
+ */
17914
18527
  this.$get = ['$templateCache', '$http', '$q', '$sce', function($templateCache, $http, $q, $sce) {
18528
+
17915
18529
  function handleRequestFn(tpl, ignoreRequestError) {
17916
18530
  handleRequestFn.totalPendingRequests++;
17917
18531
 
@@ -17934,12 +18548,10 @@ function $TemplateRequestProvider() {
17934
18548
  transformResponse = null;
17935
18549
  }
17936
18550
 
17937
- var httpOptions = {
17938
- cache: $templateCache,
17939
- transformResponse: transformResponse
17940
- };
17941
-
17942
- return $http.get(tpl, httpOptions)
18551
+ return $http.get(tpl, extend({
18552
+ cache: $templateCache,
18553
+ transformResponse: transformResponse
18554
+ }, httpOptions))
17943
18555
  ['finally'](function() {
17944
18556
  handleRequestFn.totalPendingRequests--;
17945
18557
  })
@@ -19394,13 +20006,13 @@ function dateFilter($locale) {
19394
20006
 
19395
20007
  var dateTimezoneOffset = date.getTimezoneOffset();
19396
20008
  if (timezone) {
19397
- dateTimezoneOffset = timezoneToOffset(timezone, date.getTimezoneOffset());
20009
+ dateTimezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
19398
20010
  date = convertTimezoneToLocal(date, timezone, true);
19399
20011
  }
19400
20012
  forEach(parts, function(value) {
19401
20013
  fn = DATE_FORMATS[value];
19402
20014
  text += fn ? fn(date, $locale.DATETIME_FORMATS, dateTimezoneOffset)
19403
- : value.replace(/(^'|'$)/g, '').replace(/''/g, "'");
20015
+ : value === "''" ? "'" : value.replace(/(^'|'$)/g, '').replace(/''/g, "'");
19404
20016
  });
19405
20017
 
19406
20018
  return text;
@@ -19604,8 +20216,9 @@ function limitToFilter() {
19604
20216
  * Orders a specified `array` by the `expression` predicate. It is ordered alphabetically
19605
20217
  * for strings and numerically for numbers. Note: if you notice numbers are not being sorted
19606
20218
  * as expected, make sure they are actually being saved as numbers and not strings.
20219
+ * Array-like values (e.g. NodeLists, jQuery objects, TypedArrays, Strings, etc) are also supported.
19607
20220
  *
19608
- * @param {Array} array The array to sort.
20221
+ * @param {Array} array The array (or array-like object) to sort.
19609
20222
  * @param {function(*)|string|Array.<(function(*)|string)>=} expression A predicate to be
19610
20223
  * used by the comparator to determine the order of elements.
19611
20224
  *
@@ -19792,7 +20405,10 @@ orderByFilter.$inject = ['$parse'];
19792
20405
  function orderByFilter($parse) {
19793
20406
  return function(array, sortPredicate, reverseOrder) {
19794
20407
 
19795
- if (!(isArrayLike(array))) return array;
20408
+ if (array == null) return array;
20409
+ if (!isArrayLike(array)) {
20410
+ throw minErr('orderBy')('notarray', 'Expected array but received: {0}', array);
20411
+ }
19796
20412
 
19797
20413
  if (!isArray(sortPredicate)) { sortPredicate = [sortPredicate]; }
19798
20414
  if (sortPredicate.length === 0) { sortPredicate = ['+']; }
@@ -20502,7 +21118,7 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
20502
21118
  *
20503
21119
  * However, if the method is used programmatically, for example by adding dynamically created controls,
20504
21120
  * or controls that have been previously removed without destroying their corresponding DOM element,
20505
- * it's the developers responsiblity to make sure the current state propagates to the parent form.
21121
+ * it's the developers responsibility to make sure the current state propagates to the parent form.
20506
21122
  *
20507
21123
  * For example, if an input control is added that is already `$dirty` and has `$error` properties,
20508
21124
  * calling `$setDirty()` and `$validate()` afterwards will propagate the state to the parent form.
@@ -20979,8 +21595,8 @@ var inputType = {
20979
21595
  * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
20980
21596
  * that contains the regular expression body that will be converted to a regular expression
20981
21597
  * as in the ngPattern directive.
20982
- * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
20983
- * a RegExp found by evaluating the Angular expression given in the attribute value.
21598
+ * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
21599
+ * does not match a RegExp found by evaluating the Angular expression given in the attribute value.
20984
21600
  * If the expression evaluates to a RegExp object, then this is used directly.
20985
21601
  * If the expression evaluates to a string, then it will be converted to a RegExp
20986
21602
  * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
@@ -21267,7 +21883,7 @@ var inputType = {
21267
21883
  *
21268
21884
  * @description
21269
21885
  * Input with time validation and transformation. In browsers that do not yet support
21270
- * the HTML5 date input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
21886
+ * the HTML5 time input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
21271
21887
  * local time format (HH:mm:ss), for example: `14:57:00`. Model must be a Date object. This binding will always output a
21272
21888
  * Date object to the model of January 1, 1970, or local date `new Date(1970, 0, 1, HH, mm, ss)`.
21273
21889
  *
@@ -21614,8 +22230,8 @@ var inputType = {
21614
22230
  * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
21615
22231
  * that contains the regular expression body that will be converted to a regular expression
21616
22232
  * as in the ngPattern directive.
21617
- * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
21618
- * a RegExp found by evaluating the Angular expression given in the attribute value.
22233
+ * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
22234
+ * does not match a RegExp found by evaluating the Angular expression given in the attribute value.
21619
22235
  * If the expression evaluates to a RegExp object, then this is used directly.
21620
22236
  * If the expression evaluates to a string, then it will be converted to a RegExp
21621
22237
  * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
@@ -21712,8 +22328,8 @@ var inputType = {
21712
22328
  * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
21713
22329
  * that contains the regular expression body that will be converted to a regular expression
21714
22330
  * as in the ngPattern directive.
21715
- * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
21716
- * a RegExp found by evaluating the Angular expression given in the attribute value.
22331
+ * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
22332
+ * does not match a RegExp found by evaluating the Angular expression given in the attribute value.
21717
22333
  * If the expression evaluates to a RegExp object, then this is used directly.
21718
22334
  * If the expression evaluates to a string, then it will be converted to a RegExp
21719
22335
  * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
@@ -21811,8 +22427,8 @@ var inputType = {
21811
22427
  * @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
21812
22428
  * that contains the regular expression body that will be converted to a regular expression
21813
22429
  * as in the ngPattern directive.
21814
- * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
21815
- * a RegExp found by evaluating the Angular expression given in the attribute value.
22430
+ * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
22431
+ * does not match a RegExp found by evaluating the Angular expression given in the attribute value.
21816
22432
  * If the expression evaluates to a RegExp object, then this is used directly.
21817
22433
  * If the expression evaluates to a string, then it will be converted to a RegExp
21818
22434
  * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
@@ -22272,11 +22888,7 @@ function badInputChecker(scope, element, attr, ctrl) {
22272
22888
  if (nativeValidation) {
22273
22889
  ctrl.$parsers.push(function(value) {
22274
22890
  var validity = element.prop(VALIDITY_STATE_PROPERTY) || {};
22275
- // Detect bug in FF35 for input[email] (https://bugzilla.mozilla.org/show_bug.cgi?id=1064430):
22276
- // - also sets validity.badInput (should only be validity.typeMismatch).
22277
- // - see http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#e-mail-state-(type=email)
22278
- // - can ignore this case as we can still read out the erroneous email...
22279
- return validity.badInput && !validity.typeMismatch ? undefined : value;
22891
+ return validity.badInput || validity.typeMismatch ? undefined : value;
22280
22892
  });
22281
22893
  }
22282
22894
  }
@@ -22448,8 +23060,8 @@ function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filt
22448
23060
  * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
22449
23061
  * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any
22450
23062
  * length.
22451
- * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
22452
- * a RegExp found by evaluating the Angular expression given in the attribute value.
23063
+ * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
23064
+ * does not match a RegExp found by evaluating the Angular expression given in the attribute value.
22453
23065
  * If the expression evaluates to a RegExp object, then this is used directly.
22454
23066
  * If the expression evaluates to a string, then it will be converted to a RegExp
22455
23067
  * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
@@ -22487,8 +23099,8 @@ function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filt
22487
23099
  * @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
22488
23100
  * maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any
22489
23101
  * length.
22490
- * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
22491
- * a RegExp found by evaluating the Angular expression given in the attribute value.
23102
+ * @param {string=} ngPattern Sets `pattern` validation error key if the ngModel {@link ngModel.NgModelController#$viewValue $viewValue}
23103
+ * value does not match a RegExp found by evaluating the Angular expression given in the attribute value.
22492
23104
  * If the expression evaluates to a RegExp object, then this is used directly.
22493
23105
  * If the expression evaluates to a string, then it will be converted to a RegExp
22494
23106
  * after wrapping it in `^` and `$` characters. For instance, `"abc"` will be converted to
@@ -23714,7 +24326,7 @@ var ngControllerDirective = [function() {
23714
24326
  *
23715
24327
  * * no-inline-style: this stops Angular from injecting CSS styles into the DOM
23716
24328
  *
23717
- * * no-unsafe-eval: this stops Angular from optimising $parse with unsafe eval of strings
24329
+ * * no-unsafe-eval: this stops Angular from optimizing $parse with unsafe eval of strings
23718
24330
  *
23719
24331
  * You can use these values in the following combinations:
23720
24332
  *
@@ -23731,7 +24343,7 @@ var ngControllerDirective = [function() {
23731
24343
  * inline styles. E.g. `<body ng-csp="no-unsafe-eval">`.
23732
24344
  *
23733
24345
  * * Specifying only `no-inline-style` tells Angular that we must not inject styles, but that we can
23734
- * run eval - no automcatic check for unsafe eval will occur. E.g. `<body ng-csp="no-inline-style">`
24346
+ * run eval - no automatic check for unsafe eval will occur. E.g. `<body ng-csp="no-inline-style">`
23735
24347
  *
23736
24348
  * * Specifying both `no-unsafe-eval` and `no-inline-style` tells Angular that we must not inject
23737
24349
  * styles nor use eval, which is the same as an empty: ng-csp.
@@ -24763,7 +25375,7 @@ var ngIncludeFillContentDirective = ['$compile',
24763
25375
  priority: -400,
24764
25376
  require: 'ngInclude',
24765
25377
  link: function(scope, $element, $attr, ctrl) {
24766
- if (/SVG/.test($element[0].toString())) {
25378
+ if (toString.call($element[0]).match(/SVG/)) {
24767
25379
  // WebKit: https://bugs.webkit.org/show_bug.cgi?id=135698 --- SVG elements do not
24768
25380
  // support innerHTML, so detect this here and try to generate the contents
24769
25381
  // specially.
@@ -24992,7 +25604,9 @@ var VALID_CLASS = 'ng-valid',
24992
25604
  DIRTY_CLASS = 'ng-dirty',
24993
25605
  UNTOUCHED_CLASS = 'ng-untouched',
24994
25606
  TOUCHED_CLASS = 'ng-touched',
24995
- PENDING_CLASS = 'ng-pending';
25607
+ PENDING_CLASS = 'ng-pending',
25608
+ EMPTY_CLASS = 'ng-empty',
25609
+ NOT_EMPTY_CLASS = 'ng-not-empty';
24996
25610
 
24997
25611
  var ngModelMinErr = minErr('ngModel');
24998
25612
 
@@ -25296,6 +25910,17 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
25296
25910
  return isUndefined(value) || value === '' || value === null || value !== value;
25297
25911
  };
25298
25912
 
25913
+ this.$$updateEmptyClasses = function(value) {
25914
+ if (ctrl.$isEmpty(value)) {
25915
+ $animate.removeClass($element, NOT_EMPTY_CLASS);
25916
+ $animate.addClass($element, EMPTY_CLASS);
25917
+ } else {
25918
+ $animate.removeClass($element, EMPTY_CLASS);
25919
+ $animate.addClass($element, NOT_EMPTY_CLASS);
25920
+ }
25921
+ };
25922
+
25923
+
25299
25924
  var currentValidationRunId = 0;
25300
25925
 
25301
25926
  /**
@@ -25659,6 +26284,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
25659
26284
  if (ctrl.$$lastCommittedViewValue === viewValue && (viewValue !== '' || !ctrl.$$hasNativeValidators)) {
25660
26285
  return;
25661
26286
  }
26287
+ ctrl.$$updateEmptyClasses(viewValue);
25662
26288
  ctrl.$$lastCommittedViewValue = viewValue;
25663
26289
 
25664
26290
  // change to dirty
@@ -25757,7 +26383,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
25757
26383
  * However, custom controls might also pass objects to this method. In this case, we should make
25758
26384
  * a copy of the object before passing it to `$setViewValue`. This is because `ngModel` does not
25759
26385
  * perform a deep watch of objects, it only looks for a change of identity. If you only change
25760
- * the property of the object then ngModel will not realise that the object has changed and
26386
+ * the property of the object then ngModel will not realize that the object has changed and
25761
26387
  * will not invoke the `$parsers` and `$validators` pipelines. For this reason, you should
25762
26388
  * not change properties of the copy once it has been passed to `$setViewValue`.
25763
26389
  * Otherwise you may cause the model value on the scope to change incorrectly.
@@ -25841,6 +26467,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
25841
26467
  viewValue = formatters[idx](viewValue);
25842
26468
  }
25843
26469
  if (ctrl.$viewValue !== viewValue) {
26470
+ ctrl.$$updateEmptyClasses(viewValue);
25844
26471
  ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue;
25845
26472
  ctrl.$render();
25846
26473
 
@@ -25871,7 +26498,8 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
25871
26498
  * require.
25872
26499
  * - Providing validation behavior (i.e. required, number, email, url).
25873
26500
  * - Keeping the state of the control (valid/invalid, dirty/pristine, touched/untouched, validation errors).
25874
- * - Setting related css classes on the element (`ng-valid`, `ng-invalid`, `ng-dirty`, `ng-pristine`, `ng-touched`, `ng-untouched`) including animations.
26501
+ * - Setting related css classes on the element (`ng-valid`, `ng-invalid`, `ng-dirty`, `ng-pristine`, `ng-touched`,
26502
+ * `ng-untouched`, `ng-empty`, `ng-not-empty`) including animations.
25875
26503
  * - Registering the control with its parent {@link ng.directive:form form}.
25876
26504
  *
25877
26505
  * Note: `ngModel` will try to bind to the property given by evaluating the expression on the
@@ -25899,6 +26527,22 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
25899
26527
  * - {@link ng.directive:select select}
25900
26528
  * - {@link ng.directive:textarea textarea}
25901
26529
  *
26530
+ * # Complex Models (objects or collections)
26531
+ *
26532
+ * By default, `ngModel` watches the model by reference, not value. This is important to know when
26533
+ * binding inputs to models that are objects (e.g. `Date`) or collections (e.g. arrays). If only properties of the
26534
+ * object or collection change, `ngModel` will not be notified and so the input will not be re-rendered.
26535
+ *
26536
+ * The model must be assigned an entirely new object or collection before a re-rendering will occur.
26537
+ *
26538
+ * Some directives have options that will cause them to use a custom `$watchCollection` on the model expression
26539
+ * - for example, `ngOptions` will do so when a `track by` clause is included in the comprehension expression or
26540
+ * if the select is given the `multiple` attribute.
26541
+ *
26542
+ * The `$watchCollection()` method only does a shallow comparison, meaning that changing properties deeper than the
26543
+ * first level of the object (or only changing the properties of an item in the collection if it's an array) will still
26544
+ * not trigger a re-rendering of the model.
26545
+ *
25902
26546
  * # CSS classes
25903
26547
  * The following CSS classes are added and removed on the associated input/select/textarea element
25904
26548
  * depending on the validity of the model.
@@ -25912,13 +26556,16 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
25912
26556
  * - `ng-touched`: the control has been blurred
25913
26557
  * - `ng-untouched`: the control hasn't been blurred
25914
26558
  * - `ng-pending`: any `$asyncValidators` are unfulfilled
26559
+ * - `ng-empty`: the view does not contain a value or the value is deemed "empty", as defined
26560
+ * by the {@link ngModel.NgModelController#$isEmpty} method
26561
+ * - `ng-not-empty`: the view contains a non-empty value
25915
26562
  *
25916
26563
  * Keep in mind that ngAnimate can detect each of these classes when added and removed.
25917
26564
  *
25918
26565
  * ## Animation Hooks
25919
26566
  *
25920
26567
  * Animations within models are triggered when any of the associated CSS classes are added and removed
25921
- * on the input element which is attached to the model. These classes are: `.ng-pristine`, `.ng-dirty`,
26568
+ * on the input element which is attached to the model. These classes include: `.ng-pristine`, `.ng-dirty`,
25922
26569
  * `.ng-invalid` and `.ng-valid` as well as any other validations that are performed on the model itself.
25923
26570
  * The animations that are triggered within ngModel are similar to how they work in ngClass and
25924
26571
  * animations can be hooked into using CSS transitions, keyframes as well as JS animations.
@@ -26811,14 +27458,10 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
26811
27458
  var optionTemplate = document.createElement('option'),
26812
27459
  optGroupTemplate = document.createElement('optgroup');
26813
27460
 
26814
-
26815
27461
  function ngOptionsPostLink(scope, selectElement, attr, ctrls) {
26816
27462
 
26817
- // if ngModel is not defined, we don't need to do anything
26818
- var ngModelCtrl = ctrls[1];
26819
- if (!ngModelCtrl) return;
26820
-
26821
27463
  var selectCtrl = ctrls[0];
27464
+ var ngModelCtrl = ctrls[1];
26822
27465
  var multiple = attr.multiple;
26823
27466
 
26824
27467
  // The emptyOption allows the application developer to provide their own custom "empty"
@@ -27078,7 +27721,7 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
27078
27721
  var groupElement;
27079
27722
  var optionElement;
27080
27723
 
27081
- if (option.group) {
27724
+ if (isDefined(option.group)) {
27082
27725
 
27083
27726
  // This option is to live in a group
27084
27727
  // See if we have already created this group
@@ -27152,7 +27795,7 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
27152
27795
  return {
27153
27796
  restrict: 'A',
27154
27797
  terminal: true,
27155
- require: ['select', '?ngModel'],
27798
+ require: ['select', 'ngModel'],
27156
27799
  link: {
27157
27800
  pre: function ngOptionsPreLink(scope, selectElement, attr, ctrls) {
27158
27801
  // Deactivate the SelectController.register method to prevent
@@ -27380,7 +28023,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
27380
28023
  }
27381
28024
 
27382
28025
  // If both `count` and `lastCount` are NaN, we don't need to re-register a watch.
27383
- // In JS `NaN !== NaN`, so we have to exlicitly check.
28026
+ // In JS `NaN !== NaN`, so we have to explicitly check.
27384
28027
  if ((count !== lastCount) && !(countIsNaN && isNumber(lastCount) && isNaN(lastCount))) {
27385
28028
  watchRemover();
27386
28029
  var whenExpFn = whensExpFns[count];
@@ -27497,7 +28140,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
27497
28140
  * by the identifier instead of the whole object. Should you reload your data later, `ngRepeat`
27498
28141
  * will not have to rebuild the DOM elements for items it has already rendered, even if the
27499
28142
  * JavaScript objects in the collection have been substituted for new ones. For large collections,
27500
- * this signifincantly improves rendering performance. If you don't have a unique identifier,
28143
+ * this significantly improves rendering performance. If you don't have a unique identifier,
27501
28144
  * `track by $index` can also provide a performance boost.
27502
28145
  * </div>
27503
28146
  * ```html
@@ -27574,6 +28217,8 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
27574
28217
  *
27575
28218
  * **.move** - when an adjacent item is filtered out causing a reorder or when the item contents are reordered
27576
28219
  *
28220
+ * See the example below for defining CSS animations with ngRepeat.
28221
+ *
27577
28222
  * @element ANY
27578
28223
  * @scope
27579
28224
  * @priority 1000
@@ -27626,22 +28271,11 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
27626
28271
  * For example: `item in items | filter : x | orderBy : order | limitTo : limit as results` .
27627
28272
  *
27628
28273
  * @example
27629
- * This example initializes the scope to a list of names and
27630
- * then uses `ngRepeat` to display every person:
27631
- <example module="ngAnimate" deps="angular-animate.js" animations="true">
28274
+ * This example uses `ngRepeat` to display a list of people. A filter is used to restrict the displayed
28275
+ * results by name. New (entering) and removed (leaving) items are animated.
28276
+ <example module="ngRepeat" name="ngRepeat" deps="angular-animate.js" animations="true">
27632
28277
  <file name="index.html">
27633
- <div ng-init="friends = [
27634
- {name:'John', age:25, gender:'boy'},
27635
- {name:'Jessie', age:30, gender:'girl'},
27636
- {name:'Johanna', age:28, gender:'girl'},
27637
- {name:'Joy', age:15, gender:'girl'},
27638
- {name:'Mary', age:28, gender:'girl'},
27639
- {name:'Peter', age:95, gender:'boy'},
27640
- {name:'Sebastian', age:50, gender:'boy'},
27641
- {name:'Erika', age:27, gender:'girl'},
27642
- {name:'Patrick', age:40, gender:'boy'},
27643
- {name:'Samantha', age:60, gender:'girl'}
27644
- ]">
28278
+ <div ng-controller="repeatController">
27645
28279
  I have {{friends.length}} friends. They are:
27646
28280
  <input type="search" ng-model="q" placeholder="filter friends..." aria-label="filter friends" />
27647
28281
  <ul class="example-animate-container">
@@ -27654,6 +28288,22 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
27654
28288
  </ul>
27655
28289
  </div>
27656
28290
  </file>
28291
+ <file name="script.js">
28292
+ angular.module('ngRepeat', ['ngAnimate']).controller('repeatController', function($scope) {
28293
+ $scope.friends = [
28294
+ {name:'John', age:25, gender:'boy'},
28295
+ {name:'Jessie', age:30, gender:'girl'},
28296
+ {name:'Johanna', age:28, gender:'girl'},
28297
+ {name:'Joy', age:15, gender:'girl'},
28298
+ {name:'Mary', age:28, gender:'girl'},
28299
+ {name:'Peter', age:95, gender:'boy'},
28300
+ {name:'Sebastian', age:50, gender:'boy'},
28301
+ {name:'Erika', age:27, gender:'girl'},
28302
+ {name:'Patrick', age:40, gender:'boy'},
28303
+ {name:'Samantha', age:60, gender:'girl'}
28304
+ ];
28305
+ });
28306
+ </file>
27657
28307
  <file name="animations.css">
27658
28308
  .example-animate-container {
27659
28309
  background:white;
@@ -27664,7 +28314,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
27664
28314
  }
27665
28315
 
27666
28316
  .animate-repeat {
27667
- line-height:40px;
28317
+ line-height:30px;
27668
28318
  list-style:none;
27669
28319
  box-sizing:border-box;
27670
28320
  }
@@ -27686,7 +28336,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
27686
28336
  .animate-repeat.ng-move.ng-move-active,
27687
28337
  .animate-repeat.ng-enter.ng-enter-active {
27688
28338
  opacity:1;
27689
- max-height:40px;
28339
+ max-height:30px;
27690
28340
  }
27691
28341
  </file>
27692
28342
  <file name="protractor.js" type="protractor">
@@ -28543,67 +29193,186 @@ var ngSwitchDefaultDirective = ngDirective({
28543
29193
  * @description
28544
29194
  * Directive that marks the insertion point for the transcluded DOM of the nearest parent directive that uses transclusion.
28545
29195
  *
28546
- * Any existing content of the element that this directive is placed on will be removed before the transcluded content is inserted.
29196
+ * You can specify that you want to insert a named transclusion slot, instead of the default slot, by providing the slot name
29197
+ * as the value of the `ng-transclude` or `ng-transclude-slot` attribute.
29198
+ *
29199
+ * If the transcluded content is not empty (i.e. contains one or more DOM nodes, including whitespace text nodes), any existing
29200
+ * content of this element will be removed before the transcluded content is inserted.
29201
+ * If the transcluded content is empty, the existing content is left intact. This lets you provide fallback content in the case
29202
+ * that no transcluded content is provided.
28547
29203
  *
28548
29204
  * @element ANY
28549
29205
  *
29206
+ * @param {string} ngTransclude|ngTranscludeSlot the name of the slot to insert at this point. If this is not provided, is empty
29207
+ * or its value is the same as the name of the attribute then the default slot is used.
29208
+ *
28550
29209
  * @example
28551
- <example module="transcludeExample">
28552
- <file name="index.html">
28553
- <script>
28554
- angular.module('transcludeExample', [])
28555
- .directive('pane', function(){
28556
- return {
28557
- restrict: 'E',
28558
- transclude: true,
28559
- scope: { title:'@' },
28560
- template: '<div style="border: 1px solid black;">' +
28561
- '<div style="background-color: gray">{{title}}</div>' +
28562
- '<ng-transclude></ng-transclude>' +
28563
- '</div>'
28564
- };
28565
- })
28566
- .controller('ExampleController', ['$scope', function($scope) {
28567
- $scope.title = 'Lorem Ipsum';
28568
- $scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';
28569
- }]);
28570
- </script>
28571
- <div ng-controller="ExampleController">
28572
- <input ng-model="title" aria-label="title"> <br/>
28573
- <textarea ng-model="text" aria-label="text"></textarea> <br/>
28574
- <pane title="{{title}}">{{text}}</pane>
28575
- </div>
28576
- </file>
28577
- <file name="protractor.js" type="protractor">
28578
- it('should have transcluded', function() {
28579
- var titleElement = element(by.model('title'));
28580
- titleElement.clear();
28581
- titleElement.sendKeys('TITLE');
28582
- var textElement = element(by.model('text'));
28583
- textElement.clear();
28584
- textElement.sendKeys('TEXT');
28585
- expect(element(by.binding('title')).getText()).toEqual('TITLE');
28586
- expect(element(by.binding('text')).getText()).toEqual('TEXT');
28587
- });
28588
- </file>
28589
- </example>
29210
+ * ### Basic transclusion
29211
+ * This example demonstrates basic transclusion of content into a component directive.
29212
+ * <example name="simpleTranscludeExample" module="transcludeExample">
29213
+ * <file name="index.html">
29214
+ * <script>
29215
+ * angular.module('transcludeExample', [])
29216
+ * .directive('pane', function(){
29217
+ * return {
29218
+ * restrict: 'E',
29219
+ * transclude: true,
29220
+ * scope: { title:'@' },
29221
+ * template: '<div style="border: 1px solid black;">' +
29222
+ * '<div style="background-color: gray">{{title}}</div>' +
29223
+ * '<ng-transclude></ng-transclude>' +
29224
+ * '</div>'
29225
+ * };
29226
+ * })
29227
+ * .controller('ExampleController', ['$scope', function($scope) {
29228
+ * $scope.title = 'Lorem Ipsum';
29229
+ * $scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';
29230
+ * }]);
29231
+ * </script>
29232
+ * <div ng-controller="ExampleController">
29233
+ * <input ng-model="title" aria-label="title"> <br/>
29234
+ * <textarea ng-model="text" aria-label="text"></textarea> <br/>
29235
+ * <pane title="{{title}}">{{text}}</pane>
29236
+ * </div>
29237
+ * </file>
29238
+ * <file name="protractor.js" type="protractor">
29239
+ * it('should have transcluded', function() {
29240
+ * var titleElement = element(by.model('title'));
29241
+ * titleElement.clear();
29242
+ * titleElement.sendKeys('TITLE');
29243
+ * var textElement = element(by.model('text'));
29244
+ * textElement.clear();
29245
+ * textElement.sendKeys('TEXT');
29246
+ * expect(element(by.binding('title')).getText()).toEqual('TITLE');
29247
+ * expect(element(by.binding('text')).getText()).toEqual('TEXT');
29248
+ * });
29249
+ * </file>
29250
+ * </example>
29251
+ *
29252
+ * @example
29253
+ * ### Transclude fallback content
29254
+ * This example shows how to use `NgTransclude` with fallback content, that
29255
+ * is displayed if no transcluded content is provided.
29256
+ *
29257
+ * <example module="transcludeFallbackContentExample">
29258
+ * <file name="index.html">
29259
+ * <script>
29260
+ * angular.module('transcludeFallbackContentExample', [])
29261
+ * .directive('myButton', function(){
29262
+ * return {
29263
+ * restrict: 'E',
29264
+ * transclude: true,
29265
+ * scope: true,
29266
+ * template: '<button style="cursor: pointer;">' +
29267
+ * '<ng-transclude>' +
29268
+ * '<b style="color: red;">Button1</b>' +
29269
+ * '</ng-transclude>' +
29270
+ * '</button>'
29271
+ * };
29272
+ * });
29273
+ * </script>
29274
+ * <!-- fallback button content -->
29275
+ * <my-button id="fallback"></my-button>
29276
+ * <!-- modified button content -->
29277
+ * <my-button id="modified">
29278
+ * <i style="color: green;">Button2</i>
29279
+ * </my-button>
29280
+ * </file>
29281
+ * <file name="protractor.js" type="protractor">
29282
+ * it('should have different transclude element content', function() {
29283
+ * expect(element(by.id('fallback')).getText()).toBe('Button1');
29284
+ * expect(element(by.id('modified')).getText()).toBe('Button2');
29285
+ * });
29286
+ * </file>
29287
+ * </example>
28590
29288
  *
29289
+ * @example
29290
+ * ### Multi-slot transclusion
29291
+ * This example demonstrates using multi-slot transclusion in a component directive.
29292
+ * <example name="multiSlotTranscludeExample" module="multiSlotTranscludeExample">
29293
+ * <file name="index.html">
29294
+ * <style>
29295
+ * .title, .footer {
29296
+ * background-color: gray
29297
+ * }
29298
+ * </style>
29299
+ * <div ng-controller="ExampleController">
29300
+ * <input ng-model="title" aria-label="title"> <br/>
29301
+ * <textarea ng-model="text" aria-label="text"></textarea> <br/>
29302
+ * <pane>
29303
+ * <pane-title><a ng-href="{{link}}">{{title}}</a></pane-title>
29304
+ * <pane-body><p>{{text}}</p></pane-body>
29305
+ * </pane>
29306
+ * </div>
29307
+ * </file>
29308
+ * <file name="app.js">
29309
+ * angular.module('multiSlotTranscludeExample', [])
29310
+ * .directive('pane', function(){
29311
+ * return {
29312
+ * restrict: 'E',
29313
+ * transclude: {
29314
+ * 'title': '?paneTitle',
29315
+ * 'body': 'paneBody',
29316
+ * 'footer': '?paneFooter'
29317
+ * },
29318
+ * template: '<div style="border: 1px solid black;">' +
29319
+ * '<div class="title" ng-transclude="title">Fallback Title</div>' +
29320
+ * '<div ng-transclude="body"></div>' +
29321
+ * '<div class="footer" ng-transclude="footer">Fallback Footer</div>' +
29322
+ * '</div>'
29323
+ * };
29324
+ * })
29325
+ * .controller('ExampleController', ['$scope', function($scope) {
29326
+ * $scope.title = 'Lorem Ipsum';
29327
+ * $scope.link = "https://google.com";
29328
+ * $scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';
29329
+ * }]);
29330
+ * </file>
29331
+ * <file name="protractor.js" type="protractor">
29332
+ * it('should have transcluded the title and the body', function() {
29333
+ * var titleElement = element(by.model('title'));
29334
+ * titleElement.clear();
29335
+ * titleElement.sendKeys('TITLE');
29336
+ * var textElement = element(by.model('text'));
29337
+ * textElement.clear();
29338
+ * textElement.sendKeys('TEXT');
29339
+ * expect(element(by.css('.title')).getText()).toEqual('TITLE');
29340
+ * expect(element(by.binding('text')).getText()).toEqual('TEXT');
29341
+ * expect(element(by.css('.footer')).getText()).toEqual('Fallback Footer');
29342
+ * });
29343
+ * </file>
29344
+ * </example>
28591
29345
  */
29346
+ var ngTranscludeMinErr = minErr('ngTransclude');
28592
29347
  var ngTranscludeDirective = ngDirective({
28593
29348
  restrict: 'EAC',
28594
29349
  link: function($scope, $element, $attrs, controller, $transclude) {
29350
+
29351
+ if ($attrs.ngTransclude === $attrs.$attr.ngTransclude) {
29352
+ // If the attribute is of the form: `ng-transclude="ng-transclude"`
29353
+ // then treat it like the default
29354
+ $attrs.ngTransclude = '';
29355
+ }
29356
+
29357
+ function ngTranscludeCloneAttachFn(clone) {
29358
+ if (clone.length) {
29359
+ $element.empty();
29360
+ $element.append(clone);
29361
+ }
29362
+ }
29363
+
28595
29364
  if (!$transclude) {
28596
- throw minErr('ngTransclude')('orphan',
29365
+ throw ngTranscludeMinErr('orphan',
28597
29366
  'Illegal use of ngTransclude directive in the template! ' +
28598
29367
  'No parent directive that requires a transclusion found. ' +
28599
29368
  'Element: {0}',
28600
29369
  startingTag($element));
28601
29370
  }
28602
29371
 
28603
- $transclude(function(clone) {
28604
- $element.empty();
28605
- $element.append(clone);
28606
- });
29372
+ // If there is no slot name defined or the slot name is not optional
29373
+ // then transclude the slot
29374
+ var slotName = $attrs.ngTransclude || $attrs.ngTranscludeSlot;
29375
+ $transclude(ngTranscludeCloneAttachFn, null, slotName);
28607
29376
  }
28608
29377
  });
28609
29378
 
@@ -28735,6 +29504,9 @@ var SelectController =
28735
29504
 
28736
29505
  // Tell the select control that an option, with the given value, has been added
28737
29506
  self.addOption = function(value, element) {
29507
+ // Skip comment nodes, as they only pollute the `optionsMap`
29508
+ if (element[0].nodeType === NODE_TYPE_COMMENT) return;
29509
+
28738
29510
  assertNotHasOwnProperty(value, '"option value"');
28739
29511
  if (value === '') {
28740
29512
  self.emptyOption = element;
@@ -28819,7 +29591,7 @@ var SelectController =
28819
29591
  *
28820
29592
  * <div class="alert alert-warning">
28821
29593
  * Note that the value of a `select` directive used without `ngOptions` is always a string.
28822
- * When the model needs to be bound to a non-string value, you must either explictly convert it
29594
+ * When the model needs to be bound to a non-string value, you must either explicitly convert it
28823
29595
  * using a directive (see example below) or use `ngOptions` to specify the set of options.
28824
29596
  * This is because an option element can only be bound to string values at present.
28825
29597
  * </div>
@@ -29107,7 +29879,6 @@ var optionDirective = ['$interpolate', function($interpolate) {
29107
29879
  restrict: 'E',
29108
29880
  priority: 100,
29109
29881
  compile: function(element, attr) {
29110
-
29111
29882
  if (isDefined(attr.value)) {
29112
29883
  // If the value attribute is defined, check if it contains an interpolation
29113
29884
  var interpolateValueFn = $interpolate(attr.value, true);
@@ -29121,7 +29892,6 @@ var optionDirective = ['$interpolate', function($interpolate) {
29121
29892
  }
29122
29893
 
29123
29894
  return function(scope, element, attr) {
29124
-
29125
29895
  // This is an optimization over using ^^ since we don't want to have to search
29126
29896
  // all the way to the root of the DOM for every single option element
29127
29897
  var selectCtrlName = '$selectController',
@@ -29158,7 +29928,7 @@ var styleDirective = valueFn({
29158
29928
  * for more info.
29159
29929
  *
29160
29930
  * The validator will set the `required` error key to true if the `required` attribute is set and
29161
- * calling {@link ngModel.NgModelController#$isEmpty `NgModelController.$isEmpty` with the
29931
+ * calling {@link ngModel.NgModelController#$isEmpty `NgModelController.$isEmpty`} with the
29162
29932
  * {@link ngModel.NgModelController#$viewValue `ngModel.$viewValue`} returns `true`. For example, the
29163
29933
  * `$isEmpty()` implementation for `input[text]` checks the length of the `$viewValue`. When developing
29164
29934
  * custom controls, `$isEmpty()` can be overwritten to account for a $viewValue that is not string-based.
@@ -29644,6 +30414,7 @@ $provide.value("$locale", {
29644
30414
  ]
29645
30415
  },
29646
30416
  "id": "en-us",
30417
+ "localeID": "en_US",
29647
30418
  "pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
29648
30419
  });
29649
30420
  }]);