angularjs-rails 1.2.20 → 1.2.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/angularjs-rails/version.rb +2 -2
- data/vendor/assets/javascripts/angular-animate.js +3 -3
- data/vendor/assets/javascripts/angular-cookies.js +1 -1
- data/vendor/assets/javascripts/angular-loader.js +2 -2
- data/vendor/assets/javascripts/angular-mocks.js +3 -1
- data/vendor/assets/javascripts/angular-resource.js +12 -12
- data/vendor/assets/javascripts/angular-route.js +2 -4
- data/vendor/assets/javascripts/angular-sanitize.js +16 -8
- data/vendor/assets/javascripts/angular-scenario.js +275 -214
- data/vendor/assets/javascripts/angular-touch.js +1 -1
- data/vendor/assets/javascripts/angular.js +275 -214
- data/vendor/assets/javascripts/unstable/angular-animate.js +3 -3
- data/vendor/assets/javascripts/unstable/angular-cookies.js +1 -1
- data/vendor/assets/javascripts/unstable/angular-loader.js +2 -2
- data/vendor/assets/javascripts/unstable/angular-messages.js +1 -1
- data/vendor/assets/javascripts/unstable/angular-mocks.js +3 -1
- data/vendor/assets/javascripts/unstable/angular-resource.js +12 -12
- data/vendor/assets/javascripts/unstable/angular-route.js +2 -4
- data/vendor/assets/javascripts/unstable/angular-sanitize.js +16 -8
- data/vendor/assets/javascripts/unstable/angular-scenario.js +617 -407
- data/vendor/assets/javascripts/unstable/angular-touch.js +1 -1
- data/vendor/assets/javascripts/unstable/angular.js +615 -405
- metadata +14 -14
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.3.0-beta.
|
2
|
+
* @license AngularJS v1.3.0-beta.17
|
3
3
|
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -68,7 +68,7 @@ function minErr(module) {
|
|
68
68
|
return match;
|
69
69
|
});
|
70
70
|
|
71
|
-
message = message + '\nhttp://errors.angularjs.org/1.3.0-beta.
|
71
|
+
message = message + '\nhttp://errors.angularjs.org/1.3.0-beta.17/' +
|
72
72
|
(module ? module + '/' : '') + code;
|
73
73
|
for (i = 2; i < arguments.length; i++) {
|
74
74
|
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
|
@@ -126,6 +126,7 @@ function minErr(module) {
|
|
126
126
|
isFile: true,
|
127
127
|
isBlob: true,
|
128
128
|
isBoolean: true,
|
129
|
+
isPromiseLike: true,
|
129
130
|
trim: true,
|
130
131
|
isElement: true,
|
131
132
|
makeMap: true,
|
@@ -648,6 +649,11 @@ function isBoolean(value) {
|
|
648
649
|
}
|
649
650
|
|
650
651
|
|
652
|
+
function isPromiseLike(obj) {
|
653
|
+
return obj && isFunction(obj.then);
|
654
|
+
}
|
655
|
+
|
656
|
+
|
651
657
|
var trim = (function() {
|
652
658
|
// native trim is way faster: http://jsperf.com/angular-trim-test
|
653
659
|
// but IE doesn't have it... :-(
|
@@ -814,7 +820,7 @@ function isLeafNode (node) {
|
|
814
820
|
</div>
|
815
821
|
|
816
822
|
<script>
|
817
|
-
angular.module('copyExample')
|
823
|
+
angular.module('copyExample', [])
|
818
824
|
.controller('ExampleController', ['$scope', function($scope) {
|
819
825
|
$scope.master= {};
|
820
826
|
|
@@ -848,7 +854,8 @@ function copy(source, destination, stackSource, stackDest) {
|
|
848
854
|
} else if (isDate(source)) {
|
849
855
|
destination = new Date(source.getTime());
|
850
856
|
} else if (isRegExp(source)) {
|
851
|
-
destination = new RegExp(source.source);
|
857
|
+
destination = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]);
|
858
|
+
destination.lastIndex = source.lastIndex;
|
852
859
|
} else if (isObject(source)) {
|
853
860
|
var emptyObject = Object.create(Object.getPrototypeOf(source));
|
854
861
|
destination = copy(source, emptyObject, stackSource, stackDest);
|
@@ -1000,12 +1007,25 @@ function equals(o1, o2) {
|
|
1000
1007
|
return false;
|
1001
1008
|
}
|
1002
1009
|
|
1010
|
+
var csp = function() {
|
1011
|
+
if (isDefined(csp.isActive_)) return csp.isActive_;
|
1012
|
+
|
1013
|
+
var active = !!(document.querySelector('[ng-csp]') ||
|
1014
|
+
document.querySelector('[data-ng-csp]'));
|
1015
|
+
|
1016
|
+
if (!active) {
|
1017
|
+
try {
|
1018
|
+
/* jshint -W031, -W054 */
|
1019
|
+
new Function('');
|
1020
|
+
/* jshint +W031, +W054 */
|
1021
|
+
} catch (e) {
|
1022
|
+
active = true;
|
1023
|
+
}
|
1024
|
+
}
|
1025
|
+
|
1026
|
+
return (csp.isActive_ = active);
|
1027
|
+
};
|
1003
1028
|
|
1004
|
-
function csp() {
|
1005
|
-
return (document.securityPolicy && document.securityPolicy.isActive) ||
|
1006
|
-
(document.querySelector &&
|
1007
|
-
!!(document.querySelector('[ng-csp]') || document.querySelector('[data-ng-csp]')));
|
1008
|
-
}
|
1009
1029
|
|
1010
1030
|
|
1011
1031
|
function concat(array1, array2, index) {
|
@@ -1165,7 +1185,7 @@ function parseKeyValue(/**string*/keyValue) {
|
|
1165
1185
|
var obj = {}, key_value, key;
|
1166
1186
|
forEach((keyValue || "").split('&'), function(keyValue) {
|
1167
1187
|
if ( keyValue ) {
|
1168
|
-
key_value = keyValue.split('=');
|
1188
|
+
key_value = keyValue.replace(/\+/g,'%20').split('=');
|
1169
1189
|
key = tryDecodeURIComponent(key_value[0]);
|
1170
1190
|
if ( isDefined(key) ) {
|
1171
1191
|
var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
|
@@ -1241,7 +1261,7 @@ function encodeUriQuery(val, pctEncodeSpaces) {
|
|
1241
1261
|
var ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-'];
|
1242
1262
|
|
1243
1263
|
function getNgAttribute(element, ngAttr) {
|
1244
|
-
var attr, i, ii = ngAttrPrefixes.length
|
1264
|
+
var attr, i, ii = ngAttrPrefixes.length;
|
1245
1265
|
element = jqLite(element);
|
1246
1266
|
for (i=0; i<ii; ++i) {
|
1247
1267
|
attr = ngAttrPrefixes[i] + ngAttr;
|
@@ -1380,46 +1400,26 @@ function getNgAttribute(element, ngAttr) {
|
|
1380
1400
|
</example>
|
1381
1401
|
*/
|
1382
1402
|
function angularInit(element, bootstrap) {
|
1383
|
-
var
|
1384
|
-
appElement,
|
1403
|
+
var appElement,
|
1385
1404
|
module,
|
1386
|
-
config = {}
|
1387
|
-
names = ['ng:app', 'ng-app', 'x-ng-app', 'data-ng-app'],
|
1388
|
-
options = {
|
1389
|
-
'boolean': ['strict-di']
|
1390
|
-
},
|
1391
|
-
NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;
|
1405
|
+
config = {};
|
1392
1406
|
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1407
|
+
// The element `element` has priority over any other element
|
1408
|
+
forEach(ngAttrPrefixes, function(prefix) {
|
1409
|
+
var name = prefix + 'app';
|
1396
1410
|
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
name = name.replace(':', '\\:');
|
1401
|
-
if (element.querySelectorAll) {
|
1402
|
-
forEach(element.querySelectorAll('.' + name), append);
|
1403
|
-
forEach(element.querySelectorAll('.' + name + '\\:'), append);
|
1404
|
-
forEach(element.querySelectorAll('[' + name + ']'), append);
|
1411
|
+
if (!appElement && element.hasAttribute && element.hasAttribute(name)) {
|
1412
|
+
appElement = element;
|
1413
|
+
module = element.getAttribute(name);
|
1405
1414
|
}
|
1406
1415
|
});
|
1416
|
+
forEach(ngAttrPrefixes, function(prefix) {
|
1417
|
+
var name = prefix + 'app';
|
1418
|
+
var candidate;
|
1407
1419
|
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
var match = NG_APP_CLASS_REGEXP.exec(className);
|
1412
|
-
if (match) {
|
1413
|
-
appElement = element;
|
1414
|
-
module = (match[2] || '').replace(/\s+/g, ',');
|
1415
|
-
} else {
|
1416
|
-
forEach(element.attributes, function(attr) {
|
1417
|
-
if (!appElement && names[attr.name]) {
|
1418
|
-
appElement = element;
|
1419
|
-
module = attr.value;
|
1420
|
-
}
|
1421
|
-
});
|
1422
|
-
}
|
1420
|
+
if (!appElement && (candidate = element.querySelector('[' + name.replace(':', '\\:') + ']'))) {
|
1421
|
+
appElement = candidate;
|
1422
|
+
module = candidate.getAttribute(name);
|
1423
1423
|
}
|
1424
1424
|
});
|
1425
1425
|
if (appElement) {
|
@@ -2067,11 +2067,11 @@ function setupModuleLoader(window) {
|
|
2067
2067
|
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
|
2068
2068
|
*/
|
2069
2069
|
var version = {
|
2070
|
-
full: '1.3.0-beta.
|
2070
|
+
full: '1.3.0-beta.17', // all of these placeholder strings will be replaced by grunt's
|
2071
2071
|
major: 1, // package task
|
2072
2072
|
minor: 3,
|
2073
2073
|
dot: 0,
|
2074
|
-
codeName: '
|
2074
|
+
codeName: 'turing-autocompletion'
|
2075
2075
|
};
|
2076
2076
|
|
2077
2077
|
|
@@ -2614,25 +2614,22 @@ function jqLiteController(element, name) {
|
|
2614
2614
|
}
|
2615
2615
|
|
2616
2616
|
function jqLiteInheritedData(element, name, value) {
|
2617
|
-
element = jqLite(element);
|
2618
|
-
|
2619
2617
|
// if element is the document object work with the html element instead
|
2620
2618
|
// this makes $(document).scope() possible
|
2621
|
-
if(element
|
2622
|
-
element = element.
|
2619
|
+
if(element.nodeType == 9) {
|
2620
|
+
element = element.documentElement;
|
2623
2621
|
}
|
2624
2622
|
var names = isArray(name) ? name : [name];
|
2625
2623
|
|
2626
|
-
while (element
|
2627
|
-
var node = element[0];
|
2624
|
+
while (element) {
|
2628
2625
|
for (var i = 0, ii = names.length; i < ii; i++) {
|
2629
|
-
if ((value =
|
2626
|
+
if ((value = jqLite.data(element, names[i])) !== undefined) return value;
|
2630
2627
|
}
|
2631
2628
|
|
2632
2629
|
// If dealing with a document fragment node with a host element, and no parent, use the host
|
2633
2630
|
// element as the parent. This enables directives within a Shadow DOM or polyfilled Shadow DOM
|
2634
2631
|
// to lookup parent controllers.
|
2635
|
-
element =
|
2632
|
+
element = element.parentNode || (element.nodeType === 11 && element.host);
|
2636
2633
|
}
|
2637
2634
|
}
|
2638
2635
|
|
@@ -2715,18 +2712,25 @@ function getAliasedAttrName(element, name) {
|
|
2715
2712
|
return (nodeName === 'INPUT' || nodeName === 'TEXTAREA') && ALIASED_ATTR[name];
|
2716
2713
|
}
|
2717
2714
|
|
2715
|
+
forEach({
|
2716
|
+
data: jqLiteData,
|
2717
|
+
removeData: jqLiteRemoveData
|
2718
|
+
}, function(fn, name) {
|
2719
|
+
JQLite[name] = fn;
|
2720
|
+
});
|
2721
|
+
|
2718
2722
|
forEach({
|
2719
2723
|
data: jqLiteData,
|
2720
2724
|
inheritedData: jqLiteInheritedData,
|
2721
2725
|
|
2722
2726
|
scope: function(element) {
|
2723
2727
|
// Can't use jqLiteData here directly so we stay compatible with jQuery!
|
2724
|
-
return jqLite
|
2728
|
+
return jqLite.data(element, '$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']);
|
2725
2729
|
},
|
2726
2730
|
|
2727
2731
|
isolateScope: function(element) {
|
2728
2732
|
// Can't use jqLiteData here directly so we stay compatible with jQuery!
|
2729
|
-
return jqLite
|
2733
|
+
return jqLite.data(element, '$isolateScope') || jqLite.data(element, '$isolateScopeNoTemplate');
|
2730
2734
|
},
|
2731
2735
|
|
2732
2736
|
controller: jqLiteController,
|
@@ -3147,7 +3151,9 @@ forEach({
|
|
3147
3151
|
clone: jqLiteClone,
|
3148
3152
|
|
3149
3153
|
triggerHandler: function(element, eventName, eventData) {
|
3150
|
-
|
3154
|
+
// Copy event handlers in case event handlers array is modified during execution.
|
3155
|
+
var eventFns = (jqLiteExpandoStore(element, 'events') || {})[eventName],
|
3156
|
+
eventFnsCopy = shallowCopy(eventFns || []);
|
3151
3157
|
|
3152
3158
|
eventData = eventData || [];
|
3153
3159
|
|
@@ -3161,7 +3167,7 @@ forEach({
|
|
3161
3167
|
stopPropagation: noop
|
3162
3168
|
}];
|
3163
3169
|
|
3164
|
-
forEach(
|
3170
|
+
forEach(eventFnsCopy, function(fn) {
|
3165
3171
|
fn.apply(element, event.concat(eventData));
|
3166
3172
|
});
|
3167
3173
|
}
|
@@ -3284,7 +3290,7 @@ HashMap.prototype = {
|
|
3284
3290
|
*
|
3285
3291
|
* // use the injector to kick off your application
|
3286
3292
|
* // use the type inference to auto inject arguments, or use implicit injection
|
3287
|
-
* $injector.invoke(function($rootScope, $compile, $document){
|
3293
|
+
* $injector.invoke(function($rootScope, $compile, $document) {
|
3288
3294
|
* $compile($document)($rootScope);
|
3289
3295
|
* $rootScope.$digest();
|
3290
3296
|
* });
|
@@ -3358,8 +3364,8 @@ function annotate(fn, strictDi, name) {
|
|
3358
3364
|
}
|
3359
3365
|
fnText = fn.toString().replace(STRIP_COMMENTS, '');
|
3360
3366
|
argDecl = fnText.match(FN_ARGS);
|
3361
|
-
forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
|
3362
|
-
arg.replace(FN_ARG, function(all, underscore, name){
|
3367
|
+
forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) {
|
3368
|
+
arg.replace(FN_ARG, function(all, underscore, name) {
|
3363
3369
|
$inject.push(name);
|
3364
3370
|
});
|
3365
3371
|
});
|
@@ -3394,7 +3400,7 @@ function annotate(fn, strictDi, name) {
|
|
3394
3400
|
* ```js
|
3395
3401
|
* var $injector = angular.injector();
|
3396
3402
|
* expect($injector.get('$injector')).toBe($injector);
|
3397
|
-
* expect($injector.invoke(function($injector){
|
3403
|
+
* expect($injector.invoke(function($injector) {
|
3398
3404
|
* return $injector;
|
3399
3405
|
* }).toBe($injector);
|
3400
3406
|
* ```
|
@@ -4030,7 +4036,7 @@ function createInjector(modulesToLoad, strictDi) {
|
|
4030
4036
|
}
|
4031
4037
|
}
|
4032
4038
|
|
4033
|
-
function invoke(fn, self, locals, serviceName){
|
4039
|
+
function invoke(fn, self, locals, serviceName) {
|
4034
4040
|
if (typeof locals === 'string') {
|
4035
4041
|
serviceName = locals;
|
4036
4042
|
locals = null;
|
@@ -4729,16 +4735,15 @@ function Browser(window, document, $log, $sniffer) {
|
|
4729
4735
|
* @returns {Object} Hash of all cookies (if called without any parameter)
|
4730
4736
|
*/
|
4731
4737
|
self.cookies = function(name, value) {
|
4732
|
-
/* global escape: false, unescape: false */
|
4733
4738
|
var cookieLength, cookieArray, cookie, i, index;
|
4734
4739
|
|
4735
4740
|
if (name) {
|
4736
4741
|
if (value === undefined) {
|
4737
|
-
rawDocument.cookie =
|
4742
|
+
rawDocument.cookie = encodeURIComponent(name) + "=;path=" + cookiePath +
|
4738
4743
|
";expires=Thu, 01 Jan 1970 00:00:00 GMT";
|
4739
4744
|
} else {
|
4740
4745
|
if (isString(value)) {
|
4741
|
-
cookieLength = (rawDocument.cookie =
|
4746
|
+
cookieLength = (rawDocument.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value) +
|
4742
4747
|
';path=' + cookiePath).length + 1;
|
4743
4748
|
|
4744
4749
|
// per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum:
|
@@ -4762,12 +4767,12 @@ function Browser(window, document, $log, $sniffer) {
|
|
4762
4767
|
cookie = cookieArray[i];
|
4763
4768
|
index = cookie.indexOf('=');
|
4764
4769
|
if (index > 0) { //ignore nameless cookies
|
4765
|
-
name =
|
4770
|
+
name = decodeURIComponent(cookie.substring(0, index));
|
4766
4771
|
// the first value that is seen for a cookie is the most
|
4767
4772
|
// specific one. values for the same cookie name that
|
4768
4773
|
// follow are for less specific paths.
|
4769
4774
|
if (lastCookies[name] === undefined) {
|
4770
|
-
lastCookies[name] =
|
4775
|
+
lastCookies[name] = decodeURIComponent(cookie.substring(index + 1));
|
4771
4776
|
}
|
4772
4777
|
}
|
4773
4778
|
}
|
@@ -5340,6 +5345,13 @@ function $TemplateCacheProvider() {
|
|
5340
5345
|
* The directive definition object provides instructions to the {@link ng.$compile
|
5341
5346
|
* compiler}. The attributes are:
|
5342
5347
|
*
|
5348
|
+
* ### `multiElement`
|
5349
|
+
* When this property is set to true, the HTML compiler will collect DOM nodes between
|
5350
|
+
* nodes with the attributes `directive-name-start` and `directive-name-end`, and group them
|
5351
|
+
* together as the directive elements. It is recomended that this feature be used on directives
|
5352
|
+
* which are not strictly behavioural (such as {@link api/ng.directive:ngClick ngClick}), and which
|
5353
|
+
* do not manipulate or replace child nodes (such as {@link api/ng.directive:ngInclude ngInclude}).
|
5354
|
+
*
|
5343
5355
|
* #### `priority`
|
5344
5356
|
* When there are multiple directives defined on a single DOM element, sometimes it
|
5345
5357
|
* is necessary to specify the order in which the directives are applied. The `priority` is used
|
@@ -5435,7 +5447,7 @@ function $TemplateCacheProvider() {
|
|
5435
5447
|
* String of subset of `EACM` which restricts the directive to a specific directive
|
5436
5448
|
* declaration style. If omitted, the default (attributes only) is used.
|
5437
5449
|
*
|
5438
|
-
* * `E` - Element name: `<my-directive></my-directive>`
|
5450
|
+
* * `E` - Element name (default): `<my-directive></my-directive>`
|
5439
5451
|
* * `A` - Attribute (default): `<div my-directive="exp"></div>`
|
5440
5452
|
* * `C` - Class: `<div class="my-directive: exp;"></div>`
|
5441
5453
|
* * `M` - Comment: `<!-- directive: my-directive exp -->`
|
@@ -5455,14 +5467,16 @@ function $TemplateCacheProvider() {
|
|
5455
5467
|
* If no `type` is specified, then the type is considered to be html.
|
5456
5468
|
*
|
5457
5469
|
* #### `template`
|
5458
|
-
*
|
5459
|
-
*
|
5460
|
-
*
|
5461
|
-
*
|
5470
|
+
* HTML markup that may:
|
5471
|
+
* * Replace the contents of the directive's element (defualt).
|
5472
|
+
* * Replace the directive's element itself (if `replace` is true - DEPRECATED).
|
5473
|
+
* * Wrap the contents of the directive's element (if `transclude` is true).
|
5474
|
+
*
|
5475
|
+
* Value may be:
|
5462
5476
|
*
|
5463
|
-
*
|
5464
|
-
* two arguments `tElement` and `tAttrs` (described in the `compile`
|
5465
|
-
* returns a string value
|
5477
|
+
* * A string. For example `<div red-on-hover>{{delete_str}}</div>`.
|
5478
|
+
* * A function which takes two arguments `tElement` and `tAttrs` (described in the `compile`
|
5479
|
+
* function api below) and returns a string value.
|
5466
5480
|
*
|
5467
5481
|
*
|
5468
5482
|
* #### `templateUrl`
|
@@ -5477,11 +5491,14 @@ function $TemplateCacheProvider() {
|
|
5477
5491
|
*
|
5478
5492
|
*
|
5479
5493
|
* #### `replace` ([*DEPRECATED*!], will be removed in next major release)
|
5480
|
-
* specify
|
5494
|
+
* specify what the template should replace. Defaults to `false`.
|
5481
5495
|
*
|
5482
|
-
* * `true` - the template will replace the
|
5483
|
-
* * `false` - the template will replace the contents of the
|
5496
|
+
* * `true` - the template will replace the directive's element.
|
5497
|
+
* * `false` - the template will replace the contents of the directive's element.
|
5484
5498
|
*
|
5499
|
+
* The replacement process migrates all of the attributes / classes from the old element to the new
|
5500
|
+
* one. See the {@link guide/directive#creating-custom-directives_creating-directives_template-expanding-directive
|
5501
|
+
* Directives Guide} for an example.
|
5485
5502
|
*
|
5486
5503
|
* #### `transclude`
|
5487
5504
|
* compile the content of the element and make it available to the directive.
|
@@ -5495,6 +5512,11 @@ function $TemplateCacheProvider() {
|
|
5495
5512
|
* * `true` - transclude the content of the directive.
|
5496
5513
|
* * `'element'` - transclude the whole element including any directives defined at lower priority.
|
5497
5514
|
*
|
5515
|
+
* <div class="alert alert-warning">
|
5516
|
+
* **Note:** When testing an element transclude directive you must not place the directive at the root of the
|
5517
|
+
* DOM fragment that is being compiled. See {@link guide/unit-testing#testing-transclusion-directives
|
5518
|
+
* Testing Transclusion Directives}.
|
5519
|
+
* </div>
|
5498
5520
|
*
|
5499
5521
|
* #### `compile`
|
5500
5522
|
*
|
@@ -5793,7 +5815,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
5793
5815
|
directive.index = index;
|
5794
5816
|
directive.name = directive.name || name;
|
5795
5817
|
directive.require = directive.require || (directive.controller && directive.name);
|
5796
|
-
directive.restrict = directive.restrict || '
|
5818
|
+
directive.restrict = directive.restrict || 'EA';
|
5797
5819
|
directives.push(directive);
|
5798
5820
|
} catch (e) {
|
5799
5821
|
$exceptionHandler(e);
|
@@ -6143,7 +6165,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6143
6165
|
: null;
|
6144
6166
|
|
6145
6167
|
if (nodeLinkFn && nodeLinkFn.scope) {
|
6146
|
-
safeAddClass(
|
6168
|
+
safeAddClass(attrs.$$element, 'ng-scope');
|
6147
6169
|
}
|
6148
6170
|
|
6149
6171
|
childLinkFn = (nodeLinkFn && nodeLinkFn.terminal ||
|
@@ -6165,7 +6187,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6165
6187
|
return linkFnFound ? compositeLinkFn : null;
|
6166
6188
|
|
6167
6189
|
function compositeLinkFn(scope, nodeList, $rootElement, parentBoundTranscludeFn) {
|
6168
|
-
var nodeLinkFn, childLinkFn, node,
|
6190
|
+
var nodeLinkFn, childLinkFn, node, childScope, i, ii, n, childBoundTranscludeFn;
|
6169
6191
|
|
6170
6192
|
// copy nodeList so that linking doesn't break due to live list updates.
|
6171
6193
|
var nodeListLength = nodeList.length,
|
@@ -6178,12 +6200,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6178
6200
|
node = stableNodeList[n];
|
6179
6201
|
nodeLinkFn = linkFns[i++];
|
6180
6202
|
childLinkFn = linkFns[i++];
|
6181
|
-
$node = jqLite(node);
|
6182
6203
|
|
6183
6204
|
if (nodeLinkFn) {
|
6184
6205
|
if (nodeLinkFn.scope) {
|
6185
6206
|
childScope = scope.$new();
|
6186
|
-
|
6207
|
+
jqLite.data(node, '$scope', childScope);
|
6187
6208
|
} else {
|
6188
6209
|
childScope = scope;
|
6189
6210
|
}
|
@@ -6271,10 +6292,12 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6271
6292
|
}
|
6272
6293
|
|
6273
6294
|
var directiveNName = ngAttrName.replace(/(Start|End)$/, '');
|
6274
|
-
if (
|
6275
|
-
|
6276
|
-
|
6277
|
-
|
6295
|
+
if (directiveIsMultiElement(directiveNName)) {
|
6296
|
+
if (ngAttrName === directiveNName + 'Start') {
|
6297
|
+
attrStartName = name;
|
6298
|
+
attrEndName = name.substr(0, name.length - 5) + 'end';
|
6299
|
+
name = name.substr(0, name.length - 6);
|
6300
|
+
}
|
6278
6301
|
}
|
6279
6302
|
|
6280
6303
|
nName = directiveNormalize(name.toLowerCase());
|
@@ -6483,12 +6506,12 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6483
6506
|
if (directiveValue == 'element') {
|
6484
6507
|
hasElementTranscludeDirective = true;
|
6485
6508
|
terminalPriority = directive.priority;
|
6486
|
-
$template =
|
6509
|
+
$template = $compileNode;
|
6487
6510
|
$compileNode = templateAttrs.$$element =
|
6488
6511
|
jqLite(document.createComment(' ' + directiveName + ': ' +
|
6489
6512
|
templateAttrs[directiveName] + ' '));
|
6490
6513
|
compileNode = $compileNode[0];
|
6491
|
-
replaceWith(jqCollection,
|
6514
|
+
replaceWith(jqCollection, sliceArgs($template), compileNode);
|
6492
6515
|
|
6493
6516
|
childTranscludeFn = compile($template, transcludeFn, terminalPriority,
|
6494
6517
|
replaceDirective && replaceDirective.name, {
|
@@ -6665,29 +6688,26 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6665
6688
|
function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {
|
6666
6689
|
var attrs, $element, i, ii, linkFn, controller, isolateScope, elementControllers = {}, transcludeFn;
|
6667
6690
|
|
6668
|
-
|
6669
|
-
|
6670
|
-
|
6671
|
-
attrs = shallowCopy(templateAttrs, new Attributes(jqLite(linkNode), templateAttrs.$attr));
|
6672
|
-
}
|
6691
|
+
attrs = (compileNode === linkNode)
|
6692
|
+
? templateAttrs
|
6693
|
+
: shallowCopy(templateAttrs, new Attributes(jqLite(linkNode), templateAttrs.$attr));
|
6673
6694
|
$element = attrs.$$element;
|
6674
6695
|
|
6675
6696
|
if (newIsolateScopeDirective) {
|
6676
6697
|
var LOCAL_REGEXP = /^\s*([@=&])(\??)\s*(\w*)\s*$/;
|
6677
|
-
var $linkNode = jqLite(linkNode);
|
6678
6698
|
|
6679
6699
|
isolateScope = scope.$new(true);
|
6680
6700
|
|
6681
6701
|
if (templateDirective && (templateDirective === newIsolateScopeDirective ||
|
6682
6702
|
templateDirective === newIsolateScopeDirective.$$originalDirective)) {
|
6683
|
-
$
|
6703
|
+
$element.data('$isolateScope', isolateScope);
|
6684
6704
|
} else {
|
6685
|
-
$
|
6705
|
+
$element.data('$isolateScopeNoTemplate', isolateScope);
|
6686
6706
|
}
|
6687
6707
|
|
6688
6708
|
|
6689
6709
|
|
6690
|
-
safeAddClass($
|
6710
|
+
safeAddClass($element, 'ng-isolate-scope');
|
6691
6711
|
|
6692
6712
|
forEach(newIsolateScopeDirective.scope, function(definition, scopeName) {
|
6693
6713
|
var match = definition.match(LOCAL_REGEXP) || [],
|
@@ -6731,8 +6751,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6731
6751
|
attrs[attrName], newIsolateScopeDirective.name);
|
6732
6752
|
};
|
6733
6753
|
lastValue = isolateScope[scopeName] = parentGet(scope);
|
6734
|
-
|
6735
|
-
var parentValue = parentGet(scope);
|
6754
|
+
var unwatch = scope.$watch($parse(attrs[attrName], function parentValueWatch(parentValue) {
|
6736
6755
|
if (!compare(parentValue, isolateScope[scopeName])) {
|
6737
6756
|
// we are out of sync and need to copy
|
6738
6757
|
if (!compare(parentValue, lastValue)) {
|
@@ -6743,9 +6762,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6743
6762
|
parentSet(scope, parentValue = isolateScope[scopeName]);
|
6744
6763
|
}
|
6745
6764
|
}
|
6746
|
-
parentValueWatch.$$unwatch = parentGet.$$unwatch;
|
6747
6765
|
return lastValue = parentValue;
|
6748
|
-
}, null, parentGet.literal);
|
6766
|
+
}), null, parentGet.literal);
|
6767
|
+
isolateScope.$on('$destroy', unwatch);
|
6749
6768
|
break;
|
6750
6769
|
|
6751
6770
|
case '&':
|
@@ -6890,6 +6909,27 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
6890
6909
|
}
|
6891
6910
|
|
6892
6911
|
|
6912
|
+
/**
|
6913
|
+
* looks up the directive and returns true if it is a multi-element directive,
|
6914
|
+
* and therefore requires DOM nodes between -start and -end markers to be grouped
|
6915
|
+
* together.
|
6916
|
+
*
|
6917
|
+
* @param {string} name name of the directive to look up.
|
6918
|
+
* @returns true if directive was registered as multi-element.
|
6919
|
+
*/
|
6920
|
+
function directiveIsMultiElement(name) {
|
6921
|
+
if (hasDirectives.hasOwnProperty(name)) {
|
6922
|
+
for(var directive, directives = $injector.get(name + Suffix),
|
6923
|
+
i = 0, ii = directives.length; i<ii; i++) {
|
6924
|
+
directive = directives[i];
|
6925
|
+
if (directive.multiElement) {
|
6926
|
+
return true;
|
6927
|
+
}
|
6928
|
+
}
|
6929
|
+
}
|
6930
|
+
return false;
|
6931
|
+
}
|
6932
|
+
|
6893
6933
|
/**
|
6894
6934
|
* When the element is replaced with HTML template then the new attributes
|
6895
6935
|
* on the template need to be merged with the existing attributes in the DOM.
|
@@ -7081,9 +7121,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7081
7121
|
return function textInterpolateLinkFn(scope, node) {
|
7082
7122
|
var parent = node.parent(),
|
7083
7123
|
bindings = parent.data('$binding') || [];
|
7084
|
-
// Need to interpolate again in case this is using one-time bindings in multiple clones
|
7085
|
-
// of transcluded templates.
|
7086
|
-
interpolateFn = $interpolate(text);
|
7087
7124
|
bindings.push(interpolateFn);
|
7088
7125
|
parent.data('$binding', bindings);
|
7089
7126
|
if (!hasCompileParent) safeAddClass(parent, 'ng-binding');
|
@@ -7525,11 +7562,7 @@ function parseHeaders(headers) {
|
|
7525
7562
|
val = trim(line.substr(i + 1));
|
7526
7563
|
|
7527
7564
|
if (key) {
|
7528
|
-
|
7529
|
-
parsed[key] += ', ' + val;
|
7530
|
-
} else {
|
7531
|
-
parsed[key] = val;
|
7532
|
-
}
|
7565
|
+
parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
|
7533
7566
|
}
|
7534
7567
|
});
|
7535
7568
|
|
@@ -8294,7 +8327,7 @@ function $HttpProvider() {
|
|
8294
8327
|
* Shortcut method to perform `JSONP` request.
|
8295
8328
|
*
|
8296
8329
|
* @param {string} url Relative or absolute URL specifying the destination of the request.
|
8297
|
-
*
|
8330
|
+
* The name of the callback should be the string `JSON_CALLBACK`.
|
8298
8331
|
* @param {Object=} config Optional configuration object
|
8299
8332
|
* @returns {HttpPromise} Future object
|
8300
8333
|
*/
|
@@ -8328,8 +8361,7 @@ function $HttpProvider() {
|
|
8328
8361
|
|
8329
8362
|
/**
|
8330
8363
|
* @ngdoc method
|
8331
|
-
* @name
|
8332
|
-
* @methodOf ng.$http
|
8364
|
+
* @name $http#patch
|
8333
8365
|
*
|
8334
8366
|
* @description
|
8335
8367
|
* Shortcut method to perform `PATCH` request.
|
@@ -8408,7 +8440,7 @@ function $HttpProvider() {
|
|
8408
8440
|
if (cache) {
|
8409
8441
|
cachedResp = cache.get(url);
|
8410
8442
|
if (isDefined(cachedResp)) {
|
8411
|
-
if (cachedResp
|
8443
|
+
if (isPromiseLike(cachedResp)) {
|
8412
8444
|
// cached request has already been sent, but there is no response yet
|
8413
8445
|
cachedResp.then(removePendingReq, removePendingReq);
|
8414
8446
|
return cachedResp;
|
@@ -8490,27 +8522,29 @@ function $HttpProvider() {
|
|
8490
8522
|
|
8491
8523
|
|
8492
8524
|
function buildUrl(url, params) {
|
8493
|
-
|
8494
|
-
|
8495
|
-
|
8496
|
-
|
8497
|
-
|
8498
|
-
|
8499
|
-
|
8500
|
-
|
8501
|
-
|
8502
|
-
|
8503
|
-
|
8504
|
-
|
8505
|
-
}
|
8506
|
-
});
|
8507
|
-
if(parts.length > 0) {
|
8508
|
-
url += ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&');
|
8525
|
+
if (!params) return url;
|
8526
|
+
var parts = [];
|
8527
|
+
forEachSorted(params, function(value, key) {
|
8528
|
+
if (value === null || isUndefined(value)) return;
|
8529
|
+
if (!isArray(value)) value = [value];
|
8530
|
+
|
8531
|
+
forEach(value, function(v) {
|
8532
|
+
if (isObject(v)) {
|
8533
|
+
if (isDate(v)){
|
8534
|
+
v = v.toISOString();
|
8535
|
+
} else if (isObject(v)) {
|
8536
|
+
v = toJson(v);
|
8537
|
+
}
|
8509
8538
|
}
|
8510
|
-
|
8511
|
-
|
8512
|
-
|
8513
|
-
|
8539
|
+
parts.push(encodeUriQuery(key) + '=' +
|
8540
|
+
encodeUriQuery(v));
|
8541
|
+
});
|
8542
|
+
});
|
8543
|
+
if(parts.length > 0) {
|
8544
|
+
url += ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&');
|
8545
|
+
}
|
8546
|
+
return url;
|
8547
|
+
}
|
8514
8548
|
}];
|
8515
8549
|
}
|
8516
8550
|
|
@@ -8646,7 +8680,7 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
|
|
8646
8680
|
|
8647
8681
|
if (timeout > 0) {
|
8648
8682
|
var timeoutId = $browserDefer(timeoutRequest, timeout);
|
8649
|
-
} else if (timeout
|
8683
|
+
} else if (isPromiseLike(timeout)) {
|
8650
8684
|
timeout.then(timeoutRequest);
|
8651
8685
|
}
|
8652
8686
|
|
@@ -8840,9 +8874,9 @@ function $InterpolateProvider() {
|
|
8840
8874
|
*
|
8841
8875
|
* // "allOrNothing" mode
|
8842
8876
|
* exp = $interpolate('{{greeting}} {{name}}!', false, null, true);
|
8843
|
-
* expect(exp(context
|
8877
|
+
* expect(exp(context)).toBeUndefined();
|
8844
8878
|
* context.name = 'Angular';
|
8845
|
-
* expect(exp(context
|
8879
|
+
* expect(exp(context)).toEqual('Hello Angular!');
|
8846
8880
|
* ```
|
8847
8881
|
*
|
8848
8882
|
* `allOrNothing` is useful for interpolating URLs. `ngSrc` and `ngSrcset` use this behavior.
|
@@ -8910,8 +8944,7 @@ function $InterpolateProvider() {
|
|
8910
8944
|
hasInterpolation = false,
|
8911
8945
|
hasText = false,
|
8912
8946
|
exp,
|
8913
|
-
concat = []
|
8914
|
-
lastValuesCache = { values: {}, results: {}};
|
8947
|
+
concat = [];
|
8915
8948
|
|
8916
8949
|
while(index < textLength) {
|
8917
8950
|
if ( ((startIndex = text.indexOf(startSymbol, index)) != -1) &&
|
@@ -8920,7 +8953,7 @@ function $InterpolateProvider() {
|
|
8920
8953
|
separators.push(text.substring(index, startIndex));
|
8921
8954
|
exp = text.substring(startIndex + startSymbolLength, endIndex);
|
8922
8955
|
expressions.push(exp);
|
8923
|
-
parseFns.push($parse(exp));
|
8956
|
+
parseFns.push($parse(exp, parseStringifyInterceptor));
|
8924
8957
|
index = endIndex + endSymbolLength;
|
8925
8958
|
hasInterpolation = true;
|
8926
8959
|
} else {
|
@@ -8961,6 +8994,7 @@ function $InterpolateProvider() {
|
|
8961
8994
|
|
8962
8995
|
var compute = function(values) {
|
8963
8996
|
for(var i = 0, ii = expressions.length; i < ii; i++) {
|
8997
|
+
if (allOrNothing && isUndefined(values[i])) return;
|
8964
8998
|
concat[2*i] = separators[i];
|
8965
8999
|
concat[(2*i)+1] = values[i];
|
8966
9000
|
}
|
@@ -8969,13 +9003,9 @@ function $InterpolateProvider() {
|
|
8969
9003
|
};
|
8970
9004
|
|
8971
9005
|
var getValue = function (value) {
|
8972
|
-
|
8973
|
-
|
8974
|
-
|
8975
|
-
value = $sce.valueOf(value);
|
8976
|
-
}
|
8977
|
-
|
8978
|
-
return value;
|
9006
|
+
return trustedContext ?
|
9007
|
+
$sce.getTrusted(trustedContext, value) :
|
9008
|
+
$sce.valueOf(value);
|
8979
9009
|
};
|
8980
9010
|
|
8981
9011
|
var stringify = function (value) {
|
@@ -8999,64 +9029,49 @@ function $InterpolateProvider() {
|
|
8999
9029
|
};
|
9000
9030
|
|
9001
9031
|
return extend(function interpolationFn(context) {
|
9002
|
-
var scopeId = (context && context.$id) || 'notAScope';
|
9003
|
-
var lastValues = lastValuesCache.values[scopeId];
|
9004
|
-
var lastResult = lastValuesCache.results[scopeId];
|
9005
9032
|
var i = 0;
|
9006
9033
|
var ii = expressions.length;
|
9007
9034
|
var values = new Array(ii);
|
9008
|
-
var val;
|
9009
|
-
var inputsChanged = lastResult === undefined ? true: false;
|
9010
|
-
|
9011
|
-
|
9012
|
-
// if we haven't seen this context before, initialize the cache and try to setup
|
9013
|
-
// a cleanup routine that purges the cache when the scope goes away.
|
9014
|
-
if (!lastValues) {
|
9015
|
-
lastValues = [];
|
9016
|
-
inputsChanged = true;
|
9017
|
-
if (context && context.$on) {
|
9018
|
-
context.$on('$destroy', function() {
|
9019
|
-
lastValuesCache.values[scopeId] = null;
|
9020
|
-
lastValuesCache.results[scopeId] = null;
|
9021
|
-
});
|
9022
|
-
}
|
9023
|
-
}
|
9024
|
-
|
9025
9035
|
|
9026
9036
|
try {
|
9027
|
-
interpolationFn.$$unwatch = true;
|
9028
9037
|
for (; i < ii; i++) {
|
9029
|
-
|
9030
|
-
if (allOrNothing && isUndefined(val)) {
|
9031
|
-
interpolationFn.$$unwatch = undefined;
|
9032
|
-
return;
|
9033
|
-
}
|
9034
|
-
val = stringify(val);
|
9035
|
-
if (val !== lastValues[i]) {
|
9036
|
-
inputsChanged = true;
|
9037
|
-
}
|
9038
|
-
values[i] = val;
|
9039
|
-
interpolationFn.$$unwatch = interpolationFn.$$unwatch && parseFns[i].$$unwatch;
|
9038
|
+
values[i] = parseFns[i](context);
|
9040
9039
|
}
|
9041
9040
|
|
9042
|
-
|
9043
|
-
lastValuesCache.values[scopeId] = values;
|
9044
|
-
lastValuesCache.results[scopeId] = lastResult = compute(values);
|
9045
|
-
}
|
9041
|
+
return compute(values);
|
9046
9042
|
} catch(err) {
|
9047
9043
|
var newErr = $interpolateMinErr('interr', "Can't interpolate: {0}\n{1}", text,
|
9048
9044
|
err.toString());
|
9049
9045
|
$exceptionHandler(newErr);
|
9050
9046
|
}
|
9051
9047
|
|
9052
|
-
return lastResult;
|
9053
9048
|
}, {
|
9054
9049
|
// all of these properties are undocumented for now
|
9055
9050
|
exp: text, //just for compatibility with regular watchers created via $watch
|
9056
9051
|
separators: separators,
|
9057
|
-
expressions: expressions
|
9052
|
+
expressions: expressions,
|
9053
|
+
$$watchDelegate: function (scope, listener, objectEquality, deregisterNotifier) {
|
9054
|
+
var lastValue;
|
9055
|
+
return scope.$watchGroup(parseFns, function interpolateFnWatcher(values, oldValues) {
|
9056
|
+
var currValue = compute(values);
|
9057
|
+
if (isFunction(listener)) {
|
9058
|
+
listener.call(this, currValue, values !== oldValues ? lastValue : currValue, scope);
|
9059
|
+
}
|
9060
|
+
lastValue = currValue;
|
9061
|
+
}, objectEquality, deregisterNotifier);
|
9062
|
+
}
|
9058
9063
|
});
|
9059
9064
|
}
|
9065
|
+
|
9066
|
+
function parseStringifyInterceptor(value) {
|
9067
|
+
try {
|
9068
|
+
return stringify(getValue(value));
|
9069
|
+
} catch(err) {
|
9070
|
+
var newErr = $interpolateMinErr('interr', "Can't interpolate: {0}\n{1}", text,
|
9071
|
+
err.toString());
|
9072
|
+
$exceptionHandler(newErr);
|
9073
|
+
}
|
9074
|
+
}
|
9060
9075
|
}
|
9061
9076
|
|
9062
9077
|
|
@@ -9177,7 +9192,7 @@ function $IntervalProvider() {
|
|
9177
9192
|
* // Make sure that the interval nis destroyed too
|
9178
9193
|
* $scope.stopFight();
|
9179
9194
|
* });
|
9180
|
-
* })
|
9195
|
+
* }])
|
9181
9196
|
* // Register the 'myCurrentTime' directive factory method.
|
9182
9197
|
* // We inject $interval and dateFilter service since the factory method is DI.
|
9183
9198
|
* .directive('myCurrentTime', ['$interval', 'dateFilter',
|
@@ -9206,7 +9221,7 @@ function $IntervalProvider() {
|
|
9206
9221
|
* $interval.cancel(stopTime);
|
9207
9222
|
* });
|
9208
9223
|
* }
|
9209
|
-
* });
|
9224
|
+
* }]);
|
9210
9225
|
* </script>
|
9211
9226
|
*
|
9212
9227
|
* <div>
|
@@ -10622,11 +10637,7 @@ Lexer.prototype = {
|
|
10622
10637
|
string += String.fromCharCode(parseInt(hex, 16));
|
10623
10638
|
} else {
|
10624
10639
|
var rep = ESCAPE[ch];
|
10625
|
-
|
10626
|
-
string += rep;
|
10627
|
-
} else {
|
10628
|
-
string += ch;
|
10629
|
-
}
|
10640
|
+
string = string + (rep || ch);
|
10630
10641
|
}
|
10631
10642
|
escape = false;
|
10632
10643
|
} else if (ch === '\\') {
|
@@ -11187,7 +11198,7 @@ function getterFn(path, options, fullExp) {
|
|
11187
11198
|
// we simply dereference 's' on any .dot notation
|
11188
11199
|
? 's'
|
11189
11200
|
// but if we are first then we check locals first, and if so read it first
|
11190
|
-
: '((k&&k.hasOwnProperty("' + key + '"))?k:s)') + '
|
11201
|
+
: '((k&&k.hasOwnProperty("' + key + '"))?k:s)') + '.' + key + ';\n';
|
11191
11202
|
});
|
11192
11203
|
code += 'return s;';
|
11193
11204
|
|
@@ -11269,69 +11280,89 @@ function $ParseProvider() {
|
|
11269
11280
|
this.$get = ['$filter', '$sniffer', function($filter, $sniffer) {
|
11270
11281
|
$parseOptions.csp = $sniffer.csp;
|
11271
11282
|
|
11272
|
-
return function(exp) {
|
11273
|
-
var parsedExpression,
|
11274
|
-
|
11283
|
+
return function(exp, interceptorFn) {
|
11284
|
+
var parsedExpression, oneTime,
|
11285
|
+
cacheKey = (exp = trim(exp));
|
11275
11286
|
|
11276
11287
|
switch (typeof exp) {
|
11277
11288
|
case 'string':
|
11289
|
+
if (cache.hasOwnProperty(cacheKey)) {
|
11290
|
+
parsedExpression = cache[cacheKey];
|
11291
|
+
} else {
|
11292
|
+
if (exp.charAt(0) === ':' && exp.charAt(1) === ':') {
|
11293
|
+
oneTime = true;
|
11294
|
+
exp = exp.substring(2);
|
11295
|
+
}
|
11278
11296
|
|
11279
|
-
|
11280
|
-
|
11281
|
-
|
11282
|
-
oneTime = true;
|
11283
|
-
exp = exp.substring(2);
|
11284
|
-
}
|
11285
|
-
|
11286
|
-
if (cache.hasOwnProperty(exp)) {
|
11287
|
-
return oneTime ? oneTimeWrapper(cache[exp]) : cache[exp];
|
11288
|
-
}
|
11297
|
+
var lexer = new Lexer($parseOptions);
|
11298
|
+
var parser = new Parser(lexer, $filter, $parseOptions);
|
11299
|
+
parsedExpression = parser.parse(exp);
|
11289
11300
|
|
11290
|
-
|
11291
|
-
|
11292
|
-
parsedExpression = parser.parse(exp);
|
11301
|
+
if (parsedExpression.constant) parsedExpression.$$watchDelegate = constantWatch;
|
11302
|
+
else if (oneTime) parsedExpression.$$watchDelegate = oneTimeWatch;
|
11293
11303
|
|
11294
|
-
|
11295
|
-
|
11296
|
-
|
11297
|
-
|
11304
|
+
if (cacheKey !== 'hasOwnProperty') {
|
11305
|
+
// Only cache the value if it's not going to mess up the cache object
|
11306
|
+
// This is more performant that using Object.prototype.hasOwnProperty.call
|
11307
|
+
cache[cacheKey] = parsedExpression;
|
11308
|
+
}
|
11298
11309
|
}
|
11299
|
-
|
11300
|
-
return oneTime || parsedExpression.constant ? oneTimeWrapper(parsedExpression) : parsedExpression;
|
11310
|
+
return addInterceptor(parsedExpression, interceptorFn);
|
11301
11311
|
|
11302
11312
|
case 'function':
|
11303
|
-
return exp;
|
11313
|
+
return addInterceptor(exp, interceptorFn);
|
11304
11314
|
|
11305
11315
|
default:
|
11306
|
-
return noop;
|
11316
|
+
return addInterceptor(noop, interceptorFn);
|
11307
11317
|
}
|
11318
|
+
};
|
11308
11319
|
|
11309
|
-
|
11310
|
-
|
11311
|
-
|
11312
|
-
|
11313
|
-
|
11314
|
-
|
11315
|
-
|
11316
|
-
|
11317
|
-
|
11318
|
-
|
11319
|
-
|
11320
|
-
|
11321
|
-
|
11322
|
-
self.$$postDigestQueue.push(function () {
|
11323
|
-
// create a copy if the value is defined and it is not a $sce value
|
11324
|
-
if ((stable = isDefined(lastValue)) &&
|
11325
|
-
(lastValue === null || !lastValue.$$unwrapTrustedValue)) {
|
11326
|
-
lastValue = copy(lastValue, null);
|
11327
|
-
}
|
11328
|
-
});
|
11320
|
+
function oneTimeWatch(scope, listener, objectEquality, deregisterNotifier, parsedExpression) {
|
11321
|
+
var unwatch, lastValue;
|
11322
|
+
return unwatch = scope.$watch(function oneTimeWatch(scope) {
|
11323
|
+
return parsedExpression(scope);
|
11324
|
+
}, function oneTimeListener(value, old, scope) {
|
11325
|
+
lastValue = value;
|
11326
|
+
if (isFunction(listener)) {
|
11327
|
+
listener.apply(this, arguments);
|
11328
|
+
}
|
11329
|
+
if (isDefined(value)) {
|
11330
|
+
scope.$$postDigest(function () {
|
11331
|
+
if (isDefined(lastValue)) {
|
11332
|
+
unwatch();
|
11329
11333
|
}
|
11330
|
-
}
|
11331
|
-
|
11334
|
+
});
|
11335
|
+
}
|
11336
|
+
}, objectEquality, deregisterNotifier);
|
11337
|
+
}
|
11338
|
+
|
11339
|
+
function constantWatch(scope, listener, objectEquality, deregisterNotifier, parsedExpression) {
|
11340
|
+
var unwatch;
|
11341
|
+
return unwatch = scope.$watch(function constantWatch(scope) {
|
11342
|
+
return parsedExpression(scope);
|
11343
|
+
}, function constantListener(value, old, scope) {
|
11344
|
+
if (isFunction(listener)) {
|
11345
|
+
listener.apply(this, arguments);
|
11332
11346
|
}
|
11347
|
+
unwatch();
|
11348
|
+
}, objectEquality, deregisterNotifier);
|
11349
|
+
}
|
11350
|
+
|
11351
|
+
function addInterceptor(parsedExpression, interceptorFn) {
|
11352
|
+
if (isFunction(interceptorFn)) {
|
11353
|
+
var fn = function interceptedExpression(scope, locals) {
|
11354
|
+
var value = parsedExpression(scope, locals);
|
11355
|
+
var result = interceptorFn(value, scope, locals);
|
11356
|
+
// we only return the interceptor's result if the
|
11357
|
+
// initial value is defined (for bind-once)
|
11358
|
+
return isDefined(value) ? result : value;
|
11359
|
+
};
|
11360
|
+
fn.$$watchDelegate = parsedExpression.$$watchDelegate;
|
11361
|
+
return fn;
|
11362
|
+
} else {
|
11363
|
+
return parsedExpression;
|
11333
11364
|
}
|
11334
|
-
}
|
11365
|
+
}
|
11335
11366
|
}];
|
11336
11367
|
}
|
11337
11368
|
|
@@ -11343,6 +11374,46 @@ function $ParseProvider() {
|
|
11343
11374
|
* @description
|
11344
11375
|
* A promise/deferred implementation inspired by [Kris Kowal's Q](https://github.com/kriskowal/q).
|
11345
11376
|
*
|
11377
|
+
* $q can be used in two fashions --- One, which is more similar to Kris Kowal's Q or jQuery's Deferred
|
11378
|
+
* implementations, the other resembles ES6 promises to some degree.
|
11379
|
+
*
|
11380
|
+
* # $q constructor
|
11381
|
+
*
|
11382
|
+
* The streamlined ES6 style promise is essentially just using $q as a constructor which takes a `resolver`
|
11383
|
+
* function as the first argument). This is similar to the native Promise implementation from ES6 Harmony,
|
11384
|
+
* see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).
|
11385
|
+
*
|
11386
|
+
* While the constructor-style use is supported, not all of the supporting methods from Harmony promises are
|
11387
|
+
* available yet.
|
11388
|
+
*
|
11389
|
+
* It can be used like so:
|
11390
|
+
*
|
11391
|
+
* ```js
|
11392
|
+
* return $q(function(resolve, reject) {
|
11393
|
+
* // perform some asynchronous operation, resolve or reject the promise when appropriate.
|
11394
|
+
* setInterval(function() {
|
11395
|
+
* if (pollStatus > 0) {
|
11396
|
+
* resolve(polledValue);
|
11397
|
+
* } else if (pollStatus < 0) {
|
11398
|
+
* reject(polledValue);
|
11399
|
+
* } else {
|
11400
|
+
* pollStatus = pollAgain(function(value) {
|
11401
|
+
* polledValue = value;
|
11402
|
+
* });
|
11403
|
+
* }
|
11404
|
+
* }, 10000);
|
11405
|
+
* }).
|
11406
|
+
* then(function(value) {
|
11407
|
+
* // handle success
|
11408
|
+
* }, function(reason) {
|
11409
|
+
* // handle failure
|
11410
|
+
* });
|
11411
|
+
* ```
|
11412
|
+
*
|
11413
|
+
* Note, progress/notify callbacks are not currently supported via the ES6-style interface.
|
11414
|
+
*
|
11415
|
+
* However, the more traditional CommonJS style usage is still available, and documented below.
|
11416
|
+
*
|
11346
11417
|
* [The CommonJS Promise proposal](http://wiki.commonjs.org/wiki/Promises) describes a promise as an
|
11347
11418
|
* interface for interacting with an object that represents the result of an action that is
|
11348
11419
|
* performed asynchronously, and may or may not be finished at any given point in time.
|
@@ -11389,7 +11460,6 @@ function $ParseProvider() {
|
|
11389
11460
|
* For more on this please see the [Q documentation](https://github.com/kriskowal/q) especially the
|
11390
11461
|
* section on serial or parallel joining of promises.
|
11391
11462
|
*
|
11392
|
-
*
|
11393
11463
|
* # The Deferred API
|
11394
11464
|
*
|
11395
11465
|
* A new instance of deferred is constructed by calling `$q.defer()`.
|
@@ -11498,6 +11568,12 @@ function $ParseProvider() {
|
|
11498
11568
|
* expect(resolvedValue).toEqual(123);
|
11499
11569
|
* }));
|
11500
11570
|
* ```
|
11571
|
+
*
|
11572
|
+
* @param {function(function, function)} resolver Function which is responsible for resolving or
|
11573
|
+
* rejecting the newly created promise. The first parameteter is a function which resolves the
|
11574
|
+
* promise, the second parameter is a function which rejects the promise.
|
11575
|
+
*
|
11576
|
+
* @returns {Promise} The newly created promise.
|
11501
11577
|
*/
|
11502
11578
|
function $QProvider() {
|
11503
11579
|
|
@@ -11645,7 +11721,7 @@ function qFactory(nextTick, exceptionHandler) {
|
|
11645
11721
|
} catch(e) {
|
11646
11722
|
return makePromise(e, false);
|
11647
11723
|
}
|
11648
|
-
if (
|
11724
|
+
if (isPromiseLike(callbackOutput)) {
|
11649
11725
|
return callbackOutput.then(function() {
|
11650
11726
|
return makePromise(value, isResolved);
|
11651
11727
|
}, function(error) {
|
@@ -11670,7 +11746,7 @@ function qFactory(nextTick, exceptionHandler) {
|
|
11670
11746
|
|
11671
11747
|
|
11672
11748
|
var ref = function(value) {
|
11673
|
-
if (
|
11749
|
+
if (isPromiseLike(value)) return value;
|
11674
11750
|
return {
|
11675
11751
|
then: function(callback) {
|
11676
11752
|
var result = defer();
|
@@ -11854,12 +11930,38 @@ function qFactory(nextTick, exceptionHandler) {
|
|
11854
11930
|
return deferred.promise;
|
11855
11931
|
}
|
11856
11932
|
|
11857
|
-
|
11858
|
-
|
11859
|
-
|
11860
|
-
|
11861
|
-
|
11933
|
+
var $Q = function Q(resolver) {
|
11934
|
+
if (!isFunction(resolver)) {
|
11935
|
+
// TODO(@caitp): minErr this
|
11936
|
+
throw new TypeError('Expected resolverFn');
|
11937
|
+
}
|
11938
|
+
|
11939
|
+
if (!(this instanceof Q)) {
|
11940
|
+
// More useful when $Q is the Promise itself.
|
11941
|
+
return new Q(resolver);
|
11942
|
+
}
|
11943
|
+
|
11944
|
+
var deferred = defer();
|
11945
|
+
|
11946
|
+
function resolveFn(value) {
|
11947
|
+
deferred.resolve(value);
|
11948
|
+
}
|
11949
|
+
|
11950
|
+
function rejectFn(reason) {
|
11951
|
+
deferred.reject(reason);
|
11952
|
+
}
|
11953
|
+
|
11954
|
+
resolver(resolveFn, rejectFn);
|
11955
|
+
|
11956
|
+
return deferred.promise;
|
11862
11957
|
};
|
11958
|
+
|
11959
|
+
$Q.defer = defer;
|
11960
|
+
$Q.reject = reject;
|
11961
|
+
$Q.when = when;
|
11962
|
+
$Q.all = all;
|
11963
|
+
|
11964
|
+
return $Q;
|
11863
11965
|
}
|
11864
11966
|
|
11865
11967
|
function $$RAFProvider(){ //rAF
|
@@ -12209,20 +12311,25 @@ function $RootScopeProvider(){
|
|
12209
12311
|
*
|
12210
12312
|
* - `string`: Evaluated as {@link guide/expression expression}
|
12211
12313
|
* - `function(scope)`: called with current `scope` as a parameter.
|
12212
|
-
* @param {
|
12213
|
-
*
|
12214
|
-
*
|
12215
|
-
* - `string`: Evaluated as {@link guide/expression expression}
|
12216
|
-
* - `function(newValue, oldValue, scope)`: called with current and previous values as
|
12217
|
-
* parameters.
|
12314
|
+
* @param {function(newVal, oldVal, scope)} listener Callback called whenever the value
|
12315
|
+
* of `watchExpression` changes.
|
12218
12316
|
*
|
12317
|
+
* - `newVal` contains the current value of the `watchExpression`
|
12318
|
+
* - `oldVal` contains the previous value of the `watchExpression`
|
12319
|
+
* - `scope` refers to the current scope
|
12219
12320
|
* @param {boolean=} objectEquality Compare for object equality using {@link angular.equals} instead of
|
12220
12321
|
* comparing for reference equality.
|
12322
|
+
* @param {function()=} deregisterNotifier Function to call when the deregistration function
|
12323
|
+
* get called.
|
12221
12324
|
* @returns {function()} Returns a deregistration function for this listener.
|
12222
12325
|
*/
|
12223
|
-
$watch: function(watchExp, listener, objectEquality) {
|
12326
|
+
$watch: function(watchExp, listener, objectEquality, deregisterNotifier) {
|
12327
|
+
var get = compileToFn(watchExp, 'watch');
|
12328
|
+
|
12329
|
+
if (get.$$watchDelegate) {
|
12330
|
+
return get.$$watchDelegate(this, listener, objectEquality, deregisterNotifier, get);
|
12331
|
+
}
|
12224
12332
|
var scope = this,
|
12225
|
-
get = compileToFn(watchExp, 'watch'),
|
12226
12333
|
array = scope.$$watchers,
|
12227
12334
|
watcher = {
|
12228
12335
|
fn: listener,
|
@@ -12234,10 +12341,8 @@ function $RootScopeProvider(){
|
|
12234
12341
|
|
12235
12342
|
lastDirtyWatch = null;
|
12236
12343
|
|
12237
|
-
// in the case user pass string, we need to compile it, do we really need this ?
|
12238
12344
|
if (!isFunction(listener)) {
|
12239
|
-
|
12240
|
-
watcher.fn = function(newVal, oldVal, scope) {listenFn(scope);};
|
12345
|
+
watcher.fn = noop;
|
12241
12346
|
}
|
12242
12347
|
|
12243
12348
|
if (!array) {
|
@@ -12250,6 +12355,9 @@ function $RootScopeProvider(){
|
|
12250
12355
|
return function deregisterWatch() {
|
12251
12356
|
arrayRemove(array, watcher);
|
12252
12357
|
lastDirtyWatch = null;
|
12358
|
+
if (isFunction(deregisterNotifier)) {
|
12359
|
+
deregisterNotifier();
|
12360
|
+
}
|
12253
12361
|
};
|
12254
12362
|
},
|
12255
12363
|
|
@@ -12276,7 +12384,6 @@ function $RootScopeProvider(){
|
|
12276
12384
|
* and the `oldValues` array contains the previous values of the `watchExpressions`, with the indexes matching
|
12277
12385
|
* those of `watchExpression`
|
12278
12386
|
* The `scope` refers to the current scope.
|
12279
|
-
*
|
12280
12387
|
* @returns {function()} Returns a de-registration function for all listeners.
|
12281
12388
|
*/
|
12282
12389
|
$watchGroup: function(watchExpressions, listener) {
|
@@ -12285,37 +12392,43 @@ function $RootScopeProvider(){
|
|
12285
12392
|
var deregisterFns = [];
|
12286
12393
|
var changeCount = 0;
|
12287
12394
|
var self = this;
|
12288
|
-
var
|
12289
|
-
|
12395
|
+
var masterUnwatch;
|
12396
|
+
|
12397
|
+
if (watchExpressions.length === 1) {
|
12398
|
+
// Special case size of one
|
12399
|
+
return this.$watch(watchExpressions[0], function watchGroupAction(value, oldValue, scope) {
|
12400
|
+
newValues[0] = value;
|
12401
|
+
oldValues[0] = oldValue;
|
12402
|
+
listener.call(this, newValues, (value === oldValue) ? newValues : oldValues, scope);
|
12403
|
+
});
|
12404
|
+
}
|
12290
12405
|
|
12291
12406
|
forEach(watchExpressions, function (expr, i) {
|
12292
|
-
var
|
12293
|
-
deregisterFns.push(self.$watch(exprFn, function (value, oldValue) {
|
12407
|
+
var unwatch = self.$watch(expr, function watchGroupSubAction(value, oldValue) {
|
12294
12408
|
newValues[i] = value;
|
12295
12409
|
oldValues[i] = oldValue;
|
12296
12410
|
changeCount++;
|
12297
|
-
|
12298
|
-
|
12299
|
-
|
12300
|
-
|
12411
|
+
}, false, function watchGroupDeregNotifier() {
|
12412
|
+
arrayRemove(deregisterFns, unwatch);
|
12413
|
+
if (!deregisterFns.length) {
|
12414
|
+
masterUnwatch();
|
12415
|
+
}
|
12416
|
+
});
|
12417
|
+
|
12418
|
+
deregisterFns.push(unwatch);
|
12301
12419
|
}, this);
|
12302
12420
|
|
12303
|
-
|
12304
|
-
|
12305
|
-
|
12306
|
-
|
12307
|
-
|
12308
|
-
watchGroupFn.$$unwatch = false;
|
12309
|
-
}
|
12310
|
-
}));
|
12421
|
+
masterUnwatch = self.$watch(function watchGroupChangeWatch() {
|
12422
|
+
return changeCount;
|
12423
|
+
}, function watchGroupChangeAction(value, oldValue) {
|
12424
|
+
listener(newValues, (value === oldValue) ? newValues : oldValues, self);
|
12425
|
+
});
|
12311
12426
|
|
12312
12427
|
return function deregisterWatchGroup() {
|
12313
|
-
|
12314
|
-
|
12315
|
-
}
|
12428
|
+
while (deregisterFns.length) {
|
12429
|
+
deregisterFns[0]();
|
12430
|
+
}
|
12316
12431
|
};
|
12317
|
-
|
12318
|
-
function watchGroupFn() {return changeCount;}
|
12319
12432
|
},
|
12320
12433
|
|
12321
12434
|
|
@@ -12386,15 +12499,15 @@ function $RootScopeProvider(){
|
|
12386
12499
|
// only track veryOldValue if the listener is asking for it
|
12387
12500
|
var trackVeryOldValue = (listener.length > 1);
|
12388
12501
|
var changeDetected = 0;
|
12389
|
-
var
|
12502
|
+
var changeDetector = $parse(obj, $watchCollectionInterceptor);
|
12390
12503
|
var internalArray = [];
|
12391
12504
|
var internalObject = {};
|
12392
12505
|
var initRun = true;
|
12393
12506
|
var oldLength = 0;
|
12394
12507
|
|
12395
|
-
function $
|
12396
|
-
newValue =
|
12397
|
-
var newLength, key;
|
12508
|
+
function $watchCollectionInterceptor(_value) {
|
12509
|
+
newValue = _value;
|
12510
|
+
var newLength, key, bothNaN;
|
12398
12511
|
|
12399
12512
|
if (!isObject(newValue)) { // if primitive
|
12400
12513
|
if (oldValue !== newValue) {
|
@@ -12418,7 +12531,7 @@ function $RootScopeProvider(){
|
|
12418
12531
|
}
|
12419
12532
|
// copy the items to oldValue and look for changes.
|
12420
12533
|
for (var i = 0; i < newLength; i++) {
|
12421
|
-
|
12534
|
+
bothNaN = (oldValue[i] !== oldValue[i]) &&
|
12422
12535
|
(newValue[i] !== newValue[i]);
|
12423
12536
|
if (!bothNaN && (oldValue[i] !== newValue[i])) {
|
12424
12537
|
changeDetected++;
|
@@ -12438,7 +12551,9 @@ function $RootScopeProvider(){
|
|
12438
12551
|
if (newValue.hasOwnProperty(key)) {
|
12439
12552
|
newLength++;
|
12440
12553
|
if (oldValue.hasOwnProperty(key)) {
|
12441
|
-
|
12554
|
+
bothNaN = (oldValue[key] !== oldValue[key]) &&
|
12555
|
+
(newValue[key] !== newValue[key]);
|
12556
|
+
if (!bothNaN && (oldValue[key] !== newValue[key])) {
|
12442
12557
|
changeDetected++;
|
12443
12558
|
oldValue[key] = newValue[key];
|
12444
12559
|
}
|
@@ -12460,7 +12575,6 @@ function $RootScopeProvider(){
|
|
12460
12575
|
}
|
12461
12576
|
}
|
12462
12577
|
}
|
12463
|
-
$watchCollectionWatch.$$unwatch = objGetter.$$unwatch;
|
12464
12578
|
return changeDetected;
|
12465
12579
|
}
|
12466
12580
|
|
@@ -12493,7 +12607,7 @@ function $RootScopeProvider(){
|
|
12493
12607
|
}
|
12494
12608
|
}
|
12495
12609
|
|
12496
|
-
return this.$watch(
|
12610
|
+
return this.$watch(changeDetector, $watchCollectionAction);
|
12497
12611
|
},
|
12498
12612
|
|
12499
12613
|
/**
|
@@ -12556,7 +12670,6 @@ function $RootScopeProvider(){
|
|
12556
12670
|
dirty, ttl = TTL,
|
12557
12671
|
next, current, target = this,
|
12558
12672
|
watchLog = [],
|
12559
|
-
stableWatchesCandidates = [],
|
12560
12673
|
logIdx, logMsg, asyncTask;
|
12561
12674
|
|
12562
12675
|
beginPhase('$digest');
|
@@ -12607,7 +12720,6 @@ function $RootScopeProvider(){
|
|
12607
12720
|
logMsg += '; newVal: ' + toJson(value) + '; oldVal: ' + toJson(last);
|
12608
12721
|
watchLog[logIdx].push(logMsg);
|
12609
12722
|
}
|
12610
|
-
if (watch.get.$$unwatch) stableWatchesCandidates.push({watch: watch, array: watchers});
|
12611
12723
|
} else if (watch === lastDirtyWatch) {
|
12612
12724
|
// If the most recently dirty watcher is now clean, short circuit since the remaining watchers
|
12613
12725
|
// have already been tested.
|
@@ -12654,13 +12766,6 @@ function $RootScopeProvider(){
|
|
12654
12766
|
$exceptionHandler(e);
|
12655
12767
|
}
|
12656
12768
|
}
|
12657
|
-
|
12658
|
-
for (length = stableWatchesCandidates.length - 1; length >= 0; --length) {
|
12659
|
-
var candidate = stableWatchesCandidates[length];
|
12660
|
-
if (candidate.watch.get.$$unwatch) {
|
12661
|
-
arrayRemove(candidate.array, candidate.watch);
|
12662
|
-
}
|
12663
|
-
}
|
12664
12769
|
},
|
12665
12770
|
|
12666
12771
|
|
@@ -13975,11 +14080,9 @@ function $SceProvider() {
|
|
13975
14080
|
if (parsed.literal && parsed.constant) {
|
13976
14081
|
return parsed;
|
13977
14082
|
} else {
|
13978
|
-
return function
|
13979
|
-
|
13980
|
-
|
13981
|
-
return result;
|
13982
|
-
};
|
14083
|
+
return $parse(expr, function (value) {
|
14084
|
+
return sce.getTrusted(type, value);
|
14085
|
+
});
|
13983
14086
|
}
|
13984
14087
|
};
|
13985
14088
|
|
@@ -15372,11 +15475,7 @@ function dateFilter($locale) {
|
|
15372
15475
|
format = format || 'mediumDate';
|
15373
15476
|
format = $locale.DATETIME_FORMATS[format] || format;
|
15374
15477
|
if (isString(date)) {
|
15375
|
-
|
15376
|
-
date = int(date);
|
15377
|
-
} else {
|
15378
|
-
date = jsonStringToDate(date);
|
15379
|
-
}
|
15478
|
+
date = NUMBER_STRING.test(date) ? int(date) : jsonStringToDate(date);
|
15380
15479
|
}
|
15381
15480
|
|
15382
15481
|
if (isNumber(date)) {
|
@@ -15651,7 +15750,7 @@ function limitToFilter(){
|
|
15651
15750
|
* @example
|
15652
15751
|
<example module="orderByExample">
|
15653
15752
|
<file name="index.html">
|
15654
|
-
<div ng-controller="
|
15753
|
+
<div ng-controller="ExampleController">
|
15655
15754
|
<table class="friend">
|
15656
15755
|
<tr>
|
15657
15756
|
<th><a href="" ng-click="reverse=false;order('name', false)">Name</a>
|
@@ -15732,6 +15831,10 @@ function orderByFilter($parse){
|
|
15732
15831
|
var t1 = typeof v1;
|
15733
15832
|
var t2 = typeof v2;
|
15734
15833
|
if (t1 == t2) {
|
15834
|
+
if (isDate(v1) && isDate(v2)) {
|
15835
|
+
v1 = v1.valueOf();
|
15836
|
+
v2 = v2.valueOf();
|
15837
|
+
}
|
15735
15838
|
if (t1 == "string") {
|
15736
15839
|
v1 = v1.toLowerCase();
|
15737
15840
|
v2 = v2.toLowerCase();
|
@@ -16154,6 +16257,7 @@ forEach(BOOLEAN_ATTR, function(propName, attrName) {
|
|
16154
16257
|
var normalized = directiveNormalize('ng-' + attrName);
|
16155
16258
|
ngAttributeAliasDirectives[normalized] = function() {
|
16156
16259
|
return {
|
16260
|
+
restrict: 'A',
|
16157
16261
|
priority: 100,
|
16158
16262
|
link: function(scope, element, attr) {
|
16159
16263
|
scope.$watch(attr[normalized], function ngBooleanAttrWatchAction(value) {
|
@@ -16206,8 +16310,12 @@ forEach(['src', 'srcset', 'href'], function(attrName) {
|
|
16206
16310
|
}
|
16207
16311
|
|
16208
16312
|
attr.$observe(normalized, function(value) {
|
16209
|
-
if (!value)
|
16210
|
-
|
16313
|
+
if (!value) {
|
16314
|
+
if (attrName === 'href') {
|
16315
|
+
attr.$set(name, null);
|
16316
|
+
}
|
16317
|
+
return;
|
16318
|
+
}
|
16211
16319
|
|
16212
16320
|
attr.$set(name, value);
|
16213
16321
|
|
@@ -16795,7 +16903,9 @@ var inputType = {
|
|
16795
16903
|
* @description
|
16796
16904
|
* Input with date validation and transformation. In browsers that do not yet support
|
16797
16905
|
* the HTML5 date input, a text element will be used. In that case, text must be entered in a valid ISO-8601
|
16798
|
-
* date format (yyyy-MM-dd), for example: `2009-01-06`.
|
16906
|
+
* date format (yyyy-MM-dd), for example: `2009-01-06`. Since many
|
16907
|
+
* modern browsers do not yet support this input type, it is important to provide cues to users on the
|
16908
|
+
* expected input format via a placeholder or label. The model must always be a Date object.
|
16799
16909
|
*
|
16800
16910
|
* @param {string} ngModel Assignable angular expression to data-bind to.
|
16801
16911
|
* @param {string=} name Property name of the form under which the control is published.
|
@@ -18838,6 +18948,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
18838
18948
|
*/
|
18839
18949
|
var ngModelDirective = function() {
|
18840
18950
|
return {
|
18951
|
+
restrict: 'A',
|
18841
18952
|
require: ['ngModel', '^?form', '^?ngModelOptions'],
|
18842
18953
|
controller: NgModelController,
|
18843
18954
|
link: {
|
@@ -18939,6 +19050,7 @@ var ngModelDirective = function() {
|
|
18939
19050
|
* </example>
|
18940
19051
|
*/
|
18941
19052
|
var ngChangeDirective = valueFn({
|
19053
|
+
restrict: 'A',
|
18942
19054
|
require: 'ngModel',
|
18943
19055
|
link: function(scope, element, attr, ctrl) {
|
18944
19056
|
ctrl.$viewChangeListeners.push(function() {
|
@@ -18950,6 +19062,7 @@ var ngChangeDirective = valueFn({
|
|
18950
19062
|
|
18951
19063
|
var requiredDirective = function() {
|
18952
19064
|
return {
|
19065
|
+
restrict: 'A',
|
18953
19066
|
require: '?ngModel',
|
18954
19067
|
link: function(scope, elm, attr, ctrl) {
|
18955
19068
|
if (!ctrl) return;
|
@@ -18969,6 +19082,7 @@ var requiredDirective = function() {
|
|
18969
19082
|
|
18970
19083
|
var patternDirective = function() {
|
18971
19084
|
return {
|
19085
|
+
restrict: 'A',
|
18972
19086
|
require: '?ngModel',
|
18973
19087
|
link: function(scope, elm, attr, ctrl) {
|
18974
19088
|
if (!ctrl) return;
|
@@ -18999,6 +19113,7 @@ var patternDirective = function() {
|
|
18999
19113
|
|
19000
19114
|
var maxlengthDirective = function() {
|
19001
19115
|
return {
|
19116
|
+
restrict: 'A',
|
19002
19117
|
require: '?ngModel',
|
19003
19118
|
link: function(scope, elm, attr, ctrl) {
|
19004
19119
|
if (!ctrl) return;
|
@@ -19017,6 +19132,7 @@ var maxlengthDirective = function() {
|
|
19017
19132
|
|
19018
19133
|
var minlengthDirective = function() {
|
19019
19134
|
return {
|
19135
|
+
restrict: 'A',
|
19020
19136
|
require: '?ngModel',
|
19021
19137
|
link: function(scope, elm, attr, ctrl) {
|
19022
19138
|
if (!ctrl) return;
|
@@ -19039,62 +19155,93 @@ var minlengthDirective = function() {
|
|
19039
19155
|
* @name ngList
|
19040
19156
|
*
|
19041
19157
|
* @description
|
19042
|
-
* Text input that converts between a delimited string and an array of strings. The
|
19043
|
-
*
|
19158
|
+
* Text input that converts between a delimited string and an array of strings. The default
|
19159
|
+
* delimiter is a comma followed by a space - equivalent to `ng-list=", "`. You can specify a custom
|
19160
|
+
* delimiter as the value of the `ngList` attribute - for example, `ng-list=" | "`.
|
19161
|
+
*
|
19162
|
+
* The behaviour of the directive is affected by the use of the `ngTrim` attribute.
|
19163
|
+
* * If `ngTrim` is set to `"false"` then whitespace around both the separator and each
|
19164
|
+
* list item is respected. This implies that the user of the directive is responsible for
|
19165
|
+
* dealing with whitespace but also allows you to use whitespace as a delimiter, such as a
|
19166
|
+
* tab or newline character.
|
19167
|
+
* * Otherwise whitespace around the delimiter is ignored when splitting (although it is respected
|
19168
|
+
* when joining the list items back together) and whitespace around each list item is stripped
|
19169
|
+
* before it is added to the model.
|
19170
|
+
*
|
19171
|
+
* ### Example with Validation
|
19172
|
+
*
|
19173
|
+
* <example name="ngList-directive" module="listExample">
|
19174
|
+
* <file name="app.js">
|
19175
|
+
* angular.module('listExample', [])
|
19176
|
+
* .controller('ExampleController', ['$scope', function($scope) {
|
19177
|
+
* $scope.names = ['morpheus', 'neo', 'trinity'];
|
19178
|
+
* }]);
|
19179
|
+
* </file>
|
19180
|
+
* <file name="index.html">
|
19181
|
+
* <form name="myForm" ng-controller="ExampleController">
|
19182
|
+
* List: <input name="namesInput" ng-model="names" ng-list required>
|
19183
|
+
* <span class="error" ng-show="myForm.namesInput.$error.required">
|
19184
|
+
* Required!</span>
|
19185
|
+
* <br>
|
19186
|
+
* <tt>names = {{names}}</tt><br/>
|
19187
|
+
* <tt>myForm.namesInput.$valid = {{myForm.namesInput.$valid}}</tt><br/>
|
19188
|
+
* <tt>myForm.namesInput.$error = {{myForm.namesInput.$error}}</tt><br/>
|
19189
|
+
* <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
|
19190
|
+
* <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
|
19191
|
+
* </form>
|
19192
|
+
* </file>
|
19193
|
+
* <file name="protractor.js" type="protractor">
|
19194
|
+
* var listInput = element(by.model('names'));
|
19195
|
+
* var names = element(by.binding('{{names}}'));
|
19196
|
+
* var valid = element(by.binding('myForm.namesInput.$valid'));
|
19197
|
+
* var error = element(by.css('span.error'));
|
19198
|
+
*
|
19199
|
+
* it('should initialize to model', function() {
|
19200
|
+
* expect(names.getText()).toContain('["morpheus","neo","trinity"]');
|
19201
|
+
* expect(valid.getText()).toContain('true');
|
19202
|
+
* expect(error.getCssValue('display')).toBe('none');
|
19203
|
+
* });
|
19044
19204
|
*
|
19045
|
-
*
|
19046
|
-
*
|
19047
|
-
*
|
19205
|
+
* it('should be invalid if empty', function() {
|
19206
|
+
* listInput.clear();
|
19207
|
+
* listInput.sendKeys('');
|
19048
19208
|
*
|
19049
|
-
*
|
19050
|
-
|
19051
|
-
|
19052
|
-
|
19053
|
-
|
19054
|
-
|
19055
|
-
|
19056
|
-
|
19057
|
-
|
19058
|
-
|
19059
|
-
|
19060
|
-
|
19061
|
-
|
19062
|
-
|
19063
|
-
|
19064
|
-
|
19065
|
-
|
19066
|
-
|
19067
|
-
|
19068
|
-
|
19069
|
-
|
19070
|
-
|
19071
|
-
|
19072
|
-
|
19073
|
-
|
19074
|
-
var error = element(by.css('span.error'));
|
19075
|
-
|
19076
|
-
it('should initialize to model', function() {
|
19077
|
-
expect(names.getText()).toContain('["igor","misko","vojta"]');
|
19078
|
-
expect(valid.getText()).toContain('true');
|
19079
|
-
expect(error.getCssValue('display')).toBe('none');
|
19080
|
-
});
|
19081
|
-
|
19082
|
-
it('should be invalid if empty', function() {
|
19083
|
-
listInput.clear();
|
19084
|
-
listInput.sendKeys('');
|
19085
|
-
|
19086
|
-
expect(names.getText()).toContain('');
|
19087
|
-
expect(valid.getText()).toContain('false');
|
19088
|
-
expect(error.getCssValue('display')).not.toBe('none'); });
|
19089
|
-
</file>
|
19090
|
-
</example>
|
19209
|
+
* expect(names.getText()).toContain('');
|
19210
|
+
* expect(valid.getText()).toContain('false');
|
19211
|
+
* expect(error.getCssValue('display')).not.toBe('none');
|
19212
|
+
* });
|
19213
|
+
* </file>
|
19214
|
+
* </example>
|
19215
|
+
*
|
19216
|
+
* ### Example - splitting on whitespace
|
19217
|
+
* <example name="ngList-directive-newlines">
|
19218
|
+
* <file name="index.html">
|
19219
|
+
* <textarea ng-model="list" ng-list=" " ng-trim="false"></textarea>
|
19220
|
+
* <pre>{{ list | json }}</pre>
|
19221
|
+
* </file>
|
19222
|
+
* <file name="protractor.js" type="protractor">
|
19223
|
+
* it("should split the text by newlines", function() {
|
19224
|
+
* var listInput = element(by.model('list'));
|
19225
|
+
* var output = element(by.binding('{{ list | json }}'));
|
19226
|
+
* listInput.sendKeys('abc\ndef\nghi');
|
19227
|
+
* expect(output.getText()).toContain('[\n "abc",\n "def",\n "ghi"\n]');
|
19228
|
+
* });
|
19229
|
+
* </file>
|
19230
|
+
* </example>
|
19231
|
+
*
|
19232
|
+
* @element input
|
19233
|
+
* @param {string=} ngList optional delimiter that should be used to split the value.
|
19091
19234
|
*/
|
19092
19235
|
var ngListDirective = function() {
|
19093
19236
|
return {
|
19237
|
+
restrict: 'A',
|
19094
19238
|
require: 'ngModel',
|
19095
19239
|
link: function(scope, element, attr, ctrl) {
|
19096
|
-
|
19097
|
-
|
19240
|
+
// We want to control whitespace trimming so we use this convoluted approach
|
19241
|
+
// to access the ngList attribute, which doesn't pre-trim the attribute
|
19242
|
+
var ngList = element.attr(attr.$attr.ngList) || ', ';
|
19243
|
+
var trimValues = attr.ngTrim !== 'false';
|
19244
|
+
var separator = trimValues ? trim(ngList) : ngList;
|
19098
19245
|
|
19099
19246
|
var parse = function(viewValue) {
|
19100
19247
|
// If the viewValue is invalid (say required but empty) it will be `undefined`
|
@@ -19104,7 +19251,7 @@ var ngListDirective = function() {
|
|
19104
19251
|
|
19105
19252
|
if (viewValue) {
|
19106
19253
|
forEach(viewValue.split(separator), function(value) {
|
19107
|
-
if (value) list.push(trim(value));
|
19254
|
+
if (value) list.push(trimValues ? trim(value) : value);
|
19108
19255
|
});
|
19109
19256
|
}
|
19110
19257
|
|
@@ -19114,7 +19261,7 @@ var ngListDirective = function() {
|
|
19114
19261
|
ctrl.$parsers.push(parse);
|
19115
19262
|
ctrl.$formatters.push(function(value) {
|
19116
19263
|
if (isArray(value)) {
|
19117
|
-
return value.join(
|
19264
|
+
return value.join(ngList);
|
19118
19265
|
}
|
19119
19266
|
|
19120
19267
|
return undefined;
|
@@ -19184,6 +19331,7 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
|
|
19184
19331
|
*/
|
19185
19332
|
var ngValueDirective = function() {
|
19186
19333
|
return {
|
19334
|
+
restrict: 'A',
|
19187
19335
|
priority: 100,
|
19188
19336
|
compile: function(tpl, tplAttr) {
|
19189
19337
|
if (CONSTANT_VALUE_REGEXP.test(tplAttr.ngValue)) {
|
@@ -19346,6 +19494,7 @@ var ngValueDirective = function() {
|
|
19346
19494
|
*/
|
19347
19495
|
var ngModelOptionsDirective = function() {
|
19348
19496
|
return {
|
19497
|
+
restrict: 'A',
|
19349
19498
|
controller: ['$scope', '$attrs', function($scope, $attrs) {
|
19350
19499
|
var that = this;
|
19351
19500
|
this.$options = $scope.$eval($attrs.ngModelOptions);
|
@@ -19377,7 +19526,7 @@ var ngModelOptionsDirective = function() {
|
|
19377
19526
|
* Typically, you don't use `ngBind` directly, but instead you use the double curly markup like
|
19378
19527
|
* `{{ expression }}` which is similar but less verbose.
|
19379
19528
|
*
|
19380
|
-
* It is preferable to use `ngBind` instead of `{{ expression }}`
|
19529
|
+
* It is preferable to use `ngBind` instead of `{{ expression }}` if a template is momentarily
|
19381
19530
|
* displayed by the browser in its raw state before Angular compiles it. Since `ngBind` is an
|
19382
19531
|
* element attribute, it makes the bindings invisible to the user while the page is loading.
|
19383
19532
|
*
|
@@ -19541,19 +19690,25 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
|
|
19541
19690
|
</example>
|
19542
19691
|
*/
|
19543
19692
|
var ngBindHtmlDirective = ['$sce', '$parse', function($sce, $parse) {
|
19544
|
-
return
|
19545
|
-
|
19693
|
+
return {
|
19694
|
+
restrict: 'A',
|
19695
|
+
compile: function (tElement, tAttrs) {
|
19696
|
+
tElement.addClass('ng-binding');
|
19546
19697
|
|
19547
|
-
|
19548
|
-
|
19549
|
-
|
19550
|
-
|
19551
|
-
|
19552
|
-
|
19698
|
+
return function (scope, element, attr) {
|
19699
|
+
element.data('$binding', attr.ngBindHtml);
|
19700
|
+
var parsed = $parse(attr.ngBindHtml);
|
19701
|
+
var changeDetector = $parse(attr.ngBindHtml, function getStringValue(value) {
|
19702
|
+
return (value || '').toString();
|
19703
|
+
});
|
19553
19704
|
|
19554
|
-
|
19555
|
-
|
19556
|
-
|
19705
|
+
scope.$watch(changeDetector, function ngBindHtmlWatchAction() {
|
19706
|
+
// we re-evaluate the expr because we want a TrustedValueHolderType
|
19707
|
+
// for $sce, not a string
|
19708
|
+
element.html($sce.getTrustedHtml(parsed(scope)) || '');
|
19709
|
+
});
|
19710
|
+
};
|
19711
|
+
}
|
19557
19712
|
};
|
19558
19713
|
}];
|
19559
19714
|
|
@@ -20199,6 +20354,7 @@ var ngCloakDirective = ngDirective({
|
|
20199
20354
|
*/
|
20200
20355
|
var ngControllerDirective = [function() {
|
20201
20356
|
return {
|
20357
|
+
restrict: 'A',
|
20202
20358
|
scope: true,
|
20203
20359
|
controller: '@',
|
20204
20360
|
priority: 500
|
@@ -20216,8 +20372,10 @@ var ngControllerDirective = [function() {
|
|
20216
20372
|
* This is necessary when developing things like Google Chrome Extensions.
|
20217
20373
|
*
|
20218
20374
|
* CSP forbids apps to use `eval` or `Function(string)` generated functions (among other things).
|
20219
|
-
* For
|
20220
|
-
*
|
20375
|
+
* For Angular to be CSP compatible there are only two things that we need to do differently:
|
20376
|
+
*
|
20377
|
+
* - don't use `Function` constructor to generate optimized value getters
|
20378
|
+
* - don't inject custom stylesheet into the document
|
20221
20379
|
*
|
20222
20380
|
* AngularJS uses `Function(string)` generated functions as a speed optimization. Applying the `ngCsp`
|
20223
20381
|
* directive will cause Angular to use CSP compatibility mode. When this mode is on AngularJS will
|
@@ -20228,7 +20386,18 @@ var ngControllerDirective = [function() {
|
|
20228
20386
|
* includes some CSS rules (e.g. {@link ng.directive:ngCloak ngCloak}).
|
20229
20387
|
* To make those directives work in CSP mode, include the `angular-csp.css` manually.
|
20230
20388
|
*
|
20231
|
-
*
|
20389
|
+
* Angular tries to autodetect if CSP is active and automatically turn on the CSP-safe mode. This
|
20390
|
+
* autodetection however triggers a CSP error to be logged in the console:
|
20391
|
+
*
|
20392
|
+
* ```
|
20393
|
+
* Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of
|
20394
|
+
* script in the following Content Security Policy directive: "default-src 'self'". Note that
|
20395
|
+
* 'script-src' was not explicitly set, so 'default-src' is used as a fallback.
|
20396
|
+
* ```
|
20397
|
+
*
|
20398
|
+
* This error is harmless but annoying. To prevent the error from showing up, put the `ngCsp`
|
20399
|
+
* directive on the root element of the application or on the `angular.js` script tag, whichever
|
20400
|
+
* appears first in the html document.
|
20232
20401
|
*
|
20233
20402
|
* *Note: This directive is only available in the `ng-csp` and `data-ng-csp` attribute form.*
|
20234
20403
|
*
|
@@ -20243,9 +20412,9 @@ var ngControllerDirective = [function() {
|
|
20243
20412
|
```
|
20244
20413
|
*/
|
20245
20414
|
|
20246
|
-
// ngCsp is not implemented as a proper directive any more, because we need it be processed while we
|
20247
|
-
// the system (before $parse is instantiated), for this reason we just have
|
20248
|
-
// anywhere in the current doc
|
20415
|
+
// ngCsp is not implemented as a proper directive any more, because we need it be processed while we
|
20416
|
+
// bootstrap the system (before $parse is instantiated), for this reason we just have
|
20417
|
+
// the csp.isActive() fn that looks for ng-csp attribute anywhere in the current doc
|
20249
20418
|
|
20250
20419
|
/**
|
20251
20420
|
* @ngdoc directive
|
@@ -20290,6 +20459,7 @@ forEach(
|
|
20290
20459
|
var directiveName = directiveNormalize('ng-' + name);
|
20291
20460
|
ngEventDirectives[directiveName] = ['$parse', function($parse) {
|
20292
20461
|
return {
|
20462
|
+
restrict: 'A',
|
20293
20463
|
compile: function($element, attr) {
|
20294
20464
|
var fn = $parse(attr[directiveName]);
|
20295
20465
|
return function ngEventHandler(scope, element) {
|
@@ -20772,6 +20942,7 @@ forEach(
|
|
20772
20942
|
*/
|
20773
20943
|
var ngIfDirective = ['$animate', function($animate) {
|
20774
20944
|
return {
|
20945
|
+
multiElement: true,
|
20775
20946
|
transclude: 'element',
|
20776
20947
|
priority: 600,
|
20777
20948
|
terminal: true,
|
@@ -21505,6 +21676,13 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
|
|
21505
21676
|
* For example: `item in items` is equivalent to `item in items track by $id(item)`. This implies that the DOM elements
|
21506
21677
|
* will be associated by item identity in the array.
|
21507
21678
|
*
|
21679
|
+
* * `variable in expression as alias_expression` – You can also provide an optional alias expression which will then store the
|
21680
|
+
* intermediate results of the repeater after the filters have been applied. Typically this is used to render a special message
|
21681
|
+
* when a filter is active on the repeater, but the filtered result set is empty.
|
21682
|
+
*
|
21683
|
+
* For example: `item in items | filter:x as results` will store the fragment of the repeated items as `results`, but only after
|
21684
|
+
* the items have been processed through the filter.
|
21685
|
+
*
|
21508
21686
|
* For example: `item in items track by $id(item)`. A built in `$id()` function can be used to assign a unique
|
21509
21687
|
* `$$hashKey` property to each item in the array. This property is then used as a key to associated DOM elements
|
21510
21688
|
* with the corresponding item in the array by identity. Moving the same object in array would move the DOM
|
@@ -21537,9 +21715,12 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
|
|
21537
21715
|
I have {{friends.length}} friends. They are:
|
21538
21716
|
<input type="search" ng-model="q" placeholder="filter friends..." />
|
21539
21717
|
<ul class="example-animate-container">
|
21540
|
-
<li class="animate-repeat" ng-repeat="friend in friends | filter:q">
|
21718
|
+
<li class="animate-repeat" ng-repeat="friend in friends | filter:q as results">
|
21541
21719
|
[{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
|
21542
21720
|
</li>
|
21721
|
+
<li class="animate-repeat" ng-if="results.length == 0">
|
21722
|
+
<strong>No results found...</strong>
|
21723
|
+
</li>
|
21543
21724
|
</ul>
|
21544
21725
|
</div>
|
21545
21726
|
</file>
|
@@ -21607,14 +21788,16 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
21607
21788
|
var NG_REMOVED = '$$NG_REMOVED';
|
21608
21789
|
var ngRepeatMinErr = minErr('ngRepeat');
|
21609
21790
|
return {
|
21791
|
+
restrict: 'A',
|
21792
|
+
multiElement: true,
|
21610
21793
|
transclude: 'element',
|
21611
21794
|
priority: 1000,
|
21612
21795
|
terminal: true,
|
21613
21796
|
$$tlb: true,
|
21614
21797
|
link: function($scope, $element, $attr, ctrl, $transclude){
|
21615
21798
|
var expression = $attr.ngRepeat;
|
21616
|
-
var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/),
|
21617
|
-
trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn,
|
21799
|
+
var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/),
|
21800
|
+
trackByExp, trackByExpGetter, aliasAs, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn,
|
21618
21801
|
lhs, rhs, valueIdentifier, keyIdentifier,
|
21619
21802
|
hashFnLocals = {$id: hashKey};
|
21620
21803
|
|
@@ -21625,7 +21808,8 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
21625
21808
|
|
21626
21809
|
lhs = match[1];
|
21627
21810
|
rhs = match[2];
|
21628
|
-
|
21811
|
+
aliasAs = match[3];
|
21812
|
+
trackByExp = match[4];
|
21629
21813
|
|
21630
21814
|
if (trackByExp) {
|
21631
21815
|
trackByExpGetter = $parse(trackByExp);
|
@@ -21677,6 +21861,10 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
21677
21861
|
nextBlockOrder = [],
|
21678
21862
|
elementsToRemove;
|
21679
21863
|
|
21864
|
+
if (aliasAs) {
|
21865
|
+
$scope[aliasAs] = collection;
|
21866
|
+
}
|
21867
|
+
|
21680
21868
|
var updateScope = function(scope, index) {
|
21681
21869
|
scope[valueIdentifier] = value;
|
21682
21870
|
if (keyIdentifier) scope[keyIdentifier] = key;
|
@@ -21952,10 +22140,14 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
21952
22140
|
</example>
|
21953
22141
|
*/
|
21954
22142
|
var ngShowDirective = ['$animate', function($animate) {
|
21955
|
-
return
|
21956
|
-
|
21957
|
-
|
21958
|
-
|
22143
|
+
return {
|
22144
|
+
restrict: 'A',
|
22145
|
+
multiElement: true,
|
22146
|
+
link: function(scope, element, attr) {
|
22147
|
+
scope.$watch(attr.ngShow, function ngShowWatchAction(value){
|
22148
|
+
$animate[value ? 'removeClass' : 'addClass'](element, 'ng-hide');
|
22149
|
+
});
|
22150
|
+
}
|
21959
22151
|
};
|
21960
22152
|
}];
|
21961
22153
|
|
@@ -22103,10 +22295,14 @@ var ngShowDirective = ['$animate', function($animate) {
|
|
22103
22295
|
</example>
|
22104
22296
|
*/
|
22105
22297
|
var ngHideDirective = ['$animate', function($animate) {
|
22106
|
-
return
|
22107
|
-
|
22108
|
-
|
22109
|
-
|
22298
|
+
return {
|
22299
|
+
restrict: 'A',
|
22300
|
+
multiElement: true,
|
22301
|
+
link: function(scope, element, attr) {
|
22302
|
+
scope.$watch(attr.ngHide, function ngHideWatchAction(value){
|
22303
|
+
$animate[value ? 'addClass' : 'removeClass'](element, 'ng-hide');
|
22304
|
+
});
|
22305
|
+
}
|
22110
22306
|
};
|
22111
22307
|
}];
|
22112
22308
|
|
@@ -22317,7 +22513,7 @@ var ngSwitchDirective = ['$animate', function($animate) {
|
|
22317
22513
|
previousElements.length = 0;
|
22318
22514
|
|
22319
22515
|
for (i = 0, ii = selectedScopes.length; i < ii; ++i) {
|
22320
|
-
var selected = selectedElements[i];
|
22516
|
+
var selected = getBlockElements(selectedElements[i].clone);
|
22321
22517
|
selectedScopes[i].$destroy();
|
22322
22518
|
previousElements[i] = selected;
|
22323
22519
|
$animate.leave(selected, function() {
|
@@ -22331,12 +22527,13 @@ var ngSwitchDirective = ['$animate', function($animate) {
|
|
22331
22527
|
if ((selectedTranscludes = ngSwitchController.cases['!' + value] || ngSwitchController.cases['?'])) {
|
22332
22528
|
scope.$eval(attr.change);
|
22333
22529
|
forEach(selectedTranscludes, function(selectedTransclude) {
|
22334
|
-
|
22335
|
-
|
22336
|
-
selectedTransclude.transclude(selectedScope, function(caseElement) {
|
22530
|
+
selectedTransclude.transclude(function(caseElement, selectedScope) {
|
22531
|
+
selectedScopes.push(selectedScope);
|
22337
22532
|
var anchor = selectedTransclude.element;
|
22533
|
+
caseElement[caseElement.length++] = document.createComment(' end ngSwitchWhen: ');
|
22534
|
+
var block = { clone: caseElement };
|
22338
22535
|
|
22339
|
-
selectedElements.push(
|
22536
|
+
selectedElements.push(block);
|
22340
22537
|
$animate.enter(caseElement, anchor.parent(), anchor);
|
22341
22538
|
});
|
22342
22539
|
});
|
@@ -22348,8 +22545,9 @@ var ngSwitchDirective = ['$animate', function($animate) {
|
|
22348
22545
|
|
22349
22546
|
var ngSwitchWhenDirective = ngDirective({
|
22350
22547
|
transclude: 'element',
|
22351
|
-
priority:
|
22548
|
+
priority: 1200,
|
22352
22549
|
require: '^ngSwitch',
|
22550
|
+
multiElement: true,
|
22353
22551
|
link: function(scope, element, attrs, ctrl, $transclude) {
|
22354
22552
|
ctrl.cases['!' + attrs.ngSwitchWhen] = (ctrl.cases['!' + attrs.ngSwitchWhen] || []);
|
22355
22553
|
ctrl.cases['!' + attrs.ngSwitchWhen].push({ transclude: $transclude, element: element });
|
@@ -22358,8 +22556,9 @@ var ngSwitchWhenDirective = ngDirective({
|
|
22358
22556
|
|
22359
22557
|
var ngSwitchDefaultDirective = ngDirective({
|
22360
22558
|
transclude: 'element',
|
22361
|
-
priority:
|
22559
|
+
priority: 1200,
|
22362
22560
|
require: '^ngSwitch',
|
22561
|
+
multiElement: true,
|
22363
22562
|
link: function(scope, element, attr, ctrl, $transclude) {
|
22364
22563
|
ctrl.cases['?'] = (ctrl.cases['?'] || []);
|
22365
22564
|
ctrl.cases['?'].push({ transclude: $transclude, element: element });
|
@@ -22369,7 +22568,7 @@ var ngSwitchDefaultDirective = ngDirective({
|
|
22369
22568
|
/**
|
22370
22569
|
* @ngdoc directive
|
22371
22570
|
* @name ngTransclude
|
22372
|
-
* @restrict
|
22571
|
+
* @restrict EAC
|
22373
22572
|
*
|
22374
22573
|
* @description
|
22375
22574
|
* Directive that marks the insertion point for the transcluded DOM of the nearest parent directive that uses transclusion.
|
@@ -22390,7 +22589,7 @@ var ngSwitchDefaultDirective = ngDirective({
|
|
22390
22589
|
scope: { title:'@' },
|
22391
22590
|
template: '<div style="border: 1px solid black;">' +
|
22392
22591
|
'<div style="background-color: gray">{{title}}</div>' +
|
22393
|
-
'<
|
22592
|
+
'<ng-transclude></ng-transclude>' +
|
22394
22593
|
'</div>'
|
22395
22594
|
};
|
22396
22595
|
})
|
@@ -22421,6 +22620,7 @@ var ngSwitchDefaultDirective = ngDirective({
|
|
22421
22620
|
*
|
22422
22621
|
*/
|
22423
22622
|
var ngTranscludeDirective = ngDirective({
|
22623
|
+
restrict: 'EAC',
|
22424
22624
|
link: function($scope, $element, $attrs, controller, $transclude) {
|
22425
22625
|
if (!$transclude) {
|
22426
22626
|
throw minErr('ngTransclude')('orphan',
|
@@ -22621,7 +22821,11 @@ var ngOptionsMinErr = minErr('ngOptions');
|
|
22621
22821
|
</example>
|
22622
22822
|
*/
|
22623
22823
|
|
22624
|
-
var ngOptionsDirective = valueFn({
|
22824
|
+
var ngOptionsDirective = valueFn({
|
22825
|
+
restrict: 'A',
|
22826
|
+
terminal: true
|
22827
|
+
});
|
22828
|
+
|
22625
22829
|
// jshint maxlen: false
|
22626
22830
|
var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
22627
22831
|
//000011111111110000000000022222222220000000000000000000003333333333000000000000004444444444444440000000005555555555555550000000666666666666666000000000000000777777777700000000000000000008888888888
|
@@ -23032,6 +23236,12 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
23032
23236
|
// lastElement.prop('selected') provided by jQuery has side-effects
|
23033
23237
|
if (existingOption.selected !== option.selected) {
|
23034
23238
|
lastElement.prop('selected', (existingOption.selected = option.selected));
|
23239
|
+
if (msie) {
|
23240
|
+
// See #7692
|
23241
|
+
// The selected item wouldn't visually update on IE without this.
|
23242
|
+
// Tested on Win7: IE9, IE10 and IE11. Future IEs should be tested as well
|
23243
|
+
lastElement.prop('selected', existingOption.selected);
|
23244
|
+
}
|
23035
23245
|
}
|
23036
23246
|
} else {
|
23037
23247
|
// grow elements
|