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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/rails-angularjs/version.rb +1 -1
- data/vendor/assets/javascripts/angular-animate.js +296 -48
- data/vendor/assets/javascripts/angular-animate.min.js +52 -51
- data/vendor/assets/javascripts/angular-animate.min.js.map +3 -3
- data/vendor/assets/javascripts/angular-aria.js +51 -51
- data/vendor/assets/javascripts/angular-aria.min.js +10 -10
- data/vendor/assets/javascripts/angular-aria.min.js.map +2 -2
- data/vendor/assets/javascripts/angular-cookies.js +9 -8
- data/vendor/assets/javascripts/angular-cookies.min.js +2 -2
- data/vendor/assets/javascripts/angular-cookies.min.js.map +1 -1
- data/vendor/assets/javascripts/angular-loader.js +16 -3
- data/vendor/assets/javascripts/angular-loader.min.js +5 -5
- data/vendor/assets/javascripts/angular-loader.min.js.map +2 -2
- data/vendor/assets/javascripts/angular-message-format.js +2 -2
- data/vendor/assets/javascripts/angular-message-format.min.js +2 -2
- data/vendor/assets/javascripts/angular-messages.js +7 -5
- data/vendor/assets/javascripts/angular-messages.min.js +8 -8
- data/vendor/assets/javascripts/angular-messages.min.js.map +2 -2
- data/vendor/assets/javascripts/angular-mocks.js +323 -30
- data/vendor/assets/javascripts/angular-resource.js +116 -42
- data/vendor/assets/javascripts/angular-resource.min.js +11 -10
- data/vendor/assets/javascripts/angular-resource.min.js.map +3 -3
- data/vendor/assets/javascripts/angular-route.js +36 -11
- data/vendor/assets/javascripts/angular-route.min.js +11 -11
- data/vendor/assets/javascripts/angular-route.min.js.map +2 -2
- data/vendor/assets/javascripts/angular-sanitize.js +280 -246
- data/vendor/assets/javascripts/angular-sanitize.min.js +11 -12
- data/vendor/assets/javascripts/angular-sanitize.min.js.map +3 -3
- data/vendor/assets/javascripts/angular-scenario.js +1227 -456
- data/vendor/assets/javascripts/angular-touch.js +114 -12
- data/vendor/assets/javascripts/angular-touch.min.js +10 -9
- data/vendor/assets/javascripts/angular-touch.min.js.map +3 -3
- data/vendor/assets/javascripts/angular.js +1227 -456
- data/vendor/assets/javascripts/angular.min.js +302 -293
- data/vendor/assets/javascripts/angular.min.js.map +3 -3
- metadata +1 -1
@@ -1,10 +1,13 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.
|
3
|
-
* (c) 2010-
|
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
|
-
|
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.
|
3
|
-
(c) 2010-
|
2
|
+
AngularJS v1.5.0
|
3
|
+
(c) 2010-2016 Google, Inc. http://angularjs.org
|
4
4
|
License: MIT
|
5
5
|
*/
|
6
|
-
(function(x,
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
[a]
|
12
|
-
|
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":
|
5
|
-
"mappings":"A;;;;;aAKC,SAAQ,CAACA,CAAD,CAASC,CAAT,CAAkBC,CAAlB,CAA6B,
|
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","
|
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.
|
3
|
-
* (c) 2010-
|
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.
|
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
|
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) {
|
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(
|
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 (
|
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 (
|
1044
|
-
if (isArray(
|
1045
|
-
|
1046
|
-
|
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 (
|
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
|
1293
|
-
|
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) {
|
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
|
-
|
1790
|
-
|
1791
|
-
|
1792
|
-
|
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.
|
2427
|
+
full: '1.5.0', // all of these placeholder strings will be replaced by grunt's
|
2405
2428
|
major: 1, // package task
|
2406
|
-
minor:
|
2407
|
-
dot:
|
2408
|
-
codeName: '
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
4199
|
-
*
|
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
|
-
|
4400
|
+
protoInstanceInjector =
|
4350
4401
|
createInternalInjector(instanceCache, function(serviceName, caller) {
|
4351
4402
|
var provider = providerInjector.get(serviceName + providerSuffix, caller);
|
4352
|
-
return instanceInjector.invoke(
|
4353
|
-
|
4354
|
-
|
4403
|
+
return instanceInjector.invoke(
|
4404
|
+
provider.$get, provider, undefined, serviceName);
|
4405
|
+
}),
|
4406
|
+
instanceInjector = protoInstanceInjector;
|
4355
4407
|
|
4356
|
-
|
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
|
-
|
4525
|
-
|
4526
|
-
|
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
|
-
|
4534
|
-
|
4535
|
-
|
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
|
-
|
4542
|
-
var
|
4543
|
-
|
4544
|
-
|
4545
|
-
return
|
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 `
|
5163
|
-
* // to listen for `enter` on the given `
|
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
|
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
|
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
|
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
|
6611
|
-
* attribute name is assumed to be the same as the local name.
|
6612
|
-
*
|
6613
|
-
*
|
6614
|
-
*
|
6615
|
-
*
|
6616
|
-
*
|
6617
|
-
*
|
6618
|
-
*
|
6619
|
-
*
|
6620
|
-
* name
|
6621
|
-
*
|
6622
|
-
*
|
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
|
6625
|
-
*
|
6626
|
-
*
|
6627
|
-
*
|
6628
|
-
*
|
6629
|
-
*
|
6630
|
-
*
|
6631
|
-
*
|
6632
|
-
*
|
6633
|
-
*
|
6634
|
-
*
|
6635
|
-
*
|
6636
|
-
*
|
6637
|
-
*
|
6638
|
-
*
|
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.
|
6663
|
-
*
|
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
|
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 & 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`
|
6699
|
-
*
|
6700
|
-
*
|
6701
|
-
*
|
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
|
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
|
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
|
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
|
-
*
|
7029
|
-
*
|
7030
|
-
* the attributes
|
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*([
|
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
|
-
|
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 == '{{'
|
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
|
-
|
7746
|
-
|
7747
|
-
|
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' &&
|
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 =
|
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 =
|
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
|
-
|
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
|
-
//
|
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
|
-
|
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
|
9003
|
-
|
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
|
-
|
9021
|
-
|
9022
|
-
|
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
|
-
|
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(
|
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 '{
|
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
|
10268
|
-
*
|
10269
|
-
* to counter XSRF. When performing XHR requests, the
|
10270
|
-
* (by default, `XSRF-TOKEN`) and sets it as an HTTP
|
10271
|
-
* JavaScript that runs on your domain could read the
|
10272
|
-
* the XHR came from JavaScript running on your domain.
|
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 (!
|
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
|
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
|
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
|
-
//
|
12791
|
-
//
|
12792
|
-
//
|
12793
|
-
|
12794
|
-
|
12795
|
-
|
12796
|
-
|
12797
|
-
|
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 + '
|
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
|
14338
|
-
lhs
|
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
|
14354
|
-
lhs
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
15034
|
-
|
15035
|
-
|
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,
|
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
|
-
|
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 = ['$
|
15392
|
-
function($
|
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
|
-
|
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
|
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
|
-
*
|
16891
|
-
*
|
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
|
-
*
|
16894
|
-
*
|
17463
|
+
* Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
|
17464
|
+
* allowed in this array.
|
16895
17465
|
*
|
16896
|
-
*
|
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
|
-
*
|
16920
|
-
*
|
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
|
-
*
|
16923
|
-
*
|
17494
|
+
* Follow {@link ng.$sce#resourceUrlPatternItem this link} for a description of the items
|
17495
|
+
* allowed in this array.
|
16924
17496
|
*
|
16925
|
-
*
|
16926
|
-
*
|
16927
|
-
*
|
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
|
-
*
|
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
|
17896
|
-
* @name $
|
17897
|
-
*
|
18472
|
+
* @ngdoc provider
|
18473
|
+
* @name $templateRequestProvider
|
17898
18474
|
* @description
|
17899
|
-
*
|
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
|
-
*
|
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
|
-
|
17938
|
-
|
17939
|
-
|
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,
|
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 (
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
-
|
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
|
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
|
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
|
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
|
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 (
|
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
|
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`,
|
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
|
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', '
|
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
|
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
|
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
|
27630
|
-
*
|
27631
|
-
<example module="
|
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-
|
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:
|
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:
|
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
|
-
*
|
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
|
-
|
28552
|
-
|
28553
|
-
|
28554
|
-
|
28555
|
-
|
28556
|
-
|
28557
|
-
|
28558
|
-
|
28559
|
-
|
28560
|
-
|
28561
|
-
|
28562
|
-
|
28563
|
-
'</div>'
|
28564
|
-
|
28565
|
-
|
28566
|
-
|
28567
|
-
|
28568
|
-
|
28569
|
-
|
28570
|
-
|
28571
|
-
|
28572
|
-
|
28573
|
-
|
28574
|
-
|
28575
|
-
|
28576
|
-
|
28577
|
-
|
28578
|
-
|
28579
|
-
|
28580
|
-
|
28581
|
-
|
28582
|
-
|
28583
|
-
|
28584
|
-
|
28585
|
-
|
28586
|
-
|
28587
|
-
|
28588
|
-
|
28589
|
-
|
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
|
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
|
-
|
28604
|
-
|
28605
|
-
|
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
|
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
|
}]);
|