angular-gem 1.3.2 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
|
|