angular_velocity 0.0.6alpha → 1.0.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.
- data/Gemfile +1 -1
- data/lib/angular_velocity/version.rb +1 -1
- data/lib/generators/angular_velocity/install/templates/angular-cookies.js +16 -3
- data/lib/generators/angular_velocity/install/templates/angular-mocks.js +144 -103
- data/lib/generators/angular_velocity/install/templates/angular-resource.js +19 -7
- data/lib/generators/angular_velocity/install/templates/angular-sanitize.js +27 -6
- data/lib/generators/angular_velocity/install/templates/angular-scenario.js +885 -459
- data/lib/generators/angular_velocity/install/templates/angular.js +754 -356
- data/lib/generators/angular_velocity/install/templates/templates_controller.rb +2 -1
- metadata +6 -6
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.0.
|
2
|
+
* @license AngularJS v1.0.8
|
3
3
|
* (c) 2010-2012 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -24,6 +24,17 @@
|
|
24
24
|
* The returned resource object has action methods which provide high-level behaviors without
|
25
25
|
* the need to interact with the low level {@link ng.$http $http} service.
|
26
26
|
*
|
27
|
+
* # Installation
|
28
|
+
* To use $resource make sure you have included the `angular-resource.js` that comes in Angular
|
29
|
+
* package. You can also find this file on Google CDN, bower as well as at
|
30
|
+
* {@link http://code.angularjs.org/ code.angularjs.org}.
|
31
|
+
*
|
32
|
+
* Finally load the module in your application:
|
33
|
+
*
|
34
|
+
* angular.module('app', ['ngResource']);
|
35
|
+
*
|
36
|
+
* and you are ready to get started!
|
37
|
+
*
|
27
38
|
* @param {string} url A parameterized URL template with parameters prefixed by `:` as in
|
28
39
|
* `/user/:username`. If you are using a URL with a port number (e.g.
|
29
40
|
* `http://example.com:8080/api`), you'll need to escape the colon character before the port
|
@@ -50,12 +61,12 @@
|
|
50
61
|
*
|
51
62
|
* Where:
|
52
63
|
*
|
53
|
-
* - `action`
|
64
|
+
* - `action` – {string} – The name of action. This name becomes the name of the method on your
|
54
65
|
* resource object.
|
55
|
-
* - `method`
|
66
|
+
* - `method` – {string} – HTTP request method. Valid methods are: `GET`, `POST`, `PUT`, `DELETE`,
|
56
67
|
* and `JSONP`
|
57
|
-
* - `params`
|
58
|
-
* - isArray
|
68
|
+
* - `params` – {object=} – Optional set of pre-bound parameters for this action.
|
69
|
+
* - isArray – {boolean=} – If true then the returned object for this action is an array, see
|
59
70
|
* `returns` section.
|
60
71
|
*
|
61
72
|
* @returns {Object} A resource "class" object with methods for the default set of resource actions
|
@@ -268,7 +279,7 @@ angular.module('ngResource', ['ng']).
|
|
268
279
|
replace(/%3A/gi, ':').
|
269
280
|
replace(/%24/g, '$').
|
270
281
|
replace(/%2C/gi, ',').
|
271
|
-
replace((pctEncodeSpaces ?
|
282
|
+
replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
|
272
283
|
}
|
273
284
|
|
274
285
|
function Route(template, defaults) {
|
@@ -442,4 +453,5 @@ angular.module('ngResource', ['ng']).
|
|
442
453
|
return ResourceFactory;
|
443
454
|
}]);
|
444
455
|
|
445
|
-
|
456
|
+
|
457
|
+
})(window, window.angular);
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.0.
|
2
|
+
* @license AngularJS v1.0.8
|
3
3
|
* (c) 2010-2012 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -10,6 +10,25 @@
|
|
10
10
|
* @ngdoc overview
|
11
11
|
* @name ngSanitize
|
12
12
|
* @description
|
13
|
+
*
|
14
|
+
* The `ngSanitize` module provides functionality to sanitize HTML.
|
15
|
+
*
|
16
|
+
* # Installation
|
17
|
+
* As a separate module, it must be loaded after Angular core is loaded; otherwise, an 'Uncaught Error:
|
18
|
+
* No module: ngSanitize' runtime error will occur.
|
19
|
+
*
|
20
|
+
* <pre>
|
21
|
+
* <script src="angular.js"></script>
|
22
|
+
* <script src="angular-sanitize.js"></script>
|
23
|
+
* </pre>
|
24
|
+
*
|
25
|
+
* # Usage
|
26
|
+
* To make sure the module is available to your application, declare it as a dependency of you application
|
27
|
+
* module.
|
28
|
+
*
|
29
|
+
* <pre>
|
30
|
+
* angular.module('app', ['ngSanitize']);
|
31
|
+
* </pre>
|
13
32
|
*/
|
14
33
|
|
15
34
|
/*
|
@@ -129,7 +148,7 @@ var START_TAG_REGEXP = /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:
|
|
129
148
|
BEGING_END_TAGE_REGEXP = /^<\s*\//,
|
130
149
|
COMMENT_REGEXP = /<!--(.*?)-->/g,
|
131
150
|
CDATA_REGEXP = /<!\[CDATA\[(.*?)]]>/g,
|
132
|
-
URI_REGEXP = /^((ftp|https?):\/\/|mailto:|#)
|
151
|
+
URI_REGEXP = /^((ftp|https?):\/\/|mailto:|#)/i,
|
133
152
|
NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g; // Match everything outside of normal chars and " (quote character)
|
134
153
|
|
135
154
|
|
@@ -283,10 +302,10 @@ function htmlParser( html, handler ) {
|
|
283
302
|
|
284
303
|
var attrs = {};
|
285
304
|
|
286
|
-
rest.replace(ATTR_REGEXP, function(match, name, doubleQuotedValue,
|
305
|
+
rest.replace(ATTR_REGEXP, function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) {
|
287
306
|
var value = doubleQuotedValue
|
288
|
-
||
|
289
|
-
||
|
307
|
+
|| singleQuotedValue
|
308
|
+
|| unquotedValue
|
290
309
|
|| '';
|
291
310
|
|
292
311
|
attrs[name] = decodeEntities(value);
|
@@ -422,6 +441,7 @@ angular.module('ngSanitize').directive('ngBindHtml', ['$sanitize', function($san
|
|
422
441
|
});
|
423
442
|
};
|
424
443
|
}]);
|
444
|
+
|
425
445
|
/**
|
426
446
|
* @ngdoc filter
|
427
447
|
* @name ngSanitize.filter:linky
|
@@ -532,4 +552,5 @@ angular.module('ngSanitize').filter('linky', function() {
|
|
532
552
|
};
|
533
553
|
});
|
534
554
|
|
535
|
-
|
555
|
+
|
556
|
+
})(window, window.angular);
|
@@ -9403,8 +9403,9 @@ if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
|
|
9403
9403
|
|
9404
9404
|
|
9405
9405
|
})( window );
|
9406
|
+
|
9406
9407
|
/**
|
9407
|
-
* @license AngularJS v1.0.
|
9408
|
+
* @license AngularJS v1.0.8
|
9408
9409
|
* (c) 2010-2012 Google, Inc. http://angularjs.org
|
9409
9410
|
* License: MIT
|
9410
9411
|
*/
|
@@ -9439,12 +9440,12 @@ var uppercase = function(string){return isString(string) ? string.toUpperCase()
|
|
9439
9440
|
|
9440
9441
|
var manualLowercase = function(s) {
|
9441
9442
|
return isString(s)
|
9442
|
-
? s.replace(/[A-Z]/g, function(ch) {return fromCharCode(ch.charCodeAt(0) | 32);})
|
9443
|
+
? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})
|
9443
9444
|
: s;
|
9444
9445
|
};
|
9445
9446
|
var manualUppercase = function(s) {
|
9446
9447
|
return isString(s)
|
9447
|
-
? s.replace(/[a-z]/g, function(ch) {return fromCharCode(ch.charCodeAt(0) & ~32);})
|
9448
|
+
? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})
|
9448
9449
|
: s;
|
9449
9450
|
};
|
9450
9451
|
|
@@ -9457,8 +9458,6 @@ if ('i' !== 'I'.toLowerCase()) {
|
|
9457
9458
|
uppercase = manualUppercase;
|
9458
9459
|
}
|
9459
9460
|
|
9460
|
-
function fromCharCode(code) {return String.fromCharCode(code);}
|
9461
|
-
|
9462
9461
|
|
9463
9462
|
var /** holds major version number for IE or NaN for real browsers */
|
9464
9463
|
msie = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]),
|
@@ -9474,6 +9473,29 @@ var /** holds major version number for IE or NaN for real browsers */
|
|
9474
9473
|
nodeName_,
|
9475
9474
|
uid = ['0', '0', '0'];
|
9476
9475
|
|
9476
|
+
|
9477
|
+
/**
|
9478
|
+
* @private
|
9479
|
+
* @param {*} obj
|
9480
|
+
* @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...)
|
9481
|
+
*/
|
9482
|
+
function isArrayLike(obj) {
|
9483
|
+
if (!obj || (typeof obj.length !== 'number')) return false;
|
9484
|
+
|
9485
|
+
// We have on object which has length property. Should we treat it as array?
|
9486
|
+
if (typeof obj.hasOwnProperty != 'function' &&
|
9487
|
+
typeof obj.constructor != 'function') {
|
9488
|
+
// This is here for IE8: it is a bogus object treat it as array;
|
9489
|
+
return true;
|
9490
|
+
} else {
|
9491
|
+
return obj instanceof JQLite || // JQLite
|
9492
|
+
(jQuery && obj instanceof jQuery) || // jQuery
|
9493
|
+
toString.call(obj) !== '[object Object]' || // some browser native object
|
9494
|
+
typeof obj.callee === 'function'; // arguments (on IE8 looks like regular obj)
|
9495
|
+
}
|
9496
|
+
}
|
9497
|
+
|
9498
|
+
|
9477
9499
|
/**
|
9478
9500
|
* @ngdoc function
|
9479
9501
|
* @name angular.forEach
|
@@ -9501,30 +9523,6 @@ var /** holds major version number for IE or NaN for real browsers */
|
|
9501
9523
|
* @param {Object=} context Object to become context (`this`) for the iterator function.
|
9502
9524
|
* @returns {Object|Array} Reference to `obj`.
|
9503
9525
|
*/
|
9504
|
-
|
9505
|
-
|
9506
|
-
/**
|
9507
|
-
* @private
|
9508
|
-
* @param {*} obj
|
9509
|
-
* @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...)
|
9510
|
-
*/
|
9511
|
-
function isArrayLike(obj) {
|
9512
|
-
if (!obj || (typeof obj.length !== 'number')) return false;
|
9513
|
-
|
9514
|
-
// We have on object which has length property. Should we treat it as array?
|
9515
|
-
if (typeof obj.hasOwnProperty != 'function' &&
|
9516
|
-
typeof obj.constructor != 'function') {
|
9517
|
-
// This is here for IE8: it is a bogus object treat it as array;
|
9518
|
-
return true;
|
9519
|
-
} else {
|
9520
|
-
return obj instanceof JQLite || // JQLite
|
9521
|
-
(jQuery && obj instanceof jQuery) || // jQuery
|
9522
|
-
toString.call(obj) !== '[object Object]' || // some browser native object
|
9523
|
-
typeof obj.callee === 'function'; // arguments (on IE8 looks like regular obj)
|
9524
|
-
}
|
9525
|
-
}
|
9526
|
-
|
9527
|
-
|
9528
9526
|
function forEach(obj, iterator, context) {
|
9529
9527
|
var key;
|
9530
9528
|
if (obj) {
|
@@ -9608,6 +9606,21 @@ function nextUid() {
|
|
9608
9606
|
return uid.join('');
|
9609
9607
|
}
|
9610
9608
|
|
9609
|
+
|
9610
|
+
/**
|
9611
|
+
* Set or clear the hashkey for an object.
|
9612
|
+
* @param obj object
|
9613
|
+
* @param h the hashkey (!truthy to delete the hashkey)
|
9614
|
+
*/
|
9615
|
+
function setHashKey(obj, h) {
|
9616
|
+
if (h) {
|
9617
|
+
obj.$$hashKey = h;
|
9618
|
+
}
|
9619
|
+
else {
|
9620
|
+
delete obj.$$hashKey;
|
9621
|
+
}
|
9622
|
+
}
|
9623
|
+
|
9611
9624
|
/**
|
9612
9625
|
* @ngdoc function
|
9613
9626
|
* @name angular.extend
|
@@ -9619,8 +9632,10 @@ function nextUid() {
|
|
9619
9632
|
*
|
9620
9633
|
* @param {Object} dst Destination object.
|
9621
9634
|
* @param {...Object} src Source object(s).
|
9635
|
+
* @returns {Object} Reference to `dst`.
|
9622
9636
|
*/
|
9623
9637
|
function extend(dst) {
|
9638
|
+
var h = dst.$$hashKey;
|
9624
9639
|
forEach(arguments, function(obj){
|
9625
9640
|
if (obj !== dst) {
|
9626
9641
|
forEach(obj, function(value, key){
|
@@ -9628,6 +9643,8 @@ function extend(dst) {
|
|
9628
9643
|
});
|
9629
9644
|
}
|
9630
9645
|
});
|
9646
|
+
|
9647
|
+
setHashKey(dst,h);
|
9631
9648
|
return dst;
|
9632
9649
|
}
|
9633
9650
|
|
@@ -9671,7 +9688,7 @@ noop.$inject = [];
|
|
9671
9688
|
*
|
9672
9689
|
<pre>
|
9673
9690
|
function transformer(transformationFn, value) {
|
9674
|
-
return (transformationFn || identity)(value);
|
9691
|
+
return (transformationFn || angular.identity)(value);
|
9675
9692
|
};
|
9676
9693
|
</pre>
|
9677
9694
|
*/
|
@@ -9798,6 +9815,18 @@ function isArray(value) {
|
|
9798
9815
|
function isFunction(value){return typeof value == 'function';}
|
9799
9816
|
|
9800
9817
|
|
9818
|
+
/**
|
9819
|
+
* Determines if a value is a regular expression object.
|
9820
|
+
*
|
9821
|
+
* @private
|
9822
|
+
* @param {*} value Reference to check.
|
9823
|
+
* @returns {boolean} True if `value` is a `RegExp`.
|
9824
|
+
*/
|
9825
|
+
function isRegExp(value) {
|
9826
|
+
return toString.apply(value) == '[object RegExp]';
|
9827
|
+
}
|
9828
|
+
|
9829
|
+
|
9801
9830
|
/**
|
9802
9831
|
* Checks if `obj` is a window object.
|
9803
9832
|
*
|
@@ -9825,9 +9854,20 @@ function isBoolean(value) {
|
|
9825
9854
|
}
|
9826
9855
|
|
9827
9856
|
|
9828
|
-
|
9829
|
-
|
9830
|
-
|
9857
|
+
var trim = (function() {
|
9858
|
+
// native trim is way faster: http://jsperf.com/angular-trim-test
|
9859
|
+
// but IE doesn't have it... :-(
|
9860
|
+
// TODO: we should move this into IE/ES5 polyfill
|
9861
|
+
if (!String.prototype.trim) {
|
9862
|
+
return function(value) {
|
9863
|
+
return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
|
9864
|
+
};
|
9865
|
+
}
|
9866
|
+
return function(value) {
|
9867
|
+
return isString(value) ? value.trim() : value;
|
9868
|
+
};
|
9869
|
+
})();
|
9870
|
+
|
9831
9871
|
|
9832
9872
|
/**
|
9833
9873
|
* @ngdoc function
|
@@ -9970,6 +10010,8 @@ function copy(source, destination){
|
|
9970
10010
|
destination = copy(source, []);
|
9971
10011
|
} else if (isDate(source)) {
|
9972
10012
|
destination = new Date(source.getTime());
|
10013
|
+
} else if (isRegExp(source)) {
|
10014
|
+
destination = new RegExp(source.source);
|
9973
10015
|
} else if (isObject(source)) {
|
9974
10016
|
destination = copy(source, {});
|
9975
10017
|
}
|
@@ -9982,12 +10024,14 @@ function copy(source, destination){
|
|
9982
10024
|
destination.push(copy(source[i]));
|
9983
10025
|
}
|
9984
10026
|
} else {
|
10027
|
+
var h = destination.$$hashKey;
|
9985
10028
|
forEach(destination, function(value, key){
|
9986
10029
|
delete destination[key];
|
9987
10030
|
});
|
9988
10031
|
for ( var key in source) {
|
9989
10032
|
destination[key] = copy(source[key]);
|
9990
10033
|
}
|
10034
|
+
setHashKey(destination,h);
|
9991
10035
|
}
|
9992
10036
|
}
|
9993
10037
|
return destination;
|
@@ -10015,7 +10059,7 @@ function shallowCopy(src, dst) {
|
|
10015
10059
|
* @function
|
10016
10060
|
*
|
10017
10061
|
* @description
|
10018
|
-
* Determines if two objects or two values are equivalent. Supports value types, arrays and
|
10062
|
+
* Determines if two objects or two values are equivalent. Supports value types, regular expressions, arrays and
|
10019
10063
|
* objects.
|
10020
10064
|
*
|
10021
10065
|
* Two objects or values are considered equivalent if at least one of the following is true:
|
@@ -10023,11 +10067,14 @@ function shallowCopy(src, dst) {
|
|
10023
10067
|
* * Both objects or values pass `===` comparison.
|
10024
10068
|
* * Both objects or values are of the same type and all of their properties pass `===` comparison.
|
10025
10069
|
* * Both values are NaN. (In JavasScript, NaN == NaN => false. But we consider two NaN as equal)
|
10070
|
+
* * Both values represent the same regular expression (In JavasScript,
|
10071
|
+
* /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual
|
10072
|
+
* representation matches).
|
10026
10073
|
*
|
10027
10074
|
* During a property comparision, properties of `function` type and properties with names
|
10028
10075
|
* that begin with `$` are ignored.
|
10029
10076
|
*
|
10030
|
-
* Scope and DOMWindow objects are being compared only
|
10077
|
+
* Scope and DOMWindow objects are being compared only by identify (`===`).
|
10031
10078
|
*
|
10032
10079
|
* @param {*} o1 Object or value to compare.
|
10033
10080
|
* @param {*} o2 Object or value to compare.
|
@@ -10041,6 +10088,7 @@ function equals(o1, o2) {
|
|
10041
10088
|
if (t1 == t2) {
|
10042
10089
|
if (t1 == 'object') {
|
10043
10090
|
if (isArray(o1)) {
|
10091
|
+
if (!isArray(o2)) return false;
|
10044
10092
|
if ((length = o1.length) == o2.length) {
|
10045
10093
|
for(key=0; key<length; key++) {
|
10046
10094
|
if (!equals(o1[key], o2[key])) return false;
|
@@ -10049,8 +10097,10 @@ function equals(o1, o2) {
|
|
10049
10097
|
}
|
10050
10098
|
} else if (isDate(o1)) {
|
10051
10099
|
return isDate(o2) && o1.getTime() == o2.getTime();
|
10100
|
+
} else if (isRegExp(o1) && isRegExp(o2)) {
|
10101
|
+
return o1.toString() == o2.toString();
|
10052
10102
|
} else {
|
10053
|
-
if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2)) return false;
|
10103
|
+
if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || isArray(o2)) return false;
|
10054
10104
|
keySet = {};
|
10055
10105
|
for(key in o1) {
|
10056
10106
|
if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
|
@@ -10087,7 +10137,7 @@ function sliceArgs(args, startIndex) {
|
|
10087
10137
|
*
|
10088
10138
|
* @description
|
10089
10139
|
* Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
|
10090
|
-
* `fn`). You can supply optional `args` that are
|
10140
|
+
* `fn`). You can supply optional `args` that are prebound to the function. This feature is also
|
10091
10141
|
* known as [function currying](http://en.wikipedia.org/wiki/Currying).
|
10092
10142
|
*
|
10093
10143
|
* @param {Object} self Context which `fn` should be evaluated in.
|
@@ -10139,13 +10189,15 @@ function toJsonReplacer(key, value) {
|
|
10139
10189
|
* @function
|
10140
10190
|
*
|
10141
10191
|
* @description
|
10142
|
-
* Serializes input into a JSON-formatted string.
|
10192
|
+
* Serializes input into a JSON-formatted string. Properties with leading $ characters will be
|
10193
|
+
* stripped since angular uses this notation internally.
|
10143
10194
|
*
|
10144
10195
|
* @param {Object|Array|Date|string|number} obj Input to be serialized into JSON.
|
10145
10196
|
* @param {boolean=} pretty If set to true, the JSON output will contain newlines and whitespace.
|
10146
|
-
* @returns {string} Jsonified string representing `obj`.
|
10197
|
+
* @returns {string|undefined} Jsonified string representing `obj`.
|
10147
10198
|
*/
|
10148
10199
|
function toJson(obj, pretty) {
|
10200
|
+
if (typeof obj === 'undefined') return undefined;
|
10149
10201
|
return JSON.stringify(obj, toJsonReplacer, pretty ? ' ' : null);
|
10150
10202
|
}
|
10151
10203
|
|
@@ -10205,6 +10257,23 @@ function startingTag(element) {
|
|
10205
10257
|
|
10206
10258
|
/////////////////////////////////////////////////
|
10207
10259
|
|
10260
|
+
/**
|
10261
|
+
* Tries to decode the URI component without throwing an exception.
|
10262
|
+
*
|
10263
|
+
* @private
|
10264
|
+
* @param str value potential URI component to check.
|
10265
|
+
* @returns {boolean} True if `value` can be decoded
|
10266
|
+
* with the decodeURIComponent function.
|
10267
|
+
*/
|
10268
|
+
function tryDecodeURIComponent(value) {
|
10269
|
+
try {
|
10270
|
+
return decodeURIComponent(value);
|
10271
|
+
} catch(e) {
|
10272
|
+
// Ignore any invalid uri component
|
10273
|
+
}
|
10274
|
+
}
|
10275
|
+
|
10276
|
+
|
10208
10277
|
/**
|
10209
10278
|
* Parses an escaped url query string into key-value pairs.
|
10210
10279
|
* @returns Object.<(string|boolean)>
|
@@ -10212,10 +10281,12 @@ function startingTag(element) {
|
|
10212
10281
|
function parseKeyValue(/**string*/keyValue) {
|
10213
10282
|
var obj = {}, key_value, key;
|
10214
10283
|
forEach((keyValue || "").split('&'), function(keyValue){
|
10215
|
-
if (keyValue) {
|
10284
|
+
if ( keyValue ) {
|
10216
10285
|
key_value = keyValue.split('=');
|
10217
|
-
key =
|
10218
|
-
|
10286
|
+
key = tryDecodeURIComponent(key_value[0]);
|
10287
|
+
if ( isDefined(key) ) {
|
10288
|
+
obj[key] = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
|
10289
|
+
}
|
10219
10290
|
}
|
10220
10291
|
});
|
10221
10292
|
return obj;
|
@@ -10266,7 +10337,7 @@ function encodeUriQuery(val, pctEncodeSpaces) {
|
|
10266
10337
|
replace(/%3A/gi, ':').
|
10267
10338
|
replace(/%24/g, '$').
|
10268
10339
|
replace(/%2C/gi, ',').
|
10269
|
-
replace((pctEncodeSpaces ?
|
10340
|
+
replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
|
10270
10341
|
}
|
10271
10342
|
|
10272
10343
|
|
@@ -10280,11 +10351,15 @@ function encodeUriQuery(val, pctEncodeSpaces) {
|
|
10280
10351
|
*
|
10281
10352
|
* @description
|
10282
10353
|
*
|
10283
|
-
* Use this directive to auto-bootstrap
|
10284
|
-
* one directive can be used per HTML document. The directive
|
10354
|
+
* Use this directive to auto-bootstrap an application. Only
|
10355
|
+
* one ngApp directive can be used per HTML document. The directive
|
10285
10356
|
* designates the root of the application and is typically placed
|
10286
10357
|
* at the root of the page.
|
10287
10358
|
*
|
10359
|
+
* The first ngApp found in the document will be auto-bootstrapped. To use multiple applications in an
|
10360
|
+
* HTML document you must manually bootstrap them using {@link angular.bootstrap}.
|
10361
|
+
* Applications cannot be nested.
|
10362
|
+
*
|
10288
10363
|
* In the example below if the `ngApp` directive would not be placed
|
10289
10364
|
* on the `html` element then the document would not be compiled
|
10290
10365
|
* and the `{{ 1+2 }}` would not be resolved to `3`.
|
@@ -10350,27 +10425,46 @@ function angularInit(element, bootstrap) {
|
|
10350
10425
|
*
|
10351
10426
|
* See: {@link guide/bootstrap Bootstrap}
|
10352
10427
|
*
|
10428
|
+
* Note that ngScenario-based end-to-end tests cannot use this function to bootstrap manually.
|
10429
|
+
* They must use {@link api/ng.directive:ngApp ngApp}.
|
10430
|
+
*
|
10353
10431
|
* @param {Element} element DOM element which is the root of angular application.
|
10354
10432
|
* @param {Array<String|Function>=} modules an array of module declarations. See: {@link angular.module modules}
|
10355
10433
|
* @returns {AUTO.$injector} Returns the newly created injector for this app.
|
10356
10434
|
*/
|
10357
10435
|
function bootstrap(element, modules) {
|
10358
|
-
|
10359
|
-
|
10360
|
-
|
10361
|
-
|
10362
|
-
|
10363
|
-
|
10364
|
-
|
10365
|
-
|
10366
|
-
['$rootScope', '$rootElement', '$compile', '$injector',
|
10367
|
-
|
10368
|
-
|
10369
|
-
|
10370
|
-
|
10371
|
-
|
10372
|
-
|
10373
|
-
|
10436
|
+
var doBootstrap = function() {
|
10437
|
+
element = jqLite(element);
|
10438
|
+
modules = modules || [];
|
10439
|
+
modules.unshift(['$provide', function($provide) {
|
10440
|
+
$provide.value('$rootElement', element);
|
10441
|
+
}]);
|
10442
|
+
modules.unshift('ng');
|
10443
|
+
var injector = createInjector(modules);
|
10444
|
+
injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
|
10445
|
+
function(scope, element, compile, injector) {
|
10446
|
+
scope.$apply(function() {
|
10447
|
+
element.data('$injector', injector);
|
10448
|
+
compile(element)(scope);
|
10449
|
+
});
|
10450
|
+
}]
|
10451
|
+
);
|
10452
|
+
return injector;
|
10453
|
+
};
|
10454
|
+
|
10455
|
+
var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
|
10456
|
+
|
10457
|
+
if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
|
10458
|
+
return doBootstrap();
|
10459
|
+
}
|
10460
|
+
|
10461
|
+
window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
|
10462
|
+
angular.resumeBootstrap = function(extraModules) {
|
10463
|
+
forEach(extraModules, function(module) {
|
10464
|
+
modules.push(module);
|
10465
|
+
});
|
10466
|
+
doBootstrap();
|
10467
|
+
};
|
10374
10468
|
}
|
10375
10469
|
|
10376
10470
|
var SNAKE_CASE_REGEXP = /[A-Z]/g;
|
@@ -10393,9 +10487,10 @@ function bindJQuery() {
|
|
10393
10487
|
injector: JQLitePrototype.injector,
|
10394
10488
|
inheritedData: JQLitePrototype.inheritedData
|
10395
10489
|
});
|
10396
|
-
JQLitePatchJQueryRemove(
|
10397
|
-
JQLitePatchJQueryRemove('
|
10398
|
-
JQLitePatchJQueryRemove('
|
10490
|
+
// Method signature: JQLitePatchJQueryRemove(name, dispatchThis, filterElems, getterIfNoArguments)
|
10491
|
+
JQLitePatchJQueryRemove('remove', true, true, false);
|
10492
|
+
JQLitePatchJQueryRemove('empty', false, false, false);
|
10493
|
+
JQLitePatchJQueryRemove('html', false, false, true);
|
10399
10494
|
} else {
|
10400
10495
|
jqLite = JQLite;
|
10401
10496
|
}
|
@@ -10403,7 +10498,7 @@ function bindJQuery() {
|
|
10403
10498
|
}
|
10404
10499
|
|
10405
10500
|
/**
|
10406
|
-
* throw error
|
10501
|
+
* throw error if the argument is falsy.
|
10407
10502
|
*/
|
10408
10503
|
function assertArg(arg, name, reason) {
|
10409
10504
|
if (!arg) {
|
@@ -10422,6 +10517,33 @@ function assertArgFn(arg, name, acceptArrayAnnotation) {
|
|
10422
10517
|
return arg;
|
10423
10518
|
}
|
10424
10519
|
|
10520
|
+
/**
|
10521
|
+
* Return the value accessible from the object by path. Any undefined traversals are ignored
|
10522
|
+
* @param {Object} obj starting object
|
10523
|
+
* @param {string} path path to traverse
|
10524
|
+
* @param {boolean=true} bindFnToScope
|
10525
|
+
* @returns value as accessible by path
|
10526
|
+
*/
|
10527
|
+
//TODO(misko): this function needs to be removed
|
10528
|
+
function getter(obj, path, bindFnToScope) {
|
10529
|
+
if (!path) return obj;
|
10530
|
+
var keys = path.split('.');
|
10531
|
+
var key;
|
10532
|
+
var lastInstance = obj;
|
10533
|
+
var len = keys.length;
|
10534
|
+
|
10535
|
+
for (var i = 0; i < len; i++) {
|
10536
|
+
key = keys[i];
|
10537
|
+
if (obj) {
|
10538
|
+
obj = (lastInstance = obj)[key];
|
10539
|
+
}
|
10540
|
+
}
|
10541
|
+
if (!bindFnToScope && isFunction(obj)) {
|
10542
|
+
return bind(lastInstance, obj);
|
10543
|
+
}
|
10544
|
+
return obj;
|
10545
|
+
}
|
10546
|
+
|
10425
10547
|
/**
|
10426
10548
|
* @ngdoc interface
|
10427
10549
|
* @name angular.Module
|
@@ -10452,8 +10574,8 @@ function setupModuleLoader(window) {
|
|
10452
10574
|
*
|
10453
10575
|
* # Module
|
10454
10576
|
*
|
10455
|
-
* A module is a
|
10456
|
-
* is used to configure the {@link AUTO.$injector $injector}.
|
10577
|
+
* A module is a collection of services, directives, filters, and configuration information.
|
10578
|
+
* `angular.module` is used to configure the {@link AUTO.$injector $injector}.
|
10457
10579
|
*
|
10458
10580
|
* <pre>
|
10459
10581
|
* // Create a new module
|
@@ -10677,18 +10799,18 @@ function setupModuleLoader(window) {
|
|
10677
10799
|
* An object that contains information about the current AngularJS version. This object has the
|
10678
10800
|
* following properties:
|
10679
10801
|
*
|
10680
|
-
* - `full`
|
10681
|
-
* - `major`
|
10682
|
-
* - `minor`
|
10683
|
-
* - `dot`
|
10684
|
-
* - `codeName`
|
10802
|
+
* - `full` – `{string}` – Full version string, such as "0.9.18".
|
10803
|
+
* - `major` – `{number}` – Major version number, such as "0".
|
10804
|
+
* - `minor` – `{number}` – Minor version number, such as "9".
|
10805
|
+
* - `dot` – `{number}` – Dot version number, such as "18".
|
10806
|
+
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
|
10685
10807
|
*/
|
10686
10808
|
var version = {
|
10687
|
-
full: '1.0.
|
10688
|
-
major: 1, //
|
10809
|
+
full: '1.0.8', // all of these placeholder strings will be replaced by grunt's
|
10810
|
+
major: 1, // package task
|
10689
10811
|
minor: 0,
|
10690
|
-
dot:
|
10691
|
-
codeName: '
|
10812
|
+
dot: 8,
|
10813
|
+
codeName: 'bubble-burst'
|
10692
10814
|
};
|
10693
10815
|
|
10694
10816
|
|
@@ -10757,7 +10879,6 @@ function publishExternalAPI(angular){
|
|
10757
10879
|
ngPluralize: ngPluralizeDirective,
|
10758
10880
|
ngRepeat: ngRepeatDirective,
|
10759
10881
|
ngShow: ngShowDirective,
|
10760
|
-
ngSubmit: ngSubmitDirective,
|
10761
10882
|
ngStyle: ngStyleDirective,
|
10762
10883
|
ngSwitch: ngSwitchDirective,
|
10763
10884
|
ngSwitchWhen: ngSwitchWhenDirective,
|
@@ -10827,24 +10948,25 @@ function publishExternalAPI(angular){
|
|
10827
10948
|
* Note: All element references in Angular are always wrapped with jQuery or jqLite; they are never
|
10828
10949
|
* raw DOM references.
|
10829
10950
|
*
|
10830
|
-
* ## Angular's
|
10951
|
+
* ## Angular's jqLite
|
10952
|
+
* Angular's lite version of jQuery provides only the following jQuery methods:
|
10831
10953
|
*
|
10832
10954
|
* - [addClass()](http://api.jquery.com/addClass/)
|
10833
10955
|
* - [after()](http://api.jquery.com/after/)
|
10834
10956
|
* - [append()](http://api.jquery.com/append/)
|
10835
10957
|
* - [attr()](http://api.jquery.com/attr/)
|
10836
|
-
* - [bind()](http://api.jquery.com/bind/)
|
10837
|
-
* - [children()](http://api.jquery.com/children/)
|
10958
|
+
* - [bind()](http://api.jquery.com/bind/) - Does not support namespaces
|
10959
|
+
* - [children()](http://api.jquery.com/children/) - Does not support selectors
|
10838
10960
|
* - [clone()](http://api.jquery.com/clone/)
|
10839
10961
|
* - [contents()](http://api.jquery.com/contents/)
|
10840
10962
|
* - [css()](http://api.jquery.com/css/)
|
10841
10963
|
* - [data()](http://api.jquery.com/data/)
|
10842
10964
|
* - [eq()](http://api.jquery.com/eq/)
|
10843
|
-
* - [find()](http://api.jquery.com/find/) - Limited to lookups by tag name
|
10965
|
+
* - [find()](http://api.jquery.com/find/) - Limited to lookups by tag name
|
10844
10966
|
* - [hasClass()](http://api.jquery.com/hasClass/)
|
10845
10967
|
* - [html()](http://api.jquery.com/html/)
|
10846
|
-
* - [next()](http://api.jquery.com/next/)
|
10847
|
-
* - [parent()](http://api.jquery.com/parent/)
|
10968
|
+
* - [next()](http://api.jquery.com/next/) - Does not support selectors
|
10969
|
+
* - [parent()](http://api.jquery.com/parent/) - Does not support selectors
|
10848
10970
|
* - [prepend()](http://api.jquery.com/prepend/)
|
10849
10971
|
* - [prop()](http://api.jquery.com/prop/)
|
10850
10972
|
* - [ready()](http://api.jquery.com/ready/)
|
@@ -10856,12 +10978,18 @@ function publishExternalAPI(angular){
|
|
10856
10978
|
* - [text()](http://api.jquery.com/text/)
|
10857
10979
|
* - [toggleClass()](http://api.jquery.com/toggleClass/)
|
10858
10980
|
* - [triggerHandler()](http://api.jquery.com/triggerHandler/) - Doesn't pass native event objects to handlers.
|
10859
|
-
* - [unbind()](http://api.jquery.com/unbind/)
|
10981
|
+
* - [unbind()](http://api.jquery.com/unbind/) - Does not support namespaces
|
10860
10982
|
* - [val()](http://api.jquery.com/val/)
|
10861
10983
|
* - [wrap()](http://api.jquery.com/wrap/)
|
10862
10984
|
*
|
10863
|
-
* ##
|
10985
|
+
* ## jQuery/jqLite Extras
|
10986
|
+
* Angular also provides the following additional methods and events to both jQuery and jqLite:
|
10864
10987
|
*
|
10988
|
+
* ### Events
|
10989
|
+
* - `$destroy` - AngularJS intercepts all jqLite/jQuery's DOM destruction apis and fires this event
|
10990
|
+
* on all DOM nodes being removed. This can be used to clean up and 3rd party bindings to the DOM
|
10991
|
+
* element before it is removed.
|
10992
|
+
* ### Methods
|
10865
10993
|
* - `controller(name)` - retrieves the controller of the current element or its parent. By default
|
10866
10994
|
* retrieves controller associated with the `ngController` directive. If `name` is provided as
|
10867
10995
|
* camelCase directive name, then the controller for this directive will be retrieved (e.g.
|
@@ -10908,37 +11036,38 @@ function camelCase(name) {
|
|
10908
11036
|
/////////////////////////////////////////////
|
10909
11037
|
// jQuery mutation patch
|
10910
11038
|
//
|
10911
|
-
//
|
11039
|
+
// In conjunction with bindJQuery intercepts all jQuery's DOM destruction apis and fires a
|
10912
11040
|
// $destroy event on all DOM nodes being removed.
|
10913
11041
|
//
|
10914
11042
|
/////////////////////////////////////////////
|
10915
11043
|
|
10916
|
-
function JQLitePatchJQueryRemove(name, dispatchThis) {
|
11044
|
+
function JQLitePatchJQueryRemove(name, dispatchThis, filterElems, getterIfNoArguments) {
|
10917
11045
|
var originalJqFn = jQuery.fn[name];
|
10918
11046
|
originalJqFn = originalJqFn.$original || originalJqFn;
|
10919
11047
|
removePatch.$original = originalJqFn;
|
10920
11048
|
jQuery.fn[name] = removePatch;
|
10921
11049
|
|
10922
|
-
function removePatch() {
|
10923
|
-
var list = [this],
|
11050
|
+
function removePatch(param) {
|
11051
|
+
var list = filterElems && param ? [this.filter(param)] : [this],
|
10924
11052
|
fireEvent = dispatchThis,
|
10925
11053
|
set, setIndex, setLength,
|
10926
|
-
element, childIndex, childLength, children
|
10927
|
-
|
10928
|
-
|
10929
|
-
|
10930
|
-
|
10931
|
-
|
10932
|
-
|
10933
|
-
|
10934
|
-
|
10935
|
-
|
10936
|
-
|
10937
|
-
|
10938
|
-
|
10939
|
-
|
10940
|
-
|
10941
|
-
|
11054
|
+
element, childIndex, childLength, children;
|
11055
|
+
|
11056
|
+
if (!getterIfNoArguments || param != null) {
|
11057
|
+
while(list.length) {
|
11058
|
+
set = list.shift();
|
11059
|
+
for(setIndex = 0, setLength = set.length; setIndex < setLength; setIndex++) {
|
11060
|
+
element = jqLite(set[setIndex]);
|
11061
|
+
if (fireEvent) {
|
11062
|
+
element.triggerHandler('$destroy');
|
11063
|
+
} else {
|
11064
|
+
fireEvent = !fireEvent;
|
11065
|
+
}
|
11066
|
+
for(childIndex = 0, childLength = (children = element.children()).length;
|
11067
|
+
childIndex < childLength;
|
11068
|
+
childIndex++) {
|
11069
|
+
list.push(jQuery(children[childIndex]));
|
11070
|
+
}
|
10942
11071
|
}
|
10943
11072
|
}
|
10944
11073
|
}
|
@@ -10998,7 +11127,7 @@ function JQLiteUnbind(element, type, fn) {
|
|
10998
11127
|
removeEventListenerFn(element, type, events[type]);
|
10999
11128
|
delete events[type];
|
11000
11129
|
} else {
|
11001
|
-
arrayRemove(events[type], fn);
|
11130
|
+
arrayRemove(events[type] || [], fn);
|
11002
11131
|
}
|
11003
11132
|
}
|
11004
11133
|
}
|
@@ -11272,6 +11401,15 @@ forEach({
|
|
11272
11401
|
|
11273
11402
|
val: function(element, value) {
|
11274
11403
|
if (isUndefined(value)) {
|
11404
|
+
if (nodeName_(element) === 'SELECT' && element.multiple) {
|
11405
|
+
var result = [];
|
11406
|
+
forEach(element.options, function (option) {
|
11407
|
+
if (option.selected) {
|
11408
|
+
result.push(option.value || option.text);
|
11409
|
+
}
|
11410
|
+
});
|
11411
|
+
return result.length === 0 ? null : result;
|
11412
|
+
}
|
11275
11413
|
return element.value;
|
11276
11414
|
}
|
11277
11415
|
element.value = value;
|
@@ -11403,23 +11541,43 @@ forEach({
|
|
11403
11541
|
|
11404
11542
|
if (!eventFns) {
|
11405
11543
|
if (type == 'mouseenter' || type == 'mouseleave') {
|
11406
|
-
var
|
11544
|
+
var contains = document.body.contains || document.body.compareDocumentPosition ?
|
11545
|
+
function( a, b ) {
|
11546
|
+
var adown = a.nodeType === 9 ? a.documentElement : a,
|
11547
|
+
bup = b && b.parentNode;
|
11548
|
+
return a === bup || !!( bup && bup.nodeType === 1 && (
|
11549
|
+
adown.contains ?
|
11550
|
+
adown.contains( bup ) :
|
11551
|
+
a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
|
11552
|
+
));
|
11553
|
+
} :
|
11554
|
+
function( a, b ) {
|
11555
|
+
if ( b ) {
|
11556
|
+
while ( (b = b.parentNode) ) {
|
11557
|
+
if ( b === a ) {
|
11558
|
+
return true;
|
11559
|
+
}
|
11560
|
+
}
|
11561
|
+
}
|
11562
|
+
return false;
|
11563
|
+
};
|
11407
11564
|
|
11408
|
-
events
|
11409
|
-
|
11565
|
+
events[type] = [];
|
11566
|
+
|
11567
|
+
// Refer to jQuery's implementation of mouseenter & mouseleave
|
11568
|
+
// Read about mouseenter and mouseleave:
|
11569
|
+
// http://www.quirksmode.org/js/events_mouse.html#link8
|
11570
|
+
var eventmap = { mouseleave : "mouseout", mouseenter : "mouseover"}
|
11571
|
+
bindFn(element, eventmap[type], function(event) {
|
11572
|
+
var ret, target = this, related = event.relatedTarget;
|
11573
|
+
// For mousenter/leave call the handler if related is outside the target.
|
11574
|
+
// NB: No relatedTarget if the mouse left/entered the browser window
|
11575
|
+
if ( !related || (related !== target && !contains(target, related)) ){
|
11576
|
+
handle(event, type);
|
11577
|
+
}
|
11410
11578
|
|
11411
|
-
bindFn(element, 'mouseover', function(event) {
|
11412
|
-
counter++;
|
11413
|
-
if (counter == 1) {
|
11414
|
-
handle(event, 'mouseenter');
|
11415
|
-
}
|
11416
|
-
});
|
11417
|
-
bindFn(element, 'mouseout', function(event) {
|
11418
|
-
counter --;
|
11419
|
-
if (counter == 0) {
|
11420
|
-
handle(event, 'mouseleave');
|
11421
|
-
}
|
11422
11579
|
});
|
11580
|
+
|
11423
11581
|
} else {
|
11424
11582
|
addEventListenerFn(element, type, handle);
|
11425
11583
|
events[type] = [];
|
@@ -11469,12 +11627,7 @@ forEach({
|
|
11469
11627
|
if (element.nodeType === 1) {
|
11470
11628
|
var index = element.firstChild;
|
11471
11629
|
forEach(new JQLite(node), function(child){
|
11472
|
-
|
11473
|
-
element.insertBefore(child, index);
|
11474
|
-
} else {
|
11475
|
-
element.appendChild(child);
|
11476
|
-
index = child;
|
11477
|
-
}
|
11630
|
+
element.insertBefore(child, index);
|
11478
11631
|
});
|
11479
11632
|
}
|
11480
11633
|
},
|
@@ -11735,7 +11888,7 @@ function annotate(fn) {
|
|
11735
11888
|
}
|
11736
11889
|
} else if (isArray(fn)) {
|
11737
11890
|
last = fn.length - 1;
|
11738
|
-
assertArgFn(fn[last], 'fn')
|
11891
|
+
assertArgFn(fn[last], 'fn');
|
11739
11892
|
$inject = fn.slice(0, last);
|
11740
11893
|
} else {
|
11741
11894
|
assertArgFn(fn, 'fn', true);
|
@@ -11769,19 +11922,19 @@ function annotate(fn) {
|
|
11769
11922
|
* # Injection Function Annotation
|
11770
11923
|
*
|
11771
11924
|
* JavaScript does not have annotations, and annotations are needed for dependency injection. The
|
11772
|
-
* following
|
11925
|
+
* following are all valid ways of annotating function with injection arguments and are equivalent.
|
11773
11926
|
*
|
11774
11927
|
* <pre>
|
11775
11928
|
* // inferred (only works if code not minified/obfuscated)
|
11776
|
-
* $
|
11929
|
+
* $injector.invoke(function(serviceA){});
|
11777
11930
|
*
|
11778
11931
|
* // annotated
|
11779
11932
|
* function explicit(serviceA) {};
|
11780
11933
|
* explicit.$inject = ['serviceA'];
|
11781
|
-
* $
|
11934
|
+
* $injector.invoke(explicit);
|
11782
11935
|
*
|
11783
11936
|
* // inline
|
11784
|
-
* $
|
11937
|
+
* $injector.invoke(['serviceA', function(serviceA){}]);
|
11785
11938
|
* </pre>
|
11786
11939
|
*
|
11787
11940
|
* ## Inference
|
@@ -11898,7 +12051,7 @@ function annotate(fn) {
|
|
11898
12051
|
* // ...
|
11899
12052
|
* };
|
11900
12053
|
* tmpFn.$inject = ['$compile', '$rootScope'];
|
11901
|
-
* injector.invoke(
|
12054
|
+
* injector.invoke(tmpFn);
|
11902
12055
|
*
|
11903
12056
|
* // To better support inline function the inline annotation is supported
|
11904
12057
|
* injector.invoke(['$compile', '$rootScope', function(obfCompile, obfRootScope) {
|
@@ -11927,7 +12080,7 @@ function annotate(fn) {
|
|
11927
12080
|
* @description
|
11928
12081
|
*
|
11929
12082
|
* Use `$provide` to register new providers with the `$injector`. The providers are the factories for the instance.
|
11930
|
-
* The providers share the same name as the instance they create with
|
12083
|
+
* The providers share the same name as the instance they create with `Provider` suffixed to them.
|
11931
12084
|
*
|
11932
12085
|
* A provider is an object with a `$get()` method. The injector calls the `$get` method to create a new instance of
|
11933
12086
|
* a service. The Provider can have additional methods which would allow for configuration of the provider.
|
@@ -11951,7 +12104,7 @@ function annotate(fn) {
|
|
11951
12104
|
*
|
11952
12105
|
* beforeEach(module(function($provide) {
|
11953
12106
|
* $provide.provider('greet', GreetProvider);
|
11954
|
-
* });
|
12107
|
+
* }));
|
11955
12108
|
*
|
11956
12109
|
* it('should greet', inject(function(greet) {
|
11957
12110
|
* expect(greet('angular')).toEqual('Hello angular!');
|
@@ -11964,9 +12117,7 @@ function annotate(fn) {
|
|
11964
12117
|
* inject(function(greet) {
|
11965
12118
|
* expect(greet('angular')).toEqual('Ahoj angular!');
|
11966
12119
|
* });
|
11967
|
-
* )
|
11968
|
-
*
|
11969
|
-
* });
|
12120
|
+
* });
|
11970
12121
|
* </pre>
|
11971
12122
|
*/
|
11972
12123
|
|
@@ -12060,7 +12211,7 @@ function annotate(fn) {
|
|
12060
12211
|
*
|
12061
12212
|
* @param {string} name The name of the service to decorate.
|
12062
12213
|
* @param {function()} decorator This function will be invoked when the service needs to be
|
12063
|
-
*
|
12214
|
+
* instantiated. The function is called using the {@link AUTO.$injector#invoke
|
12064
12215
|
* injector.invoke} method and is therefore fully injectable. Local injection arguments:
|
12065
12216
|
*
|
12066
12217
|
* * `$delegate` - The original service instance, which can be monkey patched, configured,
|
@@ -12260,6 +12411,8 @@ function createInjector(modulesToLoad) {
|
|
12260
12411
|
var Constructor = function() {},
|
12261
12412
|
instance, returnedValue;
|
12262
12413
|
|
12414
|
+
// Check if Type is annotated and use just the given function at n-1 as parameter
|
12415
|
+
// e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);
|
12263
12416
|
Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Type).prototype;
|
12264
12417
|
instance = new Constructor();
|
12265
12418
|
returnedValue = invoke(Type, instance, locals);
|
@@ -12275,6 +12428,7 @@ function createInjector(modulesToLoad) {
|
|
12275
12428
|
};
|
12276
12429
|
}
|
12277
12430
|
}
|
12431
|
+
|
12278
12432
|
/**
|
12279
12433
|
* @ngdoc function
|
12280
12434
|
* @name ng.$anchorScroll
|
@@ -12466,7 +12620,8 @@ function Browser(window, document, $log, $sniffer) {
|
|
12466
12620
|
//////////////////////////////////////////////////////////////
|
12467
12621
|
|
12468
12622
|
var lastBrowserUrl = location.href,
|
12469
|
-
baseElement = document.find('base')
|
12623
|
+
baseElement = document.find('base'),
|
12624
|
+
replacedUrl = null;
|
12470
12625
|
|
12471
12626
|
/**
|
12472
12627
|
* @name ng.$browser#url
|
@@ -12501,14 +12656,21 @@ function Browser(window, document, $log, $sniffer) {
|
|
12501
12656
|
baseElement.attr('href', baseElement.attr('href'));
|
12502
12657
|
}
|
12503
12658
|
} else {
|
12504
|
-
if (replace)
|
12505
|
-
|
12659
|
+
if (replace) {
|
12660
|
+
location.replace(url);
|
12661
|
+
replacedUrl = url;
|
12662
|
+
} else {
|
12663
|
+
location.href = url;
|
12664
|
+
replacedUrl = null;
|
12665
|
+
}
|
12506
12666
|
}
|
12507
12667
|
return self;
|
12508
12668
|
// getter
|
12509
12669
|
} else {
|
12510
|
-
// the
|
12511
|
-
|
12670
|
+
// - the replacedUrl is a workaround for an IE8-9 issue with location.replace method that doesn't update
|
12671
|
+
// location.href synchronously
|
12672
|
+
// - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172
|
12673
|
+
return replacedUrl || location.href.replace(/%27/g,"'");
|
12512
12674
|
}
|
12513
12675
|
};
|
12514
12676
|
|
@@ -12639,7 +12801,13 @@ function Browser(window, document, $log, $sniffer) {
|
|
12639
12801
|
cookie = cookieArray[i];
|
12640
12802
|
index = cookie.indexOf('=');
|
12641
12803
|
if (index > 0) { //ignore nameless cookies
|
12642
|
-
|
12804
|
+
var name = unescape(cookie.substring(0, index));
|
12805
|
+
// the first value that is seen for a cookie is the most
|
12806
|
+
// specific one. values for the same cookie name that
|
12807
|
+
// follow are for less specific paths.
|
12808
|
+
if (lastCookies[name] === undefined) {
|
12809
|
+
lastCookies[name] = unescape(cookie.substring(index + 1));
|
12810
|
+
}
|
12643
12811
|
}
|
12644
12812
|
}
|
12645
12813
|
}
|
@@ -12703,27 +12871,41 @@ function $BrowserProvider(){
|
|
12703
12871
|
return new Browser($window, $document, $log, $sniffer);
|
12704
12872
|
}];
|
12705
12873
|
}
|
12874
|
+
|
12706
12875
|
/**
|
12707
12876
|
* @ngdoc object
|
12708
12877
|
* @name ng.$cacheFactory
|
12709
12878
|
*
|
12710
12879
|
* @description
|
12711
|
-
* Factory that constructs cache objects.
|
12880
|
+
* Factory that constructs cache objects and gives access to them.
|
12881
|
+
*
|
12882
|
+
* <pre>
|
12883
|
+
*
|
12884
|
+
* var cache = $cacheFactory('cacheId');
|
12885
|
+
* expect($cacheFactory.get('cacheId')).toBe(cache);
|
12886
|
+
* expect($cacheFactory.get('noSuchCacheId')).not.toBeDefined();
|
12887
|
+
*
|
12888
|
+
* cache.put("key", "value");
|
12889
|
+
* cache.put("another key", "another value");
|
12890
|
+
*
|
12891
|
+
* expect(cache.info()).toEqual({id: 'cacheId', size: 2}); // Since we've specified no options on creation
|
12892
|
+
*
|
12893
|
+
* </pre>
|
12712
12894
|
*
|
12713
12895
|
*
|
12714
12896
|
* @param {string} cacheId Name or id of the newly created cache.
|
12715
12897
|
* @param {object=} options Options object that specifies the cache behavior. Properties:
|
12716
12898
|
*
|
12717
|
-
* - `{number=}` `capacity`
|
12899
|
+
* - `{number=}` `capacity` — turns the cache into LRU cache.
|
12718
12900
|
*
|
12719
12901
|
* @returns {object} Newly created cache object with the following set of methods:
|
12720
12902
|
*
|
12721
|
-
* - `{object}` `info()`
|
12722
|
-
* - `{void}` `put({string} key, {*} value)`
|
12723
|
-
* - `{{*}}` `get({string} key)`
|
12724
|
-
* - `{void}` `remove({string} key)`
|
12725
|
-
* - `{void}` `removeAll()`
|
12726
|
-
* - `{void}` `destroy()`
|
12903
|
+
* - `{object}` `info()` — Returns id, size, and options of cache.
|
12904
|
+
* - `{void}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache.
|
12905
|
+
* - `{{*}}` `get({string} key)` — Returns cached value for `key` or undefined for cache miss.
|
12906
|
+
* - `{void}` `remove({string} key)` — Removes a key-value pair from the cache.
|
12907
|
+
* - `{void}` `removeAll()` — Removes all cached values.
|
12908
|
+
* - `{void}` `destroy()` — Removes references to this cache from $cacheFactory.
|
12727
12909
|
*
|
12728
12910
|
*/
|
12729
12911
|
function $CacheFactoryProvider() {
|
@@ -12840,6 +13022,16 @@ function $CacheFactoryProvider() {
|
|
12840
13022
|
}
|
12841
13023
|
|
12842
13024
|
|
13025
|
+
/**
|
13026
|
+
* @ngdoc method
|
13027
|
+
* @name ng.$cacheFactory#info
|
13028
|
+
* @methodOf ng.$cacheFactory
|
13029
|
+
*
|
13030
|
+
* @description
|
13031
|
+
* Get information about all the of the caches that have been created
|
13032
|
+
*
|
13033
|
+
* @returns {Object} - key-value map of `cacheId` to the result of calling `cache#info`
|
13034
|
+
*/
|
12843
13035
|
cacheFactory.info = function() {
|
12844
13036
|
var info = {};
|
12845
13037
|
forEach(caches, function(cache, cacheId) {
|
@@ -12849,6 +13041,17 @@ function $CacheFactoryProvider() {
|
|
12849
13041
|
};
|
12850
13042
|
|
12851
13043
|
|
13044
|
+
/**
|
13045
|
+
* @ngdoc method
|
13046
|
+
* @name ng.$cacheFactory#get
|
13047
|
+
* @methodOf ng.$cacheFactory
|
13048
|
+
*
|
13049
|
+
* @description
|
13050
|
+
* Get access to a cache object by the `cacheId` used when it was created.
|
13051
|
+
*
|
13052
|
+
* @param {string} cacheId Name or id of a cache to access.
|
13053
|
+
* @returns {object} Cache object identified by the cacheId or undefined if no such cache.
|
13054
|
+
*/
|
12852
13055
|
cacheFactory.get = function(cacheId) {
|
12853
13056
|
return caches[cacheId];
|
12854
13057
|
};
|
@@ -12863,8 +13066,44 @@ function $CacheFactoryProvider() {
|
|
12863
13066
|
* @name ng.$templateCache
|
12864
13067
|
*
|
12865
13068
|
* @description
|
12866
|
-
*
|
12867
|
-
*
|
13069
|
+
* The first time a template is used, it is loaded in the template cache for quick retrieval. You can
|
13070
|
+
* load templates directly into the cache in a `script` tag, or by consuming the `$templateCache`
|
13071
|
+
* service directly.
|
13072
|
+
*
|
13073
|
+
* Adding via the `script` tag:
|
13074
|
+
* <pre>
|
13075
|
+
* <html ng-app>
|
13076
|
+
* <head>
|
13077
|
+
* <script type="text/ng-template" id="templateId.html">
|
13078
|
+
* This is the content of the template
|
13079
|
+
* </script>
|
13080
|
+
* </head>
|
13081
|
+
* ...
|
13082
|
+
* </html>
|
13083
|
+
* </pre>
|
13084
|
+
*
|
13085
|
+
* **Note:** the `script` tag containing the template does not need to be included in the `head` of the document, but
|
13086
|
+
* it must be below the `ng-app` definition.
|
13087
|
+
*
|
13088
|
+
* Adding via the $templateCache service:
|
13089
|
+
*
|
13090
|
+
* <pre>
|
13091
|
+
* var myApp = angular.module('myApp', []);
|
13092
|
+
* myApp.run(function($templateCache) {
|
13093
|
+
* $templateCache.put('templateId.html', 'This is the content of the template');
|
13094
|
+
* });
|
13095
|
+
* </pre>
|
13096
|
+
*
|
13097
|
+
* To retrieve the template later, simply use it in your HTML:
|
13098
|
+
* <pre>
|
13099
|
+
* <div ng-include=" 'templateId.html' "></div>
|
13100
|
+
* </pre>
|
13101
|
+
*
|
13102
|
+
* or get it via Javascript:
|
13103
|
+
* <pre>
|
13104
|
+
* $templateCache.get('templateId.html')
|
13105
|
+
* </pre>
|
13106
|
+
*
|
12868
13107
|
* See {@link ng.$cacheFactory $cacheFactory}.
|
12869
13108
|
*
|
12870
13109
|
*/
|
@@ -13030,7 +13269,7 @@ function $CompileProvider($provide) {
|
|
13030
13269
|
COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,
|
13031
13270
|
CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/,
|
13032
13271
|
MULTI_ROOT_TEMPLATE_ERROR = 'Template must have exactly one root element. was: ',
|
13033
|
-
urlSanitizationWhitelist = /^\s*(https?|ftp|mailto):/;
|
13272
|
+
urlSanitizationWhitelist = /^\s*(https?|ftp|mailto|file):/;
|
13034
13273
|
|
13035
13274
|
|
13036
13275
|
/**
|
@@ -13040,11 +13279,11 @@ function $CompileProvider($provide) {
|
|
13040
13279
|
* @function
|
13041
13280
|
*
|
13042
13281
|
* @description
|
13043
|
-
* Register a new
|
13282
|
+
* Register a new directive with the compiler.
|
13044
13283
|
*
|
13045
13284
|
* @param {string} name Name of the directive in camel-case. (ie <code>ngBind</code> which will match as
|
13046
13285
|
* <code>ng-bind</code>).
|
13047
|
-
* @param {function} directiveFactory An injectable directive
|
13286
|
+
* @param {function|Array} directiveFactory An injectable directive factory function. See {@link guide/directive} for more
|
13048
13287
|
* info.
|
13049
13288
|
* @returns {ng.$compileProvider} Self for chaining.
|
13050
13289
|
*/
|
@@ -13167,7 +13406,7 @@ function $CompileProvider($provide) {
|
|
13167
13406
|
|
13168
13407
|
// href property always returns normalized absolute url, so we can match against that
|
13169
13408
|
normalizedVal = urlSanitizationNode.href;
|
13170
|
-
if (!normalizedVal.match(urlSanitizationWhitelist)) {
|
13409
|
+
if (normalizedVal !== '' && !normalizedVal.match(urlSanitizationWhitelist)) {
|
13171
13410
|
this[key] = value = 'unsafe:' + normalizedVal;
|
13172
13411
|
}
|
13173
13412
|
}
|
@@ -13232,7 +13471,7 @@ function $CompileProvider($provide) {
|
|
13232
13471
|
|
13233
13472
|
function compile($compileNodes, transcludeFn, maxPriority) {
|
13234
13473
|
if (!($compileNodes instanceof jqLite)) {
|
13235
|
-
// jquery always rewraps,
|
13474
|
+
// jquery always rewraps, whereas we need to preserve the original selector so that we can modify it.
|
13236
13475
|
$compileNodes = jqLite($compileNodes);
|
13237
13476
|
}
|
13238
13477
|
// We can not compile top level text elements since text nodes can be merged and we will
|
@@ -13284,7 +13523,7 @@ function $CompileProvider($provide) {
|
|
13284
13523
|
* functions return values - the linking functions - are combined into a composite linking
|
13285
13524
|
* function, which is the a linking function for the node.
|
13286
13525
|
*
|
13287
|
-
* @param {NodeList} nodeList an array of nodes to compile
|
13526
|
+
* @param {NodeList} nodeList an array of nodes or NodeList to compile
|
13288
13527
|
* @param {function(angular.Scope[, cloneAttachFn]} transcludeFn A linking function, where the
|
13289
13528
|
* scope argument is auto-generated to the new child of the transcluded parent scope.
|
13290
13529
|
* @param {DOMElement=} $rootElement If the nodeList is the root of the compilation tree then the
|
@@ -13307,7 +13546,7 @@ function $CompileProvider($provide) {
|
|
13307
13546
|
? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement)
|
13308
13547
|
: null;
|
13309
13548
|
|
13310
|
-
childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || !nodeList[i].childNodes.length)
|
13549
|
+
childLinkFn = (nodeLinkFn && nodeLinkFn.terminal || !nodeList[i].childNodes || !nodeList[i].childNodes.length)
|
13311
13550
|
? null
|
13312
13551
|
: compileNodes(nodeList[i].childNodes,
|
13313
13552
|
nodeLinkFn ? nodeLinkFn.transclude : transcludeFn);
|
@@ -13391,7 +13630,7 @@ function $CompileProvider($provide) {
|
|
13391
13630
|
for (var attr, name, nName, value, nAttrs = node.attributes,
|
13392
13631
|
j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) {
|
13393
13632
|
attr = nAttrs[j];
|
13394
|
-
if (attr.specified) {
|
13633
|
+
if (!msie || msie >= 8 || attr.specified) {
|
13395
13634
|
name = attr.name;
|
13396
13635
|
nName = directiveNormalize(name.toLowerCase());
|
13397
13636
|
attrsMap[nName] = name;
|
@@ -13443,9 +13682,9 @@ function $CompileProvider($provide) {
|
|
13443
13682
|
|
13444
13683
|
|
13445
13684
|
/**
|
13446
|
-
* Once the directives have been collected their compile functions
|
13685
|
+
* Once the directives have been collected, their compile functions are executed. This method
|
13447
13686
|
* is responsible for inlining directive templates as well as terminating the application
|
13448
|
-
* of the directives if the terminal directive has been reached
|
13687
|
+
* of the directives if the terminal directive has been reached.
|
13449
13688
|
*
|
13450
13689
|
* @param {Array} directives Array of collected directives to execute their compile function.
|
13451
13690
|
* this needs to be pre-sorted by priority order.
|
@@ -13453,11 +13692,11 @@ function $CompileProvider($provide) {
|
|
13453
13692
|
* @param {Object} templateAttrs The shared attribute function
|
13454
13693
|
* @param {function(angular.Scope[, cloneAttachFn]} transcludeFn A linking function, where the
|
13455
13694
|
* scope argument is auto-generated to the new child of the transcluded parent scope.
|
13456
|
-
* @param {
|
13457
|
-
* argument has the root jqLite array so that we can replace
|
13695
|
+
* @param {JQLite} jqCollection If we are working on the root of the compile tree then this
|
13696
|
+
* argument has the root jqLite array so that we can replace nodes on it.
|
13458
13697
|
* @returns linkFn
|
13459
13698
|
*/
|
13460
|
-
function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn,
|
13699
|
+
function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn, jqCollection) {
|
13461
13700
|
var terminalPriority = -Number.MAX_VALUE,
|
13462
13701
|
preLinkFns = [],
|
13463
13702
|
postLinkFns = [],
|
@@ -13511,7 +13750,7 @@ function $CompileProvider($provide) {
|
|
13511
13750
|
$compileNode = templateAttrs.$$element =
|
13512
13751
|
jqLite(document.createComment(' ' + directiveName + ': ' + templateAttrs[directiveName] + ' '));
|
13513
13752
|
compileNode = $compileNode[0];
|
13514
|
-
replaceWith(
|
13753
|
+
replaceWith(jqCollection, jqLite($template[0]), compileNode);
|
13515
13754
|
childTranscludeFn = compile($template, transcludeFn, terminalPriority);
|
13516
13755
|
} else {
|
13517
13756
|
$template = jqLite(JQLiteClone(compileNode)).contents();
|
@@ -13535,7 +13774,7 @@ function $CompileProvider($provide) {
|
|
13535
13774
|
throw new Error(MULTI_ROOT_TEMPLATE_ERROR + directiveValue);
|
13536
13775
|
}
|
13537
13776
|
|
13538
|
-
replaceWith(
|
13777
|
+
replaceWith(jqCollection, $compileNode, compileNode);
|
13539
13778
|
|
13540
13779
|
var newTemplateAttrs = {$attr: {}};
|
13541
13780
|
|
@@ -13563,7 +13802,7 @@ function $CompileProvider($provide) {
|
|
13563
13802
|
assertNoDuplicate('template', templateDirective, directive, $compileNode);
|
13564
13803
|
templateDirective = directive;
|
13565
13804
|
nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i),
|
13566
|
-
nodeLinkFn, $compileNode, templateAttrs,
|
13805
|
+
nodeLinkFn, $compileNode, templateAttrs, jqCollection, directive.replace,
|
13567
13806
|
childTranscludeFn);
|
13568
13807
|
ii = directives.length;
|
13569
13808
|
} else if (directive.compile) {
|
@@ -13696,7 +13935,7 @@ function $CompileProvider($provide) {
|
|
13696
13935
|
parentGet = $parse(attrs[attrName]);
|
13697
13936
|
scope[scopeName] = function(locals) {
|
13698
13937
|
return parentGet(parentScope, locals);
|
13699
|
-
}
|
13938
|
+
};
|
13700
13939
|
break;
|
13701
13940
|
}
|
13702
13941
|
|
@@ -13866,7 +14105,7 @@ function $CompileProvider($provide) {
|
|
13866
14105
|
|
13867
14106
|
directives.unshift(derivedSyncDirective);
|
13868
14107
|
afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs, childTranscludeFn);
|
13869
|
-
afterTemplateChildLinkFn = compileNodes($compileNode.
|
14108
|
+
afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn);
|
13870
14109
|
|
13871
14110
|
|
13872
14111
|
while(linkQueue.length) {
|
@@ -14131,7 +14370,7 @@ function $ControllerProvider() {
|
|
14131
14370
|
* @description
|
14132
14371
|
* `$controller` service is responsible for instantiating controllers.
|
14133
14372
|
*
|
14134
|
-
* It's just simple call to {@link AUTO.$injector $injector}, but extracted into
|
14373
|
+
* It's just a simple call to {@link AUTO.$injector $injector}, but extracted into
|
14135
14374
|
* a service, so that one can override this service with {@link https://gist.github.com/1649788
|
14136
14375
|
* BC version}.
|
14137
14376
|
*/
|
@@ -14184,7 +14423,7 @@ function $DocumentProvider(){
|
|
14184
14423
|
*
|
14185
14424
|
*/
|
14186
14425
|
function $ExceptionHandlerProvider() {
|
14187
|
-
this.$get = ['$log', function($log){
|
14426
|
+
this.$get = ['$log', function($log) {
|
14188
14427
|
return function(exception, cause) {
|
14189
14428
|
$log.error.apply($log, arguments);
|
14190
14429
|
};
|
@@ -14372,7 +14611,7 @@ function $InterpolateProvider() {
|
|
14372
14611
|
}];
|
14373
14612
|
}
|
14374
14613
|
|
14375
|
-
var URL_MATCH = /^([^:]+):\/\/(\w+:{0,1}\w*@)?([\w\.-]
|
14614
|
+
var URL_MATCH = /^([^:]+):\/\/(\w+:{0,1}\w*@)?(\{?[\w\.-]*\}?)(:([0-9]+))?(\/[^\?#]*)?(\?([^#]*))?(#(.*))?$/,
|
14376
14615
|
PATH_MATCH = /^([^\?#]*)?(\?([^#]*))?(#(.*))?$/,
|
14377
14616
|
HASH_MATCH = PATH_MATCH,
|
14378
14617
|
DEFAULT_PORTS = {'http': 80, 'https': 443, 'ftp': 21};
|
@@ -14451,7 +14690,8 @@ function convertToHashbangUrl(url, basePath, hashPrefix) {
|
|
14451
14690
|
var match = matchUrl(url);
|
14452
14691
|
|
14453
14692
|
// already hashbang url
|
14454
|
-
if (decodeURIComponent(match.path) == basePath)
|
14693
|
+
if (decodeURIComponent(match.path) == basePath && !isUndefined(match.hash) &&
|
14694
|
+
match.hash.indexOf(hashPrefix) === 0) {
|
14455
14695
|
return url;
|
14456
14696
|
// convert html5 url -> hashbang url
|
14457
14697
|
} else {
|
@@ -14948,6 +15188,10 @@ function $LocationProvider(){
|
|
14948
15188
|
// update $location when $browser url changes
|
14949
15189
|
$browser.onUrlChange(function(newUrl) {
|
14950
15190
|
if ($location.absUrl() != newUrl) {
|
15191
|
+
if ($rootScope.$broadcast('$locationChangeStart', newUrl, $location.absUrl()).defaultPrevented) {
|
15192
|
+
$browser.url($location.absUrl());
|
15193
|
+
return;
|
15194
|
+
}
|
14951
15195
|
$rootScope.$evalAsync(function() {
|
14952
15196
|
var oldUrl = $location.absUrl();
|
14953
15197
|
|
@@ -15256,10 +15500,10 @@ function lex(text, csp){
|
|
15256
15500
|
function readIdent() {
|
15257
15501
|
var ident = "",
|
15258
15502
|
start = index,
|
15259
|
-
lastDot, peekIndex, methodName;
|
15503
|
+
lastDot, peekIndex, methodName, ch;
|
15260
15504
|
|
15261
15505
|
while (index < text.length) {
|
15262
|
-
|
15506
|
+
ch = text.charAt(index);
|
15263
15507
|
if (ch == '.' || isIdent(ch) || isNumber(ch)) {
|
15264
15508
|
if (ch == '.') lastDot = index;
|
15265
15509
|
ident += ch;
|
@@ -15273,7 +15517,7 @@ function lex(text, csp){
|
|
15273
15517
|
if (lastDot) {
|
15274
15518
|
peekIndex = index;
|
15275
15519
|
while(peekIndex < text.length) {
|
15276
|
-
|
15520
|
+
ch = text.charAt(peekIndex);
|
15277
15521
|
if (ch == '(') {
|
15278
15522
|
methodName = ident.substr(lastDot - start + 1);
|
15279
15523
|
ident = ident.substr(0, lastDot - start);
|
@@ -15526,8 +15770,8 @@ function parser(text, json, $filter, csp){
|
|
15526
15770
|
text.substring(0, token.index) + "] can not be assigned to", token);
|
15527
15771
|
}
|
15528
15772
|
right = logicalOR();
|
15529
|
-
return function(
|
15530
|
-
return left.assign(
|
15773
|
+
return function(scope, locals){
|
15774
|
+
return left.assign(scope, right(scope, locals), locals);
|
15531
15775
|
};
|
15532
15776
|
} else {
|
15533
15777
|
return left;
|
@@ -15644,12 +15888,12 @@ function parser(text, json, $filter, csp){
|
|
15644
15888
|
var field = expect().text;
|
15645
15889
|
var getter = getterFn(field, csp);
|
15646
15890
|
return extend(
|
15647
|
-
function(
|
15648
|
-
return getter(object(
|
15891
|
+
function(scope, locals, self) {
|
15892
|
+
return getter(self || object(scope, locals), locals);
|
15649
15893
|
},
|
15650
15894
|
{
|
15651
|
-
assign:function(
|
15652
|
-
return setter(object(
|
15895
|
+
assign:function(scope, value, locals) {
|
15896
|
+
return setter(object(scope, locals), field, value);
|
15653
15897
|
}
|
15654
15898
|
}
|
15655
15899
|
);
|
@@ -15690,14 +15934,14 @@ function parser(text, json, $filter, csp){
|
|
15690
15934
|
} while (expect(','));
|
15691
15935
|
}
|
15692
15936
|
consume(')');
|
15693
|
-
return function(
|
15937
|
+
return function(scope, locals){
|
15694
15938
|
var args = [],
|
15695
|
-
context = contextGetter ? contextGetter(
|
15939
|
+
context = contextGetter ? contextGetter(scope, locals) : scope;
|
15696
15940
|
|
15697
15941
|
for ( var i = 0; i < argsFn.length; i++) {
|
15698
|
-
args.push(argsFn[i](
|
15942
|
+
args.push(argsFn[i](scope, locals));
|
15699
15943
|
}
|
15700
|
-
var fnPtr = fn(
|
15944
|
+
var fnPtr = fn(scope, locals, context) || noop;
|
15701
15945
|
// IE stupidity!
|
15702
15946
|
return fnPtr.apply
|
15703
15947
|
? fnPtr.apply(context, args)
|
@@ -15739,8 +15983,7 @@ function parser(text, json, $filter, csp){
|
|
15739
15983
|
var object = {};
|
15740
15984
|
for ( var i = 0; i < keyValues.length; i++) {
|
15741
15985
|
var keyValue = keyValues[i];
|
15742
|
-
|
15743
|
-
object[keyValue.key] = value;
|
15986
|
+
object[keyValue.key] = keyValue.value(self, locals);
|
15744
15987
|
}
|
15745
15988
|
return object;
|
15746
15989
|
};
|
@@ -15766,33 +16009,6 @@ function setter(obj, path, setValue) {
|
|
15766
16009
|
return setValue;
|
15767
16010
|
}
|
15768
16011
|
|
15769
|
-
/**
|
15770
|
-
* Return the value accesible from the object by path. Any undefined traversals are ignored
|
15771
|
-
* @param {Object} obj starting object
|
15772
|
-
* @param {string} path path to traverse
|
15773
|
-
* @param {boolean=true} bindFnToScope
|
15774
|
-
* @returns value as accesbile by path
|
15775
|
-
*/
|
15776
|
-
//TODO(misko): this function needs to be removed
|
15777
|
-
function getter(obj, path, bindFnToScope) {
|
15778
|
-
if (!path) return obj;
|
15779
|
-
var keys = path.split('.');
|
15780
|
-
var key;
|
15781
|
-
var lastInstance = obj;
|
15782
|
-
var len = keys.length;
|
15783
|
-
|
15784
|
-
for (var i = 0; i < len; i++) {
|
15785
|
-
key = keys[i];
|
15786
|
-
if (obj) {
|
15787
|
-
obj = (lastInstance = obj)[key];
|
15788
|
-
}
|
15789
|
-
}
|
15790
|
-
if (!bindFnToScope && isFunction(obj)) {
|
15791
|
-
return bind(lastInstance, obj);
|
15792
|
-
}
|
15793
|
-
return obj;
|
15794
|
-
}
|
15795
|
-
|
15796
16012
|
var getterFnCache = {};
|
15797
16013
|
|
15798
16014
|
/**
|
@@ -15862,7 +16078,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4) {
|
|
15862
16078
|
}
|
15863
16079
|
return pathVal;
|
15864
16080
|
};
|
15865
|
-
}
|
16081
|
+
}
|
15866
16082
|
|
15867
16083
|
function getterFn(path, csp) {
|
15868
16084
|
if (getterFnCache.hasOwnProperty(path)) {
|
@@ -15877,7 +16093,7 @@ function getterFn(path, csp) {
|
|
15877
16093
|
fn = (pathKeysLength < 6)
|
15878
16094
|
? cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4])
|
15879
16095
|
: function(scope, locals) {
|
15880
|
-
var i = 0, val
|
16096
|
+
var i = 0, val;
|
15881
16097
|
do {
|
15882
16098
|
val = cspSafeGetterFn(
|
15883
16099
|
pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++]
|
@@ -15942,9 +16158,9 @@ function getterFn(path, csp) {
|
|
15942
16158
|
* @param {string} expression String expression to compile.
|
15943
16159
|
* @returns {function(context, locals)} a function which represents the compiled expression:
|
15944
16160
|
*
|
15945
|
-
* * `context`
|
16161
|
+
* * `context` – `{object}` – an object against which any expressions embedded in the strings
|
15946
16162
|
* are evaluated against (tipically a scope object).
|
15947
|
-
* * `locals`
|
16163
|
+
* * `locals` – `{object=}` – local variables context object, useful for overriding values in
|
15948
16164
|
* `context`.
|
15949
16165
|
*
|
15950
16166
|
* The return function also has an `assign` property, if the expression is assignable, which
|
@@ -16033,14 +16249,14 @@ function $ParseProvider() {
|
|
16033
16249
|
*
|
16034
16250
|
* **Methods**
|
16035
16251
|
*
|
16036
|
-
* - `resolve(value)`
|
16252
|
+
* - `resolve(value)` – resolves the derived promise with the `value`. If the value is a rejection
|
16037
16253
|
* constructed via `$q.reject`, the promise will be rejected instead.
|
16038
|
-
* - `reject(reason)`
|
16254
|
+
* - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to
|
16039
16255
|
* resolving it with a rejection constructed via `$q.reject`.
|
16040
16256
|
*
|
16041
16257
|
* **Properties**
|
16042
16258
|
*
|
16043
|
-
* - promise
|
16259
|
+
* - promise – `{Promise}` – promise object associated with this deferred.
|
16044
16260
|
*
|
16045
16261
|
*
|
16046
16262
|
* # The Promise API
|
@@ -16053,9 +16269,9 @@ function $ParseProvider() {
|
|
16053
16269
|
*
|
16054
16270
|
* **Methods**
|
16055
16271
|
*
|
16056
|
-
* - `then(successCallback, errorCallback)`
|
16057
|
-
* or rejected calls one of the success or error callbacks asynchronously as soon as the result
|
16058
|
-
* is available. The callbacks are called with a single argument the result or rejection reason.
|
16272
|
+
* - `then(successCallback, errorCallback)` – regardless of when the promise was or will be resolved
|
16273
|
+
* or rejected, `then` calls one of the success or error callbacks asynchronously as soon as the result
|
16274
|
+
* is available. The callbacks are called with a single argument: the result or rejection reason.
|
16059
16275
|
*
|
16060
16276
|
* This method *returns a new promise* which is resolved or rejected via the return value of the
|
16061
16277
|
* `successCallback` or `errorCallback`.
|
@@ -16063,7 +16279,7 @@ function $ParseProvider() {
|
|
16063
16279
|
*
|
16064
16280
|
* # Chaining promises
|
16065
16281
|
*
|
16066
|
-
* Because calling `then`
|
16282
|
+
* Because calling the `then` method of a promise returns a new derived promise, it is easily possible
|
16067
16283
|
* to create a chain of promises:
|
16068
16284
|
*
|
16069
16285
|
* <pre>
|
@@ -16071,13 +16287,13 @@ function $ParseProvider() {
|
|
16071
16287
|
* return result + 1;
|
16072
16288
|
* });
|
16073
16289
|
*
|
16074
|
-
* // promiseB will be resolved immediately after promiseA is resolved and its value
|
16075
|
-
* // the result of promiseA incremented by 1
|
16290
|
+
* // promiseB will be resolved immediately after promiseA is resolved and its value
|
16291
|
+
* // will be the result of promiseA incremented by 1
|
16076
16292
|
* </pre>
|
16077
16293
|
*
|
16078
16294
|
* It is possible to create chains of any length and since a promise can be resolved with another
|
16079
16295
|
* promise (which will defer its resolution further), it is possible to pause/defer resolution of
|
16080
|
-
* the promises at any point in the chain. This makes it possible to implement powerful
|
16296
|
+
* the promises at any point in the chain. This makes it possible to implement powerful APIs like
|
16081
16297
|
* $http's response interceptors.
|
16082
16298
|
*
|
16083
16299
|
*
|
@@ -16090,7 +16306,7 @@ function $ParseProvider() {
|
|
16090
16306
|
* models and avoiding unnecessary browser repaints, which would result in flickering UI.
|
16091
16307
|
* - $q promises are recognized by the templating engine in angular, which means that in templates
|
16092
16308
|
* you can treat promises attached to a scope as if they were the resulting values.
|
16093
|
-
* - Q has many more features
|
16309
|
+
* - Q has many more features than $q, but that comes at a cost of bytes. $q is tiny, but contains
|
16094
16310
|
* all the important functionality needed for common async tasks.
|
16095
16311
|
*
|
16096
16312
|
* # Testing
|
@@ -16184,8 +16400,8 @@ function qFactory(nextTick, exceptionHandler) {
|
|
16184
16400
|
try {
|
16185
16401
|
result.resolve((callback || defaultCallback)(value));
|
16186
16402
|
} catch(e) {
|
16187
|
-
exceptionHandler(e);
|
16188
16403
|
result.reject(e);
|
16404
|
+
exceptionHandler(e);
|
16189
16405
|
}
|
16190
16406
|
};
|
16191
16407
|
|
@@ -16193,8 +16409,8 @@ function qFactory(nextTick, exceptionHandler) {
|
|
16193
16409
|
try {
|
16194
16410
|
result.resolve((errback || defaultErrback)(reason));
|
16195
16411
|
} catch(e) {
|
16196
|
-
exceptionHandler(e);
|
16197
16412
|
result.reject(e);
|
16413
|
+
exceptionHandler(e);
|
16198
16414
|
}
|
16199
16415
|
};
|
16200
16416
|
|
@@ -16285,10 +16501,7 @@ function qFactory(nextTick, exceptionHandler) {
|
|
16285
16501
|
* the promise comes from a source that can't be trusted.
|
16286
16502
|
*
|
16287
16503
|
* @param {*} value Value or a promise
|
16288
|
-
* @returns {Promise} Returns a
|
16289
|
-
* each value corresponding to the promise at the same index in the `promises` array. If any of
|
16290
|
-
* the promises is resolved with a rejection, this resulting promise will be resolved with the
|
16291
|
-
* same rejection.
|
16504
|
+
* @returns {Promise} Returns a promise of the passed value or promise
|
16292
16505
|
*/
|
16293
16506
|
var when = function(value, callback, errback) {
|
16294
16507
|
var result = defer(),
|
@@ -16406,35 +16619,37 @@ function $RouteProvider(){
|
|
16406
16619
|
* route definition.
|
16407
16620
|
*
|
16408
16621
|
* `path` can contain named groups starting with a colon (`:name`). All characters up to the
|
16409
|
-
* next slash are matched and stored in `$routeParams` under the given `name`
|
16410
|
-
*
|
16622
|
+
* next slash are matched and stored in `$routeParams` under the given `name` after the route
|
16623
|
+
* is resolved.
|
16411
16624
|
*
|
16412
16625
|
* @param {Object} route Mapping information to be assigned to `$route.current` on route
|
16413
16626
|
* match.
|
16414
16627
|
*
|
16415
16628
|
* Object properties:
|
16416
16629
|
*
|
16417
|
-
* - `controller`
|
16630
|
+
* - `controller` – `{(string|function()=}` – Controller fn that should be associated with newly
|
16418
16631
|
* created scope or the name of a {@link angular.Module#controller registered controller}
|
16419
16632
|
* if passed as a string.
|
16420
|
-
* - `template`
|
16633
|
+
* - `template` – `{string=}` – html template as a string that should be used by
|
16421
16634
|
* {@link ng.directive:ngView ngView} or
|
16422
16635
|
* {@link ng.directive:ngInclude ngInclude} directives.
|
16423
16636
|
* this property takes precedence over `templateUrl`.
|
16424
|
-
* - `templateUrl`
|
16637
|
+
* - `templateUrl` – `{string=}` – path to an html template that should be used by
|
16425
16638
|
* {@link ng.directive:ngView ngView}.
|
16426
16639
|
* - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
|
16427
16640
|
* be injected into the controller. If any of these dependencies are promises, they will be
|
16428
16641
|
* resolved and converted to a value before the controller is instantiated and the
|
16429
16642
|
* `$routeChangeSuccess` event is fired. The map object is:
|
16430
16643
|
*
|
16431
|
-
* - `key`
|
16644
|
+
* - `key` – `{string}`: a name of a dependency to be injected into the controller.
|
16432
16645
|
* - `factory` - `{string|function}`: If `string` then it is an alias for a service.
|
16433
16646
|
* Otherwise if function, then it is {@link api/AUTO.$injector#invoke injected}
|
16434
16647
|
* and the return value is treated as the dependency. If the result is a promise, it is resolved
|
16435
|
-
* before its value is injected into the controller.
|
16648
|
+
* before its value is injected into the controller. Be aware that `ngRoute.$routeParams` will
|
16649
|
+
* still refer to the previous route within these resolve functions. Use `$route.current.params`
|
16650
|
+
* to access the new route parameters, instead.
|
16436
16651
|
*
|
16437
|
-
* - `redirectTo`
|
16652
|
+
* - `redirectTo` – {(string|function())=} – value to update
|
16438
16653
|
* {@link ng.$location $location} path with and trigger route redirection.
|
16439
16654
|
*
|
16440
16655
|
* If `redirectTo` is a function, it will be called with the following parameters:
|
@@ -16645,8 +16860,9 @@ function $RouteProvider(){
|
|
16645
16860
|
* {@link ng.directive:ngView ngView} listens for the directive
|
16646
16861
|
* to instantiate the controller and render the view.
|
16647
16862
|
*
|
16863
|
+
* @param {Object} angularEvent Synthetic event object.
|
16648
16864
|
* @param {Route} current Current route information.
|
16649
|
-
* @param {Route} previous Previous route information.
|
16865
|
+
* @param {Route|Undefined} previous Previous route information, or undefined if current is first route entered.
|
16650
16866
|
*/
|
16651
16867
|
|
16652
16868
|
/**
|
@@ -16744,7 +16960,7 @@ function $RouteProvider(){
|
|
16744
16960
|
var next = parseRoute(),
|
16745
16961
|
last = $route.current;
|
16746
16962
|
|
16747
|
-
if (next && last && next
|
16963
|
+
if (next && last && next.$$route === last.$$route
|
16748
16964
|
&& equals(next.pathParams, last.pathParams) && !next.reloadOnSearch && !forceReload) {
|
16749
16965
|
last.params = next.params;
|
16750
16966
|
copy(last.params, $routeParams);
|
@@ -16823,7 +17039,7 @@ function $RouteProvider(){
|
|
16823
17039
|
match = inherit(route, {
|
16824
17040
|
params: extend({}, $location.search(), params),
|
16825
17041
|
pathParams: params});
|
16826
|
-
match
|
17042
|
+
match.$$route = route;
|
16827
17043
|
}
|
16828
17044
|
});
|
16829
17045
|
// No route matched; fallback to "otherwise" route
|
@@ -16866,6 +17082,10 @@ function $RouteProvider(){
|
|
16866
17082
|
* The service guarantees that the identity of the `$routeParams` object will remain unchanged
|
16867
17083
|
* (but its properties will likely change) even when a route change occurs.
|
16868
17084
|
*
|
17085
|
+
* Note that the `$routeParams` are only updated *after* a route change completes successfully.
|
17086
|
+
* This means that you cannot rely on `$routeParams` being correct in route resolve functions.
|
17087
|
+
* Instead you can use `$route.current.params` to access the new route's parameters.
|
17088
|
+
*
|
16869
17089
|
* @example
|
16870
17090
|
* <pre>
|
16871
17091
|
* // Given:
|
@@ -16883,22 +17103,22 @@ function $RouteParamsProvider() {
|
|
16883
17103
|
/**
|
16884
17104
|
* DESIGN NOTES
|
16885
17105
|
*
|
16886
|
-
* The design decisions behind the scope
|
17106
|
+
* The design decisions behind the scope are heavily favored for speed and memory consumption.
|
16887
17107
|
*
|
16888
17108
|
* The typical use of scope is to watch the expressions, which most of the time return the same
|
16889
17109
|
* value as last time so we optimize the operation.
|
16890
17110
|
*
|
16891
|
-
* Closures construction is expensive
|
16892
|
-
* -
|
17111
|
+
* Closures construction is expensive in terms of speed as well as memory:
|
17112
|
+
* - No closures, instead use prototypical inheritance for API
|
16893
17113
|
* - Internal state needs to be stored on scope directly, which means that private state is
|
16894
17114
|
* exposed as $$____ properties
|
16895
17115
|
*
|
16896
17116
|
* Loop operations are optimized by using while(count--) { ... }
|
16897
17117
|
* - this means that in order to keep the same order of execution as addition we have to add
|
16898
|
-
* items to the array at the
|
17118
|
+
* items to the array at the beginning (shift) instead of at the end (push)
|
16899
17119
|
*
|
16900
17120
|
* Child scopes are created and removed often
|
16901
|
-
* - Using array would be slow since inserts in
|
17121
|
+
* - Using an array would be slow since inserts in middle are expensive so we use linked list
|
16902
17122
|
*
|
16903
17123
|
* There are few watches then a lot of observers. This is why you don't want the observer to be
|
16904
17124
|
* implemented in the same way as watch. Watch requires return of initialization function which
|
@@ -16920,7 +17140,7 @@ function $RouteParamsProvider() {
|
|
16920
17140
|
* @methodOf ng.$rootScopeProvider
|
16921
17141
|
* @description
|
16922
17142
|
*
|
16923
|
-
* Sets the number of digest
|
17143
|
+
* Sets the number of digest iterations the scope should attempt to execute before giving up and
|
16924
17144
|
* assuming that the model is unstable.
|
16925
17145
|
*
|
16926
17146
|
* The current default is 10 iterations.
|
@@ -17200,7 +17420,7 @@ function $RootScopeProvider(){
|
|
17200
17420
|
* @function
|
17201
17421
|
*
|
17202
17422
|
* @description
|
17203
|
-
*
|
17423
|
+
* Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and its children.
|
17204
17424
|
* Because a {@link ng.$rootScope.Scope#$watch watcher}'s listener can change the model, the
|
17205
17425
|
* `$digest()` keeps calling the {@link ng.$rootScope.Scope#$watch watchers} until no more listeners are
|
17206
17426
|
* firing. This means that it is possible to get into an infinite loop. This function will throw
|
@@ -17273,7 +17493,7 @@ function $RootScopeProvider(){
|
|
17273
17493
|
watch = watchers[length];
|
17274
17494
|
// Most common watches are on primitives, in which case we can short
|
17275
17495
|
// circuit it with === operator, only when === fails do we use .equals
|
17276
|
-
if ((value = watch.get(current)) !== (last = watch.last) &&
|
17496
|
+
if (watch && (value = watch.get(current)) !== (last = watch.last) &&
|
17277
17497
|
!(watch.eq
|
17278
17498
|
? equals(value, last)
|
17279
17499
|
: (typeof value == 'number' && typeof last == 'number'
|
@@ -17326,6 +17546,9 @@ function $RootScopeProvider(){
|
|
17326
17546
|
*
|
17327
17547
|
* @description
|
17328
17548
|
* Broadcasted when a scope and its children are being destroyed.
|
17549
|
+
*
|
17550
|
+
* Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
|
17551
|
+
* clean up DOM bindings before an element is removed from the DOM.
|
17329
17552
|
*/
|
17330
17553
|
|
17331
17554
|
/**
|
@@ -17347,6 +17570,9 @@ function $RootScopeProvider(){
|
|
17347
17570
|
* Just before a scope is destroyed a `$destroy` event is broadcasted on this scope.
|
17348
17571
|
* Application code can register a `$destroy` event handler that will give it chance to
|
17349
17572
|
* perform any necessary cleanup.
|
17573
|
+
*
|
17574
|
+
* Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to
|
17575
|
+
* clean up DOM bindings before an element is removed from the DOM.
|
17350
17576
|
*/
|
17351
17577
|
$destroy: function() {
|
17352
17578
|
// we can't destroy the root scope or a scope that has been already destroyed
|
@@ -17542,7 +17768,7 @@ function $RootScopeProvider(){
|
|
17542
17768
|
* Afterwards, the event traverses upwards toward the root scope and calls all registered
|
17543
17769
|
* listeners along the way. The event will stop propagating if one of the listeners cancels it.
|
17544
17770
|
*
|
17545
|
-
* Any exception
|
17771
|
+
* Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed
|
17546
17772
|
* onto the {@link ng.$exceptionHandler $exceptionHandler} service.
|
17547
17773
|
*
|
17548
17774
|
* @param {string} name Event name to emit.
|
@@ -17611,7 +17837,7 @@ function $RootScopeProvider(){
|
|
17611
17837
|
* Any exception emmited from the {@link ng.$rootScope.Scope#$on listeners} will be passed
|
17612
17838
|
* onto the {@link ng.$exceptionHandler $exceptionHandler} service.
|
17613
17839
|
*
|
17614
|
-
* @param {string} name Event name to
|
17840
|
+
* @param {string} name Event name to broadcast.
|
17615
17841
|
* @param {...*} args Optional set of arguments which will be passed onto the event listeners.
|
17616
17842
|
* @return {Object} Event object, see {@link ng.$rootScope.Scope#$on}
|
17617
17843
|
*/
|
@@ -17751,16 +17977,31 @@ function $SnifferProvider() {
|
|
17751
17977
|
* it is a global variable. In angular we always refer to it through the
|
17752
17978
|
* `$window` service, so it may be overriden, removed or mocked for testing.
|
17753
17979
|
*
|
17754
|
-
*
|
17755
|
-
*
|
17980
|
+
* Expressions, like the one defined for the `ngClick` directive in the example
|
17981
|
+
* below, are evaluated with respect to the current scope. Therefore, there is
|
17982
|
+
* no risk of inadvertently coding in a dependency on a global value in such an
|
17983
|
+
* expression.
|
17756
17984
|
*
|
17757
17985
|
* @example
|
17758
17986
|
<doc:example>
|
17759
17987
|
<doc:source>
|
17760
|
-
<
|
17761
|
-
|
17988
|
+
<script>
|
17989
|
+
function Ctrl($scope, $window) {
|
17990
|
+
$scope.$window = $window;
|
17991
|
+
$scope.greeting = 'Hello, World!';
|
17992
|
+
}
|
17993
|
+
</script>
|
17994
|
+
<div ng-controller="Ctrl">
|
17995
|
+
<input type="text" ng-model="greeting" />
|
17996
|
+
<button ng-click="$window.alert(greeting)">ALERT</button>
|
17997
|
+
</div>
|
17762
17998
|
</doc:source>
|
17763
17999
|
<doc:scenario>
|
18000
|
+
it('should display the greeting in the input box', function() {
|
18001
|
+
input('greeting').enter('Hello, E2E Tests');
|
18002
|
+
// If we click the button it will block the test runner
|
18003
|
+
// element(':button').click();
|
18004
|
+
});
|
17764
18005
|
</doc:scenario>
|
17765
18006
|
</doc:example>
|
17766
18007
|
*/
|
@@ -17913,7 +18154,7 @@ function $HttpProvider() {
|
|
17913
18154
|
*
|
17914
18155
|
* @description
|
17915
18156
|
* The `$http` service is a core Angular service that facilitates communication with the remote
|
17916
|
-
* HTTP servers via browser's {@link https://developer.mozilla.org/en/xmlhttprequest
|
18157
|
+
* HTTP servers via the browser's {@link https://developer.mozilla.org/en/xmlhttprequest
|
17917
18158
|
* XMLHttpRequest} object or via {@link http://en.wikipedia.org/wiki/JSONP JSONP}.
|
17918
18159
|
*
|
17919
18160
|
* For unit testing applications that use `$http` service, see
|
@@ -17923,13 +18164,13 @@ function $HttpProvider() {
|
|
17923
18164
|
* $resource} service.
|
17924
18165
|
*
|
17925
18166
|
* The $http API is based on the {@link ng.$q deferred/promise APIs} exposed by
|
17926
|
-
* the $q service. While for simple usage
|
17927
|
-
* it is important to familiarize yourself with these
|
18167
|
+
* the $q service. While for simple usage patterns this doesn't matter much, for advanced usage
|
18168
|
+
* it is important to familiarize yourself with these APIs and the guarantees they provide.
|
17928
18169
|
*
|
17929
18170
|
*
|
17930
18171
|
* # General usage
|
17931
|
-
* The `$http` service is a function which takes a single argument
|
17932
|
-
* that is used to generate an
|
18172
|
+
* The `$http` service is a function which takes a single argument — a configuration object —
|
18173
|
+
* that is used to generate an HTTP request and returns a {@link ng.$q promise}
|
17933
18174
|
* with two $http specific methods: `success` and `error`.
|
17934
18175
|
*
|
17935
18176
|
* <pre>
|
@@ -17944,21 +18185,21 @@ function $HttpProvider() {
|
|
17944
18185
|
* });
|
17945
18186
|
* </pre>
|
17946
18187
|
*
|
17947
|
-
* Since the returned value of calling the $http function is a
|
17948
|
-
* the `then` method to register callbacks, and these callbacks will receive a single argument
|
17949
|
-
* an object representing the response. See the
|
18188
|
+
* Since the returned value of calling the $http function is a `promise`, you can also use
|
18189
|
+
* the `then` method to register callbacks, and these callbacks will receive a single argument –
|
18190
|
+
* an object representing the response. See the API signature and type info below for more
|
17950
18191
|
* details.
|
17951
18192
|
*
|
17952
|
-
* A response status code
|
18193
|
+
* A response status code between 200 and 299 is considered a success status and
|
17953
18194
|
* will result in the success callback being called. Note that if the response is a redirect,
|
17954
18195
|
* XMLHttpRequest will transparently follow it, meaning that the error callback will not be
|
17955
18196
|
* called for such responses.
|
17956
18197
|
*
|
17957
18198
|
* # Shortcut methods
|
17958
18199
|
*
|
17959
|
-
* Since all
|
17960
|
-
* POST
|
17961
|
-
* were created
|
18200
|
+
* Since all invocations of the $http service require passing in an HTTP method and URL, and
|
18201
|
+
* POST/PUT requests require request data to be provided as well, shortcut methods
|
18202
|
+
* were created:
|
17962
18203
|
*
|
17963
18204
|
* <pre>
|
17964
18205
|
* $http.get('/someUrl').success(successCallback);
|
@@ -17977,25 +18218,25 @@ function $HttpProvider() {
|
|
17977
18218
|
*
|
17978
18219
|
* # Setting HTTP Headers
|
17979
18220
|
*
|
17980
|
-
* The $http service will automatically add certain
|
18221
|
+
* The $http service will automatically add certain HTTP headers to all requests. These defaults
|
17981
18222
|
* can be fully configured by accessing the `$httpProvider.defaults.headers` configuration
|
17982
18223
|
* object, which currently contains this default configuration:
|
17983
18224
|
*
|
17984
18225
|
* - `$httpProvider.defaults.headers.common` (headers that are common for all requests):
|
17985
18226
|
* - `Accept: application/json, text/plain, * / *`
|
17986
18227
|
* - `X-Requested-With: XMLHttpRequest`
|
17987
|
-
* - `$httpProvider.defaults.headers.post`: (header defaults for
|
18228
|
+
* - `$httpProvider.defaults.headers.post`: (header defaults for POST requests)
|
17988
18229
|
* - `Content-Type: application/json`
|
17989
|
-
* - `$httpProvider.defaults.headers.put` (header defaults for
|
18230
|
+
* - `$httpProvider.defaults.headers.put` (header defaults for PUT requests)
|
17990
18231
|
* - `Content-Type: application/json`
|
17991
18232
|
*
|
17992
|
-
* To add or overwrite these defaults, simply add or remove a property from
|
18233
|
+
* To add or overwrite these defaults, simply add or remove a property from these configuration
|
17993
18234
|
* objects. To add headers for an HTTP method other than POST or PUT, simply add a new object
|
17994
|
-
* with
|
18235
|
+
* with the lowercased HTTP method name as the key, e.g.
|
17995
18236
|
* `$httpProvider.defaults.headers.get['My-Header']='value'`.
|
17996
18237
|
*
|
17997
|
-
* Additionally, the defaults can be set at runtime via the `$http.defaults` object in
|
17998
|
-
*
|
18238
|
+
* Additionally, the defaults can be set at runtime via the `$http.defaults` object in the same
|
18239
|
+
* fashion.
|
17999
18240
|
*
|
18000
18241
|
*
|
18001
18242
|
* # Transforming Requests and Responses
|
@@ -18005,32 +18246,36 @@ function $HttpProvider() {
|
|
18005
18246
|
*
|
18006
18247
|
* Request transformations:
|
18007
18248
|
*
|
18008
|
-
* -
|
18249
|
+
* - If the `data` property of the request configuration object contains an object, serialize it into
|
18009
18250
|
* JSON format.
|
18010
18251
|
*
|
18011
18252
|
* Response transformations:
|
18012
18253
|
*
|
18013
|
-
* -
|
18014
|
-
* -
|
18254
|
+
* - If XSRF prefix is detected, strip it (see Security Considerations section below).
|
18255
|
+
* - If JSON response is detected, deserialize it using a JSON parser.
|
18015
18256
|
*
|
18016
|
-
* To override
|
18017
|
-
*
|
18018
|
-
*
|
18019
|
-
*
|
18257
|
+
* To globally augment or override the default transforms, modify the `$httpProvider.defaults.transformRequest` and
|
18258
|
+
* `$httpProvider.defaults.transformResponse` properties. These properties are by default an
|
18259
|
+
* array of transform functions, which allows you to `push` or `unshift` a new transformation function into the
|
18260
|
+
* transformation chain. You can also decide to completely override any default transformations by assigning your
|
18261
|
+
* transformation functions to these properties directly without the array wrapper.
|
18262
|
+
*
|
18263
|
+
* Similarly, to locally override the request/response transforms, augment the `transformRequest` and/or
|
18264
|
+
* `transformResponse` properties of the configuration object passed into `$http`.
|
18020
18265
|
*
|
18021
18266
|
*
|
18022
18267
|
* # Caching
|
18023
18268
|
*
|
18024
|
-
* To enable caching set the configuration property `cache` to `true`. When the cache is
|
18269
|
+
* To enable caching, set the configuration property `cache` to `true`. When the cache is
|
18025
18270
|
* enabled, `$http` stores the response from the server in local cache. Next time the
|
18026
18271
|
* response is served from the cache without sending a request to the server.
|
18027
18272
|
*
|
18028
18273
|
* Note that even if the response is served from cache, delivery of the data is asynchronous in
|
18029
18274
|
* the same way that real requests are.
|
18030
18275
|
*
|
18031
|
-
* If there are multiple GET requests for the same
|
18276
|
+
* If there are multiple GET requests for the same URL that should be cached using the same
|
18032
18277
|
* cache, but the cache is not populated yet, only one request to the server will be made and
|
18033
|
-
* the remaining requests will be fulfilled using the response
|
18278
|
+
* the remaining requests will be fulfilled using the response from the first request.
|
18034
18279
|
*
|
18035
18280
|
*
|
18036
18281
|
* # Response interceptors
|
@@ -18046,7 +18291,7 @@ function $HttpProvider() {
|
|
18046
18291
|
*
|
18047
18292
|
* The interceptors are service factories that are registered with the $httpProvider by
|
18048
18293
|
* adding them to the `$httpProvider.responseInterceptors` array. The factory is called and
|
18049
|
-
* injected with dependencies (if specified) and returns the interceptor
|
18294
|
+
* injected with dependencies (if specified) and returns the interceptor — a function that
|
18050
18295
|
* takes a {@link ng.$q promise} and returns the original or a new promise.
|
18051
18296
|
*
|
18052
18297
|
* <pre>
|
@@ -18055,6 +18300,7 @@ function $HttpProvider() {
|
|
18055
18300
|
* return function(promise) {
|
18056
18301
|
* return promise.then(function(response) {
|
18057
18302
|
* // do something on success
|
18303
|
+
* return response;
|
18058
18304
|
* }, function(response) {
|
18059
18305
|
* // do something on error
|
18060
18306
|
* if (canRecover(response)) {
|
@@ -18082,7 +18328,7 @@ function $HttpProvider() {
|
|
18082
18328
|
* When designing web applications, consider security threats from:
|
18083
18329
|
*
|
18084
18330
|
* - {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
|
18085
|
-
* JSON
|
18331
|
+
* JSON vulnerability}
|
18086
18332
|
* - {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF}
|
18087
18333
|
*
|
18088
18334
|
* Both server and the client must cooperate in order to eliminate these threats. Angular comes
|
@@ -18092,8 +18338,8 @@ function $HttpProvider() {
|
|
18092
18338
|
* ## JSON Vulnerability Protection
|
18093
18339
|
*
|
18094
18340
|
* A {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
|
18095
|
-
* JSON
|
18096
|
-
* {@link http://en.wikipedia.org/wiki/
|
18341
|
+
* JSON vulnerability} allows third party website to turn your JSON resource URL into
|
18342
|
+
* {@link http://en.wikipedia.org/wiki/JSONP JSONP} request under some conditions. To
|
18097
18343
|
* counter this your server can prefix all JSON requests with following string `")]}',\n"`.
|
18098
18344
|
* Angular will automatically strip the prefix before processing it as JSON.
|
18099
18345
|
*
|
@@ -18114,41 +18360,41 @@ function $HttpProvider() {
|
|
18114
18360
|
* ## Cross Site Request Forgery (XSRF) Protection
|
18115
18361
|
*
|
18116
18362
|
* {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} is a technique by which
|
18117
|
-
* an unauthorized site can gain your user's private data. Angular provides
|
18363
|
+
* an unauthorized site can gain your user's private data. Angular provides a mechanism
|
18118
18364
|
* to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie
|
18119
18365
|
* called `XSRF-TOKEN` and sets it as the HTTP header `X-XSRF-TOKEN`. Since only JavaScript that
|
18120
18366
|
* runs on your domain could read the cookie, your server can be assured that the XHR came from
|
18121
18367
|
* JavaScript running on your domain.
|
18122
18368
|
*
|
18123
18369
|
* To take advantage of this, your server needs to set a token in a JavaScript readable session
|
18124
|
-
* cookie called `XSRF-TOKEN` on first HTTP GET request. On subsequent
|
18370
|
+
* cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the
|
18125
18371
|
* server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure
|
18126
|
-
* that only JavaScript running on your domain could have
|
18127
|
-
* unique for each user and must be verifiable by the server (to prevent the JavaScript making
|
18372
|
+
* that only JavaScript running on your domain could have sent the request. The token must be
|
18373
|
+
* unique for each user and must be verifiable by the server (to prevent the JavaScript from making
|
18128
18374
|
* up its own tokens). We recommend that the token is a digest of your site's authentication
|
18129
|
-
* cookie with {@link
|
18375
|
+
* cookie with a {@link https://en.wikipedia.org/wiki/Salt_(cryptography) salt} for added security.
|
18130
18376
|
*
|
18131
18377
|
*
|
18132
18378
|
* @param {object} config Object describing the request to be made and how it should be
|
18133
18379
|
* processed. The object has following properties:
|
18134
18380
|
*
|
18135
|
-
* - **method**
|
18136
|
-
* - **url**
|
18137
|
-
* - **params**
|
18381
|
+
* - **method** – `{string}` – HTTP method (e.g. 'GET', 'POST', etc)
|
18382
|
+
* - **url** – `{string}` – Absolute or relative URL of the resource that is being requested.
|
18383
|
+
* - **params** – `{Object.<string|Object>}` – Map of strings or objects which will be turned to
|
18138
18384
|
* `?key1=value1&key2=value2` after the url. If the value is not a string, it will be JSONified.
|
18139
|
-
* - **data**
|
18140
|
-
* - **headers**
|
18141
|
-
* - **transformRequest**
|
18385
|
+
* - **data** – `{string|Object}` – Data to be sent as the request message data.
|
18386
|
+
* - **headers** – `{Object}` – Map of strings representing HTTP headers to send to the server.
|
18387
|
+
* - **transformRequest** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
|
18142
18388
|
* transform function or an array of such functions. The transform function takes the http
|
18143
18389
|
* request body and headers and returns its transformed (typically serialized) version.
|
18144
|
-
* - **transformResponse**
|
18390
|
+
* - **transformResponse** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
|
18145
18391
|
* transform function or an array of such functions. The transform function takes the http
|
18146
18392
|
* response body and headers and returns its transformed (typically deserialized) version.
|
18147
|
-
* - **cache**
|
18393
|
+
* - **cache** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
|
18148
18394
|
* GET request, otherwise if a cache instance built with
|
18149
18395
|
* {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
|
18150
18396
|
* caching.
|
18151
|
-
* - **timeout**
|
18397
|
+
* - **timeout** – `{number}` – timeout in milliseconds.
|
18152
18398
|
* - **withCredentials** - `{boolean}` - whether to to set the `withCredentials` flag on the
|
18153
18399
|
* XHR object. See {@link https://developer.mozilla.org/en/http_access_control#section_5
|
18154
18400
|
* requests with credentials} for more information.
|
@@ -18161,10 +18407,10 @@ function $HttpProvider() {
|
|
18161
18407
|
* these functions are destructured representation of the response object passed into the
|
18162
18408
|
* `then` method. The response object has these properties:
|
18163
18409
|
*
|
18164
|
-
* - **data**
|
18165
|
-
* - **status**
|
18166
|
-
* - **headers**
|
18167
|
-
* - **config**
|
18410
|
+
* - **data** – `{string|Object}` – The response body transformed with the transform functions.
|
18411
|
+
* - **status** – `{number}` – HTTP status code of the response.
|
18412
|
+
* - **headers** – `{function([headerName])}` – Header getter function.
|
18413
|
+
* - **config** – `{Object}` – The configuration object that was used to generate the request.
|
18168
18414
|
*
|
18169
18415
|
* @property {Array.<Object>} pendingRequests Array of config objects for currently pending
|
18170
18416
|
* requests. This is primarily meant to be used for debugging purposes.
|
@@ -18246,17 +18492,40 @@ function $HttpProvider() {
|
|
18246
18492
|
|
18247
18493
|
var reqTransformFn = config.transformRequest || $config.transformRequest,
|
18248
18494
|
respTransformFn = config.transformResponse || $config.transformResponse,
|
18249
|
-
|
18250
|
-
|
18251
|
-
|
18252
|
-
|
18495
|
+
reqHeaders = extend({}, config.headers),
|
18496
|
+
defHeaders = extend(
|
18497
|
+
{'X-XSRF-TOKEN': $browser.cookies()['XSRF-TOKEN']},
|
18498
|
+
$config.headers.common,
|
18499
|
+
$config.headers[lowercase(config.method)]
|
18500
|
+
),
|
18501
|
+
reqData,
|
18502
|
+
defHeaderName, lowercaseDefHeaderName, headerName,
|
18253
18503
|
promise;
|
18254
18504
|
|
18505
|
+
// using for-in instead of forEach to avoid unecessary iteration after header has been found
|
18506
|
+
defaultHeadersIteration:
|
18507
|
+
for(defHeaderName in defHeaders) {
|
18508
|
+
lowercaseDefHeaderName = lowercase(defHeaderName);
|
18509
|
+
for(headerName in config.headers) {
|
18510
|
+
if (lowercase(headerName) === lowercaseDefHeaderName) {
|
18511
|
+
continue defaultHeadersIteration;
|
18512
|
+
}
|
18513
|
+
}
|
18514
|
+
reqHeaders[defHeaderName] = defHeaders[defHeaderName];
|
18515
|
+
}
|
18516
|
+
|
18255
18517
|
// strip content-type if data is undefined
|
18256
18518
|
if (isUndefined(config.data)) {
|
18257
|
-
|
18519
|
+
for(var header in reqHeaders) {
|
18520
|
+
if (lowercase(header) === 'content-type') {
|
18521
|
+
delete reqHeaders[header];
|
18522
|
+
break;
|
18523
|
+
}
|
18524
|
+
}
|
18258
18525
|
}
|
18259
18526
|
|
18527
|
+
reqData = transformData(config.data, headersGetter(reqHeaders), reqTransformFn);
|
18528
|
+
|
18260
18529
|
// send request
|
18261
18530
|
promise = sendReq(config, reqData, reqHeaders);
|
18262
18531
|
|
@@ -18304,7 +18573,7 @@ function $HttpProvider() {
|
|
18304
18573
|
* @methodOf ng.$http
|
18305
18574
|
*
|
18306
18575
|
* @description
|
18307
|
-
* Shortcut method to perform `GET` request
|
18576
|
+
* Shortcut method to perform `GET` request.
|
18308
18577
|
*
|
18309
18578
|
* @param {string} url Relative or absolute URL specifying the destination of the request
|
18310
18579
|
* @param {Object=} config Optional configuration object
|
@@ -18317,7 +18586,7 @@ function $HttpProvider() {
|
|
18317
18586
|
* @methodOf ng.$http
|
18318
18587
|
*
|
18319
18588
|
* @description
|
18320
|
-
* Shortcut method to perform `DELETE` request
|
18589
|
+
* Shortcut method to perform `DELETE` request.
|
18321
18590
|
*
|
18322
18591
|
* @param {string} url Relative or absolute URL specifying the destination of the request
|
18323
18592
|
* @param {Object=} config Optional configuration object
|
@@ -18330,7 +18599,7 @@ function $HttpProvider() {
|
|
18330
18599
|
* @methodOf ng.$http
|
18331
18600
|
*
|
18332
18601
|
* @description
|
18333
|
-
* Shortcut method to perform `HEAD` request
|
18602
|
+
* Shortcut method to perform `HEAD` request.
|
18334
18603
|
*
|
18335
18604
|
* @param {string} url Relative or absolute URL specifying the destination of the request
|
18336
18605
|
* @param {Object=} config Optional configuration object
|
@@ -18343,7 +18612,7 @@ function $HttpProvider() {
|
|
18343
18612
|
* @methodOf ng.$http
|
18344
18613
|
*
|
18345
18614
|
* @description
|
18346
|
-
* Shortcut method to perform `JSONP` request
|
18615
|
+
* Shortcut method to perform `JSONP` request.
|
18347
18616
|
*
|
18348
18617
|
* @param {string} url Relative or absolute URL specifying the destination of the request.
|
18349
18618
|
* Should contain `JSON_CALLBACK` string.
|
@@ -18358,7 +18627,7 @@ function $HttpProvider() {
|
|
18358
18627
|
* @methodOf ng.$http
|
18359
18628
|
*
|
18360
18629
|
* @description
|
18361
|
-
* Shortcut method to perform `POST` request
|
18630
|
+
* Shortcut method to perform `POST` request.
|
18362
18631
|
*
|
18363
18632
|
* @param {string} url Relative or absolute URL specifying the destination of the request
|
18364
18633
|
* @param {*} data Request content
|
@@ -18372,7 +18641,7 @@ function $HttpProvider() {
|
|
18372
18641
|
* @methodOf ng.$http
|
18373
18642
|
*
|
18374
18643
|
* @description
|
18375
|
-
* Shortcut method to perform `PUT` request
|
18644
|
+
* Shortcut method to perform `PUT` request.
|
18376
18645
|
*
|
18377
18646
|
* @param {string} url Relative or absolute URL specifying the destination of the request
|
18378
18647
|
* @param {*} data Request content
|
@@ -18424,7 +18693,7 @@ function $HttpProvider() {
|
|
18424
18693
|
|
18425
18694
|
|
18426
18695
|
/**
|
18427
|
-
* Makes the request
|
18696
|
+
* Makes the request.
|
18428
18697
|
*
|
18429
18698
|
* !!! ACCESSES CLOSURE VARS:
|
18430
18699
|
* $httpBackend, $config, $log, $rootScope, defaultCache, $http.pendingRequests
|
@@ -18534,6 +18803,7 @@ function $HttpProvider() {
|
|
18534
18803
|
|
18535
18804
|
}];
|
18536
18805
|
}
|
18806
|
+
|
18537
18807
|
var XHR = window.XMLHttpRequest || function() {
|
18538
18808
|
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {}
|
18539
18809
|
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {}
|
@@ -18691,7 +18961,7 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
|
|
18691
18961
|
* $locale service provides localization rules for various Angular components. As of right now the
|
18692
18962
|
* only public api is:
|
18693
18963
|
*
|
18694
|
-
* * `id`
|
18964
|
+
* * `id` – `{string}` – locale id formatted as `languageId-countryId` (e.g. `en-us`)
|
18695
18965
|
*/
|
18696
18966
|
function $LocaleProvider(){
|
18697
18967
|
this.$get = function() {
|
@@ -18770,17 +19040,17 @@ function $TimeoutProvider() {
|
|
18770
19040
|
* block and delegates any exceptions to
|
18771
19041
|
* {@link ng.$exceptionHandler $exceptionHandler} service.
|
18772
19042
|
*
|
18773
|
-
* The return value of registering a timeout function is a promise which will be resolved when
|
19043
|
+
* The return value of registering a timeout function is a promise, which will be resolved when
|
18774
19044
|
* the timeout is reached and the timeout function is executed.
|
18775
19045
|
*
|
18776
|
-
* To cancel a
|
19046
|
+
* To cancel a timeout request, call `$timeout.cancel(promise)`.
|
18777
19047
|
*
|
18778
19048
|
* In tests you can use {@link ngMock.$timeout `$timeout.flush()`} to
|
18779
19049
|
* synchronously flush the queue of deferred functions.
|
18780
19050
|
*
|
18781
|
-
* @param {function()} fn A function,
|
19051
|
+
* @param {function()} fn A function, whose execution should be delayed.
|
18782
19052
|
* @param {number=} [delay=0] Delay in milliseconds.
|
18783
|
-
* @param {boolean=} [invokeApply=true] If set to false skips model dirty checking, otherwise
|
19053
|
+
* @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
|
18784
19054
|
* will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
|
18785
19055
|
* @returns {Promise} Promise that will be resolved when the timeout is reached. The value this
|
18786
19056
|
* promise will be resolved with is the return value of the `fn` function.
|
@@ -18798,17 +19068,15 @@ function $TimeoutProvider() {
|
|
18798
19068
|
deferred.reject(e);
|
18799
19069
|
$exceptionHandler(e);
|
18800
19070
|
}
|
19071
|
+
finally {
|
19072
|
+
delete deferreds[promise.$$timeoutId];
|
19073
|
+
}
|
18801
19074
|
|
18802
19075
|
if (!skipApply) $rootScope.$apply();
|
18803
19076
|
}, delay);
|
18804
19077
|
|
18805
|
-
cleanup = function() {
|
18806
|
-
delete deferreds[promise.$$timeoutId];
|
18807
|
-
};
|
18808
|
-
|
18809
19078
|
promise.$$timeoutId = timeoutId;
|
18810
19079
|
deferreds[timeoutId] = deferred;
|
18811
|
-
promise.then(cleanup, cleanup);
|
18812
19080
|
|
18813
19081
|
return promise;
|
18814
19082
|
}
|
@@ -18820,7 +19088,7 @@ function $TimeoutProvider() {
|
|
18820
19088
|
* @methodOf ng.$timeout
|
18821
19089
|
*
|
18822
19090
|
* @description
|
18823
|
-
* Cancels a task associated with the `promise`. As a result of this the promise will be
|
19091
|
+
* Cancels a task associated with the `promise`. As a result of this, the promise will be
|
18824
19092
|
* resolved with a rejection.
|
18825
19093
|
*
|
18826
19094
|
* @param {Promise=} promise Promise returned by the `$timeout` function.
|
@@ -18830,6 +19098,7 @@ function $TimeoutProvider() {
|
|
18830
19098
|
timeout.cancel = function(promise) {
|
18831
19099
|
if (promise && promise.$$timeoutId in deferreds) {
|
18832
19100
|
deferreds[promise.$$timeoutId].reject('canceled');
|
19101
|
+
delete deferreds[promise.$$timeoutId];
|
18833
19102
|
return $browser.defer.cancel(promise.$$timeoutId);
|
18834
19103
|
}
|
18835
19104
|
return false;
|
@@ -18846,7 +19115,7 @@ function $TimeoutProvider() {
|
|
18846
19115
|
*
|
18847
19116
|
* Filters are just functions which transform input to an output. However filters need to be Dependency Injected. To
|
18848
19117
|
* achieve this a filter definition consists of a factory function which is annotated with dependencies and is
|
18849
|
-
* responsible for creating a
|
19118
|
+
* responsible for creating a filter function.
|
18850
19119
|
*
|
18851
19120
|
* <pre>
|
18852
19121
|
* // Filter registration
|
@@ -18908,7 +19177,7 @@ function $TimeoutProvider() {
|
|
18908
19177
|
*
|
18909
19178
|
* The general syntax in templates is as follows:
|
18910
19179
|
*
|
18911
|
-
* {{ expression | [
|
19180
|
+
* {{ expression [| filter_name[:parameter_value] ... ] }}
|
18912
19181
|
*
|
18913
19182
|
* @param {String} name Name of the filter function to retrieve
|
18914
19183
|
* @return {Function} the filter function
|
@@ -18984,22 +19253,22 @@ function $FilterProvider($provide) {
|
|
18984
19253
|
|
18985
19254
|
Search: <input ng-model="searchText">
|
18986
19255
|
<table id="searchTextResults">
|
18987
|
-
<tr><th>Name</th><th>Phone</th
|
19256
|
+
<tr><th>Name</th><th>Phone</th></tr>
|
18988
19257
|
<tr ng-repeat="friend in friends | filter:searchText">
|
18989
19258
|
<td>{{friend.name}}</td>
|
18990
19259
|
<td>{{friend.phone}}</td>
|
18991
|
-
|
19260
|
+
</tr>
|
18992
19261
|
</table>
|
18993
19262
|
<hr>
|
18994
19263
|
Any: <input ng-model="search.$"> <br>
|
18995
19264
|
Name only <input ng-model="search.name"><br>
|
18996
|
-
Phone only <input ng-model="search.phone"
|
19265
|
+
Phone only <input ng-model="search.phone"><br>
|
18997
19266
|
<table id="searchObjResults">
|
18998
|
-
<tr><th>Name</th><th>Phone</th
|
19267
|
+
<tr><th>Name</th><th>Phone</th></tr>
|
18999
19268
|
<tr ng-repeat="friend in friends | filter:search">
|
19000
19269
|
<td>{{friend.name}}</td>
|
19001
19270
|
<td>{{friend.phone}}</td>
|
19002
|
-
|
19271
|
+
</tr>
|
19003
19272
|
</table>
|
19004
19273
|
</doc:source>
|
19005
19274
|
<doc:scenario>
|
@@ -19166,8 +19435,10 @@ function currencyFilter($locale) {
|
|
19166
19435
|
* If the input is not a number an empty string is returned.
|
19167
19436
|
*
|
19168
19437
|
* @param {number|string} number Number to format.
|
19169
|
-
* @param {(number|string)=}
|
19170
|
-
*
|
19438
|
+
* @param {(number|string)=} fractionSize Number of decimal places to round the number to.
|
19439
|
+
* If this is not provided then the fraction size is computed from the current locale's number
|
19440
|
+
* formatting pattern. In the case of the default locale, it will be 3.
|
19441
|
+
* @returns {string} Number rounded to decimalPlaces and places a “,†after each third digit.
|
19171
19442
|
*
|
19172
19443
|
* @example
|
19173
19444
|
<doc:example>
|
@@ -19273,6 +19544,11 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
|
|
19273
19544
|
}
|
19274
19545
|
|
19275
19546
|
if (fractionSize && fractionSize !== "0") formatedText += decimalSep + fraction.substr(0, fractionSize);
|
19547
|
+
} else {
|
19548
|
+
|
19549
|
+
if (fractionSize > 0 && number > -1 && number < 1) {
|
19550
|
+
formatedText = number.toFixed(fractionSize);
|
19551
|
+
}
|
19276
19552
|
}
|
19277
19553
|
|
19278
19554
|
parts.push(isNegative ? pattern.negPre : pattern.posPre);
|
@@ -19296,6 +19572,7 @@ function padNumber(num, digits, trim) {
|
|
19296
19572
|
|
19297
19573
|
|
19298
19574
|
function dateGetter(name, size, offset, trim) {
|
19575
|
+
offset = offset || 0;
|
19299
19576
|
return function(date) {
|
19300
19577
|
var value = date['get' + name]();
|
19301
19578
|
if (offset > 0 || value > -offset)
|
@@ -19318,7 +19595,8 @@ function timeZoneGetter(date) {
|
|
19318
19595
|
var zone = -1 * date.getTimezoneOffset();
|
19319
19596
|
var paddedZone = (zone >= 0) ? "+" : "";
|
19320
19597
|
|
19321
|
-
paddedZone += padNumber(zone
|
19598
|
+
paddedZone += padNumber(Math[zone > 0 ? 'floor' : 'ceil'](zone / 60), 2) +
|
19599
|
+
padNumber(Math.abs(zone % 60), 2);
|
19322
19600
|
|
19323
19601
|
return paddedZone;
|
19324
19602
|
}
|
@@ -19384,7 +19662,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
|
|
19384
19662
|
* * `'ss'`: Second in minute, padded (00-59)
|
19385
19663
|
* * `'s'`: Second in minute (0-59)
|
19386
19664
|
* * `'a'`: am/pm marker
|
19387
|
-
* * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200
|
19665
|
+
* * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-+1200)
|
19388
19666
|
*
|
19389
19667
|
* `format` string can also be one of the following predefined
|
19390
19668
|
* {@link guide/i18n localizable formats}:
|
@@ -19394,7 +19672,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
|
|
19394
19672
|
* * `'short'`: equivalent to `'M/d/yy h:mm a'` for en_US locale (e.g. 9/3/10 12:05 pm)
|
19395
19673
|
* * `'fullDate'`: equivalent to `'EEEE, MMMM d,y'` for en_US locale
|
19396
19674
|
* (e.g. Friday, September 3, 2010)
|
19397
|
-
* * `'longDate'`: equivalent to `'MMMM d, y'` for en_US locale (e.g. September 3, 2010
|
19675
|
+
* * `'longDate'`: equivalent to `'MMMM d, y'` for en_US locale (e.g. September 3, 2010)
|
19398
19676
|
* * `'mediumDate'`: equivalent to `'MMM d, y'` for en_US locale (e.g. Sep 3, 2010)
|
19399
19677
|
* * `'shortDate'`: equivalent to `'M/d/yy'` for en_US locale (e.g. 9/3/10)
|
19400
19678
|
* * `'mediumTime'`: equivalent to `'h:mm:ss a'` for en_US locale (e.g. 12:05:08 pm)
|
@@ -19402,10 +19680,10 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
|
|
19402
19680
|
*
|
19403
19681
|
* `format` string can contain literal values. These need to be quoted with single quotes (e.g.
|
19404
19682
|
* `"h 'in the morning'"`). In order to output single quote, use two single quotes in a sequence
|
19405
|
-
* (e.g. `"h o''clock"`).
|
19683
|
+
* (e.g. `"h 'o''clock'"`).
|
19406
19684
|
*
|
19407
19685
|
* @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or
|
19408
|
-
* number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.SSSZ and
|
19686
|
+
* number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.SSSZ and its
|
19409
19687
|
* shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is
|
19410
19688
|
* specified in the string input, the time is considered to be in the local timezone.
|
19411
19689
|
* @param {string=} format Formatting rules (see Description). If not specified,
|
@@ -19696,12 +19974,12 @@ function limitToFilter(){
|
|
19696
19974
|
(<a href ng-click="predicate = '-name'; reverse=false">^</a>)</th>
|
19697
19975
|
<th><a href="" ng-click="predicate = 'phone'; reverse=!reverse">Phone Number</a></th>
|
19698
19976
|
<th><a href="" ng-click="predicate = 'age'; reverse=!reverse">Age</a></th>
|
19699
|
-
|
19977
|
+
</tr>
|
19700
19978
|
<tr ng-repeat="friend in friends | orderBy:predicate:reverse">
|
19701
19979
|
<td>{{friend.name}}</td>
|
19702
19980
|
<td>{{friend.phone}}</td>
|
19703
19981
|
<td>{{friend.age}}</td>
|
19704
|
-
|
19982
|
+
</tr>
|
19705
19983
|
</table>
|
19706
19984
|
</div>
|
19707
19985
|
</doc:source>
|
@@ -19769,8 +20047,10 @@ function orderByFilter($parse){
|
|
19769
20047
|
var t1 = typeof v1;
|
19770
20048
|
var t2 = typeof v2;
|
19771
20049
|
if (t1 == t2) {
|
19772
|
-
if (t1 == "string")
|
19773
|
-
|
20050
|
+
if (t1 == "string") {
|
20051
|
+
v1 = v1.toLowerCase();
|
20052
|
+
v2 = v2.toLowerCase();
|
20053
|
+
}
|
19774
20054
|
if (v1 === v2) return 0;
|
19775
20055
|
return v1 < v2 ? -1 : 1;
|
19776
20056
|
} else {
|
@@ -20170,7 +20450,7 @@ var nullFormCtrl = {
|
|
20170
20450
|
* @property {Object} $error Is an object hash, containing references to all invalid controls or
|
20171
20451
|
* forms, where:
|
20172
20452
|
*
|
20173
|
-
* - keys are validation tokens (error names)
|
20453
|
+
* - keys are validation tokens (error names) — such as `required`, `url` or `email`),
|
20174
20454
|
* - values are arrays of controls or forms that are invalid with given error.
|
20175
20455
|
*
|
20176
20456
|
* @description
|
@@ -20190,7 +20470,7 @@ function FormController(element, attrs) {
|
|
20190
20470
|
errors = form.$error = {};
|
20191
20471
|
|
20192
20472
|
// init state
|
20193
|
-
form.$name = attrs.name;
|
20473
|
+
form.$name = attrs.name || attrs.ngForm;
|
20194
20474
|
form.$dirty = false;
|
20195
20475
|
form.$pristine = true;
|
20196
20476
|
form.$valid = true;
|
@@ -20210,12 +20490,32 @@ function FormController(element, attrs) {
|
|
20210
20490
|
addClass((isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey);
|
20211
20491
|
}
|
20212
20492
|
|
20493
|
+
/**
|
20494
|
+
* @ngdoc function
|
20495
|
+
* @name ng.directive:form.FormController#$addControl
|
20496
|
+
* @methodOf ng.directive:form.FormController
|
20497
|
+
*
|
20498
|
+
* @description
|
20499
|
+
* Register a control with the form.
|
20500
|
+
*
|
20501
|
+
* Input elements using ngModelController do this automatically when they are linked.
|
20502
|
+
*/
|
20213
20503
|
form.$addControl = function(control) {
|
20214
20504
|
if (control.$name && !form.hasOwnProperty(control.$name)) {
|
20215
20505
|
form[control.$name] = control;
|
20216
20506
|
}
|
20217
20507
|
};
|
20218
20508
|
|
20509
|
+
/**
|
20510
|
+
* @ngdoc function
|
20511
|
+
* @name ng.directive:form.FormController#$removeControl
|
20512
|
+
* @methodOf ng.directive:form.FormController
|
20513
|
+
*
|
20514
|
+
* @description
|
20515
|
+
* Deregister a control from the form.
|
20516
|
+
*
|
20517
|
+
* Input elements using ngModelController do this automatically when they are destroyed.
|
20518
|
+
*/
|
20219
20519
|
form.$removeControl = function(control) {
|
20220
20520
|
if (control.$name && form[control.$name] === control) {
|
20221
20521
|
delete form[control.$name];
|
@@ -20225,6 +20525,16 @@ function FormController(element, attrs) {
|
|
20225
20525
|
});
|
20226
20526
|
};
|
20227
20527
|
|
20528
|
+
/**
|
20529
|
+
* @ngdoc function
|
20530
|
+
* @name ng.directive:form.FormController#$setValidity
|
20531
|
+
* @methodOf ng.directive:form.FormController
|
20532
|
+
*
|
20533
|
+
* @description
|
20534
|
+
* Sets the validity of a form control.
|
20535
|
+
*
|
20536
|
+
* This method will also propagate to parent forms.
|
20537
|
+
*/
|
20228
20538
|
form.$setValidity = function(validationToken, isValid, control) {
|
20229
20539
|
var queue = errors[validationToken];
|
20230
20540
|
|
@@ -20263,6 +20573,17 @@ function FormController(element, attrs) {
|
|
20263
20573
|
}
|
20264
20574
|
};
|
20265
20575
|
|
20576
|
+
/**
|
20577
|
+
* @ngdoc function
|
20578
|
+
* @name ng.directive:form.FormController#$setDirty
|
20579
|
+
* @methodOf ng.directive:form.FormController
|
20580
|
+
*
|
20581
|
+
* @description
|
20582
|
+
* Sets the form to a dirty state.
|
20583
|
+
*
|
20584
|
+
* This method can be called to add the 'ng-dirty' class and set the form to a dirty
|
20585
|
+
* state (ng-dirty class). This method will also propagate to parent forms.
|
20586
|
+
*/
|
20266
20587
|
form.$setDirty = function() {
|
20267
20588
|
element.removeClass(PRISTINE_CLASS).addClass(DIRTY_CLASS);
|
20268
20589
|
form.$dirty = true;
|
@@ -20439,7 +20760,7 @@ var formDirective = formDirectiveFactory();
|
|
20439
20760
|
var ngFormDirective = formDirectiveFactory(true);
|
20440
20761
|
|
20441
20762
|
var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/;
|
20442
|
-
var EMAIL_REGEXP = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,
|
20763
|
+
var EMAIL_REGEXP = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$/;
|
20443
20764
|
var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;
|
20444
20765
|
|
20445
20766
|
var inputType = {
|
@@ -20523,8 +20844,8 @@ var inputType = {
|
|
20523
20844
|
*
|
20524
20845
|
* @param {string} ngModel Assignable angular expression to data-bind to.
|
20525
20846
|
* @param {string=} name Property name of the form under which the control is published.
|
20526
|
-
* @param {string=} min Sets the `min` validation error key if the value entered is less
|
20527
|
-
* @param {string=} max Sets the `max` validation error key if the value entered is greater
|
20847
|
+
* @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
|
20848
|
+
* @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
|
20528
20849
|
* @param {string=} required Sets `required` validation error key if the value is not entered.
|
20529
20850
|
* @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
|
20530
20851
|
* the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
|
@@ -20550,9 +20871,9 @@ var inputType = {
|
|
20550
20871
|
<form name="myForm" ng-controller="Ctrl">
|
20551
20872
|
Number: <input type="number" name="input" ng-model="value"
|
20552
20873
|
min="0" max="99" required>
|
20553
|
-
<span class="error" ng-show="myForm.
|
20874
|
+
<span class="error" ng-show="myForm.input.$error.required">
|
20554
20875
|
Required!</span>
|
20555
|
-
<span class="error" ng-show="myForm.
|
20876
|
+
<span class="error" ng-show="myForm.input.$error.number">
|
20556
20877
|
Not valid number!</span>
|
20557
20878
|
<tt>value = {{value}}</tt><br/>
|
20558
20879
|
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
|
@@ -20673,6 +20994,8 @@ var inputType = {
|
|
20673
20994
|
* @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the
|
20674
20995
|
* RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
|
20675
20996
|
* patterns defined as scope expressions.
|
20997
|
+
* @param {string=} ngChange Angular expression to be executed when input changes due to user
|
20998
|
+
* interaction with the input element.
|
20676
20999
|
*
|
20677
21000
|
* @example
|
20678
21001
|
<doc:example>
|
@@ -20836,6 +21159,15 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|
20836
21159
|
} else {
|
20837
21160
|
var timeout;
|
20838
21161
|
|
21162
|
+
var deferListener = function() {
|
21163
|
+
if (!timeout) {
|
21164
|
+
timeout = $browser.defer(function() {
|
21165
|
+
listener();
|
21166
|
+
timeout = null;
|
21167
|
+
});
|
21168
|
+
}
|
21169
|
+
};
|
21170
|
+
|
20839
21171
|
element.bind('keydown', function(event) {
|
20840
21172
|
var key = event.keyCode;
|
20841
21173
|
|
@@ -20843,16 +21175,16 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|
20843
21175
|
// command modifiers arrows
|
20844
21176
|
if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return;
|
20845
21177
|
|
20846
|
-
|
20847
|
-
timeout = $browser.defer(function() {
|
20848
|
-
listener();
|
20849
|
-
timeout = null;
|
20850
|
-
});
|
20851
|
-
}
|
21178
|
+
deferListener();
|
20852
21179
|
});
|
20853
21180
|
|
20854
21181
|
// if user paste into input using mouse, we need "change" event to catch it
|
20855
21182
|
element.bind('change', listener);
|
21183
|
+
|
21184
|
+
// if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it
|
21185
|
+
if ($sniffer.hasEvent('paste')) {
|
21186
|
+
element.bind('paste cut', deferListener);
|
21187
|
+
}
|
20856
21188
|
}
|
20857
21189
|
|
20858
21190
|
|
@@ -21151,7 +21483,7 @@ function checkboxInputType(scope, element, attr, ctrl) {
|
|
21151
21483
|
<tt>myForm.userName.$valid = {{myForm.userName.$valid}}</tt><br>
|
21152
21484
|
<tt>myForm.userName.$error = {{myForm.userName.$error}}</tt><br>
|
21153
21485
|
<tt>myForm.lastName.$valid = {{myForm.lastName.$valid}}</tt><br>
|
21154
|
-
<tt>myForm.
|
21486
|
+
<tt>myForm.lastName.$error = {{myForm.lastName.$error}}</tt><br>
|
21155
21487
|
<tt>myForm.$valid = {{myForm.$valid}}</tt><br>
|
21156
21488
|
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br>
|
21157
21489
|
<tt>myForm.$error.minlength = {{!!myForm.$error.minlength}}</tt><br>
|
@@ -21222,12 +21554,25 @@ var VALID_CLASS = 'ng-valid',
|
|
21222
21554
|
*
|
21223
21555
|
* @property {string} $viewValue Actual string value in the view.
|
21224
21556
|
* @property {*} $modelValue The value in the model, that the control is bound to.
|
21225
|
-
* @property {Array.<Function>} $parsers
|
21226
|
-
|
21227
|
-
|
21228
|
-
|
21229
|
-
|
21230
|
-
|
21557
|
+
* @property {Array.<Function>} $parsers Array of functions to execute, as a pipeline, whenever
|
21558
|
+
the control reads value from the DOM. Each function is called, in turn, passing the value
|
21559
|
+
through to the next. Used to sanitize / convert the value as well as validation.
|
21560
|
+
|
21561
|
+
For validation, the parsers should update the validity state using
|
21562
|
+
{@link ng.directive:ngModel.NgModelController#$setValidity $setValidity()},
|
21563
|
+
and return `undefined` for invalid values.
|
21564
|
+
*
|
21565
|
+
* @property {Array.<Function>} $formatters Array of functions to execute, as a pipeline, whenever
|
21566
|
+
* the model value changes. Each function is called, in turn, passing the value through to the
|
21567
|
+
* next. Used to format / convert values for display in the control and validation.
|
21568
|
+
* <pre>
|
21569
|
+
* function formatter(value) {
|
21570
|
+
* if (value) {
|
21571
|
+
* return value.toUpperCase();
|
21572
|
+
* }
|
21573
|
+
* }
|
21574
|
+
* ngModel.$formatters.push(formatter);
|
21575
|
+
* </pre>
|
21231
21576
|
* @property {Object} $error An bject hash with all errors as keys.
|
21232
21577
|
*
|
21233
21578
|
* @property {boolean} $pristine True if user has not interacted with the control yet.
|
@@ -21242,6 +21587,10 @@ var VALID_CLASS = 'ng-valid',
|
|
21242
21587
|
* specifically does not contain any logic which deals with DOM rendering or listening to
|
21243
21588
|
* DOM events. The `NgModelController` is meant to be extended by other directives where, the
|
21244
21589
|
* directive provides DOM manipulation and the `NgModelController` provides the data-binding.
|
21590
|
+
* Note that you cannot use `NgModelController` in a directive with an isolated scope,
|
21591
|
+
* as, in that case, the `ng-model` value gets put into the isolated scope and does not get
|
21592
|
+
* propogated to the parent scope.
|
21593
|
+
*
|
21245
21594
|
*
|
21246
21595
|
* This example shows how to use `NgModelController` with a custom control to achieve
|
21247
21596
|
* data-binding. Notice how different directives (`contenteditable`, `ng-model`, and `required`)
|
@@ -21282,7 +21631,13 @@ var VALID_CLASS = 'ng-valid',
|
|
21282
21631
|
|
21283
21632
|
// Write data to the model
|
21284
21633
|
function read() {
|
21285
|
-
|
21634
|
+
var html = element.html();
|
21635
|
+
// When we clear the content editable the browser leaves a <br> behind
|
21636
|
+
// If strip-br attribute is provided then we strip this out
|
21637
|
+
if( attrs.stripBr && html == '<br>' ) {
|
21638
|
+
html = '';
|
21639
|
+
}
|
21640
|
+
ngModel.$setViewValue(html);
|
21286
21641
|
}
|
21287
21642
|
}
|
21288
21643
|
};
|
@@ -21292,6 +21647,7 @@ var VALID_CLASS = 'ng-valid',
|
|
21292
21647
|
<form name="myForm">
|
21293
21648
|
<div contenteditable
|
21294
21649
|
name="myWidget" ng-model="userContent"
|
21650
|
+
strip-br="true"
|
21295
21651
|
required>Change me!</div>
|
21296
21652
|
<span ng-show="myForm.myWidget.$error.required">Required!</span>
|
21297
21653
|
<hr>
|
@@ -21414,8 +21770,8 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
21414
21770
|
* For example {@link ng.directive:input input} or
|
21415
21771
|
* {@link ng.directive:select select} directives call it.
|
21416
21772
|
*
|
21417
|
-
* It internally calls all `
|
21418
|
-
* calls all registered change listeners.
|
21773
|
+
* It internally calls all `$parsers` (including validators) and updates the `$modelValue` and the actual model path.
|
21774
|
+
* Lastly it calls all registered change listeners.
|
21419
21775
|
*
|
21420
21776
|
* @param {string} value Value from the view.
|
21421
21777
|
*/
|
@@ -21480,7 +21836,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
21480
21836
|
* @element input
|
21481
21837
|
*
|
21482
21838
|
* @description
|
21483
|
-
* Is directive that tells Angular to do two-way data binding. It works together with `input`,
|
21839
|
+
* Is a directive that tells Angular to do two-way data binding. It works together with `input`,
|
21484
21840
|
* `select`, `textarea`. You can easily write your own directives to use `ngModel` as well.
|
21485
21841
|
*
|
21486
21842
|
* `ngModel` is responsible for:
|
@@ -21492,6 +21848,10 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
21492
21848
|
* - setting related css class onto the element (`ng-valid`, `ng-invalid`, `ng-dirty`, `ng-pristine`),
|
21493
21849
|
* - register the control with parent {@link ng.directive:form form}.
|
21494
21850
|
*
|
21851
|
+
* Note: `ngModel` will try to bind to the property given by evaluating the expression on the
|
21852
|
+
* current scope. If the property doesn't already exist on this scope, it will be created
|
21853
|
+
* implicitly and added to the scope.
|
21854
|
+
*
|
21495
21855
|
* For basic examples, how to use `ngModel`, see:
|
21496
21856
|
*
|
21497
21857
|
* - {@link ng.directive:input input}
|
@@ -21632,8 +21992,9 @@ var requiredDirective = function() {
|
|
21632
21992
|
</script>
|
21633
21993
|
<form name="myForm" ng-controller="Ctrl">
|
21634
21994
|
List: <input name="namesInput" ng-model="names" ng-list required>
|
21635
|
-
<span class="error" ng-show="myForm.
|
21995
|
+
<span class="error" ng-show="myForm.namesInput.$error.required">
|
21636
21996
|
Required!</span>
|
21997
|
+
<br>
|
21637
21998
|
<tt>names = {{names}}</tt><br/>
|
21638
21999
|
<tt>myForm.namesInput.$valid = {{myForm.namesInput.$valid}}</tt><br/>
|
21639
22000
|
<tt>myForm.namesInput.$error = {{myForm.namesInput.$error}}</tt><br/>
|
@@ -21645,12 +22006,14 @@ var requiredDirective = function() {
|
|
21645
22006
|
it('should initialize to model', function() {
|
21646
22007
|
expect(binding('names')).toEqual('["igor","misko","vojta"]');
|
21647
22008
|
expect(binding('myForm.namesInput.$valid')).toEqual('true');
|
22009
|
+
expect(element('span.error').css('display')).toBe('none');
|
21648
22010
|
});
|
21649
22011
|
|
21650
22012
|
it('should be invalid if empty', function() {
|
21651
22013
|
input('names').enter('');
|
21652
22014
|
expect(binding('names')).toEqual('[]');
|
21653
22015
|
expect(binding('myForm.namesInput.$valid')).toEqual('false');
|
22016
|
+
expect(element('span.error').css('display')).not().toBe('none');
|
21654
22017
|
});
|
21655
22018
|
</doc:scenario>
|
21656
22019
|
</doc:example>
|
@@ -21700,7 +22063,7 @@ var ngValueDirective = function() {
|
|
21700
22063
|
} else {
|
21701
22064
|
return function(scope, elm, attr) {
|
21702
22065
|
scope.$watch(attr.ngValue, function valueWatchAction(value) {
|
21703
|
-
attr.$set('value', value
|
22066
|
+
attr.$set('value', value);
|
21704
22067
|
});
|
21705
22068
|
};
|
21706
22069
|
}
|
@@ -21720,10 +22083,9 @@ var ngValueDirective = function() {
|
|
21720
22083
|
* Typically, you don't use `ngBind` directly, but instead you use the double curly markup like
|
21721
22084
|
* `{{ expression }}` which is similar but less verbose.
|
21722
22085
|
*
|
21723
|
-
*
|
21724
|
-
*
|
21725
|
-
*
|
21726
|
-
* bindings invisible to the user while the page is loading.
|
22086
|
+
* It is preferrable to use `ngBind` instead of `{{ expression }}` when a template is momentarily
|
22087
|
+
* displayed by the browser in its raw state before Angular compiles it. Since `ngBind` is an
|
22088
|
+
* element attribute, it makes the bindings invisible to the user while the page is loading.
|
21727
22089
|
*
|
21728
22090
|
* An alternative solution to this problem would be using the
|
21729
22091
|
* {@link ng.directive:ngCloak ngCloak} directive.
|
@@ -21769,10 +22131,11 @@ var ngBindDirective = ngDirective(function(scope, element, attr) {
|
|
21769
22131
|
*
|
21770
22132
|
* @description
|
21771
22133
|
* The `ngBindTemplate` directive specifies that the element
|
21772
|
-
* text should be replaced with the
|
21773
|
-
*
|
21774
|
-
*
|
21775
|
-
*
|
22134
|
+
* text content should be replaced with the interpolation of the template
|
22135
|
+
* in the `ngBindTemplate` attribute.
|
22136
|
+
* Unlike `ngBind`, the `ngBindTemplate` can contain multiple `{{` `}}`
|
22137
|
+
* expressions. This directive is needed since some HTML elements
|
22138
|
+
* (such as TITLE and OPTION) cannot contain SPAN elements.
|
21776
22139
|
*
|
21777
22140
|
* @element ANY
|
21778
22141
|
* @param {string} ngBindTemplate template of form
|
@@ -21861,9 +22224,9 @@ function classDirective(name, selector) {
|
|
21861
22224
|
|
21862
22225
|
if (name !== 'ngClass') {
|
21863
22226
|
scope.$watch('$index', function($index, old$index) {
|
21864
|
-
var mod = $index
|
21865
|
-
if (mod !== old$index
|
21866
|
-
if (mod
|
22227
|
+
var mod = $index & 1;
|
22228
|
+
if (mod !== old$index & 1) {
|
22229
|
+
if (mod === selector) {
|
21867
22230
|
addClass(scope.$eval(attr[name]));
|
21868
22231
|
} else {
|
21869
22232
|
removeClass(scope.$eval(attr[name]));
|
@@ -21875,12 +22238,12 @@ function classDirective(name, selector) {
|
|
21875
22238
|
|
21876
22239
|
function ngClassWatchAction(newVal) {
|
21877
22240
|
if (selector === true || scope.$index % 2 === selector) {
|
21878
|
-
if (oldVal && (newVal
|
22241
|
+
if (oldVal && !equals(newVal,oldVal)) {
|
21879
22242
|
removeClass(oldVal);
|
21880
22243
|
}
|
21881
22244
|
addClass(newVal);
|
21882
22245
|
}
|
21883
|
-
oldVal = newVal;
|
22246
|
+
oldVal = copy(newVal);
|
21884
22247
|
}
|
21885
22248
|
|
21886
22249
|
|
@@ -21908,8 +22271,8 @@ function classDirective(name, selector) {
|
|
21908
22271
|
* @name ng.directive:ngClass
|
21909
22272
|
*
|
21910
22273
|
* @description
|
21911
|
-
* The `ngClass` allows you to set CSS
|
21912
|
-
* expression that represents all classes to be added.
|
22274
|
+
* The `ngClass` allows you to set CSS classes on HTML an element, dynamically, by databinding
|
22275
|
+
* an expression that represents all classes to be added.
|
21913
22276
|
*
|
21914
22277
|
* The directive won't add duplicate classes if a particular class was already set.
|
21915
22278
|
*
|
@@ -21919,7 +22282,9 @@ function classDirective(name, selector) {
|
|
21919
22282
|
* @element ANY
|
21920
22283
|
* @param {expression} ngClass {@link guide/expression Expression} to eval. The result
|
21921
22284
|
* of the evaluation can be a string representing space delimited class
|
21922
|
-
* names, an array, or a map of class names to boolean values.
|
22285
|
+
* names, an array, or a map of class names to boolean values. In the case of a map, the
|
22286
|
+
* names of the properties whose values are truthy will be added as css classes to the
|
22287
|
+
* element.
|
21923
22288
|
*
|
21924
22289
|
* @example
|
21925
22290
|
<example>
|
@@ -22006,7 +22371,7 @@ var ngClassOddDirective = classDirective('Odd', 0);
|
|
22006
22371
|
* @name ng.directive:ngClassEven
|
22007
22372
|
*
|
22008
22373
|
* @description
|
22009
|
-
* The `ngClassOdd` and `ngClassEven`
|
22374
|
+
* The `ngClassOdd` and `ngClassEven` directives work exactly as
|
22010
22375
|
* {@link ng.directive:ngClass ngClass}, except it works in
|
22011
22376
|
* conjunction with `ngRepeat` and takes affect only on odd (even) rows.
|
22012
22377
|
*
|
@@ -22064,8 +22429,8 @@ var ngClassEvenDirective = classDirective('Even', 1);
|
|
22064
22429
|
* `angular.min.js` files. Following is the css rule:
|
22065
22430
|
*
|
22066
22431
|
* <pre>
|
22067
|
-
* [ng\:cloak], [ng-cloak], .ng-cloak {
|
22068
|
-
* display: none;
|
22432
|
+
* [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
|
22433
|
+
* display: none !important;
|
22069
22434
|
* }
|
22070
22435
|
* </pre>
|
22071
22436
|
*
|
@@ -22118,13 +22483,12 @@ var ngCloakDirective = ngDirective({
|
|
22118
22483
|
*
|
22119
22484
|
* MVC components in angular:
|
22120
22485
|
*
|
22121
|
-
* * Model
|
22122
|
-
* * View
|
22123
|
-
* * Controller
|
22486
|
+
* * Model — The Model is data in scope properties; scopes are attached to the DOM.
|
22487
|
+
* * View — The template (HTML with data bindings) is rendered into the View.
|
22488
|
+
* * Controller — The `ngController` directive specifies a Controller class; the class has
|
22124
22489
|
* methods that typically express the business logic behind the application.
|
22125
22490
|
*
|
22126
|
-
* Note that an alternative way to define controllers is via the
|
22127
|
-
* service.
|
22491
|
+
* Note that an alternative way to define controllers is via the {@link ng.$route $route} service.
|
22128
22492
|
*
|
22129
22493
|
* @element ANY
|
22130
22494
|
* @scope
|
@@ -22134,11 +22498,9 @@ var ngCloakDirective = ngDirective({
|
|
22134
22498
|
*
|
22135
22499
|
* @example
|
22136
22500
|
* Here is a simple form for editing user contact information. Adding, removing, clearing, and
|
22137
|
-
* greeting are methods declared on the controller (see source tab). These methods can
|
22138
|
-
* easily be called from the angular markup. Notice that
|
22139
|
-
*
|
22140
|
-
* notice that any changes to the data are automatically reflected in the View without the need
|
22141
|
-
* for a manual update.
|
22501
|
+
* greeting are methods declared on the $scope by the controller (see source tab). These methods can
|
22502
|
+
* easily be called from the angular markup. Notice that any changes to the data are automatically
|
22503
|
+
* reflected in the View without the need for a manual update.
|
22142
22504
|
<doc:example>
|
22143
22505
|
<doc:source>
|
22144
22506
|
<script>
|
@@ -22215,16 +22577,32 @@ var ngControllerDirective = [function() {
|
|
22215
22577
|
* @name ng.directive:ngCsp
|
22216
22578
|
* @priority 1000
|
22217
22579
|
*
|
22580
|
+
* @element html
|
22218
22581
|
* @description
|
22219
22582
|
* Enables [CSP (Content Security Policy)](https://developer.mozilla.org/en/Security/CSP) support.
|
22220
|
-
*
|
22221
|
-
*
|
22222
|
-
*
|
22223
|
-
*
|
22224
|
-
*
|
22225
|
-
*
|
22226
|
-
*
|
22227
|
-
*
|
22583
|
+
*
|
22584
|
+
* This is necessary when developing things like Google Chrome Extensions.
|
22585
|
+
*
|
22586
|
+
* CSP forbids apps to use `eval` or `Function(string)` generated functions (among other things).
|
22587
|
+
* For us to be compatible, we just need to implement the "getterFn" in $parse without violating
|
22588
|
+
* any of these restrictions.
|
22589
|
+
*
|
22590
|
+
* AngularJS uses `Function(string)` generated functions as a speed optimization. By applying `ngCsp`
|
22591
|
+
* it is be possible to opt into the CSP compatible mode. When this mode is on AngularJS will
|
22592
|
+
* evaluate all expressions up to 30% slower than in non-CSP mode, but no security violations will
|
22593
|
+
* be raised.
|
22594
|
+
*
|
22595
|
+
* In order to use this feature put `ngCsp` directive on the root element of the application.
|
22596
|
+
*
|
22597
|
+
* @example
|
22598
|
+
* This example shows how to apply the `ngCsp` directive to the `html` tag.
|
22599
|
+
<pre>
|
22600
|
+
<!doctype html>
|
22601
|
+
<html ng-app ng-csp>
|
22602
|
+
...
|
22603
|
+
...
|
22604
|
+
</html>
|
22605
|
+
</pre>
|
22228
22606
|
*/
|
22229
22607
|
|
22230
22608
|
var ngCspDirective = ['$sniffer', function($sniffer) {
|
@@ -22273,7 +22651,7 @@ var ngCspDirective = ['$sniffer', function($sniffer) {
|
|
22273
22651
|
*/
|
22274
22652
|
var ngEventDirectives = {};
|
22275
22653
|
forEach(
|
22276
|
-
'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave'.split(' '),
|
22654
|
+
'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave submit'.split(' '),
|
22277
22655
|
function(name) {
|
22278
22656
|
var directiveName = directiveNormalize('ng-' + name);
|
22279
22657
|
ngEventDirectives[directiveName] = ['$parse', function($parse) {
|
@@ -22400,6 +22778,54 @@ forEach(
|
|
22400
22778
|
*/
|
22401
22779
|
|
22402
22780
|
|
22781
|
+
/**
|
22782
|
+
* @ngdoc directive
|
22783
|
+
* @name ng.directive:ngKeydown
|
22784
|
+
*
|
22785
|
+
* @description
|
22786
|
+
* Specify custom behavior on keydown event.
|
22787
|
+
*
|
22788
|
+
* @element ANY
|
22789
|
+
* @param {expression} ngKeydown {@link guide/expression Expression} to evaluate upon
|
22790
|
+
* keydown. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
|
22791
|
+
*
|
22792
|
+
* @example
|
22793
|
+
* See {@link ng.directive:ngClick ngClick}
|
22794
|
+
*/
|
22795
|
+
|
22796
|
+
|
22797
|
+
/**
|
22798
|
+
* @ngdoc directive
|
22799
|
+
* @name ng.directive:ngKeyup
|
22800
|
+
*
|
22801
|
+
* @description
|
22802
|
+
* Specify custom behavior on keyup event.
|
22803
|
+
*
|
22804
|
+
* @element ANY
|
22805
|
+
* @param {expression} ngKeyup {@link guide/expression Expression} to evaluate upon
|
22806
|
+
* keyup. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
|
22807
|
+
*
|
22808
|
+
* @example
|
22809
|
+
* See {@link ng.directive:ngClick ngClick}
|
22810
|
+
*/
|
22811
|
+
|
22812
|
+
|
22813
|
+
/**
|
22814
|
+
* @ngdoc directive
|
22815
|
+
* @name ng.directive:ngKeypress
|
22816
|
+
*
|
22817
|
+
* @description
|
22818
|
+
* Specify custom behavior on keypress event.
|
22819
|
+
*
|
22820
|
+
* @element ANY
|
22821
|
+
* @param {expression} ngKeypress {@link guide/expression Expression} to evaluate upon
|
22822
|
+
* keypress. (Event object is available as `$event` and can be interrogated for keyCode, altKey, etc.)
|
22823
|
+
*
|
22824
|
+
* @example
|
22825
|
+
* See {@link ng.directive:ngClick ngClick}
|
22826
|
+
*/
|
22827
|
+
|
22828
|
+
|
22403
22829
|
/**
|
22404
22830
|
* @ngdoc directive
|
22405
22831
|
* @name ng.directive:ngSubmit
|
@@ -22408,10 +22834,11 @@ forEach(
|
|
22408
22834
|
* Enables binding angular expressions to onsubmit events.
|
22409
22835
|
*
|
22410
22836
|
* Additionally it prevents the default action (which for form means sending the request to the
|
22411
|
-
* server and reloading the current page)
|
22837
|
+
* server and reloading the current page) **but only if the form does not contain an `action`
|
22838
|
+
* attribute**.
|
22412
22839
|
*
|
22413
22840
|
* @element form
|
22414
|
-
* @param {expression} ngSubmit {@link guide/expression Expression} to eval.
|
22841
|
+
* @param {expression} ngSubmit {@link guide/expression Expression} to eval. (Event object is available as `$event`)
|
22415
22842
|
*
|
22416
22843
|
* @example
|
22417
22844
|
<doc:example>
|
@@ -22451,11 +22878,6 @@ forEach(
|
|
22451
22878
|
</doc:scenario>
|
22452
22879
|
</doc:example>
|
22453
22880
|
*/
|
22454
|
-
var ngSubmitDirective = ngDirective(function(scope, element, attrs) {
|
22455
|
-
element.bind('submit', function() {
|
22456
|
-
scope.$apply(attrs.ngSubmit);
|
22457
|
-
});
|
22458
|
-
});
|
22459
22881
|
|
22460
22882
|
/**
|
22461
22883
|
* @ngdoc directive
|
@@ -22663,7 +23085,7 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
|
|
22663
23085
|
* @description
|
22664
23086
|
* # Overview
|
22665
23087
|
* `ngPluralize` is a directive that displays messages according to en-US localization rules.
|
22666
|
-
* These rules are bundled with angular.js
|
23088
|
+
* These rules are bundled with angular.js, but can be overridden
|
22667
23089
|
* (see {@link guide/i18n Angular i18n} dev guide). You configure ngPluralize directive
|
22668
23090
|
* by specifying the mappings between
|
22669
23091
|
* {@link http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
|
@@ -22676,8 +23098,8 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
|
|
22676
23098
|
*
|
22677
23099
|
* While a pural category may match many numbers (for example, in en-US locale, "other" can match
|
22678
23100
|
* any number that is not 1), an explicit number rule can only match one number. For example, the
|
22679
|
-
* explicit number rule for "3" matches the number 3.
|
22680
|
-
* and explicit number rules throughout
|
23101
|
+
* explicit number rule for "3" matches the number 3. There are examples of plural categories
|
23102
|
+
* and explicit number rules throughout the rest of this documentation.
|
22681
23103
|
*
|
22682
23104
|
* # Configuring ngPluralize
|
22683
23105
|
* You configure ngPluralize by providing 2 attributes: `count` and `when`.
|
@@ -22687,8 +23109,7 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
|
|
22687
23109
|
* Angular expression}; these are evaluated on the current scope for its bound value.
|
22688
23110
|
*
|
22689
23111
|
* The `when` attribute specifies the mappings between plural categories and the actual
|
22690
|
-
* string to be displayed. The value of the attribute should be a JSON object
|
22691
|
-
* can interpret it correctly.
|
23112
|
+
* string to be displayed. The value of the attribute should be a JSON object.
|
22692
23113
|
*
|
22693
23114
|
* The following example shows how to configure ngPluralize:
|
22694
23115
|
*
|
@@ -22849,7 +23270,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
|
|
22849
23270
|
if (!isNaN(value)) {
|
22850
23271
|
//if explicit number rule such as 1, 2, 3... is defined, just use it. Otherwise,
|
22851
23272
|
//check it against pluralization rules in $locale service
|
22852
|
-
if (!whens
|
23273
|
+
if (!(value in whens)) value = $locale.pluralCat(value - offset);
|
22853
23274
|
return whensExpFns[value](scope, element, true);
|
22854
23275
|
} else {
|
22855
23276
|
return '';
|
@@ -22872,10 +23293,10 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
|
|
22872
23293
|
*
|
22873
23294
|
* Special properties are exposed on the local scope of each template instance, including:
|
22874
23295
|
*
|
22875
|
-
* * `$index`
|
22876
|
-
* * `$first`
|
22877
|
-
* * `$middle`
|
22878
|
-
* * `$last`
|
23296
|
+
* * `$index` – `{number}` – iterator offset of the repeated element (0..length-1)
|
23297
|
+
* * `$first` – `{boolean}` – true if the repeated element is first in the iterator.
|
23298
|
+
* * `$middle` – `{boolean}` – true if the repeated element is between the first and last in the iterator.
|
23299
|
+
* * `$last` – `{boolean}` – true if the repeated element is last in the iterator.
|
22879
23300
|
*
|
22880
23301
|
*
|
22881
23302
|
* @element ANY
|
@@ -22884,12 +23305,12 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
|
|
22884
23305
|
* @param {repeat_expression} ngRepeat The expression indicating how to enumerate a collection. Two
|
22885
23306
|
* formats are currently supported:
|
22886
23307
|
*
|
22887
|
-
* * `variable in expression`
|
23308
|
+
* * `variable in expression` – where variable is the user defined loop variable and `expression`
|
22888
23309
|
* is a scope expression giving the collection to enumerate.
|
22889
23310
|
*
|
22890
23311
|
* For example: `track in cd.tracks`.
|
22891
23312
|
*
|
22892
|
-
* * `(key, value) in expression`
|
23313
|
+
* * `(key, value) in expression` – where `key` and `value` can be any user defined identifiers,
|
22893
23314
|
* and `expression` is the scope expression giving the collection to enumerate.
|
22894
23315
|
*
|
22895
23316
|
* For example: `(name, age) in {'adam':10, 'amalie':12}`.
|
@@ -22957,7 +23378,7 @@ var ngRepeatDirective = ngDirective({
|
|
22957
23378
|
// Same as lastOrder but it has the current state. It will become the
|
22958
23379
|
// lastOrder on the next iteration.
|
22959
23380
|
nextOrder = new HashQueueMap(),
|
22960
|
-
|
23381
|
+
arrayBound,
|
22961
23382
|
childScope,
|
22962
23383
|
key, value, // key/value of iteration
|
22963
23384
|
array,
|
@@ -22978,7 +23399,7 @@ var ngRepeatDirective = ngDirective({
|
|
22978
23399
|
array = collection || [];
|
22979
23400
|
}
|
22980
23401
|
|
22981
|
-
|
23402
|
+
arrayBound = array.length-1;
|
22982
23403
|
|
22983
23404
|
// we are not using forEach for perf reasons (trying to avoid #call)
|
22984
23405
|
for (index = 0, length = array.length; index < length; index++) {
|
@@ -23015,7 +23436,7 @@ var ngRepeatDirective = ngDirective({
|
|
23015
23436
|
childScope.$index = index;
|
23016
23437
|
|
23017
23438
|
childScope.$first = (index === 0);
|
23018
|
-
childScope.$last = (index ===
|
23439
|
+
childScope.$last = (index === arrayBound);
|
23019
23440
|
childScope.$middle = !(childScope.$first || childScope.$last);
|
23020
23441
|
|
23021
23442
|
if (!last) {
|
@@ -23182,11 +23603,13 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
|
|
23182
23603
|
* @description
|
23183
23604
|
* Conditionally change the DOM structure.
|
23184
23605
|
*
|
23185
|
-
* @
|
23186
|
-
* <ANY ng-switch
|
23606
|
+
* @usage
|
23607
|
+
* <ANY ng-switch="expression">
|
23608
|
+
* <ANY ng-switch-when="matchValue1">...</ANY>
|
23187
23609
|
* <ANY ng-switch-when="matchValue2">...</ANY>
|
23188
23610
|
* ...
|
23189
23611
|
* <ANY ng-switch-default>...</ANY>
|
23612
|
+
* </ANY>
|
23190
23613
|
*
|
23191
23614
|
* @scope
|
23192
23615
|
* @param {*} ngSwitch|on expression to match against <tt>ng-switch-when</tt>.
|
@@ -23310,8 +23733,7 @@ var ngSwitchDefaultDirective = ngDirective({
|
|
23310
23733
|
return {
|
23311
23734
|
restrict: 'E',
|
23312
23735
|
transclude: true,
|
23313
|
-
scope: '
|
23314
|
-
locals: { title:'bind' },
|
23736
|
+
scope: { title:'@' },
|
23315
23737
|
template: '<div style="border: 1px solid black;">' +
|
23316
23738
|
'<div style="background-color: gray">{{title}}</div>' +
|
23317
23739
|
'<div ng-transclude></div>' +
|
@@ -23566,8 +23988,8 @@ var scriptDirective = ['$templateCache', function($templateCache) {
|
|
23566
23988
|
* Optionally `ngOptions` attribute can be used to dynamically generate a list of `<option>`
|
23567
23989
|
* elements for a `<select>` element using an array or an object obtained by evaluating the
|
23568
23990
|
* `ngOptions` expression.
|
23569
|
-
|
23570
|
-
* When an item in the select menu is
|
23991
|
+
*
|
23992
|
+
* When an item in the `<select>` menu is selected, the value of array element or object property
|
23571
23993
|
* represented by the selected option will be bound to the model identified by the `ngModel`
|
23572
23994
|
* directive of the parent select element.
|
23573
23995
|
*
|
@@ -23580,7 +24002,8 @@ var scriptDirective = ['$templateCache', function($templateCache) {
|
|
23580
24002
|
* `select` model to be bound to a non-string value. This is because an option element can currently
|
23581
24003
|
* be bound to string values only.
|
23582
24004
|
*
|
23583
|
-
* @param {string}
|
24005
|
+
* @param {string} ngModel Assignable angular expression to data-bind to.
|
24006
|
+
* @param {string=} name Property name of the form under which the control is published.
|
23584
24007
|
* @param {string=} required The control is considered valid only if value is entered.
|
23585
24008
|
* @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
|
23586
24009
|
* the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
|
@@ -23675,7 +24098,7 @@ var scriptDirective = ['$templateCache', function($templateCache) {
|
|
23675
24098
|
|
23676
24099
|
var ngOptionsDirective = valueFn({ terminal: true });
|
23677
24100
|
var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
23678
|
-
//
|
24101
|
+
//0000111110000000000022220000000000000000000000333300000000000000444444444444444440000000005555555555555555500000006666666666666666600000000000000077770
|
23679
24102
|
var NG_OPTIONS_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w\d]*)|(?:\(\s*([\$\w][\$\w\d]*)\s*,\s*([\$\w][\$\w\d]*)\s*\)))\s+in\s+(.*)$/,
|
23680
24103
|
nullModelCtrl = {$setViewValue: noop};
|
23681
24104
|
|
@@ -23947,10 +24370,6 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
23947
24370
|
|
23948
24371
|
if (multiple) {
|
23949
24372
|
selectedSet = new HashMap(modelValue);
|
23950
|
-
} else if (modelValue === null || nullOption) {
|
23951
|
-
// if we are not multiselect, and we are null then we have to add the nullOption
|
23952
|
-
optionGroups[''].push({selected:modelValue === null, id:'', label:''});
|
23953
|
-
selectedSet = true;
|
23954
24373
|
}
|
23955
24374
|
|
23956
24375
|
// We now build up the list of options we need (we merge later)
|
@@ -23975,9 +24394,14 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
23975
24394
|
selected: selected // determine if we should be selected
|
23976
24395
|
});
|
23977
24396
|
}
|
23978
|
-
if (!multiple
|
23979
|
-
|
23980
|
-
|
24397
|
+
if (!multiple) {
|
24398
|
+
if (nullOption || modelValue === null) {
|
24399
|
+
// insert null option if we have a placeholder, or the model is null
|
24400
|
+
optionGroups[''].unshift({id:'', label:'', selected:!selectedSet});
|
24401
|
+
} else if (!selectedSet) {
|
24402
|
+
// option could not be found, we have to insert the undefined item
|
24403
|
+
optionGroups[''].unshift({id:'?', label:'', selected:true});
|
24404
|
+
}
|
23981
24405
|
}
|
23982
24406
|
|
23983
24407
|
// Now we need to update the list of DOM nodes to match the optionGroups we computed above
|
@@ -24021,7 +24445,8 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
24021
24445
|
if (existingOption.id !== option.id) {
|
24022
24446
|
lastElement.val(existingOption.id = option.id);
|
24023
24447
|
}
|
24024
|
-
|
24448
|
+
// lastElement.prop('selected') provided by jQuery has side-effects
|
24449
|
+
if (lastElement[0].selected !== option.selected) {
|
24025
24450
|
lastElement.prop('selected', (existingOption.selected = option.selected));
|
24026
24451
|
}
|
24027
24452
|
} else {
|
@@ -26169,6 +26594,7 @@ angular.scenario.output('xml', function(context, runner, model) {
|
|
26169
26594
|
angular.scenario.output('object', function(context, runner, model) {
|
26170
26595
|
runner.$window.$result = model.value;
|
26171
26596
|
});
|
26597
|
+
|
26172
26598
|
bindJQuery();
|
26173
26599
|
publishExternalAPI(angular);
|
26174
26600
|
|
@@ -26191,5 +26617,5 @@ if (config.autotest) {
|
|
26191
26617
|
}
|
26192
26618
|
})(window, document);
|
26193
26619
|
|
26194
|
-
angular.element(document).find('head').append('<style type="text/css">@charset "UTF-8";\n\n[ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],\n.ng-cloak, .x-ng-cloak {\n display: none;\n}\n\nng\\:form {\n display: block;\n}\n</style>');
|
26620
|
+
angular.element(document).find('head').append('<style type="text/css">@charset "UTF-8";\n\n[ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],\n.ng-cloak, .x-ng-cloak {\n display: none !important;\n}\n\nng\\:form {\n display: block;\n}\n</style>');
|
26195
26621
|
angular.element(document).find('head').append('<style type="text/css">@charset "UTF-8";\n/* CSS Document */\n\n/** Structure */\nbody {\n font-family: Arial, sans-serif;\n margin: 0;\n font-size: 14px;\n}\n\n#system-error {\n font-size: 1.5em;\n text-align: center;\n}\n\n#json, #xml {\n display: none;\n}\n\n#header {\n position: fixed;\n width: 100%;\n}\n\n#specs {\n padding-top: 50px;\n}\n\n#header .angular {\n font-family: Courier New, monospace;\n font-weight: bold;\n}\n\n#header h1 {\n font-weight: normal;\n float: left;\n font-size: 30px;\n line-height: 30px;\n margin: 0;\n padding: 10px 10px;\n height: 30px;\n}\n\n#application h2,\n#specs h2 {\n margin: 0;\n padding: 0.5em;\n font-size: 1.1em;\n}\n\n#status-legend {\n margin-top: 10px;\n margin-right: 10px;\n}\n\n#header,\n#application,\n.test-info,\n.test-actions li {\n overflow: hidden;\n}\n\n#application {\n margin: 10px;\n}\n\n#application iframe {\n width: 100%;\n height: 758px;\n}\n\n#application .popout {\n float: right;\n}\n\n#application iframe {\n border: none;\n}\n\n.tests li,\n.test-actions li,\n.test-it li,\n.test-it ol,\n.status-display {\n list-style-type: none;\n}\n\n.tests,\n.test-it ol,\n.status-display {\n margin: 0;\n padding: 0;\n}\n\n.test-info {\n margin-left: 1em;\n margin-top: 0.5em;\n border-radius: 8px 0 0 8px;\n -webkit-border-radius: 8px 0 0 8px;\n -moz-border-radius: 8px 0 0 8px;\n cursor: pointer;\n}\n\n.test-info:hover .test-name {\n text-decoration: underline;\n}\n\n.test-info .closed:before {\n content: \'\\25b8\\00A0\';\n}\n\n.test-info .open:before {\n content: \'\\25be\\00A0\';\n font-weight: bold;\n}\n\n.test-it ol {\n margin-left: 2.5em;\n}\n\n.status-display,\n.status-display li {\n float: right;\n}\n\n.status-display li {\n padding: 5px 10px;\n}\n\n.timer-result,\n.test-title {\n display: inline-block;\n margin: 0;\n padding: 4px;\n}\n\n.test-actions .test-title,\n.test-actions .test-result {\n display: table-cell;\n padding-left: 0.5em;\n padding-right: 0.5em;\n}\n\n.test-actions {\n display: table;\n}\n\n.test-actions li {\n display: table-row;\n}\n\n.timer-result {\n width: 4em;\n padding: 0 10px;\n text-align: right;\n font-family: monospace;\n}\n\n.test-it pre,\n.test-actions pre {\n clear: left;\n color: black;\n margin-left: 6em;\n}\n\n.test-describe {\n padding-bottom: 0.5em;\n}\n\n.test-describe .test-describe {\n margin: 5px 5px 10px 2em;\n}\n\n.test-actions .status-pending .test-title:before {\n content: \'\\00bb\\00A0\';\n}\n\n.scrollpane {\n max-height: 20em;\n overflow: auto;\n}\n\n/** Colors */\n\n#header {\n background-color: #F2C200;\n}\n\n#specs h2 {\n border-top: 2px solid #BABAD1;\n}\n\n#specs h2,\n#application h2 {\n background-color: #efefef;\n}\n\n#application {\n border: 1px solid #BABAD1;\n}\n\n.test-describe .test-describe {\n border-left: 1px solid #BABAD1;\n border-right: 1px solid #BABAD1;\n border-bottom: 1px solid #BABAD1;\n}\n\n.status-display {\n border: 1px solid #777;\n}\n\n.status-display .status-pending,\n.status-pending .test-info {\n background-color: #F9EEBC;\n}\n\n.status-display .status-success,\n.status-success .test-info {\n background-color: #B1D7A1;\n}\n\n.status-display .status-failure,\n.status-failure .test-info {\n background-color: #FF8286;\n}\n\n.status-display .status-error,\n.status-error .test-info {\n background-color: black;\n color: white;\n}\n\n.test-actions .status-success .test-title {\n color: #30B30A;\n}\n\n.test-actions .status-failure .test-title {\n color: #DF0000;\n}\n\n.test-actions .status-error .test-title {\n color: black;\n}\n\n.test-actions .timer-result {\n color: #888;\n}\n</style>');
|