angularjs-rails 1.2.20 → 1.2.21
Sign up to get free protection for your applications and to get access to all the features.
- 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
|