angularjs-rails 1.4.4 → 1.4.7
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 +266 -123
- data/vendor/assets/javascripts/angular-aria.js +40 -36
- data/vendor/assets/javascripts/angular-cookies.js +2 -2
- data/vendor/assets/javascripts/angular-loader.js +2 -2
- data/vendor/assets/javascripts/angular-message-format.js +1 -1
- data/vendor/assets/javascripts/angular-messages.js +9 -2
- data/vendor/assets/javascripts/angular-mocks.js +62 -25
- data/vendor/assets/javascripts/angular-resource.js +10 -4
- data/vendor/assets/javascripts/angular-route.js +1 -2
- data/vendor/assets/javascripts/angular-sanitize.js +1 -1
- data/vendor/assets/javascripts/angular-scenario.js +625 -325
- data/vendor/assets/javascripts/angular-touch.js +1 -1
- data/vendor/assets/javascripts/angular.js +624 -324
- data/vendor/assets/javascripts/unstable/angular2.js +13370 -14106
- metadata +2 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.4.
|
2
|
+
* @license AngularJS v1.4.7
|
3
3
|
* (c) 2010-2015 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -57,7 +57,7 @@ function minErr(module, ErrorConstructor) {
|
|
57
57
|
return match;
|
58
58
|
});
|
59
59
|
|
60
|
-
message += '\nhttp://errors.angularjs.org/1.4.
|
60
|
+
message += '\nhttp://errors.angularjs.org/1.4.7/' +
|
61
61
|
(module ? module + '/' : '') + code;
|
62
62
|
|
63
63
|
for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
|
@@ -894,6 +894,8 @@ function copy(source, destination, stackSource, stackDest) {
|
|
894
894
|
} else if (isRegExp(source)) {
|
895
895
|
destination = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]);
|
896
896
|
destination.lastIndex = source.lastIndex;
|
897
|
+
} else if (isFunction(source.cloneNode)) {
|
898
|
+
destination = source.cloneNode(true);
|
897
899
|
} else {
|
898
900
|
var emptyObject = Object.create(getPrototypeOf(source));
|
899
901
|
return copy(source, emptyObject, stackSource, stackDest);
|
@@ -1044,7 +1046,7 @@ function equals(o1, o2) {
|
|
1044
1046
|
for (key in o2) {
|
1045
1047
|
if (!(key in keySet) &&
|
1046
1048
|
key.charAt(0) !== '$' &&
|
1047
|
-
o2[key]
|
1049
|
+
isDefined(o2[key]) &&
|
1048
1050
|
!isFunction(o2[key])) return false;
|
1049
1051
|
}
|
1050
1052
|
return true;
|
@@ -1740,10 +1742,9 @@ function bindJQuery() {
|
|
1740
1742
|
|
1741
1743
|
// bind to jQuery if present;
|
1742
1744
|
var jqName = jq();
|
1743
|
-
jQuery = window.jQuery
|
1744
|
-
|
1745
|
-
|
1746
|
-
}
|
1745
|
+
jQuery = isUndefined(jqName) ? window.jQuery : // use jQuery (if present)
|
1746
|
+
!jqName ? undefined : // use jqLite
|
1747
|
+
window[jqName]; // use jQuery specified by `ngJq`
|
1747
1748
|
|
1748
1749
|
// Use jQuery if it exists with proper functionality, otherwise default to us.
|
1749
1750
|
// Angular 1.2+ requires jQuery 1.7+ for on()/off() support.
|
@@ -1848,22 +1849,24 @@ function getter(obj, path, bindFnToScope) {
|
|
1848
1849
|
/**
|
1849
1850
|
* Return the DOM siblings between the first and last node in the given array.
|
1850
1851
|
* @param {Array} array like object
|
1851
|
-
* @returns {
|
1852
|
+
* @returns {Array} the inputted object or a jqLite collection containing the nodes
|
1852
1853
|
*/
|
1853
1854
|
function getBlockNodes(nodes) {
|
1854
|
-
// TODO(perf):
|
1855
|
-
// collection, otherwise update the original collection.
|
1855
|
+
// TODO(perf): update `nodes` instead of creating a new object?
|
1856
1856
|
var node = nodes[0];
|
1857
1857
|
var endNode = nodes[nodes.length - 1];
|
1858
|
-
var blockNodes
|
1858
|
+
var blockNodes;
|
1859
1859
|
|
1860
|
-
|
1861
|
-
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1860
|
+
for (var i = 1; node !== endNode && (node = node.nextSibling); i++) {
|
1861
|
+
if (blockNodes || nodes[i] !== node) {
|
1862
|
+
if (!blockNodes) {
|
1863
|
+
blockNodes = jqLite(slice.call(nodes, 0, i));
|
1864
|
+
}
|
1865
|
+
blockNodes.push(node);
|
1866
|
+
}
|
1867
|
+
}
|
1865
1868
|
|
1866
|
-
return
|
1869
|
+
return blockNodes || nodes;
|
1867
1870
|
}
|
1868
1871
|
|
1869
1872
|
|
@@ -2247,7 +2250,7 @@ function serializeObject(obj) {
|
|
2247
2250
|
val = toJsonReplacer(key, val);
|
2248
2251
|
if (isObject(val)) {
|
2249
2252
|
|
2250
|
-
if (seen.indexOf(val) >= 0) return '
|
2253
|
+
if (seen.indexOf(val) >= 0) return '...';
|
2251
2254
|
|
2252
2255
|
seen.push(val);
|
2253
2256
|
}
|
@@ -2258,7 +2261,7 @@ function serializeObject(obj) {
|
|
2258
2261
|
function toDebugString(obj) {
|
2259
2262
|
if (typeof obj === 'function') {
|
2260
2263
|
return obj.toString().replace(/ \{[\s\S]*$/, '');
|
2261
|
-
} else if (
|
2264
|
+
} else if (isUndefined(obj)) {
|
2262
2265
|
return 'undefined';
|
2263
2266
|
} else if (typeof obj !== 'string') {
|
2264
2267
|
return serializeObject(obj);
|
@@ -2338,6 +2341,7 @@ function toDebugString(obj) {
|
|
2338
2341
|
$HttpParamSerializerProvider,
|
2339
2342
|
$HttpParamSerializerJQLikeProvider,
|
2340
2343
|
$HttpBackendProvider,
|
2344
|
+
$xhrFactoryProvider,
|
2341
2345
|
$LocationProvider,
|
2342
2346
|
$LogProvider,
|
2343
2347
|
$ParseProvider,
|
@@ -2364,8 +2368,9 @@ function toDebugString(obj) {
|
|
2364
2368
|
* @name angular.version
|
2365
2369
|
* @module ng
|
2366
2370
|
* @description
|
2367
|
-
* An object that contains information about the current AngularJS version.
|
2368
|
-
*
|
2371
|
+
* An object that contains information about the current AngularJS version.
|
2372
|
+
*
|
2373
|
+
* This object has the following properties:
|
2369
2374
|
*
|
2370
2375
|
* - `full` – `{string}` – Full version string, such as "0.9.18".
|
2371
2376
|
* - `major` – `{number}` – Major version number, such as "0".
|
@@ -2374,11 +2379,11 @@ function toDebugString(obj) {
|
|
2374
2379
|
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
|
2375
2380
|
*/
|
2376
2381
|
var version = {
|
2377
|
-
full: '1.4.
|
2382
|
+
full: '1.4.7', // all of these placeholder strings will be replaced by grunt's
|
2378
2383
|
major: 1, // package task
|
2379
2384
|
minor: 4,
|
2380
|
-
dot:
|
2381
|
-
codeName: '
|
2385
|
+
dot: 7,
|
2386
|
+
codeName: 'dark-luminescence'
|
2382
2387
|
};
|
2383
2388
|
|
2384
2389
|
|
@@ -2495,6 +2500,7 @@ function publishExternalAPI(angular) {
|
|
2495
2500
|
$httpParamSerializer: $HttpParamSerializerProvider,
|
2496
2501
|
$httpParamSerializerJQLike: $HttpParamSerializerJQLikeProvider,
|
2497
2502
|
$httpBackend: $HttpBackendProvider,
|
2503
|
+
$xhrFactory: $xhrFactoryProvider,
|
2498
2504
|
$location: $LocationProvider,
|
2499
2505
|
$log: $LogProvider,
|
2500
2506
|
$parse: $ParseProvider,
|
@@ -2583,7 +2589,7 @@ function publishExternalAPI(angular) {
|
|
2583
2589
|
* - [`html()`](http://api.jquery.com/html/)
|
2584
2590
|
* - [`next()`](http://api.jquery.com/next/) - Does not support selectors
|
2585
2591
|
* - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
|
2586
|
-
* - [`off()`](http://api.jquery.com/off/) - Does not support namespaces or
|
2592
|
+
* - [`off()`](http://api.jquery.com/off/) - Does not support namespaces, selectors or event object as parameter
|
2587
2593
|
* - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors
|
2588
2594
|
* - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors
|
2589
2595
|
* - [`prepend()`](http://api.jquery.com/prepend/)
|
@@ -2597,7 +2603,7 @@ function publishExternalAPI(angular) {
|
|
2597
2603
|
* - [`text()`](http://api.jquery.com/text/)
|
2598
2604
|
* - [`toggleClass()`](http://api.jquery.com/toggleClass/)
|
2599
2605
|
* - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers.
|
2600
|
-
* - [`unbind()`](http://api.jquery.com/unbind/) - Does not support namespaces
|
2606
|
+
* - [`unbind()`](http://api.jquery.com/unbind/) - Does not support namespaces or event object as parameter
|
2601
2607
|
* - [`val()`](http://api.jquery.com/val/)
|
2602
2608
|
* - [`wrap()`](http://api.jquery.com/wrap/)
|
2603
2609
|
*
|
@@ -2669,10 +2675,10 @@ function camelCase(name) {
|
|
2669
2675
|
replace(MOZ_HACK_REGEXP, 'Moz$1');
|
2670
2676
|
}
|
2671
2677
|
|
2672
|
-
var SINGLE_TAG_REGEXP = /^<(\w+)\s*\/?>(?:<\/\1>|)$/;
|
2678
|
+
var SINGLE_TAG_REGEXP = /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/;
|
2673
2679
|
var HTML_REGEXP = /<|&#?\w+;/;
|
2674
|
-
var TAG_NAME_REGEXP = /<([\w
|
2675
|
-
var XHTML_TAG_REGEXP = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w
|
2680
|
+
var TAG_NAME_REGEXP = /<([\w:-]+)/;
|
2681
|
+
var XHTML_TAG_REGEXP = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi;
|
2676
2682
|
|
2677
2683
|
var wrapMap = {
|
2678
2684
|
'option': [1, '<select multiple="multiple">', '</select>'],
|
@@ -2968,7 +2974,7 @@ function jqLiteInheritedData(element, name, value) {
|
|
2968
2974
|
|
2969
2975
|
while (element) {
|
2970
2976
|
for (var i = 0, ii = names.length; i < ii; i++) {
|
2971
|
-
if ((value = jqLite.data(element, names[i]))
|
2977
|
+
if (isDefined(value = jqLite.data(element, names[i]))) return value;
|
2972
2978
|
}
|
2973
2979
|
|
2974
2980
|
// If dealing with a document fragment node with a host element, and no parent, use the host
|
@@ -3074,9 +3080,8 @@ function getBooleanAttrName(element, name) {
|
|
3074
3080
|
return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr;
|
3075
3081
|
}
|
3076
3082
|
|
3077
|
-
function getAliasedAttrName(
|
3078
|
-
|
3079
|
-
return (nodeName === 'INPUT' || nodeName === 'TEXTAREA') && ALIASED_ATTR[name];
|
3083
|
+
function getAliasedAttrName(name) {
|
3084
|
+
return ALIASED_ATTR[name];
|
3080
3085
|
}
|
3081
3086
|
|
3082
3087
|
forEach({
|
@@ -3213,7 +3218,7 @@ forEach({
|
|
3213
3218
|
// in a way that survives minification.
|
3214
3219
|
// jqLiteEmpty takes no arguments but is a setter.
|
3215
3220
|
if (fn !== jqLiteEmpty &&
|
3216
|
-
(((fn.length == 2 && (fn !== jqLiteHasClass && fn !== jqLiteController)) ? arg1 : arg2)
|
3221
|
+
(isUndefined((fn.length == 2 && (fn !== jqLiteHasClass && fn !== jqLiteController)) ? arg1 : arg2))) {
|
3217
3222
|
if (isObject(arg1)) {
|
3218
3223
|
|
3219
3224
|
// we are a write, but the object properties are the key/values
|
@@ -3234,7 +3239,7 @@ forEach({
|
|
3234
3239
|
// TODO: do we still need this?
|
3235
3240
|
var value = fn.$dv;
|
3236
3241
|
// Only if we have $dv do we iterate over all, otherwise it is just the first element.
|
3237
|
-
var jj = (value
|
3242
|
+
var jj = (isUndefined(value)) ? Math.min(nodeCount, 1) : nodeCount;
|
3238
3243
|
for (var j = 0; j < jj; j++) {
|
3239
3244
|
var nodeValue = fn(this[j], arg1, arg2);
|
3240
3245
|
value = value ? value + nodeValue : nodeValue;
|
@@ -4873,61 +4878,66 @@ var $$CoreAnimateQueueProvider = function() {
|
|
4873
4878
|
}
|
4874
4879
|
};
|
4875
4880
|
|
4876
|
-
function addRemoveClassesPostDigest(element, add, remove) {
|
4877
|
-
var classVal, data = postDigestQueue.get(element);
|
4878
4881
|
|
4879
|
-
|
4880
|
-
|
4881
|
-
|
4882
|
+
function updateData(data, classes, value) {
|
4883
|
+
var changed = false;
|
4884
|
+
if (classes) {
|
4885
|
+
classes = isString(classes) ? classes.split(' ') :
|
4886
|
+
isArray(classes) ? classes : [];
|
4887
|
+
forEach(classes, function(className) {
|
4888
|
+
if (className) {
|
4889
|
+
changed = true;
|
4890
|
+
data[className] = value;
|
4891
|
+
}
|
4892
|
+
});
|
4882
4893
|
}
|
4883
|
-
|
4884
|
-
|
4885
|
-
|
4886
|
-
|
4887
|
-
|
4888
|
-
|
4889
|
-
|
4890
|
-
|
4891
|
-
|
4892
|
-
|
4894
|
+
return changed;
|
4895
|
+
}
|
4896
|
+
|
4897
|
+
function handleCSSClassChanges() {
|
4898
|
+
forEach(postDigestElements, function(element) {
|
4899
|
+
var data = postDigestQueue.get(element);
|
4900
|
+
if (data) {
|
4901
|
+
var existing = splitClasses(element.attr('class'));
|
4902
|
+
var toAdd = '';
|
4903
|
+
var toRemove = '';
|
4904
|
+
forEach(data, function(status, className) {
|
4905
|
+
var hasClass = !!existing[className];
|
4906
|
+
if (status !== hasClass) {
|
4907
|
+
if (status) {
|
4908
|
+
toAdd += (toAdd.length ? ' ' : '') + className;
|
4909
|
+
} else {
|
4910
|
+
toRemove += (toRemove.length ? ' ' : '') + className;
|
4911
|
+
}
|
4893
4912
|
}
|
4894
4913
|
});
|
4914
|
+
|
4915
|
+
forEach(element, function(elm) {
|
4916
|
+
toAdd && jqLiteAddClass(elm, toAdd);
|
4917
|
+
toRemove && jqLiteRemoveClass(elm, toRemove);
|
4918
|
+
});
|
4919
|
+
postDigestQueue.remove(element);
|
4895
4920
|
}
|
4896
|
-
|
4897
|
-
|
4921
|
+
});
|
4922
|
+
postDigestElements.length = 0;
|
4923
|
+
}
|
4898
4924
|
|
4899
|
-
var classesAdded = updateData(add, true);
|
4900
|
-
var classesRemoved = updateData(remove, false);
|
4901
|
-
if ((!classesAdded && !classesRemoved) || postDigestElements.length > 1) return;
|
4902
|
-
|
4903
|
-
$rootScope.$$postDigest(function() {
|
4904
|
-
forEach(postDigestElements, function(element) {
|
4905
|
-
var data = postDigestQueue.get(element);
|
4906
|
-
if (data) {
|
4907
|
-
var existing = splitClasses(element.attr('class'));
|
4908
|
-
var toAdd = '';
|
4909
|
-
var toRemove = '';
|
4910
|
-
forEach(data, function(status, className) {
|
4911
|
-
var hasClass = !!existing[className];
|
4912
|
-
if (status !== hasClass) {
|
4913
|
-
if (status) {
|
4914
|
-
toAdd += (toAdd.length ? ' ' : '') + className;
|
4915
|
-
} else {
|
4916
|
-
toRemove += (toRemove.length ? ' ' : '') + className;
|
4917
|
-
}
|
4918
|
-
}
|
4919
|
-
});
|
4920
4925
|
|
4921
|
-
|
4922
|
-
|
4923
|
-
toRemove && jqLiteRemoveClass(elm, toRemove);
|
4924
|
-
});
|
4925
|
-
postDigestQueue.remove(element);
|
4926
|
-
}
|
4927
|
-
});
|
4926
|
+
function addRemoveClassesPostDigest(element, add, remove) {
|
4927
|
+
var data = postDigestQueue.get(element) || {};
|
4928
4928
|
|
4929
|
-
|
4930
|
-
|
4929
|
+
var classesAdded = updateData(data, add, true);
|
4930
|
+
var classesRemoved = updateData(data, remove, false);
|
4931
|
+
|
4932
|
+
if (classesAdded || classesRemoved) {
|
4933
|
+
|
4934
|
+
postDigestQueue.put(element, data);
|
4935
|
+
postDigestElements.push(element);
|
4936
|
+
|
4937
|
+
if (postDigestElements.length === 1) {
|
4938
|
+
$rootScope.$$postDigest(handleCSSClassChanges);
|
4939
|
+
}
|
4940
|
+
}
|
4931
4941
|
}
|
4932
4942
|
}];
|
4933
4943
|
};
|
@@ -5392,14 +5402,21 @@ var $CoreAnimateCssProvider = function() {
|
|
5392
5402
|
return this.getPromise().then(f1,f2);
|
5393
5403
|
},
|
5394
5404
|
'catch': function(f1) {
|
5395
|
-
return this.getPromise()
|
5405
|
+
return this.getPromise()['catch'](f1);
|
5396
5406
|
},
|
5397
5407
|
'finally': function(f1) {
|
5398
|
-
return this.getPromise()
|
5408
|
+
return this.getPromise()['finally'](f1);
|
5399
5409
|
}
|
5400
5410
|
};
|
5401
5411
|
|
5402
5412
|
return function(element, options) {
|
5413
|
+
// there is no point in applying the styles since
|
5414
|
+
// there is no animation that goes on at all in
|
5415
|
+
// this version of $animateCss.
|
5416
|
+
if (options.cleanupStyles) {
|
5417
|
+
options.from = options.to = null;
|
5418
|
+
}
|
5419
|
+
|
5403
5420
|
if (options.from) {
|
5404
5421
|
element.css(options.from);
|
5405
5422
|
options.from = null;
|
@@ -5528,7 +5545,7 @@ function Browser(window, document, $log, $sniffer) {
|
|
5528
5545
|
var cachedState, lastHistoryState,
|
5529
5546
|
lastBrowserUrl = location.href,
|
5530
5547
|
baseElement = document.find('base'),
|
5531
|
-
|
5548
|
+
pendingLocation = null;
|
5532
5549
|
|
5533
5550
|
cacheState();
|
5534
5551
|
lastHistoryState = cachedState;
|
@@ -5588,8 +5605,8 @@ function Browser(window, document, $log, $sniffer) {
|
|
5588
5605
|
// Do the assignment again so that those two variables are referentially identical.
|
5589
5606
|
lastHistoryState = cachedState;
|
5590
5607
|
} else {
|
5591
|
-
if (!sameBase ||
|
5592
|
-
|
5608
|
+
if (!sameBase || pendingLocation) {
|
5609
|
+
pendingLocation = url;
|
5593
5610
|
}
|
5594
5611
|
if (replace) {
|
5595
5612
|
location.replace(url);
|
@@ -5598,14 +5615,18 @@ function Browser(window, document, $log, $sniffer) {
|
|
5598
5615
|
} else {
|
5599
5616
|
location.hash = getHash(url);
|
5600
5617
|
}
|
5618
|
+
if (location.href !== url) {
|
5619
|
+
pendingLocation = url;
|
5620
|
+
}
|
5601
5621
|
}
|
5602
5622
|
return self;
|
5603
5623
|
// getter
|
5604
5624
|
} else {
|
5605
|
-
// -
|
5606
|
-
// the new location.href if a reload happened
|
5625
|
+
// - pendingLocation is needed as browsers don't allow to read out
|
5626
|
+
// the new location.href if a reload happened or if there is a bug like in iOS 9 (see
|
5627
|
+
// https://openradar.appspot.com/22186109).
|
5607
5628
|
// - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172
|
5608
|
-
return
|
5629
|
+
return pendingLocation || location.href.replace(/%27/g,"'");
|
5609
5630
|
}
|
5610
5631
|
};
|
5611
5632
|
|
@@ -5627,6 +5648,7 @@ function Browser(window, document, $log, $sniffer) {
|
|
5627
5648
|
urlChangeInit = false;
|
5628
5649
|
|
5629
5650
|
function cacheStateAndFireUrlChange() {
|
5651
|
+
pendingLocation = null;
|
5630
5652
|
cacheState();
|
5631
5653
|
fireUrlChange();
|
5632
5654
|
}
|
@@ -5862,10 +5884,10 @@ function $BrowserProvider() {
|
|
5862
5884
|
$scope.keys = [];
|
5863
5885
|
$scope.cache = $cacheFactory('cacheId');
|
5864
5886
|
$scope.put = function(key, value) {
|
5865
|
-
if ($scope.cache.get(key)
|
5887
|
+
if (angular.isUndefined($scope.cache.get(key))) {
|
5866
5888
|
$scope.keys.push(key);
|
5867
5889
|
}
|
5868
|
-
$scope.cache.put(key, value
|
5890
|
+
$scope.cache.put(key, angular.isUndefined(value) ? null : value);
|
5869
5891
|
};
|
5870
5892
|
}]);
|
5871
5893
|
</file>
|
@@ -6341,18 +6363,24 @@ function $TemplateCacheProvider() {
|
|
6341
6363
|
* and other directives used in the directive's template will also be excluded from execution.
|
6342
6364
|
*
|
6343
6365
|
* #### `scope`
|
6344
|
-
*
|
6345
|
-
*
|
6346
|
-
*
|
6366
|
+
* The scope property can be `true`, an object or a falsy value:
|
6367
|
+
*
|
6368
|
+
* * **falsy:** No scope will be created for the directive. The directive will use its parent's scope.
|
6369
|
+
*
|
6370
|
+
* * **`true`:** A new child scope that prototypically inherits from its parent will be created for
|
6371
|
+
* the directive's element. If multiple directives on the same element request a new scope,
|
6372
|
+
* only one new scope is created. The new scope rule does not apply for the root of the template
|
6373
|
+
* since the root of the template always gets a new scope.
|
6347
6374
|
*
|
6348
|
-
*
|
6349
|
-
* normal scope in that it does not prototypically inherit from
|
6350
|
-
* when creating reusable components, which should not accidentally read or modify
|
6351
|
-
* parent scope.
|
6375
|
+
* * **`{...}` (an object hash):** A new "isolate" scope is created for the directive's element. The
|
6376
|
+
* 'isolate' scope differs from normal scope in that it does not prototypically inherit from its parent
|
6377
|
+
* scope. This is useful when creating reusable components, which should not accidentally read or modify
|
6378
|
+
* data in the parent scope.
|
6352
6379
|
*
|
6353
|
-
* The 'isolate' scope
|
6354
|
-
*
|
6355
|
-
*
|
6380
|
+
* The 'isolate' scope object hash defines a set of local scope properties derived from attributes on the
|
6381
|
+
* directive's element. These local properties are useful for aliasing values for templates. The keys in
|
6382
|
+
* the object hash map to the name of the property on the isolate scope; the values define how the property
|
6383
|
+
* is bound to the parent scope, via matching attributes on the directive's element:
|
6356
6384
|
*
|
6357
6385
|
* * `@` or `@attr` - bind a local scope property to the value of DOM attribute. The result is
|
6358
6386
|
* always a string since DOM attributes are strings. If no `attr` name is specified then the
|
@@ -6385,6 +6413,20 @@ function $TemplateCacheProvider() {
|
|
6385
6413
|
* For example, if the expression is `increment(amount)` then we can specify the amount value
|
6386
6414
|
* by calling the `localFn` as `localFn({amount: 22})`.
|
6387
6415
|
*
|
6416
|
+
* In general it's possible to apply more than one directive to one element, but there might be limitations
|
6417
|
+
* depending on the type of scope required by the directives. The following points will help explain these limitations.
|
6418
|
+
* For simplicity only two directives are taken into account, but it is also applicable for several directives:
|
6419
|
+
*
|
6420
|
+
* * **no scope** + **no scope** => Two directives which don't require their own scope will use their parent's scope
|
6421
|
+
* * **child scope** + **no scope** => Both directives will share one single child scope
|
6422
|
+
* * **child scope** + **child scope** => Both directives will share one single child scope
|
6423
|
+
* * **isolated scope** + **no scope** => The isolated directive will use it's own created isolated scope. The other directive will use
|
6424
|
+
* its parent's scope
|
6425
|
+
* * **isolated scope** + **child scope** => **Won't work!** Only one scope can be related to one element. Therefore these directives cannot
|
6426
|
+
* be applied to the same element.
|
6427
|
+
* * **isolated scope** + **isolated scope** => **Won't work!** Only one scope can be related to one element. Therefore these directives
|
6428
|
+
* cannot be applied to the same element.
|
6429
|
+
*
|
6388
6430
|
*
|
6389
6431
|
* #### `bindToController`
|
6390
6432
|
* When an isolate scope is used for a component (see above), and `controllerAs` is used, `bindToController: true` will
|
@@ -6393,7 +6435,7 @@ function $TemplateCacheProvider() {
|
|
6393
6435
|
*
|
6394
6436
|
* #### `controller`
|
6395
6437
|
* Controller constructor function. The controller is instantiated before the
|
6396
|
-
* pre-linking phase and
|
6438
|
+
* pre-linking phase and can be accessed by other directives (see
|
6397
6439
|
* `require` attribute). This allows the directives to communicate with each other and augment
|
6398
6440
|
* each other's behavior. The controller is injectable (and supports bracket notation) with the following locals:
|
6399
6441
|
*
|
@@ -6433,9 +6475,10 @@ function $TemplateCacheProvider() {
|
|
6433
6475
|
*
|
6434
6476
|
* #### `controllerAs`
|
6435
6477
|
* Identifier name for a reference to the controller in the directive's scope.
|
6436
|
-
* This allows the controller to be referenced from the directive template.
|
6437
|
-
*
|
6438
|
-
* directive
|
6478
|
+
* This allows the controller to be referenced from the directive template. This is especially
|
6479
|
+
* useful when a directive is used as component, i.e. with an `isolate` scope. It's also possible
|
6480
|
+
* to use it in a directive without an `isolate` / `new` scope, but you need to be aware that the
|
6481
|
+
* `controllerAs` reference might overwrite a property that already exists on the parent scope.
|
6439
6482
|
*
|
6440
6483
|
*
|
6441
6484
|
* #### `restrict`
|
@@ -7272,7 +7315,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7272
7315
|
|
7273
7316
|
var node = this.$$element[0],
|
7274
7317
|
booleanKey = getBooleanAttrName(node, key),
|
7275
|
-
aliasedKey = getAliasedAttrName(
|
7318
|
+
aliasedKey = getAliasedAttrName(key),
|
7276
7319
|
observer = key,
|
7277
7320
|
nodeName;
|
7278
7321
|
|
@@ -7339,7 +7382,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7339
7382
|
}
|
7340
7383
|
|
7341
7384
|
if (writeAttr !== false) {
|
7342
|
-
if (value === null || value
|
7385
|
+
if (value === null || isUndefined(value)) {
|
7343
7386
|
this.$$element.removeAttr(attrName);
|
7344
7387
|
} else {
|
7345
7388
|
this.$$element.attr(attrName, value);
|
@@ -8305,7 +8348,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
8305
8348
|
i = 0, ii = directives.length; i < ii; i++) {
|
8306
8349
|
try {
|
8307
8350
|
directive = directives[i];
|
8308
|
-
if ((maxPriority
|
8351
|
+
if ((isUndefined(maxPriority) || maxPriority > directive.priority) &&
|
8309
8352
|
directive.restrict.indexOf(location) != -1) {
|
8310
8353
|
if (startAttrName) {
|
8311
8354
|
directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName});
|
@@ -8601,7 +8644,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
8601
8644
|
compile: function() {
|
8602
8645
|
return {
|
8603
8646
|
pre: function attrInterpolatePreLinkFn(scope, element, attr) {
|
8604
|
-
var $$observers = (attr.$$observers || (attr.$$observers =
|
8647
|
+
var $$observers = (attr.$$observers || (attr.$$observers = createMap()));
|
8605
8648
|
|
8606
8649
|
if (EVENT_HANDLER_ATTR_REGEXP.test(name)) {
|
8607
8650
|
throw $compileMinErr('nodomevents',
|
@@ -9653,28 +9696,18 @@ function $HttpProvider() {
|
|
9653
9696
|
*
|
9654
9697
|
*
|
9655
9698
|
* ## General usage
|
9656
|
-
* The `$http` service is a function which takes a single argument — a configuration object —
|
9699
|
+
* The `$http` service is a function which takes a single argument — a {@link $http#usage configuration object} —
|
9657
9700
|
* that is used to generate an HTTP request and returns a {@link ng.$q promise}.
|
9658
9701
|
*
|
9659
9702
|
* ```js
|
9660
|
-
* // Simple GET request example
|
9661
|
-
* $http
|
9662
|
-
*
|
9663
|
-
*
|
9664
|
-
*
|
9665
|
-
* }, function(response) {
|
9666
|
-
* // called asynchronously if an error occurs
|
9667
|
-
* // or server returns response with an error status.
|
9668
|
-
* });
|
9669
|
-
* ```
|
9670
|
-
*
|
9671
|
-
* ```js
|
9672
|
-
* // Simple POST request example (passing data) :
|
9673
|
-
* $http.post('/someUrl', {msg:'hello word!'}).
|
9674
|
-
* then(function(response) {
|
9703
|
+
* // Simple GET request example:
|
9704
|
+
* $http({
|
9705
|
+
* method: 'GET',
|
9706
|
+
* url: '/someUrl'
|
9707
|
+
* }).then(function successCallback(response) {
|
9675
9708
|
* // this callback will be called asynchronously
|
9676
9709
|
* // when the response is available
|
9677
|
-
* }, function(response) {
|
9710
|
+
* }, function errorCallback(response) {
|
9678
9711
|
* // called asynchronously if an error occurs
|
9679
9712
|
* // or server returns response with an error status.
|
9680
9713
|
* });
|
@@ -9694,25 +9727,16 @@ function $HttpProvider() {
|
|
9694
9727
|
* XMLHttpRequest will transparently follow it, meaning that the error callback will not be
|
9695
9728
|
* called for such responses.
|
9696
9729
|
*
|
9697
|
-
* ## Writing Unit Tests that use $http
|
9698
|
-
* When unit testing (using {@link ngMock ngMock}), it is necessary to call
|
9699
|
-
* {@link ngMock.$httpBackend#flush $httpBackend.flush()} to flush each pending
|
9700
|
-
* request using trained responses.
|
9701
|
-
*
|
9702
|
-
* ```
|
9703
|
-
* $httpBackend.expectGET(...);
|
9704
|
-
* $http.get(...);
|
9705
|
-
* $httpBackend.flush();
|
9706
|
-
* ```
|
9707
9730
|
*
|
9708
9731
|
* ## Shortcut methods
|
9709
9732
|
*
|
9710
9733
|
* Shortcut methods are also available. All shortcut methods require passing in the URL, and
|
9711
|
-
* request data must be passed in for POST/PUT requests.
|
9734
|
+
* request data must be passed in for POST/PUT requests. An optional config can be passed as the
|
9735
|
+
* last argument.
|
9712
9736
|
*
|
9713
9737
|
* ```js
|
9714
|
-
* $http.get('/someUrl').then(successCallback);
|
9715
|
-
* $http.post('/someUrl', data).then(successCallback);
|
9738
|
+
* $http.get('/someUrl', config).then(successCallback, errorCallback);
|
9739
|
+
* $http.post('/someUrl', data, config).then(successCallback, errorCallback);
|
9716
9740
|
* ```
|
9717
9741
|
*
|
9718
9742
|
* Complete list of shortcut methods:
|
@@ -9726,6 +9750,17 @@ function $HttpProvider() {
|
|
9726
9750
|
* - {@link ng.$http#patch $http.patch}
|
9727
9751
|
*
|
9728
9752
|
*
|
9753
|
+
* ## Writing Unit Tests that use $http
|
9754
|
+
* When unit testing (using {@link ngMock ngMock}), it is necessary to call
|
9755
|
+
* {@link ngMock.$httpBackend#flush $httpBackend.flush()} to flush each pending
|
9756
|
+
* request using trained responses.
|
9757
|
+
*
|
9758
|
+
* ```
|
9759
|
+
* $httpBackend.expectGET(...);
|
9760
|
+
* $http.get(...);
|
9761
|
+
* $httpBackend.flush();
|
9762
|
+
* ```
|
9763
|
+
*
|
9729
9764
|
* ## Deprecation Notice
|
9730
9765
|
* <div class="alert alert-danger">
|
9731
9766
|
* The `$http` legacy promise methods `success` and `error` have been deprecated.
|
@@ -9883,7 +9918,7 @@ function $HttpProvider() {
|
|
9883
9918
|
*
|
9884
9919
|
* There are two kinds of interceptors (and two kinds of rejection interceptors):
|
9885
9920
|
*
|
9886
|
-
* * `request`: interceptors get called with a http
|
9921
|
+
* * `request`: interceptors get called with a http {@link $http#usage config} object. The function is free to
|
9887
9922
|
* modify the `config` object or create a new one. The function needs to return the `config`
|
9888
9923
|
* object directly, or a promise containing the `config` or a new `config` object.
|
9889
9924
|
* * `requestError`: interceptor gets called when a previous interceptor threw an error or
|
@@ -10517,8 +10552,8 @@ function $HttpProvider() {
|
|
10517
10552
|
* Resolves the raw $http promise.
|
10518
10553
|
*/
|
10519
10554
|
function resolvePromise(response, status, headers, statusText) {
|
10520
|
-
//
|
10521
|
-
status =
|
10555
|
+
//status: HTTP response status code, 0, -1 (aborted by timeout / promise)
|
10556
|
+
status = status >= -1 ? status : 0;
|
10522
10557
|
|
10523
10558
|
(isSuccess(status) ? deferred.resolve : deferred.reject)({
|
10524
10559
|
data: response,
|
@@ -10549,8 +10584,33 @@ function $HttpProvider() {
|
|
10549
10584
|
}];
|
10550
10585
|
}
|
10551
10586
|
|
10552
|
-
|
10553
|
-
|
10587
|
+
/**
|
10588
|
+
* @ngdoc service
|
10589
|
+
* @name $xhrFactory
|
10590
|
+
*
|
10591
|
+
* @description
|
10592
|
+
* Factory function used to create XMLHttpRequest objects.
|
10593
|
+
*
|
10594
|
+
* Replace or decorate this service to create your own custom XMLHttpRequest objects.
|
10595
|
+
*
|
10596
|
+
* ```
|
10597
|
+
* angular.module('myApp', [])
|
10598
|
+
* .factory('$xhrFactory', function() {
|
10599
|
+
* return function createXhr(method, url) {
|
10600
|
+
* return new window.XMLHttpRequest({mozSystem: true});
|
10601
|
+
* };
|
10602
|
+
* });
|
10603
|
+
* ```
|
10604
|
+
*
|
10605
|
+
* @param {string} method HTTP method of the request (GET, POST, PUT, ..)
|
10606
|
+
* @param {string} url URL of the request.
|
10607
|
+
*/
|
10608
|
+
function $xhrFactoryProvider() {
|
10609
|
+
this.$get = function() {
|
10610
|
+
return function createXhr() {
|
10611
|
+
return new window.XMLHttpRequest();
|
10612
|
+
};
|
10613
|
+
};
|
10554
10614
|
}
|
10555
10615
|
|
10556
10616
|
/**
|
@@ -10558,6 +10618,7 @@ function createXhr() {
|
|
10558
10618
|
* @name $httpBackend
|
10559
10619
|
* @requires $window
|
10560
10620
|
* @requires $document
|
10621
|
+
* @requires $xhrFactory
|
10561
10622
|
*
|
10562
10623
|
* @description
|
10563
10624
|
* HTTP backend used by the {@link ng.$http service} that delegates to
|
@@ -10570,8 +10631,8 @@ function createXhr() {
|
|
10570
10631
|
* $httpBackend} which can be trained with responses.
|
10571
10632
|
*/
|
10572
10633
|
function $HttpBackendProvider() {
|
10573
|
-
this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) {
|
10574
|
-
return createHttpBackend($browser,
|
10634
|
+
this.$get = ['$browser', '$window', '$document', '$xhrFactory', function($browser, $window, $document, $xhrFactory) {
|
10635
|
+
return createHttpBackend($browser, $xhrFactory, $browser.defer, $window.angular.callbacks, $document[0]);
|
10575
10636
|
}];
|
10576
10637
|
}
|
10577
10638
|
|
@@ -10595,7 +10656,7 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
|
|
10595
10656
|
});
|
10596
10657
|
} else {
|
10597
10658
|
|
10598
|
-
var xhr = createXhr();
|
10659
|
+
var xhr = createXhr(method, url);
|
10599
10660
|
|
10600
10661
|
xhr.open(method, url, true);
|
10601
10662
|
forEach(headers, function(value, key) {
|
@@ -10658,7 +10719,7 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
|
|
10658
10719
|
}
|
10659
10720
|
}
|
10660
10721
|
|
10661
|
-
xhr.send(post);
|
10722
|
+
xhr.send(isUndefined(post) ? null : post);
|
10662
10723
|
}
|
10663
10724
|
|
10664
10725
|
if (timeout > 0) {
|
@@ -10675,7 +10736,7 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
|
|
10675
10736
|
|
10676
10737
|
function completeRequest(callback, status, response, headersString, statusText) {
|
10677
10738
|
// cancel timeout and subsequent timeout promise resolution
|
10678
|
-
if (timeoutId
|
10739
|
+
if (isDefined(timeoutId)) {
|
10679
10740
|
$browserDefer.cancel(timeoutId);
|
10680
10741
|
}
|
10681
10742
|
jsonpDone = xhr = null;
|
@@ -10861,7 +10922,7 @@ function $InterpolateProvider() {
|
|
10861
10922
|
* ```js
|
10862
10923
|
* var $interpolate = ...; // injected
|
10863
10924
|
* var exp = $interpolate('Hello {{name | uppercase}}!');
|
10864
|
-
* expect(exp({name:'Angular'}).toEqual('Hello ANGULAR!');
|
10925
|
+
* expect(exp({name:'Angular'})).toEqual('Hello ANGULAR!');
|
10865
10926
|
* ```
|
10866
10927
|
*
|
10867
10928
|
* `$interpolate` takes an optional fourth argument, `allOrNothing`. If `allOrNothing` is
|
@@ -11414,14 +11475,14 @@ function LocationHtml5Url(appBase, appBaseNoFile, basePrefix) {
|
|
11414
11475
|
var appUrl, prevAppUrl;
|
11415
11476
|
var rewrittenUrl;
|
11416
11477
|
|
11417
|
-
if ((appUrl = beginsWith(appBase, url))
|
11478
|
+
if (isDefined(appUrl = beginsWith(appBase, url))) {
|
11418
11479
|
prevAppUrl = appUrl;
|
11419
|
-
if ((appUrl = beginsWith(basePrefix, appUrl))
|
11480
|
+
if (isDefined(appUrl = beginsWith(basePrefix, appUrl))) {
|
11420
11481
|
rewrittenUrl = appBaseNoFile + (beginsWith('/', appUrl) || appUrl);
|
11421
11482
|
} else {
|
11422
11483
|
rewrittenUrl = appBase + prevAppUrl;
|
11423
11484
|
}
|
11424
|
-
} else if ((appUrl = beginsWith(appBaseNoFile, url))
|
11485
|
+
} else if (isDefined(appUrl = beginsWith(appBaseNoFile, url))) {
|
11425
11486
|
rewrittenUrl = appBaseNoFile + appUrl;
|
11426
11487
|
} else if (appBaseNoFile == url + '/') {
|
11427
11488
|
rewrittenUrl = appBaseNoFile;
|
@@ -12474,6 +12535,25 @@ function ensureSafeMemberName(name, fullExpression) {
|
|
12474
12535
|
return name;
|
12475
12536
|
}
|
12476
12537
|
|
12538
|
+
function getStringValue(name, fullExpression) {
|
12539
|
+
// From the JavaScript docs:
|
12540
|
+
// Property names must be strings. This means that non-string objects cannot be used
|
12541
|
+
// as keys in an object. Any non-string object, including a number, is typecasted
|
12542
|
+
// into a string via the toString method.
|
12543
|
+
//
|
12544
|
+
// So, to ensure that we are checking the same `name` that JavaScript would use,
|
12545
|
+
// we cast it to a string, if possible.
|
12546
|
+
// Doing `name + ''` can cause a repl error if the result to `toString` is not a string,
|
12547
|
+
// this is, this will handle objects that misbehave.
|
12548
|
+
name = name + '';
|
12549
|
+
if (!isString(name)) {
|
12550
|
+
throw $parseMinErr('iseccst',
|
12551
|
+
'Cannot convert object to primitive value! '
|
12552
|
+
+ 'Expression: {0}', fullExpression);
|
12553
|
+
}
|
12554
|
+
return name;
|
12555
|
+
}
|
12556
|
+
|
12477
12557
|
function ensureSafeObject(obj, fullExpression) {
|
12478
12558
|
// nifty check if obj is Function that is fast and works across iframes and other contexts
|
12479
12559
|
if (obj) {
|
@@ -12519,6 +12599,16 @@ function ensureSafeFunction(obj, fullExpression) {
|
|
12519
12599
|
}
|
12520
12600
|
}
|
12521
12601
|
|
12602
|
+
function ensureSafeAssignContext(obj, fullExpression) {
|
12603
|
+
if (obj) {
|
12604
|
+
if (obj === (0).constructor || obj === (false).constructor || obj === ''.constructor ||
|
12605
|
+
obj === {}.constructor || obj === [].constructor || obj === Function.constructor) {
|
12606
|
+
throw $parseMinErr('isecaf',
|
12607
|
+
'Assigning to a constructor is disallowed! Expression: {0}', fullExpression);
|
12608
|
+
}
|
12609
|
+
}
|
12610
|
+
}
|
12611
|
+
|
12522
12612
|
var OPERATORS = createMap();
|
12523
12613
|
forEach('+ - * / % === !== == != < > <= >= && || ! = |'.split(' '), function(operator) { OPERATORS[operator] = true; });
|
12524
12614
|
var ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'};
|
@@ -13200,6 +13290,7 @@ ASTCompiler.prototype = {
|
|
13200
13290
|
this.state.computing = 'assign';
|
13201
13291
|
var result = this.nextId();
|
13202
13292
|
this.recurse(assignable, result);
|
13293
|
+
this.return_(result);
|
13203
13294
|
extra = 'fn.assign=' + this.generateFunction('assign', 's,v,l');
|
13204
13295
|
}
|
13205
13296
|
var toWatch = getInputs(ast.body);
|
@@ -13232,6 +13323,8 @@ ASTCompiler.prototype = {
|
|
13232
13323
|
'ensureSafeMemberName',
|
13233
13324
|
'ensureSafeObject',
|
13234
13325
|
'ensureSafeFunction',
|
13326
|
+
'getStringValue',
|
13327
|
+
'ensureSafeAssignContext',
|
13235
13328
|
'ifDefined',
|
13236
13329
|
'plus',
|
13237
13330
|
'text',
|
@@ -13240,6 +13333,8 @@ ASTCompiler.prototype = {
|
|
13240
13333
|
ensureSafeMemberName,
|
13241
13334
|
ensureSafeObject,
|
13242
13335
|
ensureSafeFunction,
|
13336
|
+
getStringValue,
|
13337
|
+
ensureSafeAssignContext,
|
13243
13338
|
ifDefined,
|
13244
13339
|
plusFn,
|
13245
13340
|
expression);
|
@@ -13383,6 +13478,7 @@ ASTCompiler.prototype = {
|
|
13383
13478
|
if (ast.computed) {
|
13384
13479
|
right = self.nextId();
|
13385
13480
|
self.recurse(ast.property, right);
|
13481
|
+
self.getStringValue(right);
|
13386
13482
|
self.addEnsureSafeMemberName(right);
|
13387
13483
|
if (create && create !== 1) {
|
13388
13484
|
self.if_(self.not(self.computedMember(left, right)), self.lazyAssign(self.computedMember(left, right), '{}'));
|
@@ -13466,6 +13562,7 @@ ASTCompiler.prototype = {
|
|
13466
13562
|
self.if_(self.notNull(left.context), function() {
|
13467
13563
|
self.recurse(ast.right, right);
|
13468
13564
|
self.addEnsureSafeObject(self.member(left.context, left.name, left.computed));
|
13565
|
+
self.addEnsureSafeAssignContext(left.context);
|
13469
13566
|
expression = self.member(left.context, left.name, left.computed) + ast.operator + right;
|
13470
13567
|
self.assign(intoId, expression);
|
13471
13568
|
recursionFn(intoId || expression);
|
@@ -13591,6 +13688,10 @@ ASTCompiler.prototype = {
|
|
13591
13688
|
this.current().body.push(this.ensureSafeFunction(item), ';');
|
13592
13689
|
},
|
13593
13690
|
|
13691
|
+
addEnsureSafeAssignContext: function(item) {
|
13692
|
+
this.current().body.push(this.ensureSafeAssignContext(item), ';');
|
13693
|
+
},
|
13694
|
+
|
13594
13695
|
ensureSafeObject: function(item) {
|
13595
13696
|
return 'ensureSafeObject(' + item + ',text)';
|
13596
13697
|
},
|
@@ -13603,6 +13704,14 @@ ASTCompiler.prototype = {
|
|
13603
13704
|
return 'ensureSafeFunction(' + item + ',text)';
|
13604
13705
|
},
|
13605
13706
|
|
13707
|
+
getStringValue: function(item) {
|
13708
|
+
this.assign(item, 'getStringValue(' + item + ',text)');
|
13709
|
+
},
|
13710
|
+
|
13711
|
+
ensureSafeAssignContext: function(item) {
|
13712
|
+
return 'ensureSafeAssignContext(' + item + ',text)';
|
13713
|
+
},
|
13714
|
+
|
13606
13715
|
lazyRecurse: function(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck) {
|
13607
13716
|
var self = this;
|
13608
13717
|
return function() {
|
@@ -13780,6 +13889,7 @@ ASTInterpreter.prototype = {
|
|
13780
13889
|
var lhs = left(scope, locals, assign, inputs);
|
13781
13890
|
var rhs = right(scope, locals, assign, inputs);
|
13782
13891
|
ensureSafeObject(lhs.value, self.expression);
|
13892
|
+
ensureSafeAssignContext(lhs.context);
|
13783
13893
|
lhs.context[lhs.name] = rhs;
|
13784
13894
|
return context ? {value: rhs} : rhs;
|
13785
13895
|
};
|
@@ -13977,6 +14087,7 @@ ASTInterpreter.prototype = {
|
|
13977
14087
|
var value;
|
13978
14088
|
if (lhs != null) {
|
13979
14089
|
rhs = right(scope, locals, assign, inputs);
|
14090
|
+
rhs = getStringValue(rhs);
|
13980
14091
|
ensureSafeMemberName(rhs, expression);
|
13981
14092
|
if (create && create !== 1 && lhs && !(lhs[rhs])) {
|
13982
14093
|
lhs[rhs] = {};
|
@@ -14917,7 +15028,7 @@ function $$RAFProvider() { //rAF
|
|
14917
15028
|
$window.webkitCancelRequestAnimationFrame;
|
14918
15029
|
|
14919
15030
|
var rafSupported = !!requestAnimationFrame;
|
14920
|
-
var
|
15031
|
+
var raf = rafSupported
|
14921
15032
|
? function(fn) {
|
14922
15033
|
var id = requestAnimationFrame(fn);
|
14923
15034
|
return function() {
|
@@ -14931,47 +15042,9 @@ function $$RAFProvider() { //rAF
|
|
14931
15042
|
};
|
14932
15043
|
};
|
14933
15044
|
|
14934
|
-
|
14935
|
-
|
14936
|
-
var cancelLastRAF;
|
14937
|
-
var taskCount = 0;
|
14938
|
-
var taskQueue = [];
|
14939
|
-
return queueFn;
|
14940
|
-
|
14941
|
-
function flush() {
|
14942
|
-
for (var i = 0; i < taskQueue.length; i++) {
|
14943
|
-
var task = taskQueue[i];
|
14944
|
-
if (task) {
|
14945
|
-
taskQueue[i] = null;
|
14946
|
-
task();
|
14947
|
-
}
|
14948
|
-
}
|
14949
|
-
taskCount = taskQueue.length = 0;
|
14950
|
-
}
|
14951
|
-
|
14952
|
-
function queueFn(asyncFn) {
|
14953
|
-
var index = taskQueue.length;
|
15045
|
+
raf.supported = rafSupported;
|
14954
15046
|
|
14955
|
-
|
14956
|
-
taskQueue.push(asyncFn);
|
14957
|
-
|
14958
|
-
if (index === 0) {
|
14959
|
-
cancelLastRAF = rafFn(flush);
|
14960
|
-
}
|
14961
|
-
|
14962
|
-
return function cancelQueueFn() {
|
14963
|
-
if (index >= 0) {
|
14964
|
-
taskQueue[index] = null;
|
14965
|
-
index = null;
|
14966
|
-
|
14967
|
-
if (--taskCount === 0 && cancelLastRAF) {
|
14968
|
-
cancelLastRAF();
|
14969
|
-
cancelLastRAF = null;
|
14970
|
-
taskQueue.length = 0;
|
14971
|
-
}
|
14972
|
-
}
|
14973
|
-
};
|
14974
|
-
}
|
15047
|
+
return raf;
|
14975
15048
|
}];
|
14976
15049
|
}
|
14977
15050
|
|
@@ -15228,10 +15301,10 @@ function $RootScopeProvider() {
|
|
15228
15301
|
* Registers a `listener` callback to be executed whenever the `watchExpression` changes.
|
15229
15302
|
*
|
15230
15303
|
* - The `watchExpression` is called on every call to {@link ng.$rootScope.Scope#$digest
|
15231
|
-
* $digest()} and should return the value that will be watched. (
|
15232
|
-
*
|
15233
|
-
* `watchExpression`
|
15234
|
-
*
|
15304
|
+
* $digest()} and should return the value that will be watched. (`watchExpression` should not change
|
15305
|
+
* its value when executed multiple times with the same input because it may be executed multiple
|
15306
|
+
* times by {@link ng.$rootScope.Scope#$digest $digest()}. That is, `watchExpression` should be
|
15307
|
+
* [idempotent](http://en.wikipedia.org/wiki/Idempotence).
|
15235
15308
|
* - The `listener` is called only when the value from the current `watchExpression` and the
|
15236
15309
|
* previous call to `watchExpression` are not equal (with the exception of the initial run,
|
15237
15310
|
* see below). Inequality is determined according to reference inequality,
|
@@ -15580,7 +15653,7 @@ function $RootScopeProvider() {
|
|
15580
15653
|
// copy the items to oldValue and look for changes.
|
15581
15654
|
newLength = 0;
|
15582
15655
|
for (key in newValue) {
|
15583
|
-
if (
|
15656
|
+
if (hasOwnProperty.call(newValue, key)) {
|
15584
15657
|
newLength++;
|
15585
15658
|
newItem = newValue[key];
|
15586
15659
|
oldItem = oldValue[key];
|
@@ -15602,7 +15675,7 @@ function $RootScopeProvider() {
|
|
15602
15675
|
// we used to have more keys, need to find them and destroy them.
|
15603
15676
|
changeDetected++;
|
15604
15677
|
for (key in oldValue) {
|
15605
|
-
if (!
|
15678
|
+
if (!hasOwnProperty.call(newValue, key)) {
|
15606
15679
|
oldLength--;
|
15607
15680
|
delete oldValue[key];
|
15608
15681
|
}
|
@@ -16687,7 +16760,7 @@ function $SceDelegateProvider() {
|
|
16687
16760
|
'Attempted to trust a value in invalid context. Context: {0}; Value: {1}',
|
16688
16761
|
type, trustedValue);
|
16689
16762
|
}
|
16690
|
-
if (trustedValue === null || trustedValue
|
16763
|
+
if (trustedValue === null || isUndefined(trustedValue) || trustedValue === '') {
|
16691
16764
|
return trustedValue;
|
16692
16765
|
}
|
16693
16766
|
// All the current contexts in SCE_CONTEXTS happen to be strings. In order to avoid trusting
|
@@ -16742,7 +16815,7 @@ function $SceDelegateProvider() {
|
|
16742
16815
|
* `$sceDelegate.trustAs`} if valid in this context. Otherwise, throws an exception.
|
16743
16816
|
*/
|
16744
16817
|
function getTrusted(type, maybeTrusted) {
|
16745
|
-
if (maybeTrusted === null || maybeTrusted
|
16818
|
+
if (maybeTrusted === null || isUndefined(maybeTrusted) || maybeTrusted === '') {
|
16746
16819
|
return maybeTrusted;
|
16747
16820
|
}
|
16748
16821
|
var constructor = (byType.hasOwnProperty(type) ? byType[type] : null);
|
@@ -18003,7 +18076,7 @@ function $$CookieReader($document) {
|
|
18003
18076
|
// the first value that is seen for a cookie is the most
|
18004
18077
|
// specific one. values for the same cookie name that
|
18005
18078
|
// follow are for less specific paths.
|
18006
|
-
if (lastCookies[name]
|
18079
|
+
if (isUndefined(lastCookies[name])) {
|
18007
18080
|
lastCookies[name] = safeDecodeURIComponent(cookie.substring(index + 1));
|
18008
18081
|
}
|
18009
18082
|
}
|
@@ -18651,6 +18724,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
|
|
18651
18724
|
if (fractionSize > 0 && number < 1) {
|
18652
18725
|
formatedText = number.toFixed(fractionSize);
|
18653
18726
|
number = parseFloat(formatedText);
|
18727
|
+
formatedText = formatedText.replace(DECIMAL_SEP, decimalSep);
|
18654
18728
|
}
|
18655
18729
|
}
|
18656
18730
|
|
@@ -19949,6 +20023,7 @@ function nullFormRenameControl(control, name) {
|
|
19949
20023
|
* @property {boolean} $dirty True if user has already interacted with the form.
|
19950
20024
|
* @property {boolean} $valid True if all of the containing forms and controls are valid.
|
19951
20025
|
* @property {boolean} $invalid True if at least one containing control or form is invalid.
|
20026
|
+
* @property {boolean} $pending True if at least one containing control or form is pending.
|
19952
20027
|
* @property {boolean} $submitted True if user has submitted the form even if its invalid.
|
19953
20028
|
*
|
19954
20029
|
* @property {Object} $error Is an object hash, containing references to controls or
|
@@ -19988,8 +20063,6 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
|
|
19988
20063
|
var form = this,
|
19989
20064
|
controls = [];
|
19990
20065
|
|
19991
|
-
var parentForm = form.$$parentForm = element.parent().controller('form') || nullFormCtrl;
|
19992
|
-
|
19993
20066
|
// init state
|
19994
20067
|
form.$error = {};
|
19995
20068
|
form.$$success = {};
|
@@ -20000,8 +20073,7 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
|
|
20000
20073
|
form.$valid = true;
|
20001
20074
|
form.$invalid = false;
|
20002
20075
|
form.$submitted = false;
|
20003
|
-
|
20004
|
-
parentForm.$addControl(form);
|
20076
|
+
form.$$parentForm = nullFormCtrl;
|
20005
20077
|
|
20006
20078
|
/**
|
20007
20079
|
* @ngdoc method
|
@@ -20040,11 +20112,23 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
|
|
20040
20112
|
/**
|
20041
20113
|
* @ngdoc method
|
20042
20114
|
* @name form.FormController#$addControl
|
20115
|
+
* @param {object} control control object, either a {@link form.FormController} or an
|
20116
|
+
* {@link ngModel.NgModelController}
|
20043
20117
|
*
|
20044
20118
|
* @description
|
20045
|
-
* Register a control with the form.
|
20119
|
+
* Register a control with the form. Input elements using ngModelController do this automatically
|
20120
|
+
* when they are linked.
|
20046
20121
|
*
|
20047
|
-
*
|
20122
|
+
* Note that the current state of the control will not be reflected on the new parent form. This
|
20123
|
+
* is not an issue with normal use, as freshly compiled and linked controls are in a `$pristine`
|
20124
|
+
* state.
|
20125
|
+
*
|
20126
|
+
* However, if the method is used programmatically, for example by adding dynamically created controls,
|
20127
|
+
* or controls that have been previously removed without destroying their corresponding DOM element,
|
20128
|
+
* it's the developers responsiblity to make sure the current state propagates to the parent form.
|
20129
|
+
*
|
20130
|
+
* For example, if an input control is added that is already `$dirty` and has `$error` properties,
|
20131
|
+
* calling `$setDirty()` and `$validate()` afterwards will propagate the state to the parent form.
|
20048
20132
|
*/
|
20049
20133
|
form.$addControl = function(control) {
|
20050
20134
|
// Breaking change - before, inputs whose name was "hasOwnProperty" were quietly ignored
|
@@ -20055,6 +20139,8 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
|
|
20055
20139
|
if (control.$name) {
|
20056
20140
|
form[control.$name] = control;
|
20057
20141
|
}
|
20142
|
+
|
20143
|
+
control.$$parentForm = form;
|
20058
20144
|
};
|
20059
20145
|
|
20060
20146
|
// Private API: rename a form control
|
@@ -20071,11 +20157,18 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
|
|
20071
20157
|
/**
|
20072
20158
|
* @ngdoc method
|
20073
20159
|
* @name form.FormController#$removeControl
|
20160
|
+
* @param {object} control control object, either a {@link form.FormController} or an
|
20161
|
+
* {@link ngModel.NgModelController}
|
20074
20162
|
*
|
20075
20163
|
* @description
|
20076
20164
|
* Deregister a control from the form.
|
20077
20165
|
*
|
20078
20166
|
* Input elements using ngModelController do this automatically when they are destroyed.
|
20167
|
+
*
|
20168
|
+
* Note that only the removed control's validation state (`$errors`etc.) will be removed from the
|
20169
|
+
* form. `$dirty`, `$submitted` states will not be changed, because the expected behavior can be
|
20170
|
+
* different from case to case. For example, removing the only `$dirty` control from a form may or
|
20171
|
+
* may not mean that the form is still `$dirty`.
|
20079
20172
|
*/
|
20080
20173
|
form.$removeControl = function(control) {
|
20081
20174
|
if (control.$name && form[control.$name] === control) {
|
@@ -20092,6 +20185,7 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
|
|
20092
20185
|
});
|
20093
20186
|
|
20094
20187
|
arrayRemove(controls, control);
|
20188
|
+
control.$$parentForm = nullFormCtrl;
|
20095
20189
|
};
|
20096
20190
|
|
20097
20191
|
|
@@ -20128,7 +20222,6 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
|
|
20128
20222
|
delete object[property];
|
20129
20223
|
}
|
20130
20224
|
},
|
20131
|
-
parentForm: parentForm,
|
20132
20225
|
$animate: $animate
|
20133
20226
|
});
|
20134
20227
|
|
@@ -20147,7 +20240,7 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
|
|
20147
20240
|
$animate.addClass(element, DIRTY_CLASS);
|
20148
20241
|
form.$dirty = true;
|
20149
20242
|
form.$pristine = false;
|
20150
|
-
parentForm.$setDirty();
|
20243
|
+
form.$$parentForm.$setDirty();
|
20151
20244
|
};
|
20152
20245
|
|
20153
20246
|
/**
|
@@ -20203,7 +20296,7 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
|
|
20203
20296
|
form.$setSubmitted = function() {
|
20204
20297
|
$animate.addClass(element, SUBMITTED_CLASS);
|
20205
20298
|
form.$submitted = true;
|
20206
|
-
parentForm.$setSubmitted();
|
20299
|
+
form.$$parentForm.$setSubmitted();
|
20207
20300
|
};
|
20208
20301
|
}
|
20209
20302
|
|
@@ -20253,6 +20346,7 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
|
|
20253
20346
|
* # CSS classes
|
20254
20347
|
* - `ng-valid` is set if the form is valid.
|
20255
20348
|
* - `ng-invalid` is set if the form is invalid.
|
20349
|
+
* - `ng-pending` is set if the form is pending.
|
20256
20350
|
* - `ng-pristine` is set if the form is pristine.
|
20257
20351
|
* - `ng-dirty` is set if the form is dirty.
|
20258
20352
|
* - `ng-submitted` is set if the form was submitted.
|
@@ -20328,7 +20422,6 @@ function FormController(element, attrs, $scope, $animate, $interpolate) {
|
|
20328
20422
|
</script>
|
20329
20423
|
<style>
|
20330
20424
|
.my-form {
|
20331
|
-
-webkit-transition:all linear 0.5s;
|
20332
20425
|
transition:all linear 0.5s;
|
20333
20426
|
background: transparent;
|
20334
20427
|
}
|
@@ -20377,6 +20470,7 @@ var formDirectiveFactory = function(isNgForm) {
|
|
20377
20470
|
var formDirective = {
|
20378
20471
|
name: 'form',
|
20379
20472
|
restrict: isNgForm ? 'EAC' : 'E',
|
20473
|
+
require: ['form', '^^?form'], //first is the form's own ctrl, second is an optional parent form
|
20380
20474
|
controller: FormController,
|
20381
20475
|
compile: function ngFormCompile(formElement, attr) {
|
20382
20476
|
// Setup initial state of the control
|
@@ -20385,7 +20479,9 @@ var formDirectiveFactory = function(isNgForm) {
|
|
20385
20479
|
var nameAttr = attr.name ? 'name' : (isNgForm && attr.ngForm ? 'ngForm' : false);
|
20386
20480
|
|
20387
20481
|
return {
|
20388
|
-
pre: function ngFormPreLink(scope, formElement, attr,
|
20482
|
+
pre: function ngFormPreLink(scope, formElement, attr, ctrls) {
|
20483
|
+
var controller = ctrls[0];
|
20484
|
+
|
20389
20485
|
// if `action` attr is not present on the form, prevent the default action (submission)
|
20390
20486
|
if (!('action' in attr)) {
|
20391
20487
|
// we can't use jq events because if a form is destroyed during submission the default
|
@@ -20414,7 +20510,9 @@ var formDirectiveFactory = function(isNgForm) {
|
|
20414
20510
|
});
|
20415
20511
|
}
|
20416
20512
|
|
20417
|
-
var parentFormCtrl = controller.$$parentForm;
|
20513
|
+
var parentFormCtrl = ctrls[1] || controller.$$parentForm;
|
20514
|
+
parentFormCtrl.$addControl(controller);
|
20515
|
+
|
20418
20516
|
var setter = nameAttr ? getSetter(controller.$name) : noop;
|
20419
20517
|
|
20420
20518
|
if (nameAttr) {
|
@@ -20422,13 +20520,13 @@ var formDirectiveFactory = function(isNgForm) {
|
|
20422
20520
|
attr.$observe(nameAttr, function(newValue) {
|
20423
20521
|
if (controller.$name === newValue) return;
|
20424
20522
|
setter(scope, undefined);
|
20425
|
-
|
20523
|
+
controller.$$parentForm.$$renameControl(controller, newValue);
|
20426
20524
|
setter = getSetter(controller.$name);
|
20427
20525
|
setter(scope, controller);
|
20428
20526
|
});
|
20429
20527
|
}
|
20430
20528
|
formElement.on('$destroy', function() {
|
20431
|
-
|
20529
|
+
controller.$$parentForm.$removeControl(controller);
|
20432
20530
|
setter(scope, undefined);
|
20433
20531
|
extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards
|
20434
20532
|
});
|
@@ -20590,9 +20688,17 @@ var inputType = {
|
|
20590
20688
|
* @param {string} ngModel Assignable angular expression to data-bind to.
|
20591
20689
|
* @param {string=} name Property name of the form under which the control is published.
|
20592
20690
|
* @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. This must be a
|
20593
|
-
*
|
20691
|
+
* valid ISO date string (yyyy-MM-dd). You can also use interpolation inside this attribute
|
20692
|
+
* (e.g. `min="{{minDate | date:'yyyy-MM-dd'}}"`). Note that `min` will also add native HTML5
|
20693
|
+
* constraint validation.
|
20594
20694
|
* @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. This must be
|
20595
|
-
*
|
20695
|
+
* a valid ISO date string (yyyy-MM-dd). You can also use interpolation inside this attribute
|
20696
|
+
* (e.g. `max="{{maxDate | date:'yyyy-MM-dd'}}"`). Note that `max` will also add native HTML5
|
20697
|
+
* constraint validation.
|
20698
|
+
* @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO date string
|
20699
|
+
* the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.
|
20700
|
+
* @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO date string
|
20701
|
+
* the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.
|
20596
20702
|
* @param {string=} required Sets `required` validation error key if the value is not entered.
|
20597
20703
|
* @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
|
20598
20704
|
* the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
|
@@ -20684,10 +20790,18 @@ var inputType = {
|
|
20684
20790
|
*
|
20685
20791
|
* @param {string} ngModel Assignable angular expression to data-bind to.
|
20686
20792
|
* @param {string=} name Property name of the form under which the control is published.
|
20687
|
-
* @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
|
20688
|
-
* valid ISO datetime format (yyyy-MM-ddTHH:mm:ss).
|
20689
|
-
*
|
20690
|
-
*
|
20793
|
+
* @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
|
20794
|
+
* This must be a valid ISO datetime format (yyyy-MM-ddTHH:mm:ss). You can also use interpolation
|
20795
|
+
* inside this attribute (e.g. `min="{{minDatetimeLocal | date:'yyyy-MM-ddTHH:mm:ss'}}"`).
|
20796
|
+
* Note that `min` will also add native HTML5 constraint validation.
|
20797
|
+
* @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
|
20798
|
+
* This must be a valid ISO datetime format (yyyy-MM-ddTHH:mm:ss). You can also use interpolation
|
20799
|
+
* inside this attribute (e.g. `max="{{maxDatetimeLocal | date:'yyyy-MM-ddTHH:mm:ss'}}"`).
|
20800
|
+
* Note that `max` will also add native HTML5 constraint validation.
|
20801
|
+
* @param {(date|string)=} ngMin Sets the `min` validation error key to the Date / ISO datetime string
|
20802
|
+
* the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.
|
20803
|
+
* @param {(date|string)=} ngMax Sets the `max` validation error key to the Date / ISO datetime string
|
20804
|
+
* the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.
|
20691
20805
|
* @param {string=} required Sets `required` validation error key if the value is not entered.
|
20692
20806
|
* @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
|
20693
20807
|
* the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
|
@@ -20780,10 +20894,18 @@ var inputType = {
|
|
20780
20894
|
*
|
20781
20895
|
* @param {string} ngModel Assignable angular expression to data-bind to.
|
20782
20896
|
* @param {string=} name Property name of the form under which the control is published.
|
20783
|
-
* @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
|
20784
|
-
* valid ISO time format (HH:mm:ss).
|
20785
|
-
*
|
20786
|
-
*
|
20897
|
+
* @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
|
20898
|
+
* This must be a valid ISO time format (HH:mm:ss). You can also use interpolation inside this
|
20899
|
+
* attribute (e.g. `min="{{minTime | date:'HH:mm:ss'}}"`). Note that `min` will also add
|
20900
|
+
* native HTML5 constraint validation.
|
20901
|
+
* @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
|
20902
|
+
* This must be a valid ISO time format (HH:mm:ss). You can also use interpolation inside this
|
20903
|
+
* attribute (e.g. `max="{{maxTime | date:'HH:mm:ss'}}"`). Note that `max` will also add
|
20904
|
+
* native HTML5 constraint validation.
|
20905
|
+
* @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO time string the
|
20906
|
+
* `ngMin` expression evaluates to. Note that it does not set the `min` attribute.
|
20907
|
+
* @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO time string the
|
20908
|
+
* `ngMax` expression evaluates to. Note that it does not set the `max` attribute.
|
20787
20909
|
* @param {string=} required Sets `required` validation error key if the value is not entered.
|
20788
20910
|
* @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
|
20789
20911
|
* the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
|
@@ -20875,10 +20997,18 @@ var inputType = {
|
|
20875
20997
|
*
|
20876
20998
|
* @param {string} ngModel Assignable angular expression to data-bind to.
|
20877
20999
|
* @param {string=} name Property name of the form under which the control is published.
|
20878
|
-
* @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
|
20879
|
-
* valid ISO week format (yyyy-W##).
|
20880
|
-
*
|
20881
|
-
*
|
21000
|
+
* @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
|
21001
|
+
* This must be a valid ISO week format (yyyy-W##). You can also use interpolation inside this
|
21002
|
+
* attribute (e.g. `min="{{minWeek | date:'yyyy-Www'}}"`). Note that `min` will also add
|
21003
|
+
* native HTML5 constraint validation.
|
21004
|
+
* @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
|
21005
|
+
* This must be a valid ISO week format (yyyy-W##). You can also use interpolation inside this
|
21006
|
+
* attribute (e.g. `max="{{maxWeek | date:'yyyy-Www'}}"`). Note that `max` will also add
|
21007
|
+
* native HTML5 constraint validation.
|
21008
|
+
* @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO week string
|
21009
|
+
* the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.
|
21010
|
+
* @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO week string
|
21011
|
+
* the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.
|
20882
21012
|
* @param {string=} required Sets `required` validation error key if the value is not entered.
|
20883
21013
|
* @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
|
20884
21014
|
* the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
|
@@ -20972,10 +21102,19 @@ var inputType = {
|
|
20972
21102
|
*
|
20973
21103
|
* @param {string} ngModel Assignable angular expression to data-bind to.
|
20974
21104
|
* @param {string=} name Property name of the form under which the control is published.
|
20975
|
-
* @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
|
20976
|
-
* a valid ISO month format (yyyy-MM).
|
20977
|
-
*
|
20978
|
-
*
|
21105
|
+
* @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
|
21106
|
+
* This must be a valid ISO month format (yyyy-MM). You can also use interpolation inside this
|
21107
|
+
* attribute (e.g. `min="{{minMonth | date:'yyyy-MM'}}"`). Note that `min` will also add
|
21108
|
+
* native HTML5 constraint validation.
|
21109
|
+
* @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
|
21110
|
+
* This must be a valid ISO month format (yyyy-MM). You can also use interpolation inside this
|
21111
|
+
* attribute (e.g. `max="{{maxMonth | date:'yyyy-MM'}}"`). Note that `max` will also add
|
21112
|
+
* native HTML5 constraint validation.
|
21113
|
+
* @param {(date|string)=} ngMin Sets the `min` validation constraint to the Date / ISO week string
|
21114
|
+
* the `ngMin` expression evaluates to. Note that it does not set the `min` attribute.
|
21115
|
+
* @param {(date|string)=} ngMax Sets the `max` validation constraint to the Date / ISO week string
|
21116
|
+
* the `ngMax` expression evaluates to. Note that it does not set the `max` attribute.
|
21117
|
+
|
20979
21118
|
* @param {string=} required Sets `required` validation error key if the value is not entered.
|
20980
21119
|
* @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
|
20981
21120
|
* the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
|
@@ -21737,7 +21876,7 @@ function createDateInputType(type, regexp, parseDate, format) {
|
|
21737
21876
|
}
|
21738
21877
|
|
21739
21878
|
function parseObservedDateValue(val) {
|
21740
|
-
return isDefined(val)
|
21879
|
+
return isDefined(val) && !isDate(val) ? parseDate(val) || undefined : val;
|
21741
21880
|
}
|
21742
21881
|
};
|
21743
21882
|
}
|
@@ -22232,7 +22371,7 @@ var ngBindDirective = ['$compile', function($compile) {
|
|
22232
22371
|
$compile.$$addBindingInfo(element, attr.ngBind);
|
22233
22372
|
element = element[0];
|
22234
22373
|
scope.$watch(attr.ngBind, function ngBindWatchAction(value) {
|
22235
|
-
element.textContent = value
|
22374
|
+
element.textContent = isUndefined(value) ? '' : value;
|
22236
22375
|
});
|
22237
22376
|
};
|
22238
22377
|
}
|
@@ -22300,7 +22439,7 @@ var ngBindTemplateDirective = ['$interpolate', '$compile', function($interpolate
|
|
22300
22439
|
$compile.$$addBindingInfo(element, interpolateFn.expressions);
|
22301
22440
|
element = element[0];
|
22302
22441
|
attr.$observe('ngBindTemplate', function(value) {
|
22303
|
-
element.textContent = value
|
22442
|
+
element.textContent = isUndefined(value) ? '' : value;
|
22304
22443
|
});
|
22305
22444
|
};
|
22306
22445
|
}
|
@@ -22717,7 +22856,6 @@ function classDirective(name, selector) {
|
|
22717
22856
|
</file>
|
22718
22857
|
<file name="style.css">
|
22719
22858
|
.base-class {
|
22720
|
-
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
22721
22859
|
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
22722
22860
|
}
|
22723
22861
|
|
@@ -23892,7 +24030,6 @@ forEach(
|
|
23892
24030
|
}
|
23893
24031
|
|
23894
24032
|
.animate-if.ng-enter, .animate-if.ng-leave {
|
23895
|
-
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
23896
24033
|
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
23897
24034
|
}
|
23898
24035
|
|
@@ -24041,7 +24178,6 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
24041
24178
|
}
|
24042
24179
|
|
24043
24180
|
.slide-animate.ng-enter, .slide-animate.ng-leave {
|
24044
|
-
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
24045
24181
|
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
24046
24182
|
|
24047
24183
|
position:absolute;
|
@@ -24260,16 +24396,18 @@ var ngIncludeFillContentDirective = ['$compile',
|
|
24260
24396
|
* current scope.
|
24261
24397
|
*
|
24262
24398
|
* <div class="alert alert-danger">
|
24263
|
-
*
|
24264
|
-
*
|
24265
|
-
*
|
24266
|
-
*
|
24399
|
+
* This directive can be abused to add unnecessary amounts of logic into your templates.
|
24400
|
+
* There are only a few appropriate uses of `ngInit`, such as for aliasing special properties of
|
24401
|
+
* {@link ng.directive:ngRepeat `ngRepeat`}, as seen in the demo below; and for injecting data via
|
24402
|
+
* server side scripting. Besides these few cases, you should use {@link guide/controller controllers}
|
24403
|
+
* rather than `ngInit` to initialize values on a scope.
|
24267
24404
|
* </div>
|
24405
|
+
*
|
24268
24406
|
* <div class="alert alert-warning">
|
24269
|
-
* **Note**: If you have assignment in `ngInit` along with {@link ng.$filter
|
24270
|
-
* sure you have
|
24407
|
+
* **Note**: If you have assignment in `ngInit` along with a {@link ng.$filter `filter`}, make
|
24408
|
+
* sure you have parentheses to ensure correct operator precedence:
|
24271
24409
|
* <pre class="prettyprint">
|
24272
|
-
* `<div ng-init="test1 = (
|
24410
|
+
* `<div ng-init="test1 = ($index | toString)"></div>`
|
24273
24411
|
* </pre>
|
24274
24412
|
* </div>
|
24275
24413
|
*
|
@@ -24382,7 +24520,7 @@ var ngInitDirective = ngDirective({
|
|
24382
24520
|
* </file>
|
24383
24521
|
* </example>
|
24384
24522
|
*
|
24385
|
-
* ### Example - splitting on
|
24523
|
+
* ### Example - splitting on newline
|
24386
24524
|
* <example name="ngList-directive-newlines">
|
24387
24525
|
* <file name="index.html">
|
24388
24526
|
* <textarea ng-model="list" ng-list=" " ng-trim="false"></textarea>
|
@@ -24467,7 +24605,9 @@ var ngModelMinErr = minErr('ngModel');
|
|
24467
24605
|
* @ngdoc type
|
24468
24606
|
* @name ngModel.NgModelController
|
24469
24607
|
*
|
24470
|
-
* @property {
|
24608
|
+
* @property {*} $viewValue The actual value from the control's view. For `input` elements, this is a
|
24609
|
+
* String. See {@link ngModel.NgModelController#$setViewValue} for information about when the $viewValue
|
24610
|
+
* is set.
|
24471
24611
|
* @property {*} $modelValue The value in the model that the control is bound to.
|
24472
24612
|
* @property {Array.<Function>} $parsers Array of functions to execute, as a pipeline, whenever
|
24473
24613
|
the control reads value from the DOM. The functions are called in array order, each passing
|
@@ -24681,7 +24821,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
24681
24821
|
this.$$success = {}; // keep valid keys here
|
24682
24822
|
this.$pending = undefined; // keep pending keys here
|
24683
24823
|
this.$name = $interpolate($attr.name || '', false)($scope);
|
24684
|
-
|
24824
|
+
this.$$parentForm = nullFormCtrl;
|
24685
24825
|
|
24686
24826
|
var parsedNgModel = $parse($attr.ngModel),
|
24687
24827
|
parsedNgModelAssign = parsedNgModel.assign,
|
@@ -24761,8 +24901,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
24761
24901
|
return isUndefined(value) || value === '' || value === null || value !== value;
|
24762
24902
|
};
|
24763
24903
|
|
24764
|
-
var
|
24765
|
-
currentValidationRunId = 0;
|
24904
|
+
var currentValidationRunId = 0;
|
24766
24905
|
|
24767
24906
|
/**
|
24768
24907
|
* @ngdoc method
|
@@ -24795,7 +24934,6 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
24795
24934
|
unset: function(object, property) {
|
24796
24935
|
delete object[property];
|
24797
24936
|
},
|
24798
|
-
parentForm: parentForm,
|
24799
24937
|
$animate: $animate
|
24800
24938
|
});
|
24801
24939
|
|
@@ -24833,7 +24971,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
24833
24971
|
ctrl.$pristine = false;
|
24834
24972
|
$animate.removeClass($element, PRISTINE_CLASS);
|
24835
24973
|
$animate.addClass($element, DIRTY_CLASS);
|
24836
|
-
parentForm.$setDirty();
|
24974
|
+
ctrl.$$parentForm.$setDirty();
|
24837
24975
|
};
|
24838
24976
|
|
24839
24977
|
/**
|
@@ -25003,7 +25141,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
25003
25141
|
|
25004
25142
|
function processParseErrors() {
|
25005
25143
|
var errorKey = ctrl.$$parserName || 'parse';
|
25006
|
-
if (parserValid
|
25144
|
+
if (isUndefined(parserValid)) {
|
25007
25145
|
setValidity(errorKey, null);
|
25008
25146
|
} else {
|
25009
25147
|
if (!parserValid) {
|
@@ -25173,37 +25311,47 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
25173
25311
|
* @description
|
25174
25312
|
* Update the view value.
|
25175
25313
|
*
|
25176
|
-
* This method should be called when
|
25177
|
-
* this is done from within a DOM event handler.
|
25178
|
-
*
|
25179
|
-
*
|
25180
|
-
* {@link ng.directive:select select} calls it when an option is selected.
|
25181
|
-
*
|
25182
|
-
* If the new `value` is an object (rather than a string or a number), we should make a copy of the
|
25183
|
-
* object before passing it to `$setViewValue`. This is because `ngModel` does not perform a deep
|
25184
|
-
* watch of objects, it only looks for a change of identity. If you only change the property of
|
25185
|
-
* the object then ngModel will not realise that the object has changed and will not invoke the
|
25186
|
-
* `$parsers` and `$validators` pipelines.
|
25187
|
-
*
|
25188
|
-
* For this reason, you should not change properties of the copy once it has been passed to
|
25189
|
-
* `$setViewValue`. Otherwise you may cause the model value on the scope to change incorrectly.
|
25314
|
+
* This method should be called when a control wants to change the view value; typically,
|
25315
|
+
* this is done from within a DOM event handler. For example, the {@link ng.directive:input input}
|
25316
|
+
* directive calls it when the value of the input changes and {@link ng.directive:select select}
|
25317
|
+
* calls it when an option is selected.
|
25190
25318
|
*
|
25191
|
-
* When
|
25319
|
+
* When `$setViewValue` is called, the new `value` will be staged for committing through the `$parsers`
|
25192
25320
|
* and `$validators` pipelines. If there are no special {@link ngModelOptions} specified then the staged
|
25193
25321
|
* value sent directly for processing, finally to be applied to `$modelValue` and then the
|
25194
|
-
* **expression** specified in the `ng-model` attribute.
|
25195
|
-
*
|
25196
|
-
* Lastly, all the registered change listeners, in the `$viewChangeListeners` list, are called.
|
25322
|
+
* **expression** specified in the `ng-model` attribute. Lastly, all the registered change listeners,
|
25323
|
+
* in the `$viewChangeListeners` list, are called.
|
25197
25324
|
*
|
25198
25325
|
* In case the {@link ng.directive:ngModelOptions ngModelOptions} directive is used with `updateOn`
|
25199
25326
|
* and the `default` trigger is not listed, all those actions will remain pending until one of the
|
25200
25327
|
* `updateOn` events is triggered on the DOM element.
|
25201
25328
|
* All these actions will be debounced if the {@link ng.directive:ngModelOptions ngModelOptions}
|
25202
25329
|
* directive is used with a custom debounce for this particular event.
|
25330
|
+
* Note that a `$digest` is only triggered once the `updateOn` events are fired, or if `debounce`
|
25331
|
+
* is specified, once the timer runs out.
|
25332
|
+
*
|
25333
|
+
* When used with standard inputs, the view value will always be a string (which is in some cases
|
25334
|
+
* parsed into another type, such as a `Date` object for `input[date]`.)
|
25335
|
+
* However, custom controls might also pass objects to this method. In this case, we should make
|
25336
|
+
* a copy of the object before passing it to `$setViewValue`. This is because `ngModel` does not
|
25337
|
+
* perform a deep watch of objects, it only looks for a change of identity. If you only change
|
25338
|
+
* the property of the object then ngModel will not realise that the object has changed and
|
25339
|
+
* will not invoke the `$parsers` and `$validators` pipelines. For this reason, you should
|
25340
|
+
* not change properties of the copy once it has been passed to `$setViewValue`.
|
25341
|
+
* Otherwise you may cause the model value on the scope to change incorrectly.
|
25342
|
+
*
|
25343
|
+
* <div class="alert alert-info">
|
25344
|
+
* In any case, the value passed to the method should always reflect the current value
|
25345
|
+
* of the control. For example, if you are calling `$setViewValue` for an input element,
|
25346
|
+
* you should pass the input DOM value. Otherwise, the control and the scope model become
|
25347
|
+
* out of sync. It's also important to note that `$setViewValue` does not call `$render` or change
|
25348
|
+
* the control's DOM value in any way. If we want to change the control's DOM value
|
25349
|
+
* programmatically, we should update the `ngModel` scope expression. Its new value will be
|
25350
|
+
* picked up by the model controller, which will run it through the `$formatters`, `$render` it
|
25351
|
+
* to update the DOM, and finally call `$validate` on it.
|
25352
|
+
* </div>
|
25203
25353
|
*
|
25204
|
-
*
|
25205
|
-
*
|
25206
|
-
* @param {string} value Value from the view.
|
25354
|
+
* @param {*} value value from the view.
|
25207
25355
|
* @param {string} trigger Event that triggered the update.
|
25208
25356
|
*/
|
25209
25357
|
this.$setViewValue = function(value, trigger) {
|
@@ -25380,7 +25528,6 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
25380
25528
|
</script>
|
25381
25529
|
<style>
|
25382
25530
|
.my-input {
|
25383
|
-
-webkit-transition:all linear 0.5s;
|
25384
25531
|
transition:all linear 0.5s;
|
25385
25532
|
background: transparent;
|
25386
25533
|
}
|
@@ -25467,7 +25614,7 @@ var ngModelDirective = ['$rootScope', function($rootScope) {
|
|
25467
25614
|
return {
|
25468
25615
|
pre: function ngModelPreLink(scope, element, attr, ctrls) {
|
25469
25616
|
var modelCtrl = ctrls[0],
|
25470
|
-
formCtrl = ctrls[1] ||
|
25617
|
+
formCtrl = ctrls[1] || modelCtrl.$$parentForm;
|
25471
25618
|
|
25472
25619
|
modelCtrl.$$setOptions(ctrls[2] && ctrls[2].$options);
|
25473
25620
|
|
@@ -25476,12 +25623,12 @@ var ngModelDirective = ['$rootScope', function($rootScope) {
|
|
25476
25623
|
|
25477
25624
|
attr.$observe('name', function(newValue) {
|
25478
25625
|
if (modelCtrl.$name !== newValue) {
|
25479
|
-
|
25626
|
+
modelCtrl.$$parentForm.$$renameControl(modelCtrl, newValue);
|
25480
25627
|
}
|
25481
25628
|
});
|
25482
25629
|
|
25483
25630
|
scope.$on('$destroy', function() {
|
25484
|
-
|
25631
|
+
modelCtrl.$$parentForm.$removeControl(modelCtrl);
|
25485
25632
|
});
|
25486
25633
|
},
|
25487
25634
|
post: function ngModelPostLink(scope, element, attr, ctrls) {
|
@@ -25676,7 +25823,7 @@ var ngModelOptionsDirective = function() {
|
|
25676
25823
|
var that = this;
|
25677
25824
|
this.$options = copy($scope.$eval($attrs.ngModelOptions));
|
25678
25825
|
// Allow adding/overriding bound events
|
25679
|
-
if (this.$options.updateOn
|
25826
|
+
if (isDefined(this.$options.updateOn)) {
|
25680
25827
|
this.$options.updateOnDefault = false;
|
25681
25828
|
// extract "default" pseudo-event from list of events that can trigger a model update
|
25682
25829
|
this.$options.updateOn = trim(this.$options.updateOn.replace(DEFAULT_REGEXP, function() {
|
@@ -25699,7 +25846,6 @@ function addSetValidityMethod(context) {
|
|
25699
25846
|
classCache = {},
|
25700
25847
|
set = context.set,
|
25701
25848
|
unset = context.unset,
|
25702
|
-
parentForm = context.parentForm,
|
25703
25849
|
$animate = context.$animate;
|
25704
25850
|
|
25705
25851
|
classCache[INVALID_CLASS] = !(classCache[VALID_CLASS] = $element.hasClass(VALID_CLASS));
|
@@ -25707,7 +25853,7 @@ function addSetValidityMethod(context) {
|
|
25707
25853
|
ctrl.$setValidity = setValidity;
|
25708
25854
|
|
25709
25855
|
function setValidity(validationErrorKey, state, controller) {
|
25710
|
-
if (state
|
25856
|
+
if (isUndefined(state)) {
|
25711
25857
|
createAndSet('$pending', validationErrorKey, controller);
|
25712
25858
|
} else {
|
25713
25859
|
unsetAndCleanup('$pending', validationErrorKey, controller);
|
@@ -25751,7 +25897,7 @@ function addSetValidityMethod(context) {
|
|
25751
25897
|
}
|
25752
25898
|
|
25753
25899
|
toggleValidationCss(validationErrorKey, combinedState);
|
25754
|
-
parentForm.$setValidity(validationErrorKey, combinedState, ctrl);
|
25900
|
+
ctrl.$$parentForm.$setValidity(validationErrorKey, combinedState, ctrl);
|
25755
25901
|
}
|
25756
25902
|
|
25757
25903
|
function createAndSet(name, value, controller) {
|
@@ -26412,11 +26558,16 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
26412
26558
|
function updateOptionElement(option, element) {
|
26413
26559
|
option.element = element;
|
26414
26560
|
element.disabled = option.disabled;
|
26415
|
-
|
26561
|
+
// NOTE: The label must be set before the value, otherwise IE10/11/EDGE create unresponsive
|
26562
|
+
// selects in certain circumstances when multiple selects are next to each other and display
|
26563
|
+
// the option list in listbox style, i.e. the select is [multiple], or specifies a [size].
|
26564
|
+
// See https://github.com/angular/angular.js/issues/11314 for more info.
|
26565
|
+
// This is unfortunately untestable with unit / e2e tests
|
26416
26566
|
if (option.label !== element.label) {
|
26417
26567
|
element.label = option.label;
|
26418
26568
|
element.textContent = option.label;
|
26419
26569
|
}
|
26570
|
+
if (option.value !== element.value) element.value = option.selectValue;
|
26420
26571
|
}
|
26421
26572
|
|
26422
26573
|
function addOrReuseElement(parent, current, type, templateElement) {
|
@@ -26457,7 +26608,10 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
26457
26608
|
if (emptyOption_ || unknownOption_) {
|
26458
26609
|
while (current &&
|
26459
26610
|
(current === emptyOption_ ||
|
26460
|
-
current === unknownOption_
|
26611
|
+
current === unknownOption_ ||
|
26612
|
+
emptyOption_ && emptyOption_.nodeType === NODE_TYPE_COMMENT)) {
|
26613
|
+
// Empty options might have directives that transclude
|
26614
|
+
// and insert comments (e.g. ngIf)
|
26461
26615
|
current = current.nextSibling;
|
26462
26616
|
}
|
26463
26617
|
}
|
@@ -26819,8 +26973,10 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
|
|
26819
26973
|
* | `$even` | {@type boolean} | true if the iterator position `$index` is even (otherwise false). |
|
26820
26974
|
* | `$odd` | {@type boolean} | true if the iterator position `$index` is odd (otherwise false). |
|
26821
26975
|
*
|
26822
|
-
*
|
26823
|
-
*
|
26976
|
+
* <div class="alert alert-info">
|
26977
|
+
* Creating aliases for these properties is possible with {@link ng.directive:ngInit `ngInit`}.
|
26978
|
+
* This may be useful when, for instance, nesting ngRepeats.
|
26979
|
+
* </div>
|
26824
26980
|
*
|
26825
26981
|
*
|
26826
26982
|
* # Iterating over object properties
|
@@ -27054,7 +27210,6 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
|
|
27054
27210
|
.animate-repeat.ng-move,
|
27055
27211
|
.animate-repeat.ng-enter,
|
27056
27212
|
.animate-repeat.ng-leave {
|
27057
|
-
-webkit-transition:all linear 0.5s;
|
27058
27213
|
transition:all linear 0.5s;
|
27059
27214
|
}
|
27060
27215
|
|
@@ -27226,7 +27381,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
27226
27381
|
// if object, extract keys, in enumeration order, unsorted
|
27227
27382
|
collectionKeys = [];
|
27228
27383
|
for (var itemKey in collection) {
|
27229
|
-
if (
|
27384
|
+
if (hasOwnProperty.call(collection, itemKey) && itemKey.charAt(0) !== '$') {
|
27230
27385
|
collectionKeys.push(itemKey);
|
27231
27386
|
}
|
27232
27387
|
}
|
@@ -27451,9 +27606,7 @@ var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';
|
|
27451
27606
|
background: white;
|
27452
27607
|
}
|
27453
27608
|
|
27454
|
-
.animate-show.ng-hide-add.ng-hide-
|
27455
|
-
.animate-show.ng-hide-remove.ng-hide-remove-active {
|
27456
|
-
-webkit-transition: all linear 0.5s;
|
27609
|
+
.animate-show.ng-hide-add, .animate-show.ng-hide-remove {
|
27457
27610
|
transition: all linear 0.5s;
|
27458
27611
|
}
|
27459
27612
|
|
@@ -27610,7 +27763,6 @@ var ngShowDirective = ['$animate', function($animate) {
|
|
27610
27763
|
</file>
|
27611
27764
|
<file name="animations.css">
|
27612
27765
|
.animate-hide {
|
27613
|
-
-webkit-transition: all linear 0.5s;
|
27614
27766
|
transition: all linear 0.5s;
|
27615
27767
|
line-height: 20px;
|
27616
27768
|
opacity: 1;
|
@@ -27809,7 +27961,6 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
|
|
27809
27961
|
}
|
27810
27962
|
|
27811
27963
|
.animate-switch.ng-animate {
|
27812
|
-
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
27813
27964
|
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
27814
27965
|
|
27815
27966
|
position:absolute;
|
@@ -28150,31 +28301,162 @@ var SelectController =
|
|
28150
28301
|
* @description
|
28151
28302
|
* HTML `SELECT` element with angular data-binding.
|
28152
28303
|
*
|
28153
|
-
*
|
28154
|
-
*
|
28155
|
-
*
|
28156
|
-
*
|
28157
|
-
* comprehension expression.
|
28304
|
+
* The `select` directive is used together with {@link ngModel `ngModel`} to provide data-binding
|
28305
|
+
* between the scope and the `<select>` control (including setting default values).
|
28306
|
+
* Ìt also handles dynamic `<option>` elements, which can be added using the {@link ngRepeat `ngRepeat}` or
|
28307
|
+
* {@link ngOptions `ngOptions`} directives.
|
28158
28308
|
*
|
28159
|
-
* When an item in the `<select>` menu is selected, the
|
28160
|
-
*
|
28161
|
-
*
|
28309
|
+
* When an item in the `<select>` menu is selected, the value of the selected option will be bound
|
28310
|
+
* to the model identified by the `ngModel` directive. With static or repeated options, this is
|
28311
|
+
* the content of the `value` attribute or the textContent of the `<option>`, if the value attribute is missing.
|
28312
|
+
* If you want dynamic value attributes, you can use interpolation inside the value attribute.
|
28162
28313
|
*
|
28163
|
-
*
|
28164
|
-
*
|
28314
|
+
* <div class="alert alert-warning">
|
28315
|
+
* Note that the value of a `select` directive used without `ngOptions` is always a string.
|
28316
|
+
* When the model needs to be bound to a non-string value, you must either explictly convert it
|
28317
|
+
* using a directive (see example below) or use `ngOptions` to specify the set of options.
|
28318
|
+
* This is because an option element can only be bound to string values at present.
|
28319
|
+
* </div>
|
28320
|
+
*
|
28321
|
+
* If the viewValue of `ngModel` does not match any of the options, then the control
|
28322
|
+
* will automatically add an "unknown" option, which it then removes when the mismatch is resolved.
|
28165
28323
|
*
|
28166
28324
|
* Optionally, a single hard-coded `<option>` element, with the value set to an empty string, can
|
28167
28325
|
* be nested into the `<select>` element. This element will then represent the `null` or "not selected"
|
28168
28326
|
* option. See example below for demonstration.
|
28169
28327
|
*
|
28170
28328
|
* <div class="alert alert-info">
|
28171
|
-
*
|
28172
|
-
*
|
28173
|
-
*
|
28174
|
-
*
|
28329
|
+
* In many cases, `ngRepeat` can be used on `<option>` elements instead of {@link ng.directive:ngOptions
|
28330
|
+
* ngOptions} to achieve a similar result. However, `ngOptions` provides some benefits, such as
|
28331
|
+
* more flexibility in how the `<select>`'s model is assigned via the `select` **`as`** part of the
|
28332
|
+
* comprehension expression, and additionally in reducing memory and increasing speed by not creating
|
28333
|
+
* a new scope for each repeated instance.
|
28334
|
+
* </div>
|
28335
|
+
*
|
28336
|
+
*
|
28337
|
+
* @param {string} ngModel Assignable angular expression to data-bind to.
|
28338
|
+
* @param {string=} name Property name of the form under which the control is published.
|
28339
|
+
* @param {string=} required Sets `required` validation error key if the value is not entered.
|
28340
|
+
* @param {string=} ngRequired Adds required attribute and required validation constraint to
|
28341
|
+
* the element when the ngRequired expression evaluates to true. Use ngRequired instead of required
|
28342
|
+
* when you want to data-bind to the required attribute.
|
28343
|
+
* @param {string=} ngChange Angular expression to be executed when selected option(s) changes due to user
|
28344
|
+
* interaction with the select element.
|
28345
|
+
* @param {string=} ngOptions sets the options that the select is populated with and defines what is
|
28346
|
+
* set on the model on selection. See {@link ngOptions `ngOptions`}.
|
28347
|
+
*
|
28348
|
+
* @example
|
28349
|
+
* ### Simple `select` elements with static options
|
28350
|
+
*
|
28351
|
+
* <example name="static-select" module="staticSelect">
|
28352
|
+
* <file name="index.html">
|
28353
|
+
* <div ng-controller="ExampleController">
|
28354
|
+
* <form name="myForm">
|
28355
|
+
* <label for="singleSelect"> Single select: </label><br>
|
28356
|
+
* <select name="singleSelect" ng-model="data.singleSelect">
|
28357
|
+
* <option value="option-1">Option 1</option>
|
28358
|
+
* <option value="option-2">Option 2</option>
|
28359
|
+
* </select><br>
|
28360
|
+
*
|
28361
|
+
* <label for="singleSelect"> Single select with "not selected" option and dynamic option values: </label><br>
|
28362
|
+
* <select name="singleSelect" id="singleSelect" ng-model="data.singleSelect">
|
28363
|
+
* <option value="">---Please select---</option> <!-- not selected / blank option -->
|
28364
|
+
* <option value="{{data.option1}}">Option 1</option> <!-- interpolation -->
|
28365
|
+
* <option value="option-2">Option 2</option>
|
28366
|
+
* </select><br>
|
28367
|
+
* <button ng-click="forceUnknownOption()">Force unknown option</button><br>
|
28368
|
+
* <tt>singleSelect = {{data.singleSelect}}</tt>
|
28369
|
+
*
|
28370
|
+
* <hr>
|
28371
|
+
* <label for="multipleSelect"> Multiple select: </label><br>
|
28372
|
+
* <select name="multipleSelect" id="multipleSelect" ng-model="data.multipleSelect" multiple>
|
28373
|
+
* <option value="option-1">Option 1</option>
|
28374
|
+
* <option value="option-2">Option 2</option>
|
28375
|
+
* <option value="option-3">Option 3</option>
|
28376
|
+
* </select><br>
|
28377
|
+
* <tt>multipleSelect = {{data.multipleSelect}}</tt><br/>
|
28378
|
+
* </form>
|
28379
|
+
* </div>
|
28380
|
+
* </file>
|
28381
|
+
* <file name="app.js">
|
28382
|
+
* angular.module('staticSelect', [])
|
28383
|
+
* .controller('ExampleController', ['$scope', function($scope) {
|
28384
|
+
* $scope.data = {
|
28385
|
+
* singleSelect: null,
|
28386
|
+
* multipleSelect: [],
|
28387
|
+
* option1: 'option-1',
|
28388
|
+
* };
|
28389
|
+
*
|
28390
|
+
* $scope.forceUnknownOption = function() {
|
28391
|
+
* $scope.data.singleSelect = 'nonsense';
|
28392
|
+
* };
|
28393
|
+
* }]);
|
28394
|
+
* </file>
|
28395
|
+
*</example>
|
28396
|
+
*
|
28397
|
+
* ### Using `ngRepeat` to generate `select` options
|
28398
|
+
* <example name="ngrepeat-select" module="ngrepeatSelect">
|
28399
|
+
* <file name="index.html">
|
28400
|
+
* <div ng-controller="ExampleController">
|
28401
|
+
* <form name="myForm">
|
28402
|
+
* <label for="repeatSelect"> Repeat select: </label>
|
28403
|
+
* <select name="repeatSelect" id="repeatSelect" ng-model="data.repeatSelect">
|
28404
|
+
* <option ng-repeat="option in data.availableOptions" value="{{option.id}}">{{option.name}}</option>
|
28405
|
+
* </select>
|
28406
|
+
* </form>
|
28407
|
+
* <hr>
|
28408
|
+
* <tt>repeatSelect = {{data.repeatSelect}}</tt><br/>
|
28175
28409
|
* </div>
|
28410
|
+
* </file>
|
28411
|
+
* <file name="app.js">
|
28412
|
+
* angular.module('ngrepeatSelect', [])
|
28413
|
+
* .controller('ExampleController', ['$scope', function($scope) {
|
28414
|
+
* $scope.data = {
|
28415
|
+
* repeatSelect: null,
|
28416
|
+
* availableOptions: [
|
28417
|
+
* {id: '1', name: 'Option A'},
|
28418
|
+
* {id: '2', name: 'Option B'},
|
28419
|
+
* {id: '3', name: 'Option C'}
|
28420
|
+
* ],
|
28421
|
+
* };
|
28422
|
+
* }]);
|
28423
|
+
* </file>
|
28424
|
+
*</example>
|
28176
28425
|
*
|
28177
|
-
*
|
28426
|
+
*
|
28427
|
+
* ### Using `select` with `ngOptions` and setting a default value
|
28428
|
+
* See the {@link ngOptions ngOptions documentation} for more `ngOptions` usage examples.
|
28429
|
+
*
|
28430
|
+
* <example name="select-with-default-values" module="defaultValueSelect">
|
28431
|
+
* <file name="index.html">
|
28432
|
+
* <div ng-controller="ExampleController">
|
28433
|
+
* <form name="myForm">
|
28434
|
+
* <label for="mySelect">Make a choice:</label>
|
28435
|
+
* <select name="mySelect" id="mySelect"
|
28436
|
+
* ng-options="option.name for option in data.availableOptions track by option.id"
|
28437
|
+
* ng-model="data.selectedOption"></select>
|
28438
|
+
* </form>
|
28439
|
+
* <hr>
|
28440
|
+
* <tt>option = {{data.selectedOption}}</tt><br/>
|
28441
|
+
* </div>
|
28442
|
+
* </file>
|
28443
|
+
* <file name="app.js">
|
28444
|
+
* angular.module('defaultValueSelect', [])
|
28445
|
+
* .controller('ExampleController', ['$scope', function($scope) {
|
28446
|
+
* $scope.data = {
|
28447
|
+
* availableOptions: [
|
28448
|
+
* {id: '1', name: 'Option A'},
|
28449
|
+
* {id: '2', name: 'Option B'},
|
28450
|
+
* {id: '3', name: 'Option C'}
|
28451
|
+
* ],
|
28452
|
+
* selectedOption: {id: '3', name: 'Option C'} //This sets the default value of the select in the ui
|
28453
|
+
* };
|
28454
|
+
* }]);
|
28455
|
+
* </file>
|
28456
|
+
*</example>
|
28457
|
+
*
|
28458
|
+
*
|
28459
|
+
* ### Binding `select` to a non-string value via `ngModel` parsing / formatting
|
28178
28460
|
*
|
28179
28461
|
* <example name="select-with-non-string-options" module="nonStringSelect">
|
28180
28462
|
* <file name="index.html">
|
@@ -28312,9 +28594,12 @@ var optionDirective = ['$interpolate', function($interpolate) {
|
|
28312
28594
|
priority: 100,
|
28313
28595
|
compile: function(element, attr) {
|
28314
28596
|
|
28315
|
-
|
28316
|
-
|
28317
|
-
|
28597
|
+
if (isDefined(attr.value)) {
|
28598
|
+
// If the value attribute is defined, check if it contains an interpolation
|
28599
|
+
var valueInterpolated = $interpolate(attr.value, true);
|
28600
|
+
} else {
|
28601
|
+
// If the value attribute is not defined then we fall back to the
|
28602
|
+
// text content of the option element, which may be interpolated
|
28318
28603
|
var interpolateFn = $interpolate(element.text(), true);
|
28319
28604
|
if (!interpolateFn) {
|
28320
28605
|
attr.$set('value', element.text());
|
@@ -28330,24 +28615,38 @@ var optionDirective = ['$interpolate', function($interpolate) {
|
|
28330
28615
|
selectCtrl = parent.data(selectCtrlName) ||
|
28331
28616
|
parent.parent().data(selectCtrlName); // in case we are in optgroup
|
28332
28617
|
|
28618
|
+
function addOption(optionValue) {
|
28619
|
+
selectCtrl.addOption(optionValue, element);
|
28620
|
+
selectCtrl.ngModelCtrl.$render();
|
28621
|
+
chromeHack(element);
|
28622
|
+
}
|
28623
|
+
|
28333
28624
|
// Only update trigger option updates if this is an option within a `select`
|
28334
28625
|
// that also has `ngModel` attached
|
28335
28626
|
if (selectCtrl && selectCtrl.ngModelCtrl) {
|
28336
28627
|
|
28337
|
-
if (
|
28628
|
+
if (valueInterpolated) {
|
28629
|
+
// The value attribute is interpolated
|
28630
|
+
var oldVal;
|
28631
|
+
attr.$observe('value', function valueAttributeObserveAction(newVal) {
|
28632
|
+
if (isDefined(oldVal)) {
|
28633
|
+
selectCtrl.removeOption(oldVal);
|
28634
|
+
}
|
28635
|
+
oldVal = newVal;
|
28636
|
+
addOption(newVal);
|
28637
|
+
});
|
28638
|
+
} else if (interpolateFn) {
|
28639
|
+
// The text content is interpolated
|
28338
28640
|
scope.$watch(interpolateFn, function interpolateWatchAction(newVal, oldVal) {
|
28339
28641
|
attr.$set('value', newVal);
|
28340
28642
|
if (oldVal !== newVal) {
|
28341
28643
|
selectCtrl.removeOption(oldVal);
|
28342
28644
|
}
|
28343
|
-
|
28344
|
-
selectCtrl.ngModelCtrl.$render();
|
28345
|
-
chromeHack(element);
|
28645
|
+
addOption(newVal);
|
28346
28646
|
});
|
28347
28647
|
} else {
|
28348
|
-
|
28349
|
-
|
28350
|
-
chromeHack(element);
|
28648
|
+
// The value attribute is static
|
28649
|
+
addOption(attr.value);
|
28351
28650
|
}
|
28352
28651
|
|
28353
28652
|
element.on('$destroy', function() {
|
@@ -28408,8 +28707,9 @@ var patternDirective = function() {
|
|
28408
28707
|
ctrl.$validate();
|
28409
28708
|
});
|
28410
28709
|
|
28411
|
-
ctrl.$validators.pattern = function(
|
28412
|
-
|
28710
|
+
ctrl.$validators.pattern = function(modelValue, viewValue) {
|
28711
|
+
// HTML5 pattern constraint validates the input value, so we validate the viewValue
|
28712
|
+
return ctrl.$isEmpty(viewValue) || isUndefined(regexp) || regexp.test(viewValue);
|
28413
28713
|
};
|
28414
28714
|
}
|
28415
28715
|
};
|