angular-gem 1.3.2 → 1.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/angular-gem/version.rb +1 -1
- data/vendor/assets/javascripts/1.3.4/angular-animate.js +2136 -0
- data/vendor/assets/javascripts/1.3.4/angular-aria.js +321 -0
- data/vendor/assets/javascripts/1.3.4/angular-cookies.js +206 -0
- data/vendor/assets/javascripts/1.3.4/angular-loader.js +405 -0
- data/vendor/assets/javascripts/1.3.4/angular-messages.js +400 -0
- data/vendor/assets/javascripts/1.3.4/angular-mocks.js +2380 -0
- data/vendor/assets/javascripts/1.3.4/angular-resource.js +667 -0
- data/vendor/assets/javascripts/1.3.4/angular-route.js +996 -0
- data/vendor/assets/javascripts/1.3.4/angular-sanitize.js +678 -0
- data/vendor/assets/javascripts/1.3.4/angular-scenario.js +37269 -0
- data/vendor/assets/javascripts/1.3.4/angular-touch.js +622 -0
- data/vendor/assets/javascripts/1.3.4/angular.js +25915 -0
- data/vendor/assets/javascripts/angular-animate.js +15 -15
- data/vendor/assets/javascripts/angular-aria.js +83 -23
- data/vendor/assets/javascripts/angular-cookies.js +1 -1
- data/vendor/assets/javascripts/angular-loader.js +6 -23
- data/vendor/assets/javascripts/angular-messages.js +1 -1
- data/vendor/assets/javascripts/angular-mocks.js +21 -17
- data/vendor/assets/javascripts/angular-resource.js +1 -1
- data/vendor/assets/javascripts/angular-route.js +21 -7
- data/vendor/assets/javascripts/angular-sanitize.js +26 -26
- data/vendor/assets/javascripts/angular-scenario.js +646 -453
- data/vendor/assets/javascripts/angular-touch.js +3 -3
- data/vendor/assets/javascripts/angular.js +641 -448
- metadata +14 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.3.
|
2
|
+
* @license AngularJS v1.3.4
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -301,7 +301,7 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
|
|
301
301
|
// Splices out the allowable region from the list after it has been used.
|
302
302
|
function checkAllowableRegions(touchCoordinates, x, y) {
|
303
303
|
for (var i = 0; i < touchCoordinates.length; i += 2) {
|
304
|
-
if (hit(touchCoordinates[i], touchCoordinates[i+1], x, y)) {
|
304
|
+
if (hit(touchCoordinates[i], touchCoordinates[i + 1], x, y)) {
|
305
305
|
touchCoordinates.splice(i, i + 2);
|
306
306
|
return true; // allowable region
|
307
307
|
}
|
@@ -366,7 +366,7 @@ ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement',
|
|
366
366
|
$timeout(function() {
|
367
367
|
// Remove the allowable region.
|
368
368
|
for (var i = 0; i < touchCoordinates.length; i += 2) {
|
369
|
-
if (touchCoordinates[i] == x && touchCoordinates[i+1] == y) {
|
369
|
+
if (touchCoordinates[i] == x && touchCoordinates[i + 1] == y) {
|
370
370
|
touchCoordinates.splice(i, i + 2);
|
371
371
|
return;
|
372
372
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.3.
|
2
|
+
* @license AngularJS v1.3.4
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -42,40 +42,23 @@ function minErr(module, ErrorConstructor) {
|
|
42
42
|
prefix = '[' + (module ? module + ':' : '') + code + '] ',
|
43
43
|
template = arguments[1],
|
44
44
|
templateArgs = arguments,
|
45
|
-
|
46
|
-
if (typeof obj === 'function') {
|
47
|
-
return obj.toString().replace(/ \{[\s\S]*$/, '');
|
48
|
-
} else if (typeof obj === 'undefined') {
|
49
|
-
return 'undefined';
|
50
|
-
} else if (typeof obj !== 'string') {
|
51
|
-
return JSON.stringify(obj);
|
52
|
-
}
|
53
|
-
return obj;
|
54
|
-
},
|
45
|
+
|
55
46
|
message, i;
|
56
47
|
|
57
48
|
message = prefix + template.replace(/\{\d+\}/g, function(match) {
|
58
49
|
var index = +match.slice(1, -1), arg;
|
59
50
|
|
60
51
|
if (index + 2 < templateArgs.length) {
|
61
|
-
|
62
|
-
if (typeof arg === 'function') {
|
63
|
-
return arg.toString().replace(/ ?\{[\s\S]*$/, '');
|
64
|
-
} else if (typeof arg === 'undefined') {
|
65
|
-
return 'undefined';
|
66
|
-
} else if (typeof arg !== 'string') {
|
67
|
-
return toJson(arg);
|
68
|
-
}
|
69
|
-
return arg;
|
52
|
+
return toDebugString(templateArgs[index + 2]);
|
70
53
|
}
|
71
54
|
return match;
|
72
55
|
});
|
73
56
|
|
74
|
-
message = message + '\nhttp://errors.angularjs.org/1.3.
|
57
|
+
message = message + '\nhttp://errors.angularjs.org/1.3.4/' +
|
75
58
|
(module ? module + '/' : '') + code;
|
76
59
|
for (i = 2; i < arguments.length; i++) {
|
77
|
-
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
|
78
|
-
encodeURIComponent(
|
60
|
+
message = message + (i == 2 ? '?' : '&') + 'p' + (i - 2) + '=' +
|
61
|
+
encodeURIComponent(toDebugString(arguments[i]));
|
79
62
|
}
|
80
63
|
return new ErrorConstructor(message);
|
81
64
|
};
|
@@ -443,7 +426,7 @@ function int(str) {
|
|
443
426
|
|
444
427
|
|
445
428
|
function inherit(parent, extra) {
|
446
|
-
return extend(
|
429
|
+
return extend(Object.create(parent), extra);
|
447
430
|
}
|
448
431
|
|
449
432
|
/**
|
@@ -706,7 +689,7 @@ function makeMap(str) {
|
|
706
689
|
|
707
690
|
|
708
691
|
function nodeName_(element) {
|
709
|
-
return lowercase(element.nodeName || element[0].nodeName);
|
692
|
+
return lowercase(element.nodeName || (element[0] && element[0].nodeName));
|
710
693
|
}
|
711
694
|
|
712
695
|
function includes(array, obj) {
|
@@ -715,7 +698,7 @@ function includes(array, obj) {
|
|
715
698
|
|
716
699
|
function arrayRemove(array, value) {
|
717
700
|
var index = array.indexOf(value);
|
718
|
-
if (index >=0)
|
701
|
+
if (index >= 0)
|
719
702
|
array.splice(index, 1);
|
720
703
|
return value;
|
721
704
|
}
|
@@ -916,7 +899,7 @@ function equals(o1, o2) {
|
|
916
899
|
if (isArray(o1)) {
|
917
900
|
if (!isArray(o2)) return false;
|
918
901
|
if ((length = o1.length) == o2.length) {
|
919
|
-
for (key=0; key<length; key++) {
|
902
|
+
for (key = 0; key < length; key++) {
|
920
903
|
if (!equals(o1[key], o2[key])) return false;
|
921
904
|
}
|
922
905
|
return true;
|
@@ -1002,7 +985,7 @@ function bind(self, fn) {
|
|
1002
985
|
return curryArgs.length
|
1003
986
|
? function() {
|
1004
987
|
return arguments.length
|
1005
|
-
? fn.apply(self,
|
988
|
+
? fn.apply(self, concat(curryArgs, arguments, 0))
|
1006
989
|
: fn.apply(self, curryArgs);
|
1007
990
|
}
|
1008
991
|
: function() {
|
@@ -1202,7 +1185,7 @@ var ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-'];
|
|
1202
1185
|
function getNgAttribute(element, ngAttr) {
|
1203
1186
|
var attr, i, ii = ngAttrPrefixes.length;
|
1204
1187
|
element = jqLite(element);
|
1205
|
-
for (i=0; i<ii; ++i) {
|
1188
|
+
for (i = 0; i < ii; ++i) {
|
1206
1189
|
attr = ngAttrPrefixes[i] + ngAttr;
|
1207
1190
|
if (isString(attr = element.attr(attr))) {
|
1208
1191
|
return attr;
|
@@ -1412,8 +1395,8 @@ function angularInit(element, bootstrap) {
|
|
1412
1395
|
* @param {Object=} config an object for defining configuration options for the application. The
|
1413
1396
|
* following keys are supported:
|
1414
1397
|
*
|
1415
|
-
*
|
1416
|
-
*
|
1398
|
+
* * `strictDi` - disable automatic function annotation for the application. This is meant to
|
1399
|
+
* assist in finding bugs which break minified code. Defaults to `false`.
|
1417
1400
|
*
|
1418
1401
|
* @returns {auto.$injector} Returns the newly created injector for this app.
|
1419
1402
|
*/
|
@@ -1987,6 +1970,34 @@ function setupModuleLoader(window) {
|
|
1987
1970
|
|
1988
1971
|
}
|
1989
1972
|
|
1973
|
+
/* global: toDebugString: true */
|
1974
|
+
|
1975
|
+
function serializeObject(obj) {
|
1976
|
+
var seen = [];
|
1977
|
+
|
1978
|
+
return JSON.stringify(obj, function(key, val) {
|
1979
|
+
val = toJsonReplacer(key, val);
|
1980
|
+
if (isObject(val)) {
|
1981
|
+
|
1982
|
+
if (seen.indexOf(val) >= 0) return '<<already seen>>';
|
1983
|
+
|
1984
|
+
seen.push(val);
|
1985
|
+
}
|
1986
|
+
return val;
|
1987
|
+
});
|
1988
|
+
}
|
1989
|
+
|
1990
|
+
function toDebugString(obj) {
|
1991
|
+
if (typeof obj === 'function') {
|
1992
|
+
return obj.toString().replace(/ \{[\s\S]*$/, '');
|
1993
|
+
} else if (typeof obj === 'undefined') {
|
1994
|
+
return 'undefined';
|
1995
|
+
} else if (typeof obj !== 'string') {
|
1996
|
+
return serializeObject(obj);
|
1997
|
+
}
|
1998
|
+
return obj;
|
1999
|
+
}
|
2000
|
+
|
1990
2001
|
/* global angularModule: true,
|
1991
2002
|
version: true,
|
1992
2003
|
|
@@ -2089,11 +2100,11 @@ function setupModuleLoader(window) {
|
|
2089
2100
|
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
|
2090
2101
|
*/
|
2091
2102
|
var version = {
|
2092
|
-
full: '1.3.
|
2103
|
+
full: '1.3.4', // all of these placeholder strings will be replaced by grunt's
|
2093
2104
|
major: 1, // package task
|
2094
2105
|
minor: 3,
|
2095
|
-
dot:
|
2096
|
-
codeName: '
|
2106
|
+
dot: 4,
|
2107
|
+
codeName: 'highfalutin-petroglyph'
|
2097
2108
|
};
|
2098
2109
|
|
2099
2110
|
|
@@ -2316,10 +2327,12 @@ function publishExternalAPI(angular) {
|
|
2316
2327
|
* `'ngModel'`).
|
2317
2328
|
* - `injector()` - retrieves the injector of the current element or its parent.
|
2318
2329
|
* - `scope()` - retrieves the {@link ng.$rootScope.Scope scope} of the current
|
2319
|
-
* element or its parent.
|
2330
|
+
* element or its parent. Requires {@link guide/production#disabling-debug-data Debug Data} to
|
2331
|
+
* be enabled.
|
2320
2332
|
* - `isolateScope()` - retrieves an isolate {@link ng.$rootScope.Scope scope} if one is attached directly to the
|
2321
2333
|
* current element. This getter should be used only on elements that contain a directive which starts a new isolate
|
2322
2334
|
* scope. Calling `scope()` on this element always returns the original non-isolate scope.
|
2335
|
+
* Requires {@link guide/production#disabling-debug-data Debug Data} to be enabled.
|
2323
2336
|
* - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top
|
2324
2337
|
* parent element is reached.
|
2325
2338
|
*
|
@@ -2826,7 +2839,7 @@ forEach({
|
|
2826
2839
|
}
|
2827
2840
|
} else {
|
2828
2841
|
return (element[name] ||
|
2829
|
-
(element.attributes.getNamedItem(name)|| noop).specified)
|
2842
|
+
(element.attributes.getNamedItem(name) || noop).specified)
|
2830
2843
|
? lowercasedName
|
2831
2844
|
: undefined;
|
2832
2845
|
}
|
@@ -3314,9 +3327,10 @@ HashMap.prototype = {
|
|
3314
3327
|
* Creates an injector object that can be used for retrieving services as well as for
|
3315
3328
|
* dependency injection (see {@link guide/di dependency injection}).
|
3316
3329
|
*
|
3317
|
-
|
3318
3330
|
* @param {Array.<string|Function>} modules A list of module functions or their aliases. See
|
3319
|
-
*
|
3331
|
+
* {@link angular.module}. The `ng` module must be explicitly added.
|
3332
|
+
* @param {boolean=} [strictDi=false] Whether the injector should be in strict mode, which
|
3333
|
+
* disallows argument name annotation inference.
|
3320
3334
|
* @returns {injector} Injector object. See {@link auto.$injector $injector}.
|
3321
3335
|
*
|
3322
3336
|
* @example
|
@@ -3462,8 +3476,10 @@ function annotate(fn, strictDi, name) {
|
|
3462
3476
|
* ## Inference
|
3463
3477
|
*
|
3464
3478
|
* In JavaScript calling `toString()` on a function returns the function definition. The definition
|
3465
|
-
* can then be parsed and the function arguments can be extracted.
|
3466
|
-
*
|
3479
|
+
* can then be parsed and the function arguments can be extracted. This method of discovering
|
3480
|
+
* annotations is disallowed when the injector is in strict mode.
|
3481
|
+
* *NOTE:* This does not work with minification, and obfuscation tools since these tools change the
|
3482
|
+
* argument names.
|
3467
3483
|
*
|
3468
3484
|
* ## `$inject` Annotation
|
3469
3485
|
* By adding an `$inject` property onto a function the injection parameters can be specified.
|
@@ -3548,6 +3564,8 @@ function annotate(fn, strictDi, name) {
|
|
3548
3564
|
* expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
|
3549
3565
|
* ```
|
3550
3566
|
*
|
3567
|
+
* You can disallow this method by using strict injection mode.
|
3568
|
+
*
|
3551
3569
|
* This method does not work with code minification / obfuscation. For this reason the following
|
3552
3570
|
* annotation strategies are supported.
|
3553
3571
|
*
|
@@ -3600,6 +3618,8 @@ function annotate(fn, strictDi, name) {
|
|
3600
3618
|
* @param {Function|Array.<string|Function>} fn Function for which dependent service names need to
|
3601
3619
|
* be retrieved as described above.
|
3602
3620
|
*
|
3621
|
+
* @param {boolean=} [strictDi=false] Disallow argument name annotation inference.
|
3622
|
+
*
|
3603
3623
|
* @returns {Array.<string>} The names of the services which the function requires.
|
3604
3624
|
*/
|
3605
3625
|
|
@@ -4119,14 +4139,11 @@ function createInjector(modulesToLoad, strictDi) {
|
|
4119
4139
|
}
|
4120
4140
|
|
4121
4141
|
function instantiate(Type, locals, serviceName) {
|
4122
|
-
var Constructor = function() {},
|
4123
|
-
instance, returnedValue;
|
4124
|
-
|
4125
4142
|
// Check if Type is annotated and use just the given function at n-1 as parameter
|
4126
4143
|
// e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);
|
4127
|
-
|
4128
|
-
instance =
|
4129
|
-
returnedValue = invoke(Type, instance, locals, serviceName);
|
4144
|
+
// Object creation: http://jsperf.com/create-constructor/2
|
4145
|
+
var instance = Object.create((isArray(Type) ? Type[Type.length - 1] : Type).prototype);
|
4146
|
+
var returnedValue = invoke(Type, instance, locals, serviceName);
|
4130
4147
|
|
4131
4148
|
return isObject(returnedValue) || isFunction(returnedValue) ? returnedValue : instance;
|
4132
4149
|
}
|
@@ -4162,7 +4179,7 @@ function $AnchorScrollProvider() {
|
|
4162
4179
|
* @name $anchorScrollProvider#disableAutoScrolling
|
4163
4180
|
*
|
4164
4181
|
* @description
|
4165
|
-
* By default, {@link ng.$anchorScroll $anchorScroll()} will automatically
|
4182
|
+
* By default, {@link ng.$anchorScroll $anchorScroll()} will automatically detect changes to
|
4166
4183
|
* {@link ng.$location#hash $location.hash()} and scroll to the element matching the new hash.<br />
|
4167
4184
|
* Use this method to disable automatic scrolling.
|
4168
4185
|
*
|
@@ -4811,8 +4828,7 @@ function $$AsyncCallbackProvider() {
|
|
4811
4828
|
/**
|
4812
4829
|
* @param {object} window The global window object.
|
4813
4830
|
* @param {object} document jQuery wrapped document.
|
4814
|
-
* @param {
|
4815
|
-
* @param {object} $log console.log or an object with the same interface.
|
4831
|
+
* @param {object} $log window.console or an object with the same interface.
|
4816
4832
|
* @param {object} $sniffer $sniffer service
|
4817
4833
|
*/
|
4818
4834
|
function Browser(window, document, $log, $sniffer) {
|
@@ -4963,7 +4979,7 @@ function Browser(window, document, $log, $sniffer) {
|
|
4963
4979
|
// IE<10 from getting into redirect loop when in LocationHashbangInHtml5Url mode.
|
4964
4980
|
// See https://github.com/angular/angular.js/commit/ffb2701
|
4965
4981
|
if (lastBrowserUrl === url && (!$sniffer.history || sameState)) {
|
4966
|
-
return;
|
4982
|
+
return self;
|
4967
4983
|
}
|
4968
4984
|
var sameBase = lastBrowserUrl && stripHash(lastBrowserUrl) === stripHash(url);
|
4969
4985
|
lastBrowserUrl = url;
|
@@ -5162,8 +5178,8 @@ function Browser(window, document, $log, $sniffer) {
|
|
5162
5178
|
// - 20 cookies per unique domain
|
5163
5179
|
// - 4096 bytes per cookie
|
5164
5180
|
if (cookieLength > 4096) {
|
5165
|
-
$log.warn("Cookie '"+ name +
|
5166
|
-
"' possibly not set or overflowed because it was too large ("+
|
5181
|
+
$log.warn("Cookie '" + name +
|
5182
|
+
"' possibly not set or overflowed because it was too large (" +
|
5167
5183
|
cookieLength + " > 4096 bytes)!");
|
5168
5184
|
}
|
5169
5185
|
}
|
@@ -5828,7 +5844,7 @@ function $TemplateCacheProvider() {
|
|
5828
5844
|
*
|
5829
5845
|
*
|
5830
5846
|
* #### `bindToController`
|
5831
|
-
* When an isolate scope is used for a component (see above), and `controllerAs` is used, `bindToController` will
|
5847
|
+
* When an isolate scope is used for a component (see above), and `controllerAs` is used, `bindToController: true` will
|
5832
5848
|
* allow a component to have its properties bound to the controller, rather than to scope. When the controller
|
5833
5849
|
* is instantiated, the initial values of the isolate scope bindings are already available.
|
5834
5850
|
*
|
@@ -6677,16 +6693,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6677
6693
|
|
6678
6694
|
// for each tuples
|
6679
6695
|
var nbrUrisWith2parts = Math.floor(rawUris.length / 2);
|
6680
|
-
for (var i=0; i<nbrUrisWith2parts; i++) {
|
6681
|
-
var innerIdx = i*2;
|
6696
|
+
for (var i = 0; i < nbrUrisWith2parts; i++) {
|
6697
|
+
var innerIdx = i * 2;
|
6682
6698
|
// sanitize the uri
|
6683
6699
|
result += $$sanitizeUri(trim(rawUris[innerIdx]), true);
|
6684
6700
|
// add the descriptor
|
6685
|
-
result += (" " + trim(rawUris[innerIdx+1]));
|
6701
|
+
result += (" " + trim(rawUris[innerIdx + 1]));
|
6686
6702
|
}
|
6687
6703
|
|
6688
6704
|
// split the last item into uri and descriptor
|
6689
|
-
var lastTuple = trim(rawUris[i*2]).split(/\s/);
|
6705
|
+
var lastTuple = trim(rawUris[i * 2]).split(/\s/);
|
6690
6706
|
|
6691
6707
|
// sanitize the last uri
|
6692
6708
|
result += $$sanitizeUri(trim(lastTuple[0]), true);
|
@@ -6880,7 +6896,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6880
6896
|
if (!node) {
|
6881
6897
|
return 'html';
|
6882
6898
|
} else {
|
6883
|
-
return nodeName_(node) !== 'foreignobject' && node.toString().match(/SVG/) ? 'svg': 'html';
|
6899
|
+
return nodeName_(node) !== 'foreignobject' && node.toString().match(/SVG/) ? 'svg' : 'html';
|
6884
6900
|
}
|
6885
6901
|
}
|
6886
6902
|
|
@@ -7693,7 +7709,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7693
7709
|
var match = null;
|
7694
7710
|
if (hasDirectives.hasOwnProperty(name)) {
|
7695
7711
|
for (var directive, directives = $injector.get(name + Suffix),
|
7696
|
-
i = 0, ii = directives.length; i<ii; i++) {
|
7712
|
+
i = 0, ii = directives.length; i < ii; i++) {
|
7697
7713
|
try {
|
7698
7714
|
directive = directives[i];
|
7699
7715
|
if ((maxPriority === undefined || maxPriority > directive.priority) &&
|
@@ -7722,7 +7738,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7722
7738
|
function directiveIsMultiElement(name) {
|
7723
7739
|
if (hasDirectives.hasOwnProperty(name)) {
|
7724
7740
|
for (var directive, directives = $injector.get(name + Suffix),
|
7725
|
-
i = 0, ii = directives.length; i<ii; i++) {
|
7741
|
+
i = 0, ii = directives.length; i < ii; i++) {
|
7726
7742
|
directive = directives[i];
|
7727
7743
|
if (directive.multiElement) {
|
7728
7744
|
return true;
|
@@ -7875,10 +7891,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7875
7891
|
var childBoundTranscludeFn = boundTranscludeFn;
|
7876
7892
|
if (scope.$$destroyed) return;
|
7877
7893
|
if (linkQueue) {
|
7878
|
-
linkQueue.push(scope
|
7879
|
-
|
7880
|
-
|
7881
|
-
|
7894
|
+
linkQueue.push(scope,
|
7895
|
+
node,
|
7896
|
+
rootElement,
|
7897
|
+
childBoundTranscludeFn);
|
7882
7898
|
} else {
|
7883
7899
|
if (afterTemplateNodeLinkFn.transcludeOnThisElement) {
|
7884
7900
|
childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);
|
@@ -7941,7 +7957,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7941
7957
|
case 'svg':
|
7942
7958
|
case 'math':
|
7943
7959
|
var wrapper = document.createElement('div');
|
7944
|
-
wrapper.innerHTML = '<'+type+'>'+template+'</'+type+'>';
|
7960
|
+
wrapper.innerHTML = '<' + type + '>' + template + '</' + type + '>';
|
7945
7961
|
return wrapper.childNodes[0].childNodes;
|
7946
7962
|
default:
|
7947
7963
|
return template;
|
@@ -8298,6 +8314,10 @@ function $ControllerProvider() {
|
|
8298
8314
|
* * if $controllerProvider#allowGlobals, check `window[constructor]` on the global
|
8299
8315
|
* `window` object (not recommended)
|
8300
8316
|
*
|
8317
|
+
* The string can use the `controller as property` syntax, where the controller instance is published
|
8318
|
+
* as the specified property on the `scope`; the `scope` must be injected into `locals` param for this
|
8319
|
+
* to work correctly.
|
8320
|
+
*
|
8301
8321
|
* @param {Object} locals Injection locals for Controller.
|
8302
8322
|
* @return {Object} Instance of given controller.
|
8303
8323
|
*
|
@@ -8343,10 +8363,10 @@ function $ControllerProvider() {
|
|
8343
8363
|
//
|
8344
8364
|
// This feature is not intended for use by applications, and is thus not documented
|
8345
8365
|
// publicly.
|
8346
|
-
|
8347
|
-
|
8366
|
+
// Object creation: http://jsperf.com/create-constructor/2
|
8367
|
+
var controllerPrototype = (isArray(expression) ?
|
8348
8368
|
expression[expression.length - 1] : expression).prototype;
|
8349
|
-
instance =
|
8369
|
+
instance = Object.create(controllerPrototype);
|
8350
8370
|
|
8351
8371
|
if (identifier) {
|
8352
8372
|
addIdentifier(locals, identifier, instance, constructor || expression.name);
|
@@ -8472,7 +8492,7 @@ function defaultHttpResponseTransform(data, headers) {
|
|
8472
8492
|
// strip json vulnerability protection prefix
|
8473
8493
|
data = data.replace(JSON_PROTECTION_PREFIX, '');
|
8474
8494
|
var contentType = headers('Content-Type');
|
8475
|
-
if ((contentType && contentType.indexOf(APPLICATION_JSON) === 0) ||
|
8495
|
+
if ((contentType && contentType.indexOf(APPLICATION_JSON) === 0 && data.trim()) ||
|
8476
8496
|
(JSON_START.test(data) && JSON_END.test(data))) {
|
8477
8497
|
data = fromJson(data);
|
8478
8498
|
}
|
@@ -8487,7 +8507,7 @@ function defaultHttpResponseTransform(data, headers) {
|
|
8487
8507
|
* @returns {Object} Parsed headers as key value object
|
8488
8508
|
*/
|
8489
8509
|
function parseHeaders(headers) {
|
8490
|
-
var parsed =
|
8510
|
+
var parsed = createMap(), key, val, i;
|
8491
8511
|
|
8492
8512
|
if (!headers) return parsed;
|
8493
8513
|
|
@@ -8524,7 +8544,11 @@ function headersGetter(headers) {
|
|
8524
8544
|
if (!headersObj) headersObj = parseHeaders(headers);
|
8525
8545
|
|
8526
8546
|
if (name) {
|
8527
|
-
|
8547
|
+
var value = headersObj[lowercase(name)];
|
8548
|
+
if (value === void 0) {
|
8549
|
+
value = null;
|
8550
|
+
}
|
8551
|
+
return value;
|
8528
8552
|
}
|
8529
8553
|
|
8530
8554
|
return headersObj;
|
@@ -8573,6 +8597,11 @@ function $HttpProvider() {
|
|
8573
8597
|
*
|
8574
8598
|
* Object containing default values for all {@link ng.$http $http} requests.
|
8575
8599
|
*
|
8600
|
+
* - **`defaults.cache`** - {Object} - an object built with {@link ng.$cacheFactory `$cacheFactory`}
|
8601
|
+
* that will provide the cache for all requests who set their `cache` property to `true`.
|
8602
|
+
* If you set the `default.cache = false` then only requests that specify their own custom
|
8603
|
+
* cache object will be cached. See {@link $http#caching $http Caching} for more information.
|
8604
|
+
*
|
8576
8605
|
* - **`defaults.xsrfCookieName`** - {string} - Name of cookie containing the XSRF token.
|
8577
8606
|
* Defaults value is `'XSRF-TOKEN'`.
|
8578
8607
|
*
|
@@ -8586,6 +8615,7 @@ function $HttpProvider() {
|
|
8586
8615
|
* - **`defaults.headers.post`**
|
8587
8616
|
* - **`defaults.headers.put`**
|
8588
8617
|
* - **`defaults.headers.patch`**
|
8618
|
+
*
|
8589
8619
|
**/
|
8590
8620
|
var defaults = this.defaults = {
|
8591
8621
|
// transform incoming response data
|
@@ -8800,6 +8830,21 @@ function $HttpProvider() {
|
|
8800
8830
|
* In addition, you can supply a `headers` property in the config object passed when
|
8801
8831
|
* calling `$http(config)`, which overrides the defaults without changing them globally.
|
8802
8832
|
*
|
8833
|
+
* To explicitly remove a header automatically added via $httpProvider.defaults.headers on a per request basis,
|
8834
|
+
* Use the `headers` property, setting the desired header to `undefined`. For example:
|
8835
|
+
*
|
8836
|
+
* ```js
|
8837
|
+
* var req = {
|
8838
|
+
* method: 'POST',
|
8839
|
+
* url: 'http://example.com',
|
8840
|
+
* headers: {
|
8841
|
+
* 'Content-Type': undefined
|
8842
|
+
* },
|
8843
|
+
* data: { test: 'test' },
|
8844
|
+
* }
|
8845
|
+
*
|
8846
|
+
* $http(req).success(function(){...}).error(function(){...});
|
8847
|
+
* ```
|
8803
8848
|
*
|
8804
8849
|
* ## Transforming Requests and Responses
|
8805
8850
|
*
|
@@ -9179,6 +9224,10 @@ function $HttpProvider() {
|
|
9179
9224
|
};
|
9180
9225
|
var headers = mergeHeaders(requestConfig);
|
9181
9226
|
|
9227
|
+
if (!angular.isObject(requestConfig)) {
|
9228
|
+
throw minErr('$http')('badreq', 'Http request configuration must be an object. Received: {0}', requestConfig);
|
9229
|
+
}
|
9230
|
+
|
9182
9231
|
extend(config, requestConfig);
|
9183
9232
|
config.headers = headers;
|
9184
9233
|
config.method = uppercase(config.method);
|
@@ -10043,7 +10092,8 @@ function $InterpolateProvider() {
|
|
10043
10092
|
|
10044
10093
|
function parseStringifyInterceptor(value) {
|
10045
10094
|
try {
|
10046
|
-
|
10095
|
+
value = getValue(value);
|
10096
|
+
return allOrNothing && !isDefined(value) ? value : stringify(value);
|
10047
10097
|
} catch (err) {
|
10048
10098
|
var newErr = $interpolateMinErr('interr', "Can't interpolate: {0}\n{1}", text,
|
10049
10099
|
err.toString());
|
@@ -10367,8 +10417,8 @@ function encodePath(path) {
|
|
10367
10417
|
return segments.join('/');
|
10368
10418
|
}
|
10369
10419
|
|
10370
|
-
function parseAbsoluteUrl(absoluteUrl, locationObj
|
10371
|
-
var parsedUrl = urlResolve(absoluteUrl
|
10420
|
+
function parseAbsoluteUrl(absoluteUrl, locationObj) {
|
10421
|
+
var parsedUrl = urlResolve(absoluteUrl);
|
10372
10422
|
|
10373
10423
|
locationObj.$$protocol = parsedUrl.protocol;
|
10374
10424
|
locationObj.$$host = parsedUrl.hostname;
|
@@ -10376,12 +10426,12 @@ function parseAbsoluteUrl(absoluteUrl, locationObj, appBase) {
|
|
10376
10426
|
}
|
10377
10427
|
|
10378
10428
|
|
10379
|
-
function parseAppUrl(relativeUrl, locationObj
|
10429
|
+
function parseAppUrl(relativeUrl, locationObj) {
|
10380
10430
|
var prefixed = (relativeUrl.charAt(0) !== '/');
|
10381
10431
|
if (prefixed) {
|
10382
10432
|
relativeUrl = '/' + relativeUrl;
|
10383
10433
|
}
|
10384
|
-
var match = urlResolve(relativeUrl
|
10434
|
+
var match = urlResolve(relativeUrl);
|
10385
10435
|
locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ?
|
10386
10436
|
match.pathname.substring(1) : match.pathname);
|
10387
10437
|
locationObj.$$search = parseKeyValue(match.search);
|
@@ -10436,7 +10486,7 @@ function LocationHtml5Url(appBase, basePrefix) {
|
|
10436
10486
|
this.$$html5 = true;
|
10437
10487
|
basePrefix = basePrefix || '';
|
10438
10488
|
var appBaseNoFile = stripFile(appBase);
|
10439
|
-
parseAbsoluteUrl(appBase, this
|
10489
|
+
parseAbsoluteUrl(appBase, this);
|
10440
10490
|
|
10441
10491
|
|
10442
10492
|
/**
|
@@ -10451,7 +10501,7 @@ function LocationHtml5Url(appBase, basePrefix) {
|
|
10451
10501
|
appBaseNoFile);
|
10452
10502
|
}
|
10453
10503
|
|
10454
|
-
parseAppUrl(pathUrl, this
|
10504
|
+
parseAppUrl(pathUrl, this);
|
10455
10505
|
|
10456
10506
|
if (!this.$$path) {
|
10457
10507
|
this.$$path = '/';
|
@@ -10514,7 +10564,7 @@ function LocationHtml5Url(appBase, basePrefix) {
|
|
10514
10564
|
function LocationHashbangUrl(appBase, hashPrefix) {
|
10515
10565
|
var appBaseNoFile = stripFile(appBase);
|
10516
10566
|
|
10517
|
-
parseAbsoluteUrl(appBase, this
|
10567
|
+
parseAbsoluteUrl(appBase, this);
|
10518
10568
|
|
10519
10569
|
|
10520
10570
|
/**
|
@@ -10534,7 +10584,7 @@ function LocationHashbangUrl(appBase, hashPrefix) {
|
|
10534
10584
|
throw $locationMinErr('ihshprfx', 'Invalid url "{0}", missing hash prefix "{1}".', url,
|
10535
10585
|
hashPrefix);
|
10536
10586
|
}
|
10537
|
-
parseAppUrl(withoutHashUrl, this
|
10587
|
+
parseAppUrl(withoutHashUrl, this);
|
10538
10588
|
|
10539
10589
|
this.$$path = removeWindowsDriveName(this.$$path, withoutHashUrl, appBase);
|
10540
10590
|
|
@@ -10672,6 +10722,13 @@ var locationPrototype = {
|
|
10672
10722
|
* Return full url representation with all segments encoded according to rules specified in
|
10673
10723
|
* [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt).
|
10674
10724
|
*
|
10725
|
+
*
|
10726
|
+
* ```js
|
10727
|
+
* // given url http://example.com/#/some/path?foo=bar&baz=xoxo
|
10728
|
+
* var absUrl = $location.absUrl();
|
10729
|
+
* // => "http://example.com/#/some/path?foo=bar&baz=xoxo"
|
10730
|
+
* ```
|
10731
|
+
*
|
10675
10732
|
* @return {string} full url
|
10676
10733
|
*/
|
10677
10734
|
absUrl: locationGetter('$$absUrl'),
|
@@ -10687,6 +10744,13 @@ var locationPrototype = {
|
|
10687
10744
|
*
|
10688
10745
|
* Change path, search and hash, when called with parameter and return `$location`.
|
10689
10746
|
*
|
10747
|
+
*
|
10748
|
+
* ```js
|
10749
|
+
* // given url http://example.com/#/some/path?foo=bar&baz=xoxo
|
10750
|
+
* var url = $location.url();
|
10751
|
+
* // => "/some/path?foo=bar&baz=xoxo"
|
10752
|
+
* ```
|
10753
|
+
*
|
10690
10754
|
* @param {string=} url New url without base prefix (e.g. `/path?a=b#hash`)
|
10691
10755
|
* @return {string} url
|
10692
10756
|
*/
|
@@ -10695,8 +10759,8 @@ var locationPrototype = {
|
|
10695
10759
|
return this.$$url;
|
10696
10760
|
|
10697
10761
|
var match = PATH_MATCH.exec(url);
|
10698
|
-
if (match[1]) this.path(decodeURIComponent(match[1]));
|
10699
|
-
if (match[2] || match[1]) this.search(match[3] || '');
|
10762
|
+
if (match[1] || url === '') this.path(decodeURIComponent(match[1]));
|
10763
|
+
if (match[2] || match[1] || url === '') this.search(match[3] || '');
|
10700
10764
|
this.hash(match[5] || '');
|
10701
10765
|
|
10702
10766
|
return this;
|
@@ -10711,6 +10775,13 @@ var locationPrototype = {
|
|
10711
10775
|
*
|
10712
10776
|
* Return protocol of current url.
|
10713
10777
|
*
|
10778
|
+
*
|
10779
|
+
* ```js
|
10780
|
+
* // given url http://example.com/#/some/path?foo=bar&baz=xoxo
|
10781
|
+
* var protocol = $location.protocol();
|
10782
|
+
* // => "http"
|
10783
|
+
* ```
|
10784
|
+
*
|
10714
10785
|
* @return {string} protocol of current url
|
10715
10786
|
*/
|
10716
10787
|
protocol: locationGetter('$$protocol'),
|
@@ -10724,6 +10795,13 @@ var locationPrototype = {
|
|
10724
10795
|
*
|
10725
10796
|
* Return host of current url.
|
10726
10797
|
*
|
10798
|
+
*
|
10799
|
+
* ```js
|
10800
|
+
* // given url http://example.com/#/some/path?foo=bar&baz=xoxo
|
10801
|
+
* var host = $location.host();
|
10802
|
+
* // => "example.com"
|
10803
|
+
* ```
|
10804
|
+
*
|
10727
10805
|
* @return {string} host of current url.
|
10728
10806
|
*/
|
10729
10807
|
host: locationGetter('$$host'),
|
@@ -10737,6 +10815,13 @@ var locationPrototype = {
|
|
10737
10815
|
*
|
10738
10816
|
* Return port of current url.
|
10739
10817
|
*
|
10818
|
+
*
|
10819
|
+
* ```js
|
10820
|
+
* // given url http://example.com/#/some/path?foo=bar&baz=xoxo
|
10821
|
+
* var port = $location.port();
|
10822
|
+
* // => 80
|
10823
|
+
* ```
|
10824
|
+
*
|
10740
10825
|
* @return {Number} port
|
10741
10826
|
*/
|
10742
10827
|
port: locationGetter('$$port'),
|
@@ -10755,6 +10840,13 @@ var locationPrototype = {
|
|
10755
10840
|
* Note: Path should always begin with forward slash (/), this method will add the forward slash
|
10756
10841
|
* if it is missing.
|
10757
10842
|
*
|
10843
|
+
*
|
10844
|
+
* ```js
|
10845
|
+
* // given url http://example.com/#/some/path?foo=bar&baz=xoxo
|
10846
|
+
* var path = $location.path();
|
10847
|
+
* // => "/some/path"
|
10848
|
+
* ```
|
10849
|
+
*
|
10758
10850
|
* @param {(string|number)=} path New path
|
10759
10851
|
* @return {string} path
|
10760
10852
|
*/
|
@@ -10780,10 +10872,9 @@ var locationPrototype = {
|
|
10780
10872
|
* var searchObject = $location.search();
|
10781
10873
|
* // => {foo: 'bar', baz: 'xoxo'}
|
10782
10874
|
*
|
10783
|
-
*
|
10784
10875
|
* // set foo to 'yipee'
|
10785
10876
|
* $location.search('foo', 'yipee');
|
10786
|
-
* // =>
|
10877
|
+
* // $location.search() => {foo: 'yipee', baz: 'xoxo'}
|
10787
10878
|
* ```
|
10788
10879
|
*
|
10789
10880
|
* @param {string|Object.<string>|Object.<Array.<string>>} search New search params - string or
|
@@ -10853,6 +10944,13 @@ var locationPrototype = {
|
|
10853
10944
|
*
|
10854
10945
|
* Change hash fragment when called with parameter and return `$location`.
|
10855
10946
|
*
|
10947
|
+
*
|
10948
|
+
* ```js
|
10949
|
+
* // given url http://example.com/some/path?foo=bar&baz=xoxo#hashValue
|
10950
|
+
* var hash = $location.hash();
|
10951
|
+
* // => "hashValue"
|
10952
|
+
* ```
|
10953
|
+
*
|
10856
10954
|
* @param {(string|number)=} hash New hash fragment
|
10857
10955
|
* @return {string} hash
|
10858
10956
|
*/
|
@@ -11174,11 +11272,19 @@ function $LocationProvider() {
|
|
11174
11272
|
$rootScope.$evalAsync(function() {
|
11175
11273
|
var oldUrl = $location.absUrl();
|
11176
11274
|
var oldState = $location.$$state;
|
11275
|
+
var defaultPrevented;
|
11177
11276
|
|
11178
11277
|
$location.$$parse(newUrl);
|
11179
11278
|
$location.$$state = newState;
|
11180
|
-
|
11181
|
-
|
11279
|
+
|
11280
|
+
defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,
|
11281
|
+
newState, oldState).defaultPrevented;
|
11282
|
+
|
11283
|
+
// if the location was changed by a `$locationChangeStart` handler then stop
|
11284
|
+
// processing this location change
|
11285
|
+
if ($location.absUrl() !== newUrl) return;
|
11286
|
+
|
11287
|
+
if (defaultPrevented) {
|
11182
11288
|
$location.$$parse(oldUrl);
|
11183
11289
|
$location.$$state = oldState;
|
11184
11290
|
setBrowserUrlWithFallback(oldUrl, false, oldState);
|
@@ -11202,13 +11308,20 @@ function $LocationProvider() {
|
|
11202
11308
|
initializing = false;
|
11203
11309
|
|
11204
11310
|
$rootScope.$evalAsync(function() {
|
11205
|
-
|
11206
|
-
|
11311
|
+
var newUrl = $location.absUrl();
|
11312
|
+
var defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl,
|
11313
|
+
$location.$$state, oldState).defaultPrevented;
|
11314
|
+
|
11315
|
+
// if the location was changed by a `$locationChangeStart` handler then stop
|
11316
|
+
// processing this location change
|
11317
|
+
if ($location.absUrl() !== newUrl) return;
|
11318
|
+
|
11319
|
+
if (defaultPrevented) {
|
11207
11320
|
$location.$$parse(oldUrl);
|
11208
11321
|
$location.$$state = oldState;
|
11209
11322
|
} else {
|
11210
11323
|
if (urlOrStateChanged) {
|
11211
|
-
setBrowserUrlWithFallback(
|
11324
|
+
setBrowserUrlWithFallback(newUrl, currentReplace,
|
11212
11325
|
oldState === $location.$$state ? null : $location.$$state);
|
11213
11326
|
}
|
11214
11327
|
afterLocationChange(oldUrl, oldState);
|
@@ -11398,7 +11511,7 @@ var $parseMinErr = minErr('$parse');
|
|
11398
11511
|
// Sandboxing Angular Expressions
|
11399
11512
|
// ------------------------------
|
11400
11513
|
// Angular expressions are generally considered safe because these expressions only have direct
|
11401
|
-
// access to
|
11514
|
+
// access to `$scope` and locals. However, one can obtain the ability to execute arbitrary JS code by
|
11402
11515
|
// obtaining a reference to native JS functions such as the Function constructor.
|
11403
11516
|
//
|
11404
11517
|
// As an example, consider the following Angular expression:
|
@@ -11407,7 +11520,7 @@ var $parseMinErr = minErr('$parse');
|
|
11407
11520
|
//
|
11408
11521
|
// This sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits
|
11409
11522
|
// against the expression language, but not to prevent exploits that were enabled by exposing
|
11410
|
-
// sensitive JavaScript or browser
|
11523
|
+
// sensitive JavaScript or browser APIs on Scope. Exposing such objects on a Scope is never a good
|
11411
11524
|
// practice and therefore we are not even trying to protect against interaction with an object
|
11412
11525
|
// explicitly exposed in this way.
|
11413
11526
|
//
|
@@ -11415,6 +11528,8 @@ var $parseMinErr = minErr('$parse');
|
|
11415
11528
|
// window or some DOM object that has a reference to window is published onto a Scope.
|
11416
11529
|
// Similarly we prevent invocations of function known to be dangerous, as well as assignments to
|
11417
11530
|
// native objects.
|
11531
|
+
//
|
11532
|
+
// See https://docs.angularjs.org/guide/security
|
11418
11533
|
|
11419
11534
|
|
11420
11535
|
function ensureSafeMemberName(name, fullExpression) {
|
@@ -11423,7 +11538,7 @@ function ensureSafeMemberName(name, fullExpression) {
|
|
11423
11538
|
|| name === "__proto__") {
|
11424
11539
|
throw $parseMinErr('isecfld',
|
11425
11540
|
'Attempting to access a disallowed field in Angular expressions! '
|
11426
|
-
+'Expression: {0}', fullExpression);
|
11541
|
+
+ 'Expression: {0}', fullExpression);
|
11427
11542
|
}
|
11428
11543
|
return name;
|
11429
11544
|
}
|
@@ -11500,24 +11615,24 @@ var OPERATORS = extend(createMap(), {
|
|
11500
11615
|
}
|
11501
11616
|
return a;
|
11502
11617
|
}
|
11503
|
-
return isDefined(b)?b:undefined;},
|
11618
|
+
return isDefined(b) ? b : undefined;},
|
11504
11619
|
'-':function(self, locals, a, b) {
|
11505
11620
|
a=a(self, locals); b=b(self, locals);
|
11506
|
-
return (isDefined(a)?a:0)-(isDefined(b)?b:0);
|
11621
|
+
return (isDefined(a) ? a : 0) - (isDefined(b) ? b : 0);
|
11507
11622
|
},
|
11508
|
-
'*':function(self, locals, a, b) {return a(self, locals)*b(self, locals);},
|
11509
|
-
'/':function(self, locals, a, b) {return a(self, locals)/b(self, locals);},
|
11510
|
-
'%':function(self, locals, a, b) {return a(self, locals)%b(self, locals);},
|
11511
|
-
'===':function(self, locals, a, b) {return a(self, locals)===b(self, locals);},
|
11512
|
-
'!==':function(self, locals, a, b) {return a(self, locals)!==b(self, locals);},
|
11513
|
-
'==':function(self, locals, a, b) {return a(self, locals)==b(self, locals);},
|
11514
|
-
'!=':function(self, locals, a, b) {return a(self, locals)!=b(self, locals);},
|
11515
|
-
'<':function(self, locals, a, b) {return a(self, locals)<b(self, locals);},
|
11516
|
-
'>':function(self, locals, a, b) {return a(self, locals)>b(self, locals);},
|
11517
|
-
'<=':function(self, locals, a, b) {return a(self, locals)<=b(self, locals);},
|
11518
|
-
'>=':function(self, locals, a, b) {return a(self, locals)>=b(self, locals);},
|
11519
|
-
'&&':function(self, locals, a, b) {return a(self, locals)&&b(self, locals);},
|
11520
|
-
'||':function(self, locals, a, b) {return a(self, locals)||b(self, locals);},
|
11623
|
+
'*':function(self, locals, a, b) {return a(self, locals) * b(self, locals);},
|
11624
|
+
'/':function(self, locals, a, b) {return a(self, locals) / b(self, locals);},
|
11625
|
+
'%':function(self, locals, a, b) {return a(self, locals) % b(self, locals);},
|
11626
|
+
'===':function(self, locals, a, b) {return a(self, locals) === b(self, locals);},
|
11627
|
+
'!==':function(self, locals, a, b) {return a(self, locals) !== b(self, locals);},
|
11628
|
+
'==':function(self, locals, a, b) {return a(self, locals) == b(self, locals);},
|
11629
|
+
'!=':function(self, locals, a, b) {return a(self, locals) != b(self, locals);},
|
11630
|
+
'<':function(self, locals, a, b) {return a(self, locals) < b(self, locals);},
|
11631
|
+
'>':function(self, locals, a, b) {return a(self, locals) > b(self, locals);},
|
11632
|
+
'<=':function(self, locals, a, b) {return a(self, locals) <= b(self, locals);},
|
11633
|
+
'>=':function(self, locals, a, b) {return a(self, locals) >= b(self, locals);},
|
11634
|
+
'&&':function(self, locals, a, b) {return a(self, locals) && b(self, locals);},
|
11635
|
+
'||':function(self, locals, a, b) {return a(self, locals) || b(self, locals);},
|
11521
11636
|
'!':function(self, locals, a) {return !a(self, locals);},
|
11522
11637
|
|
11523
11638
|
//Tokenized as operators but parsed as assignment/filters
|
@@ -11543,44 +11658,31 @@ Lexer.prototype = {
|
|
11543
11658
|
lex: function(text) {
|
11544
11659
|
this.text = text;
|
11545
11660
|
this.index = 0;
|
11546
|
-
this.ch = undefined;
|
11547
11661
|
this.tokens = [];
|
11548
11662
|
|
11549
11663
|
while (this.index < this.text.length) {
|
11550
|
-
|
11551
|
-
if (
|
11552
|
-
this.readString(
|
11553
|
-
} else if (this.isNumber(
|
11664
|
+
var ch = this.text.charAt(this.index);
|
11665
|
+
if (ch === '"' || ch === "'") {
|
11666
|
+
this.readString(ch);
|
11667
|
+
} else if (this.isNumber(ch) || ch === '.' && this.isNumber(this.peek())) {
|
11554
11668
|
this.readNumber();
|
11555
|
-
} else if (this.isIdent(
|
11669
|
+
} else if (this.isIdent(ch)) {
|
11556
11670
|
this.readIdent();
|
11557
|
-
} else if (this.is('(){}[].,;:?')) {
|
11558
|
-
this.tokens.push({
|
11559
|
-
index: this.index,
|
11560
|
-
text: this.ch
|
11561
|
-
});
|
11671
|
+
} else if (this.is(ch, '(){}[].,;:?')) {
|
11672
|
+
this.tokens.push({index: this.index, text: ch});
|
11562
11673
|
this.index++;
|
11563
|
-
} else if (this.isWhitespace(
|
11674
|
+
} else if (this.isWhitespace(ch)) {
|
11564
11675
|
this.index++;
|
11565
11676
|
} else {
|
11566
|
-
var ch2 =
|
11677
|
+
var ch2 = ch + this.peek();
|
11567
11678
|
var ch3 = ch2 + this.peek(2);
|
11568
|
-
var
|
11569
|
-
var
|
11570
|
-
var
|
11571
|
-
if (
|
11572
|
-
|
11573
|
-
this.index
|
11574
|
-
|
11575
|
-
this.tokens.push({index: this.index, text: ch2, fn: fn2});
|
11576
|
-
this.index += 2;
|
11577
|
-
} else if (fn) {
|
11578
|
-
this.tokens.push({
|
11579
|
-
index: this.index,
|
11580
|
-
text: this.ch,
|
11581
|
-
fn: fn
|
11582
|
-
});
|
11583
|
-
this.index += 1;
|
11679
|
+
var op1 = OPERATORS[ch];
|
11680
|
+
var op2 = OPERATORS[ch2];
|
11681
|
+
var op3 = OPERATORS[ch3];
|
11682
|
+
if (op1 || op2 || op3) {
|
11683
|
+
var token = op3 ? ch3 : (op2 ? ch2 : ch);
|
11684
|
+
this.tokens.push({index: this.index, text: token, operator: true});
|
11685
|
+
this.index += token.length;
|
11584
11686
|
} else {
|
11585
11687
|
this.throwError('Unexpected next character ', this.index, this.index + 1);
|
11586
11688
|
}
|
@@ -11589,8 +11691,8 @@ Lexer.prototype = {
|
|
11589
11691
|
return this.tokens;
|
11590
11692
|
},
|
11591
11693
|
|
11592
|
-
is: function(chars) {
|
11593
|
-
return chars.indexOf(
|
11694
|
+
is: function(ch, chars) {
|
11695
|
+
return chars.indexOf(ch) !== -1;
|
11594
11696
|
},
|
11595
11697
|
|
11596
11698
|
peek: function(i) {
|
@@ -11599,7 +11701,7 @@ Lexer.prototype = {
|
|
11599
11701
|
},
|
11600
11702
|
|
11601
11703
|
isNumber: function(ch) {
|
11602
|
-
return ('0' <= ch && ch <= '9');
|
11704
|
+
return ('0' <= ch && ch <= '9') && typeof ch === "string";
|
11603
11705
|
},
|
11604
11706
|
|
11605
11707
|
isWhitespace: function(ch) {
|
@@ -11652,79 +11754,28 @@ Lexer.prototype = {
|
|
11652
11754
|
}
|
11653
11755
|
this.index++;
|
11654
11756
|
}
|
11655
|
-
number = 1 * number;
|
11656
11757
|
this.tokens.push({
|
11657
11758
|
index: start,
|
11658
11759
|
text: number,
|
11659
11760
|
constant: true,
|
11660
|
-
|
11761
|
+
value: Number(number)
|
11661
11762
|
});
|
11662
11763
|
},
|
11663
11764
|
|
11664
11765
|
readIdent: function() {
|
11665
|
-
var expression = this.text;
|
11666
|
-
|
11667
|
-
var ident = '';
|
11668
11766
|
var start = this.index;
|
11669
|
-
|
11670
|
-
var lastDot, peekIndex, methodName, ch;
|
11671
|
-
|
11672
11767
|
while (this.index < this.text.length) {
|
11673
|
-
ch = this.text.charAt(this.index);
|
11674
|
-
if (
|
11675
|
-
if (ch === '.') lastDot = this.index;
|
11676
|
-
ident += ch;
|
11677
|
-
} else {
|
11768
|
+
var ch = this.text.charAt(this.index);
|
11769
|
+
if (!(this.isIdent(ch) || this.isNumber(ch))) {
|
11678
11770
|
break;
|
11679
11771
|
}
|
11680
11772
|
this.index++;
|
11681
11773
|
}
|
11682
|
-
|
11683
|
-
//check if the identifier ends with . and if so move back one char
|
11684
|
-
if (lastDot && ident[ident.length - 1] === '.') {
|
11685
|
-
this.index--;
|
11686
|
-
ident = ident.slice(0, -1);
|
11687
|
-
lastDot = ident.lastIndexOf('.');
|
11688
|
-
if (lastDot === -1) {
|
11689
|
-
lastDot = undefined;
|
11690
|
-
}
|
11691
|
-
}
|
11692
|
-
|
11693
|
-
//check if this is not a method invocation and if it is back out to last dot
|
11694
|
-
if (lastDot) {
|
11695
|
-
peekIndex = this.index;
|
11696
|
-
while (peekIndex < this.text.length) {
|
11697
|
-
ch = this.text.charAt(peekIndex);
|
11698
|
-
if (ch === '(') {
|
11699
|
-
methodName = ident.substr(lastDot - start + 1);
|
11700
|
-
ident = ident.substr(0, lastDot - start);
|
11701
|
-
this.index = peekIndex;
|
11702
|
-
break;
|
11703
|
-
}
|
11704
|
-
if (this.isWhitespace(ch)) {
|
11705
|
-
peekIndex++;
|
11706
|
-
} else {
|
11707
|
-
break;
|
11708
|
-
}
|
11709
|
-
}
|
11710
|
-
}
|
11711
|
-
|
11712
11774
|
this.tokens.push({
|
11713
11775
|
index: start,
|
11714
|
-
text:
|
11715
|
-
|
11776
|
+
text: this.text.slice(start, this.index),
|
11777
|
+
identifier: true
|
11716
11778
|
});
|
11717
|
-
|
11718
|
-
if (methodName) {
|
11719
|
-
this.tokens.push({
|
11720
|
-
index: lastDot,
|
11721
|
-
text: '.'
|
11722
|
-
});
|
11723
|
-
this.tokens.push({
|
11724
|
-
index: lastDot + 1,
|
11725
|
-
text: methodName
|
11726
|
-
});
|
11727
|
-
}
|
11728
11779
|
},
|
11729
11780
|
|
11730
11781
|
readString: function(quote) {
|
@@ -11755,9 +11806,8 @@ Lexer.prototype = {
|
|
11755
11806
|
this.tokens.push({
|
11756
11807
|
index: start,
|
11757
11808
|
text: rawString,
|
11758
|
-
string: string,
|
11759
11809
|
constant: true,
|
11760
|
-
|
11810
|
+
value: string
|
11761
11811
|
});
|
11762
11812
|
return;
|
11763
11813
|
} else {
|
@@ -11818,16 +11868,12 @@ Parser.prototype = {
|
|
11818
11868
|
primary = this.arrayDeclaration();
|
11819
11869
|
} else if (this.expect('{')) {
|
11820
11870
|
primary = this.object();
|
11871
|
+
} else if (this.peek().identifier) {
|
11872
|
+
primary = this.identifier();
|
11873
|
+
} else if (this.peek().constant) {
|
11874
|
+
primary = this.constant();
|
11821
11875
|
} else {
|
11822
|
-
|
11823
|
-
primary = token.fn;
|
11824
|
-
if (!primary) {
|
11825
|
-
this.throwError('not a primary expression', token);
|
11826
|
-
}
|
11827
|
-
if (token.constant) {
|
11828
|
-
primary.constant = true;
|
11829
|
-
primary.literal = true;
|
11830
|
-
}
|
11876
|
+
this.throwError('not a primary expression', this.peek());
|
11831
11877
|
}
|
11832
11878
|
|
11833
11879
|
var next, context;
|
@@ -11861,8 +11907,11 @@ Parser.prototype = {
|
|
11861
11907
|
},
|
11862
11908
|
|
11863
11909
|
peek: function(e1, e2, e3, e4) {
|
11864
|
-
|
11865
|
-
|
11910
|
+
return this.peekAhead(0, e1, e2, e3, e4);
|
11911
|
+
},
|
11912
|
+
peekAhead: function(i, e1, e2, e3, e4) {
|
11913
|
+
if (this.tokens.length > i) {
|
11914
|
+
var token = this.tokens[i];
|
11866
11915
|
var t = token.text;
|
11867
11916
|
if (t === e1 || t === e2 || t === e3 || t === e4 ||
|
11868
11917
|
(!e1 && !e2 && !e3 && !e4)) {
|
@@ -11882,12 +11931,19 @@ Parser.prototype = {
|
|
11882
11931
|
},
|
11883
11932
|
|
11884
11933
|
consume: function(e1) {
|
11885
|
-
if (
|
11934
|
+
if (this.tokens.length === 0) {
|
11935
|
+
throw $parseMinErr('ueoe', 'Unexpected end of expression: {0}', this.text);
|
11936
|
+
}
|
11937
|
+
|
11938
|
+
var token = this.expect(e1);
|
11939
|
+
if (!token) {
|
11886
11940
|
this.throwError('is unexpected, expecting [' + e1 + ']', this.peek());
|
11887
11941
|
}
|
11942
|
+
return token;
|
11888
11943
|
},
|
11889
11944
|
|
11890
|
-
unaryFn: function(
|
11945
|
+
unaryFn: function(op, right) {
|
11946
|
+
var fn = OPERATORS[op];
|
11891
11947
|
return extend(function $parseUnaryFn(self, locals) {
|
11892
11948
|
return fn(self, locals, right);
|
11893
11949
|
}, {
|
@@ -11896,7 +11952,8 @@ Parser.prototype = {
|
|
11896
11952
|
});
|
11897
11953
|
},
|
11898
11954
|
|
11899
|
-
binaryFn: function(left,
|
11955
|
+
binaryFn: function(left, op, right, isBranching) {
|
11956
|
+
var fn = OPERATORS[op];
|
11900
11957
|
return extend(function $parseBinaryFn(self, locals) {
|
11901
11958
|
return fn(self, locals, left, right);
|
11902
11959
|
}, {
|
@@ -11905,6 +11962,28 @@ Parser.prototype = {
|
|
11905
11962
|
});
|
11906
11963
|
},
|
11907
11964
|
|
11965
|
+
identifier: function() {
|
11966
|
+
var id = this.consume().text;
|
11967
|
+
|
11968
|
+
//Continue reading each `.identifier` unless it is a method invocation
|
11969
|
+
while (this.peek('.') && this.peekAhead(1).identifier && !this.peekAhead(2, '(')) {
|
11970
|
+
id += this.consume().text + this.consume().text;
|
11971
|
+
}
|
11972
|
+
|
11973
|
+
return CONSTANTS[id] || getterFn(id, this.options, this.text);
|
11974
|
+
},
|
11975
|
+
|
11976
|
+
constant: function() {
|
11977
|
+
var value = this.consume().value;
|
11978
|
+
|
11979
|
+
return extend(function $parseConstant() {
|
11980
|
+
return value;
|
11981
|
+
}, {
|
11982
|
+
constant: true,
|
11983
|
+
literal: true
|
11984
|
+
});
|
11985
|
+
},
|
11986
|
+
|
11908
11987
|
statements: function() {
|
11909
11988
|
var statements = [];
|
11910
11989
|
while (true) {
|
@@ -11936,8 +12015,7 @@ Parser.prototype = {
|
|
11936
12015
|
},
|
11937
12016
|
|
11938
12017
|
filter: function(inputFn) {
|
11939
|
-
var
|
11940
|
-
var fn = this.$filter(token.text);
|
12018
|
+
var fn = this.$filter(this.consume().text);
|
11941
12019
|
var argsFn;
|
11942
12020
|
var args;
|
11943
12021
|
|
@@ -12000,7 +12078,7 @@ Parser.prototype = {
|
|
12000
12078
|
var token;
|
12001
12079
|
if ((token = this.expect('?'))) {
|
12002
12080
|
middle = this.assignment();
|
12003
|
-
if (
|
12081
|
+
if (this.consume(':')) {
|
12004
12082
|
var right = this.assignment();
|
12005
12083
|
|
12006
12084
|
return extend(function $parseTernary(self, locals) {
|
@@ -12008,9 +12086,6 @@ Parser.prototype = {
|
|
12008
12086
|
}, {
|
12009
12087
|
constant: left.constant && middle.constant && right.constant
|
12010
12088
|
});
|
12011
|
-
|
12012
|
-
} else {
|
12013
|
-
this.throwError('expected :', token);
|
12014
12089
|
}
|
12015
12090
|
}
|
12016
12091
|
|
@@ -12021,7 +12096,7 @@ Parser.prototype = {
|
|
12021
12096
|
var left = this.logicalAND();
|
12022
12097
|
var token;
|
12023
12098
|
while ((token = this.expect('||'))) {
|
12024
|
-
left = this.binaryFn(left, token.
|
12099
|
+
left = this.binaryFn(left, token.text, this.logicalAND(), true);
|
12025
12100
|
}
|
12026
12101
|
return left;
|
12027
12102
|
},
|
@@ -12030,7 +12105,7 @@ Parser.prototype = {
|
|
12030
12105
|
var left = this.equality();
|
12031
12106
|
var token;
|
12032
12107
|
if ((token = this.expect('&&'))) {
|
12033
|
-
left = this.binaryFn(left, token.
|
12108
|
+
left = this.binaryFn(left, token.text, this.logicalAND(), true);
|
12034
12109
|
}
|
12035
12110
|
return left;
|
12036
12111
|
},
|
@@ -12039,7 +12114,7 @@ Parser.prototype = {
|
|
12039
12114
|
var left = this.relational();
|
12040
12115
|
var token;
|
12041
12116
|
if ((token = this.expect('==','!=','===','!=='))) {
|
12042
|
-
left = this.binaryFn(left, token.
|
12117
|
+
left = this.binaryFn(left, token.text, this.equality());
|
12043
12118
|
}
|
12044
12119
|
return left;
|
12045
12120
|
},
|
@@ -12048,7 +12123,7 @@ Parser.prototype = {
|
|
12048
12123
|
var left = this.additive();
|
12049
12124
|
var token;
|
12050
12125
|
if ((token = this.expect('<', '>', '<=', '>='))) {
|
12051
|
-
left = this.binaryFn(left, token.
|
12126
|
+
left = this.binaryFn(left, token.text, this.relational());
|
12052
12127
|
}
|
12053
12128
|
return left;
|
12054
12129
|
},
|
@@ -12057,7 +12132,7 @@ Parser.prototype = {
|
|
12057
12132
|
var left = this.multiplicative();
|
12058
12133
|
var token;
|
12059
12134
|
while ((token = this.expect('+','-'))) {
|
12060
|
-
left = this.binaryFn(left, token.
|
12135
|
+
left = this.binaryFn(left, token.text, this.multiplicative());
|
12061
12136
|
}
|
12062
12137
|
return left;
|
12063
12138
|
},
|
@@ -12066,7 +12141,7 @@ Parser.prototype = {
|
|
12066
12141
|
var left = this.unary();
|
12067
12142
|
var token;
|
12068
12143
|
while ((token = this.expect('*','/','%'))) {
|
12069
|
-
left = this.binaryFn(left, token.
|
12144
|
+
left = this.binaryFn(left, token.text, this.unary());
|
12070
12145
|
}
|
12071
12146
|
return left;
|
12072
12147
|
},
|
@@ -12076,9 +12151,9 @@ Parser.prototype = {
|
|
12076
12151
|
if (this.expect('+')) {
|
12077
12152
|
return this.primary();
|
12078
12153
|
} else if ((token = this.expect('-'))) {
|
12079
|
-
return this.binaryFn(Parser.ZERO, token.
|
12154
|
+
return this.binaryFn(Parser.ZERO, token.text, this.unary());
|
12080
12155
|
} else if ((token = this.expect('!'))) {
|
12081
|
-
return this.unaryFn(token.
|
12156
|
+
return this.unaryFn(token.text, this.unary());
|
12082
12157
|
} else {
|
12083
12158
|
return this.primary();
|
12084
12159
|
}
|
@@ -12086,7 +12161,7 @@ Parser.prototype = {
|
|
12086
12161
|
|
12087
12162
|
fieldAccess: function(object) {
|
12088
12163
|
var expression = this.text;
|
12089
|
-
var field = this.
|
12164
|
+
var field = this.consume().text;
|
12090
12165
|
var getter = getterFn(field, this.options, expression);
|
12091
12166
|
|
12092
12167
|
return extend(function $parseFieldAccess(scope, locals, self) {
|
@@ -12171,8 +12246,7 @@ Parser.prototype = {
|
|
12171
12246
|
// Support trailing commas per ES5.1.
|
12172
12247
|
break;
|
12173
12248
|
}
|
12174
|
-
|
12175
|
-
elementFns.push(elementFn);
|
12249
|
+
elementFns.push(this.expression());
|
12176
12250
|
} while (this.expect(','));
|
12177
12251
|
}
|
12178
12252
|
this.consume(']');
|
@@ -12198,11 +12272,16 @@ Parser.prototype = {
|
|
12198
12272
|
// Support trailing commas per ES5.1.
|
12199
12273
|
break;
|
12200
12274
|
}
|
12201
|
-
var token = this.
|
12202
|
-
|
12275
|
+
var token = this.consume();
|
12276
|
+
if (token.constant) {
|
12277
|
+
keys.push(token.value);
|
12278
|
+
} else if (token.identifier) {
|
12279
|
+
keys.push(token.text);
|
12280
|
+
} else {
|
12281
|
+
this.throwError("invalid key", token);
|
12282
|
+
}
|
12203
12283
|
this.consume(':');
|
12204
|
-
|
12205
|
-
valueFns.push(value);
|
12284
|
+
valueFns.push(this.expression());
|
12206
12285
|
} while (this.expect(','));
|
12207
12286
|
}
|
12208
12287
|
this.consume('}');
|
@@ -12644,13 +12723,21 @@ function $ParseProvider() {
|
|
12644
12723
|
|
12645
12724
|
function addInterceptor(parsedExpression, interceptorFn) {
|
12646
12725
|
if (!interceptorFn) return parsedExpression;
|
12726
|
+
var watchDelegate = parsedExpression.$$watchDelegate;
|
12647
12727
|
|
12648
|
-
var
|
12728
|
+
var regularWatch =
|
12729
|
+
watchDelegate !== oneTimeLiteralWatchDelegate &&
|
12730
|
+
watchDelegate !== oneTimeWatchDelegate;
|
12731
|
+
|
12732
|
+
var fn = regularWatch ? function regularInterceptedExpression(scope, locals) {
|
12733
|
+
var value = parsedExpression(scope, locals);
|
12734
|
+
return interceptorFn(value, scope, locals);
|
12735
|
+
} : function oneTimeInterceptedExpression(scope, locals) {
|
12649
12736
|
var value = parsedExpression(scope, locals);
|
12650
12737
|
var result = interceptorFn(value, scope, locals);
|
12651
12738
|
// we only return the interceptor's result if the
|
12652
12739
|
// initial value is defined (for bind-once)
|
12653
|
-
return isDefined(value)
|
12740
|
+
return isDefined(value) ? result : value;
|
12654
12741
|
};
|
12655
12742
|
|
12656
12743
|
// Propagate $$watchDelegates other then inputsWatchDelegate
|
@@ -12675,7 +12762,11 @@ function $ParseProvider() {
|
|
12675
12762
|
* @requires $rootScope
|
12676
12763
|
*
|
12677
12764
|
* @description
|
12678
|
-
* A
|
12765
|
+
* A service that helps you run functions asynchronously, and use their return values (or exceptions)
|
12766
|
+
* when they are done processing.
|
12767
|
+
*
|
12768
|
+
* This is an implementation of promises/deferred objects inspired by
|
12769
|
+
* [Kris Kowal's Q](https://github.com/kriskowal/q).
|
12679
12770
|
*
|
12680
12771
|
* $q can be used in two fashions --- one which is more similar to Kris Kowal's Q or jQuery's Deferred
|
12681
12772
|
* implementations, and the other which resembles ES6 promises to some degree.
|
@@ -12811,16 +12902,12 @@ function $ParseProvider() {
|
|
12811
12902
|
*
|
12812
12903
|
* - `catch(errorCallback)` – shorthand for `promise.then(null, errorCallback)`
|
12813
12904
|
*
|
12814
|
-
* - `finally(callback)` – allows you to observe either the fulfillment or rejection of a promise,
|
12905
|
+
* - `finally(callback, notifyCallback)` – allows you to observe either the fulfillment or rejection of a promise,
|
12815
12906
|
* but to do so without modifying the final value. This is useful to release resources or do some
|
12816
12907
|
* clean-up that needs to be done whether the promise was rejected or resolved. See the [full
|
12817
12908
|
* specification](https://github.com/kriskowal/q/wiki/API-Reference#promisefinallycallback) for
|
12818
12909
|
* more information.
|
12819
12910
|
*
|
12820
|
-
* Because `finally` is a reserved word in JavaScript and reserved keywords are not supported as
|
12821
|
-
* property names by ES3, you'll need to invoke the method like `promise['finally'](callback)` to
|
12822
|
-
* make your code IE8 and Android 2.x compatible.
|
12823
|
-
*
|
12824
12911
|
* # Chaining promises
|
12825
12912
|
*
|
12826
12913
|
* Because calling the `then` method of a promise returns a new derived promise, it is easily
|
@@ -14043,11 +14130,11 @@ function $RootScopeProvider() {
|
|
14043
14130
|
if (ttl < 5) {
|
14044
14131
|
logIdx = 4 - ttl;
|
14045
14132
|
if (!watchLog[logIdx]) watchLog[logIdx] = [];
|
14046
|
-
|
14047
|
-
|
14048
|
-
|
14049
|
-
|
14050
|
-
|
14133
|
+
watchLog[logIdx].push({
|
14134
|
+
msg: isFunction(watch.exp) ? 'fn: ' + (watch.exp.name || watch.exp.toString()) : watch.exp,
|
14135
|
+
newVal: value,
|
14136
|
+
oldVal: last
|
14137
|
+
});
|
14051
14138
|
}
|
14052
14139
|
} else if (watch === lastDirtyWatch) {
|
14053
14140
|
// If the most recently dirty watcher is now clean, short circuit since the remaining watchers
|
@@ -14080,7 +14167,7 @@ function $RootScopeProvider() {
|
|
14080
14167
|
throw $rootScopeMinErr('infdig',
|
14081
14168
|
'{0} $digest() iterations reached. Aborting!\n' +
|
14082
14169
|
'Watchers fired in the last 5 iterations: {1}',
|
14083
|
-
TTL,
|
14170
|
+
TTL, watchLog);
|
14084
14171
|
}
|
14085
14172
|
|
14086
14173
|
} while (dirty || asyncQueue.length);
|
@@ -14431,7 +14518,7 @@ function $RootScopeProvider() {
|
|
14431
14518
|
do {
|
14432
14519
|
namedListeners = scope.$$listeners[name] || empty;
|
14433
14520
|
event.currentScope = scope;
|
14434
|
-
for (i=0, length=namedListeners.length; i<length; i++) {
|
14521
|
+
for (i = 0, length = namedListeners.length; i < length; i++) {
|
14435
14522
|
|
14436
14523
|
// if listeners were deregistered, defragment the array
|
14437
14524
|
if (!namedListeners[i]) {
|
@@ -14505,7 +14592,7 @@ function $RootScopeProvider() {
|
|
14505
14592
|
while ((current = next)) {
|
14506
14593
|
event.currentScope = current;
|
14507
14594
|
listeners = current.$$listeners[name] || [];
|
14508
|
-
for (i=0, length = listeners.length; i<length; i++) {
|
14595
|
+
for (i = 0, length = listeners.length; i < length; i++) {
|
14509
14596
|
// if listeners were deregistered, defragment the array
|
14510
14597
|
if (!listeners[i]) {
|
14511
14598
|
listeners.splice(i, 1);
|
@@ -14661,7 +14748,7 @@ function $$SanitizeUriProvider() {
|
|
14661
14748
|
var normalizedVal;
|
14662
14749
|
normalizedVal = urlResolve(uri).href;
|
14663
14750
|
if (normalizedVal !== '' && !normalizedVal.match(regex)) {
|
14664
|
-
return 'unsafe:'+normalizedVal;
|
14751
|
+
return 'unsafe:' + normalizedVal;
|
14665
14752
|
}
|
14666
14753
|
return uri;
|
14667
14754
|
};
|
@@ -15760,7 +15847,7 @@ function $SnifferProvider() {
|
|
15760
15847
|
transitions = !!(('transition' in bodyStyle) || (vendorPrefix + 'Transition' in bodyStyle));
|
15761
15848
|
animations = !!(('animation' in bodyStyle) || (vendorPrefix + 'Animation' in bodyStyle));
|
15762
15849
|
|
15763
|
-
if (android && (!transitions
|
15850
|
+
if (android && (!transitions || !animations)) {
|
15764
15851
|
transitions = isString(document.body.style.webkitTransition);
|
15765
15852
|
animations = isString(document.body.style.webkitAnimation);
|
15766
15853
|
}
|
@@ -15831,7 +15918,7 @@ function $TemplateRequestProvider() {
|
|
15831
15918
|
if (isArray(transformResponse)) {
|
15832
15919
|
var original = transformResponse;
|
15833
15920
|
transformResponse = [];
|
15834
|
-
for (var i=0; i<original.length; ++i) {
|
15921
|
+
for (var i = 0; i < original.length; ++i) {
|
15835
15922
|
var transformer = original[i];
|
15836
15923
|
if (transformer !== defaultHttpResponseTransform) {
|
15837
15924
|
transformResponse.push(transformer);
|
@@ -16075,7 +16162,7 @@ function $TimeoutProvider() {
|
|
16075
16162
|
// exactly the behavior needed here. There is little value is mocking these out for this
|
16076
16163
|
// service.
|
16077
16164
|
var urlParsingNode = document.createElement("a");
|
16078
|
-
var originUrl = urlResolve(window.location.href
|
16165
|
+
var originUrl = urlResolve(window.location.href);
|
16079
16166
|
|
16080
16167
|
|
16081
16168
|
/**
|
@@ -16130,7 +16217,7 @@ var originUrl = urlResolve(window.location.href, true);
|
|
16130
16217
|
* | pathname | The pathname, beginning with "/"
|
16131
16218
|
*
|
16132
16219
|
*/
|
16133
|
-
function urlResolve(url
|
16220
|
+
function urlResolve(url) {
|
16134
16221
|
var href = url;
|
16135
16222
|
|
16136
16223
|
if (msie) {
|
@@ -16510,8 +16597,8 @@ function filterFilter() {
|
|
16510
16597
|
}
|
16511
16598
|
return false;
|
16512
16599
|
}
|
16513
|
-
text = (''+text).toLowerCase();
|
16514
|
-
return (''+obj).toLowerCase().indexOf(text) > -1;
|
16600
|
+
text = ('' + text).toLowerCase();
|
16601
|
+
return ('' + obj).toLowerCase().indexOf(text) > -1;
|
16515
16602
|
};
|
16516
16603
|
}
|
16517
16604
|
}
|
@@ -16595,7 +16682,7 @@ function filterFilter() {
|
|
16595
16682
|
*
|
16596
16683
|
* @param {number} amount Input to filter.
|
16597
16684
|
* @param {string=} symbol Currency symbol or identifier to be displayed.
|
16598
|
-
* @param {number=} fractionSize Number of decimal places to round the amount to
|
16685
|
+
* @param {number=} fractionSize Number of decimal places to round the amount to, defaults to default max fraction size for current locale
|
16599
16686
|
* @returns {string} Formatted number.
|
16600
16687
|
*
|
16601
16688
|
*
|
@@ -16645,8 +16732,7 @@ function currencyFilter($locale) {
|
|
16645
16732
|
}
|
16646
16733
|
|
16647
16734
|
if (isUndefined(fractionSize)) {
|
16648
|
-
|
16649
|
-
fractionSize = 2;
|
16735
|
+
fractionSize = formats.PATTERNS[1].maxFrac;
|
16650
16736
|
}
|
16651
16737
|
|
16652
16738
|
// if null or undefined pass it through
|
@@ -16771,7 +16857,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
|
|
16771
16857
|
if (whole.length >= (lgroup + group)) {
|
16772
16858
|
pos = whole.length - lgroup;
|
16773
16859
|
for (i = 0; i < pos; i++) {
|
16774
|
-
if ((pos - i)%group === 0 && i !== 0) {
|
16860
|
+
if ((pos - i) % group === 0 && i !== 0) {
|
16775
16861
|
formatedText += groupSep;
|
16776
16862
|
}
|
16777
16863
|
formatedText += whole.charAt(i);
|
@@ -16779,7 +16865,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
|
|
16779
16865
|
}
|
16780
16866
|
|
16781
16867
|
for (i = pos; i < whole.length; i++) {
|
16782
|
-
if ((whole.length - i)%lgroup === 0 && i !== 0) {
|
16868
|
+
if ((whole.length - i) % lgroup === 0 && i !== 0) {
|
16783
16869
|
formatedText += groupSep;
|
16784
16870
|
}
|
16785
16871
|
formatedText += whole.charAt(i);
|
@@ -16798,9 +16884,9 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
|
|
16798
16884
|
}
|
16799
16885
|
}
|
16800
16886
|
|
16801
|
-
parts.push(isNegative ? pattern.negPre : pattern.posPre
|
16802
|
-
|
16803
|
-
|
16887
|
+
parts.push(isNegative ? pattern.negPre : pattern.posPre,
|
16888
|
+
formatedText,
|
16889
|
+
isNegative ? pattern.negSuf : pattern.posSuf);
|
16804
16890
|
return parts.join('');
|
16805
16891
|
}
|
16806
16892
|
|
@@ -17019,10 +17105,10 @@ function dateFilter($locale) {
|
|
17019
17105
|
tzMin = int(match[9] + match[11]);
|
17020
17106
|
}
|
17021
17107
|
dateSetter.call(date, int(match[1]), int(match[2]) - 1, int(match[3]));
|
17022
|
-
var h = int(match[4]||0) - tzHour;
|
17023
|
-
var m = int(match[5]||0) - tzMin;
|
17024
|
-
var s = int(match[6]||0);
|
17025
|
-
var ms = Math.round(parseFloat('0.' + (match[7]||0)) * 1000);
|
17108
|
+
var h = int(match[4] || 0) - tzHour;
|
17109
|
+
var m = int(match[5] || 0) - tzMin;
|
17110
|
+
var s = int(match[6] || 0);
|
17111
|
+
var ms = Math.round(parseFloat('0.' + (match[7] || 0)) * 1000);
|
17026
17112
|
timeSetter.call(date, h, m, s, ms);
|
17027
17113
|
return date;
|
17028
17114
|
}
|
@@ -17254,7 +17340,7 @@ function limitToFilter() {
|
|
17254
17340
|
n = input.length;
|
17255
17341
|
}
|
17256
17342
|
|
17257
|
-
for (; i<n; i++) {
|
17343
|
+
for (; i < n; i++) {
|
17258
17344
|
out.push(input[i]);
|
17259
17345
|
}
|
17260
17346
|
|
@@ -17381,7 +17467,7 @@ orderByFilter.$inject = ['$parse'];
|
|
17381
17467
|
function orderByFilter($parse) {
|
17382
17468
|
return function(array, sortPredicate, reverseOrder) {
|
17383
17469
|
if (!(isArrayLike(array))) return array;
|
17384
|
-
sortPredicate = isArray(sortPredicate) ? sortPredicate: [sortPredicate];
|
17470
|
+
sortPredicate = isArray(sortPredicate) ? sortPredicate : [sortPredicate];
|
17385
17471
|
if (sortPredicate.length === 0) { sortPredicate = ['+']; }
|
17386
17472
|
sortPredicate = sortPredicate.map(function(predicate) {
|
17387
17473
|
var descending = false, get = predicate || identity;
|
@@ -17408,9 +17494,7 @@ function orderByFilter($parse) {
|
|
17408
17494
|
return compare(get(a),get(b));
|
17409
17495
|
}, descending);
|
17410
17496
|
});
|
17411
|
-
|
17412
|
-
for (var i = 0; i < array.length; i++) { arrayCopy.push(array[i]); }
|
17413
|
-
return arrayCopy.sort(reverseComparator(comparator, reverseOrder));
|
17497
|
+
return slice.call(array).sort(reverseComparator(comparator, reverseOrder));
|
17414
17498
|
|
17415
17499
|
function comparator(o1, o2) {
|
17416
17500
|
for (var i = 0; i < sortPredicate.length; i++) {
|
@@ -18382,9 +18466,7 @@ var formDirectiveFactory = function(isNgForm) {
|
|
18382
18466
|
controller.$setSubmitted();
|
18383
18467
|
});
|
18384
18468
|
|
18385
|
-
event.preventDefault
|
18386
|
-
? event.preventDefault()
|
18387
|
-
: event.returnValue = false; // IE
|
18469
|
+
event.preventDefault();
|
18388
18470
|
};
|
18389
18471
|
|
18390
18472
|
addEventListenerFn(formElement[0], 'submit', handleFormSubmission);
|
@@ -18471,10 +18553,16 @@ var inputType = {
|
|
18471
18553
|
* @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
|
18472
18554
|
* minlength.
|
18473
18555
|
* @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
|
18474
|
-
* maxlength.
|
18475
|
-
*
|
18476
|
-
*
|
18477
|
-
*
|
18556
|
+
* maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
|
18557
|
+
* any length.
|
18558
|
+
* @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
|
18559
|
+
* that contains the regular expression body that will be converted to a regular expression
|
18560
|
+
* as in the ngPattern directive.
|
18561
|
+
* @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
|
18562
|
+
* a RegExp found by evaluating the Angular expression given in the attribute value.
|
18563
|
+
* If the expression evaluates to a RegExp object then this is used directly.
|
18564
|
+
* If the expression is a string then it will be converted to a RegExp after wrapping it in `^` and `$`
|
18565
|
+
* characters. For instance, `"abc"` will be converted to `new RegExp('^abc$')`.
|
18478
18566
|
* @param {string=} ngChange Angular expression to be executed when input changes due to user
|
18479
18567
|
* interaction with the input element.
|
18480
18568
|
* @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input.
|
@@ -19014,10 +19102,16 @@ var inputType = {
|
|
19014
19102
|
* @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
|
19015
19103
|
* minlength.
|
19016
19104
|
* @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
|
19017
|
-
* maxlength.
|
19018
|
-
*
|
19019
|
-
*
|
19020
|
-
*
|
19105
|
+
* maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
|
19106
|
+
* any length.
|
19107
|
+
* @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
|
19108
|
+
* that contains the regular expression body that will be converted to a regular expression
|
19109
|
+
* as in the ngPattern directive.
|
19110
|
+
* @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
|
19111
|
+
* a RegExp found by evaluating the Angular expression given in the attribute value.
|
19112
|
+
* If the expression evaluates to a RegExp object then this is used directly.
|
19113
|
+
* If the expression is a string then it will be converted to a RegExp after wrapping it in `^` and `$`
|
19114
|
+
* characters. For instance, `"abc"` will be converted to `new RegExp('^abc$')`.
|
19021
19115
|
* @param {string=} ngChange Angular expression to be executed when input changes due to user
|
19022
19116
|
* interaction with the input element.
|
19023
19117
|
*
|
@@ -19096,10 +19190,16 @@ var inputType = {
|
|
19096
19190
|
* @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
|
19097
19191
|
* minlength.
|
19098
19192
|
* @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
|
19099
|
-
* maxlength.
|
19100
|
-
*
|
19101
|
-
*
|
19102
|
-
*
|
19193
|
+
* maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
|
19194
|
+
* any length.
|
19195
|
+
* @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
|
19196
|
+
* that contains the regular expression body that will be converted to a regular expression
|
19197
|
+
* as in the ngPattern directive.
|
19198
|
+
* @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
|
19199
|
+
* a RegExp found by evaluating the Angular expression given in the attribute value.
|
19200
|
+
* If the expression evaluates to a RegExp object then this is used directly.
|
19201
|
+
* If the expression is a string then it will be converted to a RegExp after wrapping it in `^` and `$`
|
19202
|
+
* characters. For instance, `"abc"` will be converted to `new RegExp('^abc$')`.
|
19103
19203
|
* @param {string=} ngChange Angular expression to be executed when input changes due to user
|
19104
19204
|
* interaction with the input element.
|
19105
19205
|
*
|
@@ -19179,10 +19279,16 @@ var inputType = {
|
|
19179
19279
|
* @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
|
19180
19280
|
* minlength.
|
19181
19281
|
* @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
|
19182
|
-
* maxlength.
|
19183
|
-
*
|
19184
|
-
*
|
19185
|
-
*
|
19282
|
+
* maxlength. Setting the attribute to a negative or non-numeric value, allows view values of
|
19283
|
+
* any length.
|
19284
|
+
* @param {string=} pattern Similar to `ngPattern` except that the attribute value is the actual string
|
19285
|
+
* that contains the regular expression body that will be converted to a regular expression
|
19286
|
+
* as in the ngPattern directive.
|
19287
|
+
* @param {string=} ngPattern Sets `pattern` validation error key if the ngModel value does not match
|
19288
|
+
* a RegExp found by evaluating the Angular expression given in the attribute value.
|
19289
|
+
* If the expression evaluates to a RegExp object then this is used directly.
|
19290
|
+
* If the expression is a string then it will be converted to a RegExp after wrapping it in `^` and `$`
|
19291
|
+
* characters. For instance, `"abc"` will be converted to `new RegExp('^abc$')`.
|
19186
19292
|
* @param {string=} ngChange Angular expression to be executed when input changes due to user
|
19187
19293
|
* interaction with the input element.
|
19188
19294
|
*
|
@@ -19445,7 +19551,7 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|
19445
19551
|
element.on('change', listener);
|
19446
19552
|
|
19447
19553
|
ctrl.$render = function() {
|
19448
|
-
element.val(ctrl.$isEmpty(ctrl.$
|
19554
|
+
element.val(ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue);
|
19449
19555
|
};
|
19450
19556
|
}
|
19451
19557
|
|
@@ -19493,8 +19599,8 @@ function createDateParser(regexp, mapping) {
|
|
19493
19599
|
// When a date is JSON'ified to wraps itself inside of an extra
|
19494
19600
|
// set of double quotes. This makes the date parsing code unable
|
19495
19601
|
// to match the date string and parse it as a date.
|
19496
|
-
if (iso.charAt(0) == '"' && iso.charAt(iso.length-1) == '"') {
|
19497
|
-
iso = iso.substring(1, iso.length-1);
|
19602
|
+
if (iso.charAt(0) == '"' && iso.charAt(iso.length - 1) == '"') {
|
19603
|
+
iso = iso.substring(1, iso.length - 1);
|
19498
19604
|
}
|
19499
19605
|
if (ISO_DATE_REGEXP.test(iso)) {
|
19500
19606
|
return new Date(iso);
|
@@ -19555,10 +19661,10 @@ function createDateInputType(type, regexp, parseDate, format) {
|
|
19555
19661
|
});
|
19556
19662
|
|
19557
19663
|
ctrl.$formatters.push(function(value) {
|
19558
|
-
if (!
|
19559
|
-
|
19560
|
-
|
19561
|
-
|
19664
|
+
if (value && !isDate(value)) {
|
19665
|
+
throw $ngModelMinErr('datefmt', 'Expected `{0}` to be a date', value);
|
19666
|
+
}
|
19667
|
+
if (isValidDate(value)) {
|
19562
19668
|
previousDate = value;
|
19563
19669
|
if (previousDate && timezone === 'UTC') {
|
19564
19670
|
var timezoneOffset = 60000 * previousDate.getTimezoneOffset();
|
@@ -19567,14 +19673,14 @@ function createDateInputType(type, regexp, parseDate, format) {
|
|
19567
19673
|
return $filter('date')(value, format, timezone);
|
19568
19674
|
} else {
|
19569
19675
|
previousDate = null;
|
19676
|
+
return '';
|
19570
19677
|
}
|
19571
|
-
return '';
|
19572
19678
|
});
|
19573
19679
|
|
19574
19680
|
if (isDefined(attr.min) || attr.ngMin) {
|
19575
19681
|
var minVal;
|
19576
19682
|
ctrl.$validators.min = function(value) {
|
19577
|
-
return
|
19683
|
+
return !isValidDate(value) || isUndefined(minVal) || parseDate(value) >= minVal;
|
19578
19684
|
};
|
19579
19685
|
attr.$observe('min', function(val) {
|
19580
19686
|
minVal = parseObservedDateValue(val);
|
@@ -19585,18 +19691,18 @@ function createDateInputType(type, regexp, parseDate, format) {
|
|
19585
19691
|
if (isDefined(attr.max) || attr.ngMax) {
|
19586
19692
|
var maxVal;
|
19587
19693
|
ctrl.$validators.max = function(value) {
|
19588
|
-
return
|
19694
|
+
return !isValidDate(value) || isUndefined(maxVal) || parseDate(value) <= maxVal;
|
19589
19695
|
};
|
19590
19696
|
attr.$observe('max', function(val) {
|
19591
19697
|
maxVal = parseObservedDateValue(val);
|
19592
19698
|
ctrl.$validate();
|
19593
19699
|
});
|
19594
19700
|
}
|
19595
|
-
|
19596
|
-
|
19701
|
+
|
19702
|
+
function isValidDate(value) {
|
19597
19703
|
// Invalid Date: getTime() returns NaN
|
19598
|
-
return
|
19599
|
-
}
|
19704
|
+
return value && !(value.getTime && value.getTime() !== value.getTime());
|
19705
|
+
}
|
19600
19706
|
|
19601
19707
|
function parseObservedDateValue(val) {
|
19602
19708
|
return isDefined(val) ? (isDate(val) ? val : parseDate(val)) : undefined;
|
@@ -19680,7 +19786,8 @@ function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|
19680
19786
|
stringBasedInputType(ctrl);
|
19681
19787
|
|
19682
19788
|
ctrl.$$parserName = 'url';
|
19683
|
-
ctrl.$validators.url = function(
|
19789
|
+
ctrl.$validators.url = function(modelValue, viewValue) {
|
19790
|
+
var value = modelValue || viewValue;
|
19684
19791
|
return ctrl.$isEmpty(value) || URL_REGEXP.test(value);
|
19685
19792
|
};
|
19686
19793
|
}
|
@@ -19692,7 +19799,8 @@ function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|
19692
19799
|
stringBasedInputType(ctrl);
|
19693
19800
|
|
19694
19801
|
ctrl.$$parserName = 'email';
|
19695
|
-
ctrl.$validators.email = function(
|
19802
|
+
ctrl.$validators.email = function(modelValue, viewValue) {
|
19803
|
+
var value = modelValue || viewValue;
|
19696
19804
|
return ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value);
|
19697
19805
|
};
|
19698
19806
|
}
|
@@ -19746,9 +19854,11 @@ function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filt
|
|
19746
19854
|
element[0].checked = ctrl.$viewValue;
|
19747
19855
|
};
|
19748
19856
|
|
19749
|
-
// Override the standard `$isEmpty` because an empty checkbox is
|
19857
|
+
// Override the standard `$isEmpty` because the $viewValue of an empty checkbox is always set to `false`
|
19858
|
+
// This is because of the parser below, which compares the `$modelValue` with `trueValue` to convert
|
19859
|
+
// it to a boolean.
|
19750
19860
|
ctrl.$isEmpty = function(value) {
|
19751
|
-
return value
|
19861
|
+
return value === false;
|
19752
19862
|
};
|
19753
19863
|
|
19754
19864
|
ctrl.$formatters.push(function(value) {
|
@@ -19780,7 +19890,8 @@ function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filt
|
|
19780
19890
|
* @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
|
19781
19891
|
* minlength.
|
19782
19892
|
* @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
|
19783
|
-
* maxlength.
|
19893
|
+
* maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any
|
19894
|
+
* length.
|
19784
19895
|
* @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the
|
19785
19896
|
* RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
|
19786
19897
|
* patterns defined as scope expressions.
|
@@ -19812,7 +19923,8 @@ function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filt
|
|
19812
19923
|
* @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
|
19813
19924
|
* minlength.
|
19814
19925
|
* @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
|
19815
|
-
* maxlength.
|
19926
|
+
* maxlength. Setting the attribute to a negative or non-numeric value, allows view values of any
|
19927
|
+
* length.
|
19816
19928
|
* @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the
|
19817
19929
|
* RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
|
19818
19930
|
* patterns defined as scope expressions.
|
@@ -19941,12 +20053,17 @@ var VALID_CLASS = 'ng-valid',
|
|
19941
20053
|
* @property {string} $viewValue Actual string value in the view.
|
19942
20054
|
* @property {*} $modelValue The value in the model that the control is bound to.
|
19943
20055
|
* @property {Array.<Function>} $parsers Array of functions to execute, as a pipeline, whenever
|
19944
|
-
the control reads value from the DOM. The functions are called in array order, each passing
|
19945
|
-
through to the next. The last return value is forwarded to the
|
19946
|
-
|
19947
|
-
|
19948
|
-
|
19949
|
-
|
20056
|
+
the control reads value from the DOM. The functions are called in array order, each passing
|
20057
|
+
its return value through to the next. The last return value is forwarded to the
|
20058
|
+
{@link ngModel.NgModelController#$validators `$validators`} collection.
|
20059
|
+
|
20060
|
+
Parsers are used to sanitize / convert the {@link ngModel.NgModelController#$viewValue
|
20061
|
+
`$viewValue`}.
|
20062
|
+
|
20063
|
+
Returning `undefined` from a parser means a parse error occurred. In that case,
|
20064
|
+
no {@link ngModel.NgModelController#$validators `$validators`} will run and the `ngModel`
|
20065
|
+
will be set to `undefined` unless {@link ngModelOptions `ngModelOptions.allowInvalid`}
|
20066
|
+
is set to `true`. The parse error is stored in `ngModel.$error.parse`.
|
19950
20067
|
|
19951
20068
|
*
|
19952
20069
|
* @property {Array.<Function>} $formatters Array of functions to execute, as a pipeline, whenever
|
@@ -20023,13 +20140,18 @@ var VALID_CLASS = 'ng-valid',
|
|
20023
20140
|
*
|
20024
20141
|
* @description
|
20025
20142
|
*
|
20026
|
-
* `NgModelController` provides API for the `
|
20027
|
-
* services for data-binding, validation, CSS updates, and value formatting
|
20028
|
-
* purposefully does not contain any logic which deals with DOM rendering or
|
20029
|
-
* DOM events.
|
20030
|
-
*
|
20143
|
+
* `NgModelController` provides API for the {@link ngModel `ngModel`} directive.
|
20144
|
+
* The controller contains services for data-binding, validation, CSS updates, and value formatting
|
20145
|
+
* and parsing. It purposefully does not contain any logic which deals with DOM rendering or
|
20146
|
+
* listening to DOM events.
|
20147
|
+
* Such DOM related logic should be provided by other directives which make use of
|
20148
|
+
* `NgModelController` for data-binding to control elements.
|
20149
|
+
* Angular provides this DOM logic for most {@link input `input`} elements.
|
20150
|
+
* At the end of this page you can find a {@link ngModel.NgModelController#custom-control-example
|
20151
|
+
* custom control example} that uses `ngModelController` to bind to `contenteditable` elements.
|
20031
20152
|
*
|
20032
|
-
*
|
20153
|
+
* @example
|
20154
|
+
* ### Custom Control Example
|
20033
20155
|
* This example shows how to use `NgModelController` with a custom control to achieve
|
20034
20156
|
* data-binding. Notice how different directives (`contenteditable`, `ng-model`, and `required`)
|
20035
20157
|
* collaborate together to achieve the desired result.
|
@@ -20071,7 +20193,7 @@ var VALID_CLASS = 'ng-valid',
|
|
20071
20193
|
|
20072
20194
|
// Listen for change events to enable binding
|
20073
20195
|
element.on('blur keyup change', function() {
|
20074
|
-
scope.$
|
20196
|
+
scope.$evalAsync(read);
|
20075
20197
|
});
|
20076
20198
|
read(); // initialize
|
20077
20199
|
|
@@ -20126,6 +20248,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
20126
20248
|
function($scope, $exceptionHandler, $attr, $element, $parse, $animate, $timeout, $rootScope, $q, $interpolate) {
|
20127
20249
|
this.$viewValue = Number.NaN;
|
20128
20250
|
this.$modelValue = Number.NaN;
|
20251
|
+
this.$$rawModelValue = undefined; // stores the parsed modelValue / model set from scope regardless of validity.
|
20129
20252
|
this.$validators = {};
|
20130
20253
|
this.$asyncValidators = {};
|
20131
20254
|
this.$parsers = [];
|
@@ -20144,32 +20267,33 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
20144
20267
|
|
20145
20268
|
|
20146
20269
|
var parsedNgModel = $parse($attr.ngModel),
|
20270
|
+
parsedNgModelAssign = parsedNgModel.assign,
|
20271
|
+
ngModelGet = parsedNgModel,
|
20272
|
+
ngModelSet = parsedNgModelAssign,
|
20147
20273
|
pendingDebounce = null,
|
20148
20274
|
ctrl = this;
|
20149
20275
|
|
20150
|
-
var ngModelGet = function ngModelGet() {
|
20151
|
-
var modelValue = parsedNgModel($scope);
|
20152
|
-
if (ctrl.$options && ctrl.$options.getterSetter && isFunction(modelValue)) {
|
20153
|
-
modelValue = modelValue();
|
20154
|
-
}
|
20155
|
-
return modelValue;
|
20156
|
-
};
|
20157
|
-
|
20158
|
-
var ngModelSet = function ngModelSet(newValue) {
|
20159
|
-
var getterSetter;
|
20160
|
-
if (ctrl.$options && ctrl.$options.getterSetter &&
|
20161
|
-
isFunction(getterSetter = parsedNgModel($scope))) {
|
20162
|
-
|
20163
|
-
getterSetter(ctrl.$modelValue);
|
20164
|
-
} else {
|
20165
|
-
parsedNgModel.assign($scope, ctrl.$modelValue);
|
20166
|
-
}
|
20167
|
-
};
|
20168
|
-
|
20169
20276
|
this.$$setOptions = function(options) {
|
20170
20277
|
ctrl.$options = options;
|
20171
|
-
|
20172
|
-
|
20278
|
+
if (options && options.getterSetter) {
|
20279
|
+
var invokeModelGetter = $parse($attr.ngModel + '()'),
|
20280
|
+
invokeModelSetter = $parse($attr.ngModel + '($$$p)');
|
20281
|
+
|
20282
|
+
ngModelGet = function($scope) {
|
20283
|
+
var modelValue = parsedNgModel($scope);
|
20284
|
+
if (isFunction(modelValue)) {
|
20285
|
+
modelValue = invokeModelGetter($scope);
|
20286
|
+
}
|
20287
|
+
return modelValue;
|
20288
|
+
};
|
20289
|
+
ngModelSet = function($scope, newValue) {
|
20290
|
+
if (isFunction(parsedNgModel($scope))) {
|
20291
|
+
invokeModelSetter($scope, {$$$p: ctrl.$modelValue});
|
20292
|
+
} else {
|
20293
|
+
parsedNgModelAssign($scope, ctrl.$modelValue);
|
20294
|
+
}
|
20295
|
+
};
|
20296
|
+
} else if (!parsedNgModel.assign) {
|
20173
20297
|
throw $ngModelMinErr('nonassign', "Expression '{0}' is non-assignable. Element: {1}",
|
20174
20298
|
$attr.ngModel, startingTag($element));
|
20175
20299
|
}
|
@@ -20202,17 +20326,18 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
20202
20326
|
* @name ngModel.NgModelController#$isEmpty
|
20203
20327
|
*
|
20204
20328
|
* @description
|
20205
|
-
* This is called when we need to determine if the value of
|
20329
|
+
* This is called when we need to determine if the value of an input is empty.
|
20206
20330
|
*
|
20207
20331
|
* For instance, the required directive does this to work out if the input has data or not.
|
20332
|
+
*
|
20208
20333
|
* The default `$isEmpty` function checks whether the value is `undefined`, `''`, `null` or `NaN`.
|
20209
20334
|
*
|
20210
20335
|
* You can override this for input directives whose concept of being empty is different to the
|
20211
20336
|
* default. The `checkboxInputType` directive does this because in its case a value of `false`
|
20212
20337
|
* implies empty.
|
20213
20338
|
*
|
20214
|
-
* @param {*} value
|
20215
|
-
* @returns {boolean} True if `value` is empty.
|
20339
|
+
* @param {*} value The value of the input to check for emptiness.
|
20340
|
+
* @returns {boolean} True if `value` is "empty".
|
20216
20341
|
*/
|
20217
20342
|
this.$isEmpty = function(value) {
|
20218
20343
|
return isUndefined(value) || value === '' || value === null || value !== value;
|
@@ -20263,9 +20388,9 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
20263
20388
|
* @description
|
20264
20389
|
* Sets the control to its pristine state.
|
20265
20390
|
*
|
20266
|
-
* This method can be called to remove the
|
20267
|
-
* state (ng-pristine class). A model is considered to be pristine when the
|
20268
|
-
* from when first compiled
|
20391
|
+
* This method can be called to remove the `ng-dirty` class and set the control to its pristine
|
20392
|
+
* state (`ng-pristine` class). A model is considered to be pristine when the control
|
20393
|
+
* has not been changed from when first compiled.
|
20269
20394
|
*/
|
20270
20395
|
this.$setPristine = function() {
|
20271
20396
|
ctrl.$dirty = false;
|
@@ -20274,6 +20399,25 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
20274
20399
|
$animate.addClass($element, PRISTINE_CLASS);
|
20275
20400
|
};
|
20276
20401
|
|
20402
|
+
/**
|
20403
|
+
* @ngdoc method
|
20404
|
+
* @name ngModel.NgModelController#$setDirty
|
20405
|
+
*
|
20406
|
+
* @description
|
20407
|
+
* Sets the control to its dirty state.
|
20408
|
+
*
|
20409
|
+
* This method can be called to remove the `ng-pristine` class and set the control to its dirty
|
20410
|
+
* state (`ng-dirty` class). A model is considered to be dirty when the control has been changed
|
20411
|
+
* from when first compiled.
|
20412
|
+
*/
|
20413
|
+
this.$setDirty = function() {
|
20414
|
+
ctrl.$dirty = true;
|
20415
|
+
ctrl.$pristine = false;
|
20416
|
+
$animate.removeClass($element, PRISTINE_CLASS);
|
20417
|
+
$animate.addClass($element, DIRTY_CLASS);
|
20418
|
+
parentForm.$setDirty();
|
20419
|
+
};
|
20420
|
+
|
20277
20421
|
/**
|
20278
20422
|
* @ngdoc method
|
20279
20423
|
* @name ngModel.NgModelController#$setUntouched
|
@@ -20281,8 +20425,8 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
20281
20425
|
* @description
|
20282
20426
|
* Sets the control to its untouched state.
|
20283
20427
|
*
|
20284
|
-
* This method can be called to remove the
|
20285
|
-
* untouched state (ng-untouched class). Upon compilation, a model is set as untouched
|
20428
|
+
* This method can be called to remove the `ng-touched` class and set the control to its
|
20429
|
+
* untouched state (`ng-untouched` class). Upon compilation, a model is set as untouched
|
20286
20430
|
* by default, however this function can be used to restore that state if the model has
|
20287
20431
|
* already been touched by the user.
|
20288
20432
|
*/
|
@@ -20299,10 +20443,9 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
20299
20443
|
* @description
|
20300
20444
|
* Sets the control to its touched state.
|
20301
20445
|
*
|
20302
|
-
* This method can be called to remove the
|
20303
|
-
* touched state (ng-touched class). A model is considered to be touched when the user has
|
20304
|
-
* first
|
20305
|
-
* from the input element.
|
20446
|
+
* This method can be called to remove the `ng-untouched` class and set the control to its
|
20447
|
+
* touched state (`ng-touched` class). A model is considered to be touched when the user has
|
20448
|
+
* first focused the control element and then shifted focus away from the control (blur event).
|
20306
20449
|
*/
|
20307
20450
|
this.$setTouched = function() {
|
20308
20451
|
ctrl.$touched = true;
|
@@ -20380,14 +20523,51 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
20380
20523
|
* @name ngModel.NgModelController#$validate
|
20381
20524
|
*
|
20382
20525
|
* @description
|
20383
|
-
* Runs each of the registered validators (first synchronous validators and then
|
20526
|
+
* Runs each of the registered validators (first synchronous validators and then
|
20527
|
+
* asynchronous validators).
|
20528
|
+
* If the validity changes to invalid, the model will be set to `undefined`,
|
20529
|
+
* unless {@link ngModelOptions `ngModelOptions.allowInvalid`} is `true`.
|
20530
|
+
* If the validity changes to valid, it will set the model to the last available valid
|
20531
|
+
* modelValue, i.e. either the last parsed value or the last value set from the scope.
|
20384
20532
|
*/
|
20385
20533
|
this.$validate = function() {
|
20386
20534
|
// ignore $validate before model is initialized
|
20387
20535
|
if (isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue)) {
|
20388
20536
|
return;
|
20389
20537
|
}
|
20390
|
-
|
20538
|
+
|
20539
|
+
var viewValue = ctrl.$$lastCommittedViewValue;
|
20540
|
+
// Note: we use the $$rawModelValue as $modelValue might have been
|
20541
|
+
// set to undefined during a view -> model update that found validation
|
20542
|
+
// errors. We can't parse the view here, since that could change
|
20543
|
+
// the model although neither viewValue nor the model on the scope changed
|
20544
|
+
var modelValue = ctrl.$$rawModelValue;
|
20545
|
+
|
20546
|
+
// Check if the there's a parse error, so we don't unset it accidentially
|
20547
|
+
var parserName = ctrl.$$parserName || 'parse';
|
20548
|
+
var parserValid = ctrl.$error[parserName] ? false : undefined;
|
20549
|
+
|
20550
|
+
var prevValid = ctrl.$valid;
|
20551
|
+
var prevModelValue = ctrl.$modelValue;
|
20552
|
+
|
20553
|
+
var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid;
|
20554
|
+
|
20555
|
+
ctrl.$$runValidators(parserValid, modelValue, viewValue, function(allValid) {
|
20556
|
+
// If there was no change in validity, don't update the model
|
20557
|
+
// This prevents changing an invalid modelValue to undefined
|
20558
|
+
if (!allowInvalid && prevValid !== allValid) {
|
20559
|
+
// Note: Don't check ctrl.$valid here, as we could have
|
20560
|
+
// external validators (e.g. calculated on the server),
|
20561
|
+
// that just call $setValidity and need the model value
|
20562
|
+
// to calculate their validity.
|
20563
|
+
ctrl.$modelValue = allValid ? modelValue : undefined;
|
20564
|
+
|
20565
|
+
if (ctrl.$modelValue !== prevModelValue) {
|
20566
|
+
ctrl.$$writeModelToScope();
|
20567
|
+
}
|
20568
|
+
}
|
20569
|
+
});
|
20570
|
+
|
20391
20571
|
};
|
20392
20572
|
|
20393
20573
|
this.$$runValidators = function(parseValid, modelValue, viewValue, doneCallback) {
|
@@ -20506,11 +20686,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
20506
20686
|
|
20507
20687
|
// change to dirty
|
20508
20688
|
if (ctrl.$pristine) {
|
20509
|
-
|
20510
|
-
ctrl.$pristine = false;
|
20511
|
-
$animate.removeClass($element, PRISTINE_CLASS);
|
20512
|
-
$animate.addClass($element, DIRTY_CLASS);
|
20513
|
-
parentForm.$setDirty();
|
20689
|
+
this.$setDirty();
|
20514
20690
|
}
|
20515
20691
|
this.$$parseAndValidate();
|
20516
20692
|
};
|
@@ -20531,10 +20707,11 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
20531
20707
|
}
|
20532
20708
|
if (isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue)) {
|
20533
20709
|
// ctrl.$modelValue has not been touched yet...
|
20534
|
-
ctrl.$modelValue = ngModelGet();
|
20710
|
+
ctrl.$modelValue = ngModelGet($scope);
|
20535
20711
|
}
|
20536
20712
|
var prevModelValue = ctrl.$modelValue;
|
20537
20713
|
var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid;
|
20714
|
+
ctrl.$$rawModelValue = modelValue;
|
20538
20715
|
if (allowInvalid) {
|
20539
20716
|
ctrl.$modelValue = modelValue;
|
20540
20717
|
writeToModelIfNeeded();
|
@@ -20558,7 +20735,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
20558
20735
|
};
|
20559
20736
|
|
20560
20737
|
this.$$writeModelToScope = function() {
|
20561
|
-
ngModelSet(ctrl.$modelValue);
|
20738
|
+
ngModelSet($scope, ctrl.$modelValue);
|
20562
20739
|
forEach(ctrl.$viewChangeListeners, function(listener) {
|
20563
20740
|
try {
|
20564
20741
|
listener();
|
@@ -20654,12 +20831,12 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
20654
20831
|
// ng-change executes in apply phase
|
20655
20832
|
// 4. view should be changed back to 'a'
|
20656
20833
|
$scope.$watch(function ngModelWatch() {
|
20657
|
-
var modelValue = ngModelGet();
|
20834
|
+
var modelValue = ngModelGet($scope);
|
20658
20835
|
|
20659
20836
|
// if scope model value and ngModel value are out of sync
|
20660
20837
|
// TODO(perf): why not move this to the action fn?
|
20661
20838
|
if (modelValue !== ctrl.$modelValue) {
|
20662
|
-
ctrl.$modelValue = modelValue;
|
20839
|
+
ctrl.$modelValue = ctrl.$$rawModelValue = modelValue;
|
20663
20840
|
|
20664
20841
|
var formatters = ctrl.$formatters,
|
20665
20842
|
idx = formatters.length;
|
@@ -20844,7 +21021,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
20844
21021
|
</file>
|
20845
21022
|
* </example>
|
20846
21023
|
*/
|
20847
|
-
var ngModelDirective = function() {
|
21024
|
+
var ngModelDirective = ['$rootScope', function($rootScope) {
|
20848
21025
|
return {
|
20849
21026
|
restrict: 'A',
|
20850
21027
|
require: ['ngModel', '^?form', '^?ngModelOptions'],
|
@@ -20888,15 +21065,17 @@ var ngModelDirective = function() {
|
|
20888
21065
|
element.on('blur', function(ev) {
|
20889
21066
|
if (modelCtrl.$touched) return;
|
20890
21067
|
|
20891
|
-
|
20892
|
-
modelCtrl.$setTouched
|
20893
|
-
}
|
21068
|
+
if ($rootScope.$$phase) {
|
21069
|
+
scope.$evalAsync(modelCtrl.$setTouched);
|
21070
|
+
} else {
|
21071
|
+
scope.$apply(modelCtrl.$setTouched);
|
21072
|
+
}
|
20894
21073
|
});
|
20895
21074
|
}
|
20896
21075
|
};
|
20897
21076
|
}
|
20898
21077
|
};
|
20899
|
-
};
|
21078
|
+
}];
|
20900
21079
|
|
20901
21080
|
|
20902
21081
|
/**
|
@@ -20985,8 +21164,8 @@ var requiredDirective = function() {
|
|
20985
21164
|
if (!ctrl) return;
|
20986
21165
|
attr.required = true; // force truthy in case we are on non input element
|
20987
21166
|
|
20988
|
-
ctrl.$validators.required = function(
|
20989
|
-
return !attr.required || !ctrl.$isEmpty(
|
21167
|
+
ctrl.$validators.required = function(modelValue, viewValue) {
|
21168
|
+
return !attr.required || !ctrl.$isEmpty(viewValue);
|
20990
21169
|
};
|
20991
21170
|
|
20992
21171
|
attr.$observe('required', function() {
|
@@ -21007,7 +21186,7 @@ var patternDirective = function() {
|
|
21007
21186
|
var regexp, patternExp = attr.ngPattern || attr.pattern;
|
21008
21187
|
attr.$observe('pattern', function(regex) {
|
21009
21188
|
if (isString(regex) && regex.length > 0) {
|
21010
|
-
regex = new RegExp(regex);
|
21189
|
+
regex = new RegExp('^' + regex + '$');
|
21011
21190
|
}
|
21012
21191
|
|
21013
21192
|
if (regex && !regex.test) {
|
@@ -21035,13 +21214,14 @@ var maxlengthDirective = function() {
|
|
21035
21214
|
link: function(scope, elm, attr, ctrl) {
|
21036
21215
|
if (!ctrl) return;
|
21037
21216
|
|
21038
|
-
var maxlength =
|
21217
|
+
var maxlength = -1;
|
21039
21218
|
attr.$observe('maxlength', function(value) {
|
21040
|
-
|
21219
|
+
var intVal = int(value);
|
21220
|
+
maxlength = isNaN(intVal) ? -1 : intVal;
|
21041
21221
|
ctrl.$validate();
|
21042
21222
|
});
|
21043
21223
|
ctrl.$validators.maxlength = function(modelValue, viewValue) {
|
21044
|
-
return ctrl.$isEmpty(modelValue) || viewValue.length <= maxlength;
|
21224
|
+
return (maxlength < 0) || ctrl.$isEmpty(modelValue) || (viewValue.length <= maxlength);
|
21045
21225
|
};
|
21046
21226
|
}
|
21047
21227
|
};
|
@@ -21060,7 +21240,7 @@ var minlengthDirective = function() {
|
|
21060
21240
|
ctrl.$validate();
|
21061
21241
|
});
|
21062
21242
|
ctrl.$validators.minlength = function(modelValue, viewValue) {
|
21063
|
-
return ctrl.$isEmpty(
|
21243
|
+
return ctrl.$isEmpty(viewValue) || viewValue.length >= minlength;
|
21064
21244
|
};
|
21065
21245
|
}
|
21066
21246
|
};
|
@@ -21298,7 +21478,7 @@ var ngValueDirective = function() {
|
|
21298
21478
|
* `ngModelOptions` has an effect on the element it's declared on and its descendants.
|
21299
21479
|
*
|
21300
21480
|
* @param {Object} ngModelOptions options to apply to the current model. Valid keys are:
|
21301
|
-
* - `updateOn`: string specifying which event should
|
21481
|
+
* - `updateOn`: string specifying which event should the input be bound to. You can set several
|
21302
21482
|
* events using an space delimited list. There is a special event called `default` that
|
21303
21483
|
* matches the default events belonging of the control.
|
21304
21484
|
* - `debounce`: integer value which contains the debounce model update value in milliseconds. A
|
@@ -21688,12 +21868,11 @@ var ngBindTemplateDirective = ['$interpolate', '$compile', function($interpolate
|
|
21688
21868
|
* @name ngBindHtml
|
21689
21869
|
*
|
21690
21870
|
* @description
|
21691
|
-
*
|
21692
|
-
*
|
21693
|
-
*
|
21694
|
-
*
|
21695
|
-
*
|
21696
|
-
* include "angular-sanitize.js" in your application.
|
21871
|
+
* Evaluates the expression and inserts the resulting HTML into the element in a secure way. By default,
|
21872
|
+
* the resulting HTML content will be sanitized using the {@link ngSanitize.$sanitize $sanitize} service.
|
21873
|
+
* To utilize this functionality, ensure that `$sanitize` is available, for example, by including {@link
|
21874
|
+
* ngSanitize} in your module's dependencies (not in core Angular). In order to use {@link ngSanitize}
|
21875
|
+
* in your module's dependencies, you need to include "angular-sanitize.js" in your application.
|
21697
21876
|
*
|
21698
21877
|
* You may also bypass sanitization for values you know are safe. To do so, bind to
|
21699
21878
|
* an explicitly trusted value via {@link ng.$sce#trustAsHtml $sce.trustAsHtml}. See the example
|
@@ -23757,7 +23936,9 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
|
|
23757
23936
|
</example>
|
23758
23937
|
*/
|
23759
23938
|
var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interpolate) {
|
23760
|
-
var BRACE = /{}/g
|
23939
|
+
var BRACE = /{}/g,
|
23940
|
+
IS_WHEN = /^when(Minus)?(.+)$/;
|
23941
|
+
|
23761
23942
|
return {
|
23762
23943
|
restrict: 'EA',
|
23763
23944
|
link: function(scope, element, attr) {
|
@@ -23768,34 +23949,44 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
|
|
23768
23949
|
whensExpFns = {},
|
23769
23950
|
startSymbol = $interpolate.startSymbol(),
|
23770
23951
|
endSymbol = $interpolate.endSymbol(),
|
23771
|
-
|
23952
|
+
braceReplacement = startSymbol + numberExp + '-' + offset + endSymbol,
|
23953
|
+
watchRemover = angular.noop,
|
23954
|
+
lastCount;
|
23772
23955
|
|
23773
23956
|
forEach(attr, function(expression, attributeName) {
|
23774
|
-
|
23775
|
-
|
23776
|
-
|
23957
|
+
var tmpMatch = IS_WHEN.exec(attributeName);
|
23958
|
+
if (tmpMatch) {
|
23959
|
+
var whenKey = (tmpMatch[1] ? '-' : '') + lowercase(tmpMatch[2]);
|
23960
|
+
whens[whenKey] = element.attr(attr.$attr[attributeName]);
|
23777
23961
|
}
|
23778
23962
|
});
|
23779
23963
|
forEach(whens, function(expression, key) {
|
23780
|
-
whensExpFns[key] =
|
23781
|
-
|
23782
|
-
offset + endSymbol));
|
23964
|
+
whensExpFns[key] = $interpolate(expression.replace(BRACE, braceReplacement));
|
23965
|
+
|
23783
23966
|
});
|
23784
23967
|
|
23785
|
-
scope.$watch(function
|
23786
|
-
var
|
23968
|
+
scope.$watch(numberExp, function ngPluralizeWatchAction(newVal) {
|
23969
|
+
var count = parseFloat(newVal);
|
23970
|
+
var countIsNaN = isNaN(count);
|
23787
23971
|
|
23788
|
-
if (!
|
23789
|
-
//
|
23790
|
-
//check it against pluralization rules in $locale service
|
23791
|
-
|
23792
|
-
|
23793
|
-
|
23794
|
-
|
23972
|
+
if (!countIsNaN && !(count in whens)) {
|
23973
|
+
// If an explicit number rule such as 1, 2, 3... is defined, just use it.
|
23974
|
+
// Otherwise, check it against pluralization rules in $locale service.
|
23975
|
+
count = $locale.pluralCat(count - offset);
|
23976
|
+
}
|
23977
|
+
|
23978
|
+
// If both `count` and `lastCount` are NaN, we don't need to re-register a watch.
|
23979
|
+
// In JS `NaN !== NaN`, so we have to exlicitly check.
|
23980
|
+
if ((count !== lastCount) && !(countIsNaN && isNaN(lastCount))) {
|
23981
|
+
watchRemover();
|
23982
|
+
watchRemover = scope.$watch(whensExpFns[count], updateElementText);
|
23983
|
+
lastCount = count;
|
23795
23984
|
}
|
23796
|
-
}, function ngPluralizeWatchAction(newVal) {
|
23797
|
-
element.text(newVal);
|
23798
23985
|
});
|
23986
|
+
|
23987
|
+
function updateElementText(newText) {
|
23988
|
+
element.text(newText || '');
|
23989
|
+
}
|
23799
23990
|
}
|
23800
23991
|
};
|
23801
23992
|
}];
|
@@ -24166,7 +24357,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
24166
24357
|
});
|
24167
24358
|
throw ngRepeatMinErr('dupes',
|
24168
24359
|
"Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}, Duplicate value: {2}",
|
24169
|
-
expression, trackById,
|
24360
|
+
expression, trackById, value);
|
24170
24361
|
} else {
|
24171
24362
|
// new never before seen block
|
24172
24363
|
nextBlockOrder[index] = {id: trackById, scope: undefined, clone: undefined};
|
@@ -24277,17 +24468,17 @@ var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';
|
|
24277
24468
|
*
|
24278
24469
|
* ### Overriding `.ng-hide`
|
24279
24470
|
*
|
24280
|
-
* By default, the `.ng-hide` class will style the element with `display:none!important`. If you wish to change
|
24471
|
+
* By default, the `.ng-hide` class will style the element with `display: none!important`. If you wish to change
|
24281
24472
|
* the hide behavior with ngShow/ngHide then this can be achieved by restating the styles for the `.ng-hide`
|
24282
24473
|
* class in CSS:
|
24283
24474
|
*
|
24284
24475
|
* ```css
|
24285
24476
|
* .ng-hide {
|
24286
24477
|
* /* this is just another form of hiding an element */
|
24287
|
-
* display:block!important;
|
24288
|
-
* position:absolute;
|
24289
|
-
* top
|
24290
|
-
* left
|
24478
|
+
* display: block!important;
|
24479
|
+
* position: absolute;
|
24480
|
+
* top: -9999px;
|
24481
|
+
* left: -9999px;
|
24291
24482
|
* }
|
24292
24483
|
* ```
|
24293
24484
|
*
|
@@ -24307,13 +24498,13 @@ var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';
|
|
24307
24498
|
* .my-element.ng-hide-add, .my-element.ng-hide-remove {
|
24308
24499
|
* /* this is required as of 1.3x to properly
|
24309
24500
|
* apply all styling in a show/hide animation */
|
24310
|
-
* transition:0s linear all;
|
24501
|
+
* transition: 0s linear all;
|
24311
24502
|
* }
|
24312
24503
|
*
|
24313
24504
|
* .my-element.ng-hide-add-active,
|
24314
24505
|
* .my-element.ng-hide-remove-active {
|
24315
24506
|
* /* the transition is defined in the active class */
|
24316
|
-
* transition:1s linear all;
|
24507
|
+
* transition: 1s linear all;
|
24317
24508
|
* }
|
24318
24509
|
*
|
24319
24510
|
* .my-element.ng-hide-add { ... }
|
@@ -24355,29 +24546,29 @@ var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';
|
|
24355
24546
|
</file>
|
24356
24547
|
<file name="animations.css">
|
24357
24548
|
.animate-show {
|
24358
|
-
line-height:20px;
|
24359
|
-
opacity:1;
|
24360
|
-
padding:10px;
|
24361
|
-
border:1px solid black;
|
24362
|
-
background:white;
|
24549
|
+
line-height: 20px;
|
24550
|
+
opacity: 1;
|
24551
|
+
padding: 10px;
|
24552
|
+
border: 1px solid black;
|
24553
|
+
background: white;
|
24363
24554
|
}
|
24364
24555
|
|
24365
24556
|
.animate-show.ng-hide-add.ng-hide-add-active,
|
24366
24557
|
.animate-show.ng-hide-remove.ng-hide-remove-active {
|
24367
|
-
-webkit-transition:all linear 0.5s;
|
24368
|
-
transition:all linear 0.5s;
|
24558
|
+
-webkit-transition: all linear 0.5s;
|
24559
|
+
transition: all linear 0.5s;
|
24369
24560
|
}
|
24370
24561
|
|
24371
24562
|
.animate-show.ng-hide {
|
24372
|
-
line-height:0;
|
24373
|
-
opacity:0;
|
24374
|
-
padding:0 10px;
|
24563
|
+
line-height: 0;
|
24564
|
+
opacity: 0;
|
24565
|
+
padding: 0 10px;
|
24375
24566
|
}
|
24376
24567
|
|
24377
24568
|
.check-element {
|
24378
|
-
padding:10px;
|
24379
|
-
border:1px solid black;
|
24380
|
-
background:white;
|
24569
|
+
padding: 10px;
|
24570
|
+
border: 1px solid black;
|
24571
|
+
background: white;
|
24381
24572
|
}
|
24382
24573
|
</file>
|
24383
24574
|
<file name="protractor.js" type="protractor">
|
@@ -24451,17 +24642,17 @@ var ngShowDirective = ['$animate', function($animate) {
|
|
24451
24642
|
*
|
24452
24643
|
* ### Overriding `.ng-hide`
|
24453
24644
|
*
|
24454
|
-
* By default, the `.ng-hide` class will style the element with `display:none!important`. If you wish to change
|
24645
|
+
* By default, the `.ng-hide` class will style the element with `display: none!important`. If you wish to change
|
24455
24646
|
* the hide behavior with ngShow/ngHide then this can be achieved by restating the styles for the `.ng-hide`
|
24456
24647
|
* class in CSS:
|
24457
24648
|
*
|
24458
24649
|
* ```css
|
24459
24650
|
* .ng-hide {
|
24460
24651
|
* /* this is just another form of hiding an element */
|
24461
|
-
* display:block!important;
|
24462
|
-
* position:absolute;
|
24463
|
-
* top
|
24464
|
-
* left
|
24652
|
+
* display: block!important;
|
24653
|
+
* position: absolute;
|
24654
|
+
* top: -9999px;
|
24655
|
+
* left: -9999px;
|
24465
24656
|
* }
|
24466
24657
|
* ```
|
24467
24658
|
*
|
@@ -24478,7 +24669,7 @@ var ngShowDirective = ['$animate', function($animate) {
|
|
24478
24669
|
* //a working example can be found at the bottom of this page
|
24479
24670
|
* //
|
24480
24671
|
* .my-element.ng-hide-add, .my-element.ng-hide-remove {
|
24481
|
-
* transition:0.5s linear all;
|
24672
|
+
* transition: 0.5s linear all;
|
24482
24673
|
* }
|
24483
24674
|
*
|
24484
24675
|
* .my-element.ng-hide-add { ... }
|
@@ -24520,25 +24711,25 @@ var ngShowDirective = ['$animate', function($animate) {
|
|
24520
24711
|
</file>
|
24521
24712
|
<file name="animations.css">
|
24522
24713
|
.animate-hide {
|
24523
|
-
-webkit-transition:all linear 0.5s;
|
24524
|
-
transition:all linear 0.5s;
|
24525
|
-
line-height:20px;
|
24526
|
-
opacity:1;
|
24527
|
-
padding:10px;
|
24528
|
-
border:1px solid black;
|
24529
|
-
background:white;
|
24714
|
+
-webkit-transition: all linear 0.5s;
|
24715
|
+
transition: all linear 0.5s;
|
24716
|
+
line-height: 20px;
|
24717
|
+
opacity: 1;
|
24718
|
+
padding: 10px;
|
24719
|
+
border: 1px solid black;
|
24720
|
+
background: white;
|
24530
24721
|
}
|
24531
24722
|
|
24532
24723
|
.animate-hide.ng-hide {
|
24533
|
-
line-height:0;
|
24534
|
-
opacity:0;
|
24535
|
-
padding:0 10px;
|
24724
|
+
line-height: 0;
|
24725
|
+
opacity: 0;
|
24726
|
+
padding: 0 10px;
|
24536
24727
|
}
|
24537
24728
|
|
24538
24729
|
.check-element {
|
24539
|
-
padding:10px;
|
24540
|
-
border:1px solid black;
|
24541
|
-
background:white;
|
24730
|
+
padding: 10px;
|
24731
|
+
border: 1px solid black;
|
24732
|
+
background: white;
|
24542
24733
|
}
|
24543
24734
|
</file>
|
24544
24735
|
<file name="protractor.js" type="protractor">
|
@@ -24972,7 +25163,7 @@ var ngOptionsMinErr = minErr('ngOptions');
|
|
24972
25163
|
* In many cases, `ngRepeat` can be used on `<option>` elements instead of `ngOptions` to achieve a
|
24973
25164
|
* similar result. However, the `ngOptions` provides some benefits such as reducing memory and
|
24974
25165
|
* increasing speed by not creating a new scope for each repeated instance, as well as providing
|
24975
|
-
* more flexibility in how the `select`'s model is assigned via `select as`. `ngOptions should be
|
25166
|
+
* more flexibility in how the `select`'s model is assigned via `select as`. `ngOptions` should be
|
24976
25167
|
* used when the `select` model needs to be bound to a non-string value. This is because an option
|
24977
25168
|
* element can only be bound to string values at present.
|
24978
25169
|
*
|
@@ -25570,13 +25761,14 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
25570
25761
|
lastElement = null; // start at the beginning
|
25571
25762
|
for (index = 0, length = optionGroup.length; index < length; index++) {
|
25572
25763
|
option = optionGroup[index];
|
25573
|
-
if ((existingOption = existingOptions[index+1])) {
|
25764
|
+
if ((existingOption = existingOptions[index + 1])) {
|
25574
25765
|
// reuse elements
|
25575
25766
|
lastElement = existingOption.element;
|
25576
25767
|
if (existingOption.label !== option.label) {
|
25577
25768
|
updateLabelMap(labelMap, existingOption.label, false);
|
25578
25769
|
updateLabelMap(labelMap, option.label, true);
|
25579
25770
|
lastElement.text(existingOption.label = option.label);
|
25771
|
+
lastElement.prop('label', existingOption.label);
|
25580
25772
|
}
|
25581
25773
|
if (existingOption.id !== option.id) {
|
25582
25774
|
lastElement.val(existingOption.id = option.id);
|
@@ -25606,6 +25798,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
25606
25798
|
.val(option.id)
|
25607
25799
|
.prop('selected', option.selected)
|
25608
25800
|
.attr('selected', option.selected)
|
25801
|
+
.prop('label', option.label)
|
25609
25802
|
.text(option.label);
|
25610
25803
|
}
|
25611
25804
|
|