angularjs-rails 1.5.0 → 1.5.5
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 +82 -56
- data/vendor/assets/javascripts/angular-aria.js +12 -5
- data/vendor/assets/javascripts/angular-cookies.js +2 -2
- data/vendor/assets/javascripts/angular-loader.js +5 -5
- data/vendor/assets/javascripts/angular-message-format.js +2 -2
- data/vendor/assets/javascripts/angular-messages.js +63 -28
- data/vendor/assets/javascripts/angular-mocks.js +280 -116
- data/vendor/assets/javascripts/angular-parse-ext.js +1271 -0
- data/vendor/assets/javascripts/angular-resource.js +3 -3
- data/vendor/assets/javascripts/angular-route.js +16 -7
- data/vendor/assets/javascripts/angular-sanitize.js +4 -4
- data/vendor/assets/javascripts/angular-scenario.js +882 -442
- data/vendor/assets/javascripts/angular-touch.js +2 -2
- data/vendor/assets/javascripts/angular.js +871 -431
- data/vendor/assets/javascripts/unstable/angular2-polyfills.js +1046 -1832
- data/vendor/assets/javascripts/unstable/angular2.js +22044 -18291
- metadata +7 -6
@@ -1,9 +1,9 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.5.
|
2
|
+
* @license AngularJS v1.5.5
|
3
3
|
* (c) 2010-2016 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
6
|
-
(function(window, angular
|
6
|
+
(function(window, angular) {'use strict';
|
7
7
|
|
8
8
|
/* global ngTouchClickDirectiveFactory: false,
|
9
9
|
*/
|
@@ -1,9 +1,9 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.5.
|
2
|
+
* @license AngularJS v1.5.5
|
3
3
|
* (c) 2010-2016 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
6
|
-
(function(window
|
6
|
+
(function(window) {'use strict';
|
7
7
|
|
8
8
|
/**
|
9
9
|
* @description
|
@@ -57,7 +57,7 @@ function minErr(module, ErrorConstructor) {
|
|
57
57
|
return match;
|
58
58
|
});
|
59
59
|
|
60
|
-
message += '\nhttp://errors.angularjs.org/1.5.
|
60
|
+
message += '\nhttp://errors.angularjs.org/1.5.5/' +
|
61
61
|
(module ? module + '/' : '') + code;
|
62
62
|
|
63
63
|
for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
|
@@ -171,6 +171,7 @@ function minErr(module, ErrorConstructor) {
|
|
171
171
|
* @ngdoc module
|
172
172
|
* @name ng
|
173
173
|
* @module ng
|
174
|
+
* @installation
|
174
175
|
* @description
|
175
176
|
*
|
176
177
|
* # ng (core module)
|
@@ -237,7 +238,7 @@ var
|
|
237
238
|
* documentMode is an IE-only property
|
238
239
|
* http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx
|
239
240
|
*/
|
240
|
-
msie = document.documentMode;
|
241
|
+
msie = window.document.documentMode;
|
241
242
|
|
242
243
|
|
243
244
|
/**
|
@@ -285,7 +286,7 @@ function isArrayLike(obj) {
|
|
285
286
|
*
|
286
287
|
* Unlike ES262's
|
287
288
|
* [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18),
|
288
|
-
*
|
289
|
+
* providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just
|
289
290
|
* return the value provided.
|
290
291
|
*
|
291
292
|
```js
|
@@ -526,7 +527,7 @@ function identity($) {return $;}
|
|
526
527
|
identity.$inject = [];
|
527
528
|
|
528
529
|
|
529
|
-
function valueFn(value) {return function() {return value;};}
|
530
|
+
function valueFn(value) {return function valueRef() {return value;};}
|
530
531
|
|
531
532
|
function hasCustomToString(obj) {
|
532
533
|
return isFunction(obj.toString) && obj.toString !== toString;
|
@@ -888,7 +889,7 @@ function copy(source, destination) {
|
|
888
889
|
|
889
890
|
function copyRecurse(source, destination) {
|
890
891
|
var h = destination.$$hashKey;
|
891
|
-
var
|
892
|
+
var key;
|
892
893
|
if (isArray(source)) {
|
893
894
|
for (var i = 0, ii = source.length; i < ii; i++) {
|
894
895
|
destination.push(copyElement(source[i]));
|
@@ -982,6 +983,9 @@ function copy(source, destination) {
|
|
982
983
|
var re = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]);
|
983
984
|
re.lastIndex = source.lastIndex;
|
984
985
|
return re;
|
986
|
+
|
987
|
+
case '[object Blob]':
|
988
|
+
return new source.constructor([source], {type: source.type});
|
985
989
|
}
|
986
990
|
|
987
991
|
if (isFunction(source.cloneNode)) {
|
@@ -1044,6 +1048,41 @@ function shallowCopy(src, dst) {
|
|
1044
1048
|
* @param {*} o1 Object or value to compare.
|
1045
1049
|
* @param {*} o2 Object or value to compare.
|
1046
1050
|
* @returns {boolean} True if arguments are equal.
|
1051
|
+
*
|
1052
|
+
* @example
|
1053
|
+
<example module="equalsExample" name="equalsExample">
|
1054
|
+
<file name="index.html">
|
1055
|
+
<div ng-controller="ExampleController">
|
1056
|
+
<form novalidate>
|
1057
|
+
<h3>User 1</h3>
|
1058
|
+
Name: <input type="text" ng-model="user1.name">
|
1059
|
+
Age: <input type="number" ng-model="user1.age">
|
1060
|
+
|
1061
|
+
<h3>User 2</h3>
|
1062
|
+
Name: <input type="text" ng-model="user2.name">
|
1063
|
+
Age: <input type="number" ng-model="user2.age">
|
1064
|
+
|
1065
|
+
<div>
|
1066
|
+
<br/>
|
1067
|
+
<input type="button" value="Compare" ng-click="compare()">
|
1068
|
+
</div>
|
1069
|
+
User 1: <pre>{{user1 | json}}</pre>
|
1070
|
+
User 2: <pre>{{user2 | json}}</pre>
|
1071
|
+
Equal: <pre>{{result}}</pre>
|
1072
|
+
</form>
|
1073
|
+
</div>
|
1074
|
+
</file>
|
1075
|
+
<file name="script.js">
|
1076
|
+
angular.module('equalsExample', []).controller('ExampleController', ['$scope', function($scope) {
|
1077
|
+
$scope.user1 = {};
|
1078
|
+
$scope.user2 = {};
|
1079
|
+
$scope.result;
|
1080
|
+
$scope.compare = function() {
|
1081
|
+
$scope.result = angular.equals($scope.user1, $scope.user2);
|
1082
|
+
};
|
1083
|
+
}]);
|
1084
|
+
</file>
|
1085
|
+
</example>
|
1047
1086
|
*/
|
1048
1087
|
function equals(o1, o2) {
|
1049
1088
|
if (o1 === o2) return true;
|
@@ -1090,8 +1129,8 @@ var csp = function() {
|
|
1090
1129
|
if (!isDefined(csp.rules)) {
|
1091
1130
|
|
1092
1131
|
|
1093
|
-
var ngCspElement = (document.querySelector('[ng-csp]') ||
|
1094
|
-
document.querySelector('[data-ng-csp]'));
|
1132
|
+
var ngCspElement = (window.document.querySelector('[ng-csp]') ||
|
1133
|
+
window.document.querySelector('[data-ng-csp]'));
|
1095
1134
|
|
1096
1135
|
if (ngCspElement) {
|
1097
1136
|
var ngCspAttribute = ngCspElement.getAttribute('ng-csp') ||
|
@@ -1166,7 +1205,7 @@ var jq = function() {
|
|
1166
1205
|
var i, ii = ngAttrPrefixes.length, prefix, name;
|
1167
1206
|
for (i = 0; i < ii; ++i) {
|
1168
1207
|
prefix = ngAttrPrefixes[i];
|
1169
|
-
if (el = document.querySelector('[' + prefix.replace(':', '\\:') + 'jq]')) {
|
1208
|
+
if (el = window.document.querySelector('[' + prefix.replace(':', '\\:') + 'jq]')) {
|
1170
1209
|
name = el.getAttribute(prefix + 'jq');
|
1171
1210
|
break;
|
1172
1211
|
}
|
@@ -1231,7 +1270,7 @@ function toJsonReplacer(key, value) {
|
|
1231
1270
|
val = undefined;
|
1232
1271
|
} else if (isWindow(value)) {
|
1233
1272
|
val = '$WINDOW';
|
1234
|
-
} else if (value && document === value) {
|
1273
|
+
} else if (value && window.document === value) {
|
1235
1274
|
val = '$DOCUMENT';
|
1236
1275
|
} else if (isScope(value)) {
|
1237
1276
|
val = '$SCOPE';
|
@@ -1471,10 +1510,17 @@ function getNgAttribute(element, ngAttr) {
|
|
1471
1510
|
* designates the **root element** of the application and is typically placed near the root element
|
1472
1511
|
* of the page - e.g. on the `<body>` or `<html>` tags.
|
1473
1512
|
*
|
1474
|
-
*
|
1475
|
-
*
|
1476
|
-
*
|
1477
|
-
*
|
1513
|
+
* There are a few things to keep in mind when using `ngApp`:
|
1514
|
+
* - only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp`
|
1515
|
+
* found in the document will be used to define the root element to auto-bootstrap as an
|
1516
|
+
* application. To run multiple applications in an HTML document you must manually bootstrap them using
|
1517
|
+
* {@link angular.bootstrap} instead.
|
1518
|
+
* - AngularJS applications cannot be nested within each other.
|
1519
|
+
* - Do not use a directive that uses {@link ng.$compile#transclusion transclusion} on the same element as `ngApp`.
|
1520
|
+
* This includes directives such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and
|
1521
|
+
* {@link ngRoute.ngView `ngView`}.
|
1522
|
+
* Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector},
|
1523
|
+
* causing animations to stop working and making the injector inaccessible from outside the app.
|
1478
1524
|
*
|
1479
1525
|
* You can specify an **AngularJS module** to be used as the root module for the application. This
|
1480
1526
|
* module will be loaded into the {@link auto.$injector} when the application is bootstrapped. It
|
@@ -1614,16 +1660,25 @@ function angularInit(element, bootstrap) {
|
|
1614
1660
|
* @description
|
1615
1661
|
* Use this function to manually start up angular application.
|
1616
1662
|
*
|
1617
|
-
*
|
1618
|
-
*
|
1619
|
-
* Note that Protractor based end-to-end tests cannot use this function to bootstrap manually.
|
1620
|
-
* They must use {@link ng.directive:ngApp ngApp}.
|
1663
|
+
* For more information, see the {@link guide/bootstrap Bootstrap guide}.
|
1621
1664
|
*
|
1622
1665
|
* Angular will detect if it has been loaded into the browser more than once and only allow the
|
1623
1666
|
* first loaded script to be bootstrapped and will report a warning to the browser console for
|
1624
1667
|
* each of the subsequent scripts. This prevents strange results in applications, where otherwise
|
1625
1668
|
* multiple instances of Angular try to work on the DOM.
|
1626
1669
|
*
|
1670
|
+
* <div class="alert alert-warning">
|
1671
|
+
* **Note:** Protractor based end-to-end tests cannot use this function to bootstrap manually.
|
1672
|
+
* They must use {@link ng.directive:ngApp ngApp}.
|
1673
|
+
* </div>
|
1674
|
+
*
|
1675
|
+
* <div class="alert alert-warning">
|
1676
|
+
* **Note:** Do not bootstrap the app on an element with a directive that uses {@link ng.$compile#transclusion transclusion},
|
1677
|
+
* such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and {@link ngRoute.ngView `ngView`}.
|
1678
|
+
* Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector},
|
1679
|
+
* causing animations to stop working and making the injector inaccessible from outside the app.
|
1680
|
+
* </div>
|
1681
|
+
*
|
1627
1682
|
* ```html
|
1628
1683
|
* <!doctype html>
|
1629
1684
|
* <html>
|
@@ -1667,11 +1722,11 @@ function bootstrap(element, modules, config) {
|
|
1667
1722
|
element = jqLite(element);
|
1668
1723
|
|
1669
1724
|
if (element.injector()) {
|
1670
|
-
var tag = (element[0] === document) ? 'document' : startingTag(element);
|
1725
|
+
var tag = (element[0] === window.document) ? 'document' : startingTag(element);
|
1671
1726
|
//Encode angle brackets to prevent input from being sanitized to empty string #8683
|
1672
1727
|
throw ngMinErr(
|
1673
1728
|
'btstrpd',
|
1674
|
-
"App
|
1729
|
+
"App already bootstrapped with this element '{0}'",
|
1675
1730
|
tag.replace(/</,'<').replace(/>/,'>'));
|
1676
1731
|
}
|
1677
1732
|
|
@@ -2118,9 +2173,9 @@ function setupModuleLoader(window) {
|
|
2118
2173
|
* @ngdoc method
|
2119
2174
|
* @name angular.Module#decorator
|
2120
2175
|
* @module ng
|
2121
|
-
* @param {string} The name of the service to decorate.
|
2122
|
-
* @param {Function} This function will be invoked when the service needs to be
|
2123
|
-
*
|
2176
|
+
* @param {string} name The name of the service to decorate.
|
2177
|
+
* @param {Function} decorFn This function will be invoked when the service needs to be
|
2178
|
+
* instantiated and should return the decorated service instance.
|
2124
2179
|
* @description
|
2125
2180
|
* See {@link auto.$provide#decorator $provide.decorator()}.
|
2126
2181
|
*/
|
@@ -2424,11 +2479,11 @@ function toDebugString(obj) {
|
|
2424
2479
|
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
|
2425
2480
|
*/
|
2426
2481
|
var version = {
|
2427
|
-
full: '1.5.
|
2482
|
+
full: '1.5.5', // all of these placeholder strings will be replaced by grunt's
|
2428
2483
|
major: 1, // package task
|
2429
2484
|
minor: 5,
|
2430
|
-
dot:
|
2431
|
-
codeName: '
|
2485
|
+
dot: 5,
|
2486
|
+
codeName: 'material-conspiration'
|
2432
2487
|
};
|
2433
2488
|
|
2434
2489
|
|
@@ -2685,6 +2740,9 @@ function publishExternalAPI(angular) {
|
|
2685
2740
|
* - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top
|
2686
2741
|
* parent element is reached.
|
2687
2742
|
*
|
2743
|
+
* @knownIssue You cannot spy on `angular.element` if you are using Jasmine version 1.x. See
|
2744
|
+
* https://github.com/angular/angular.js/issues/14251 for more information.
|
2745
|
+
*
|
2688
2746
|
* @param {string|DOMElement} element HTML string or DOMElement to be wrapped into jQuery.
|
2689
2747
|
* @returns {Object} jQuery object.
|
2690
2748
|
*/
|
@@ -2811,7 +2869,7 @@ function jqLiteBuildFragment(html, context) {
|
|
2811
2869
|
}
|
2812
2870
|
|
2813
2871
|
function jqLiteParseHTML(html, context) {
|
2814
|
-
context = context || document;
|
2872
|
+
context = context || window.document;
|
2815
2873
|
var parsed;
|
2816
2874
|
|
2817
2875
|
if ((parsed = SINGLE_TAG_REGEXP.exec(html))) {
|
@@ -2837,7 +2895,7 @@ function jqLiteWrapNode(node, wrapper) {
|
|
2837
2895
|
|
2838
2896
|
|
2839
2897
|
// IE9-11 has no method "contains" in SVG element and in Node.prototype. Bug #10259.
|
2840
|
-
var jqLiteContains = Node.prototype.contains || function(arg) {
|
2898
|
+
var jqLiteContains = window.Node.prototype.contains || function(arg) {
|
2841
2899
|
// jshint bitwise: false
|
2842
2900
|
return !!(this.compareDocumentPosition(arg) & 16);
|
2843
2901
|
// jshint bitwise: true
|
@@ -3109,8 +3167,8 @@ var JQLitePrototype = JQLite.prototype = {
|
|
3109
3167
|
}
|
3110
3168
|
|
3111
3169
|
// check if document is already loaded
|
3112
|
-
if (document.readyState === 'complete') {
|
3113
|
-
setTimeout(trigger);
|
3170
|
+
if (window.document.readyState === 'complete') {
|
3171
|
+
window.setTimeout(trigger);
|
3114
3172
|
} else {
|
3115
3173
|
this.on('DOMContentLoaded', trigger); // works for modern browsers and IE9
|
3116
3174
|
// we can not use jqLite since we are not done loading and jQuery could be loaded later.
|
@@ -3800,6 +3858,7 @@ var $$HashMapProvider = [function() {
|
|
3800
3858
|
/**
|
3801
3859
|
* @ngdoc module
|
3802
3860
|
* @name auto
|
3861
|
+
* @installation
|
3803
3862
|
* @description
|
3804
3863
|
*
|
3805
3864
|
* Implicit module which gets automatically added to each {@link auto.$injector $injector}.
|
@@ -3813,7 +3872,7 @@ var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
|
|
3813
3872
|
var $injectorMinErr = minErr('$injector');
|
3814
3873
|
|
3815
3874
|
function extractArgs(fn) {
|
3816
|
-
var fnText =
|
3875
|
+
var fnText = Function.prototype.toString.call(fn).replace(STRIP_COMMENTS, ''),
|
3817
3876
|
args = fnText.match(ARROW_ARG) || fnText.match(FN_ARGS);
|
3818
3877
|
return args;
|
3819
3878
|
}
|
@@ -4287,14 +4346,13 @@ function annotate(fn, strictDi, name) {
|
|
4287
4346
|
* @description
|
4288
4347
|
*
|
4289
4348
|
* Register a **value service** with the {@link auto.$injector $injector}, such as a string, a
|
4290
|
-
* number, an array, an object or a function.
|
4349
|
+
* number, an array, an object or a function. This is short for registering a service where its
|
4291
4350
|
* provider's `$get` property is a factory function that takes no arguments and returns the **value
|
4292
|
-
* service**.
|
4351
|
+
* service**. That also means it is not possible to inject other services into a value service.
|
4293
4352
|
*
|
4294
4353
|
* Value services are similar to constant services, except that they cannot be injected into a
|
4295
4354
|
* module configuration function (see {@link angular.Module#config}) but they can be overridden by
|
4296
|
-
* an Angular
|
4297
|
-
* {@link auto.$provide#decorator decorator}.
|
4355
|
+
* an Angular {@link auto.$provide#decorator decorator}.
|
4298
4356
|
*
|
4299
4357
|
* @param {string} name The name of the instance.
|
4300
4358
|
* @param {*} value The value.
|
@@ -4319,8 +4377,11 @@ function annotate(fn, strictDi, name) {
|
|
4319
4377
|
* @name $provide#constant
|
4320
4378
|
* @description
|
4321
4379
|
*
|
4322
|
-
* Register a **constant service
|
4323
|
-
*
|
4380
|
+
* Register a **constant service** with the {@link auto.$injector $injector}, such as a string,
|
4381
|
+
* a number, an array, an object or a function. Like the {@link auto.$provide#value value}, it is not
|
4382
|
+
* possible to inject other services into a constant.
|
4383
|
+
*
|
4384
|
+
* But unlike {@link auto.$provide#value value}, a constant can be
|
4324
4385
|
* injected into a module configuration function (see {@link angular.Module#config}) and it cannot
|
4325
4386
|
* be overridden by an Angular {@link auto.$provide#decorator decorator}.
|
4326
4387
|
*
|
@@ -4959,7 +5020,7 @@ function prepareAnimateOptions(options) {
|
|
4959
5020
|
}
|
4960
5021
|
|
4961
5022
|
var $$CoreAnimateJsProvider = function() {
|
4962
|
-
this.$get =
|
5023
|
+
this.$get = noop;
|
4963
5024
|
};
|
4964
5025
|
|
4965
5026
|
// this is prefixed with Core since it conflicts with
|
@@ -5231,6 +5292,9 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
5231
5292
|
* // remove all the animation event listeners listening for `enter`
|
5232
5293
|
* $animate.off('enter');
|
5233
5294
|
*
|
5295
|
+
* // remove listeners for all animation events from the container element
|
5296
|
+
* $animate.off(container);
|
5297
|
+
*
|
5234
5298
|
* // remove all the animation event listeners listening for `enter` on the given element and its children
|
5235
5299
|
* $animate.off('enter', container);
|
5236
5300
|
*
|
@@ -5239,7 +5303,9 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
5239
5303
|
* $animate.off('enter', container, callback);
|
5240
5304
|
* ```
|
5241
5305
|
*
|
5242
|
-
* @param {string} event the animation event (e.g. enter, leave, move,
|
5306
|
+
* @param {string|DOMElement} event|container the animation event (e.g. enter, leave, move,
|
5307
|
+
* addClass, removeClass, etc...), or the container element. If it is the element, all other
|
5308
|
+
* arguments are ignored.
|
5243
5309
|
* @param {DOMElement=} container the container element the event listener was placed on
|
5244
5310
|
* @param {Function=} callback the callback function that was registered as the listener
|
5245
5311
|
*/
|
@@ -5779,7 +5845,6 @@ var $CoreAnimateCssProvider = function() {
|
|
5779
5845
|
*/
|
5780
5846
|
function Browser(window, document, $log, $sniffer) {
|
5781
5847
|
var self = this,
|
5782
|
-
rawDocument = document[0],
|
5783
5848
|
location = window.location,
|
5784
5849
|
history = window.history,
|
5785
5850
|
setTimeout = window.setTimeout,
|
@@ -5842,7 +5907,14 @@ function Browser(window, document, $log, $sniffer) {
|
|
5842
5907
|
var cachedState, lastHistoryState,
|
5843
5908
|
lastBrowserUrl = location.href,
|
5844
5909
|
baseElement = document.find('base'),
|
5845
|
-
pendingLocation = null
|
5910
|
+
pendingLocation = null,
|
5911
|
+
getCurrentState = !$sniffer.history ? noop : function getCurrentState() {
|
5912
|
+
try {
|
5913
|
+
return history.state;
|
5914
|
+
} catch (e) {
|
5915
|
+
// MSIE can reportedly throw when there is no state (UNCONFIRMED).
|
5916
|
+
}
|
5917
|
+
};
|
5846
5918
|
|
5847
5919
|
cacheState();
|
5848
5920
|
lastHistoryState = cachedState;
|
@@ -5950,14 +6022,6 @@ function Browser(window, document, $log, $sniffer) {
|
|
5950
6022
|
fireUrlChange();
|
5951
6023
|
}
|
5952
6024
|
|
5953
|
-
function getCurrentState() {
|
5954
|
-
try {
|
5955
|
-
return history.state;
|
5956
|
-
} catch (e) {
|
5957
|
-
// MSIE can reportedly throw when there is no state (UNCONFIRMED).
|
5958
|
-
}
|
5959
|
-
}
|
5960
|
-
|
5961
6025
|
// This variable should be used *only* inside the cacheState function.
|
5962
6026
|
var lastCachedState = null;
|
5963
6027
|
function cacheState() {
|
@@ -6809,9 +6873,23 @@ function $TemplateCacheProvider() {
|
|
6809
6873
|
* `true` if the specified slot contains content (i.e. one or more DOM nodes).
|
6810
6874
|
*
|
6811
6875
|
* The controller can provide the following methods that act as life-cycle hooks:
|
6812
|
-
* * `$onInit` - Called on each controller after all the controllers on an element have been constructed and
|
6876
|
+
* * `$onInit()` - Called on each controller after all the controllers on an element have been constructed and
|
6813
6877
|
* had their bindings initialized (and before the pre & post linking functions for the directives on
|
6814
6878
|
* this element). This is a good place to put initialization code for your controller.
|
6879
|
+
* * `$onChanges(changesObj)` - Called whenever one-way (`<`) or interpolation (`@`) bindings are updated. The
|
6880
|
+
* `changesObj` is a hash whose keys are the names of the bound properties that have changed, and the values are an
|
6881
|
+
* object of the form `{ currentValue, previousValue, isFirstChange() }`. Use this hook to trigger updates within a
|
6882
|
+
* component such as cloning the bound value to prevent accidental mutation of the outer value.
|
6883
|
+
* * `$onDestroy()` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
|
6884
|
+
* external resources, watches and event handlers. Note that components have their `$onDestroy()` hooks called in
|
6885
|
+
* the same order as the `$scope.$broadcast` events are triggered, which is top down. This means that parent
|
6886
|
+
* components will have their `$onDestroy()` hook called before child components.
|
6887
|
+
* * `$postLink()` - Called after this controller's element and its children have been linked. Similar to the post-link
|
6888
|
+
* function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
|
6889
|
+
* Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
|
6890
|
+
* they are waiting for their template to load asynchronously and their own compilation and linking has been
|
6891
|
+
* suspended until that occurs.
|
6892
|
+
*
|
6815
6893
|
*
|
6816
6894
|
* #### `require`
|
6817
6895
|
* Require another directive and inject its controller as the fourth argument to the linking function. The
|
@@ -7348,6 +7426,9 @@ function $TemplateCacheProvider() {
|
|
7348
7426
|
|
7349
7427
|
var $compileMinErr = minErr('$compile');
|
7350
7428
|
|
7429
|
+
function UNINITIALIZED_VALUE() {}
|
7430
|
+
var _UNINITIALIZED_VALUE = new UNINITIALIZED_VALUE();
|
7431
|
+
|
7351
7432
|
/**
|
7352
7433
|
* @ngdoc provider
|
7353
7434
|
* @name $compileProvider
|
@@ -7367,13 +7448,18 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7367
7448
|
// The assumption is that future DOM event attribute names will begin with
|
7368
7449
|
// 'on' and be composed of only English letters.
|
7369
7450
|
var EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/;
|
7451
|
+
var bindingCache = createMap();
|
7370
7452
|
|
7371
7453
|
function parseIsolateBindings(scope, directiveName, isController) {
|
7372
7454
|
var LOCAL_REGEXP = /^\s*([@&<]|=(\*?))(\??)\s*(\w*)\s*$/;
|
7373
7455
|
|
7374
|
-
var bindings =
|
7456
|
+
var bindings = createMap();
|
7375
7457
|
|
7376
7458
|
forEach(scope, function(definition, scopeName) {
|
7459
|
+
if (definition in bindingCache) {
|
7460
|
+
bindings[scopeName] = bindingCache[definition];
|
7461
|
+
return;
|
7462
|
+
}
|
7377
7463
|
var match = definition.match(LOCAL_REGEXP);
|
7378
7464
|
|
7379
7465
|
if (!match) {
|
@@ -7391,6 +7477,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7391
7477
|
optional: match[3] === '?',
|
7392
7478
|
attrName: match[4] || scopeName
|
7393
7479
|
};
|
7480
|
+
if (match[4]) {
|
7481
|
+
bindingCache[definition] = bindings[scopeName];
|
7482
|
+
}
|
7394
7483
|
});
|
7395
7484
|
|
7396
7485
|
return bindings;
|
@@ -7436,11 +7525,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7436
7525
|
function assertValidDirectiveName(name) {
|
7437
7526
|
var letter = name.charAt(0);
|
7438
7527
|
if (!letter || letter !== lowercase(letter)) {
|
7439
|
-
throw $compileMinErr('baddir', "Directive name '{0}' is invalid. The first character must be a lowercase letter", name);
|
7528
|
+
throw $compileMinErr('baddir', "Directive/Component name '{0}' is invalid. The first character must be a lowercase letter", name);
|
7440
7529
|
}
|
7441
7530
|
if (name !== name.trim()) {
|
7442
7531
|
throw $compileMinErr('baddir',
|
7443
|
-
"Directive name '{0}' is invalid. The name should not contain leading or trailing whitespaces",
|
7532
|
+
"Directive/Component name '{0}' is invalid. The name should not contain leading or trailing whitespaces",
|
7444
7533
|
name);
|
7445
7534
|
}
|
7446
7535
|
}
|
@@ -7460,7 +7549,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7460
7549
|
* {@link guide/directive directive guide} and the {@link $compile compile API} for more info.
|
7461
7550
|
* @returns {ng.$compileProvider} Self for chaining.
|
7462
7551
|
*/
|
7463
|
-
|
7552
|
+
this.directive = function registerDirective(name, directiveFactory) {
|
7464
7553
|
assertNotHasOwnProperty(name, 'directive');
|
7465
7554
|
if (isString(name)) {
|
7466
7555
|
assertValidDirectiveName(name);
|
@@ -7483,11 +7572,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7483
7572
|
directive.name = directive.name || name;
|
7484
7573
|
directive.require = directive.require || (directive.controller && directive.name);
|
7485
7574
|
directive.restrict = directive.restrict || 'EA';
|
7486
|
-
var bindings = directive.$$bindings =
|
7487
|
-
parseDirectiveBindings(directive, directive.name);
|
7488
|
-
if (isObject(bindings.isolateScope)) {
|
7489
|
-
directive.$$isolateBindings = bindings.isolateScope;
|
7490
|
-
}
|
7491
7575
|
directive.$$moduleName = directiveFactory.$$moduleName;
|
7492
7576
|
directives.push(directive);
|
7493
7577
|
} catch (e) {
|
@@ -7543,7 +7627,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7543
7627
|
* See {@link ng.$compile#-bindtocontroller- `bindToController`}.
|
7544
7628
|
* - `transclude` – `{boolean=}` – whether {@link $compile#transclusion content transclusion} is enabled.
|
7545
7629
|
* Disabled by default.
|
7546
|
-
* -
|
7630
|
+
* - `require` - `{Object<string, string>=}` - requires the controllers of other directives and binds them to
|
7631
|
+
* this component's controller. The object keys specify the property names under which the required
|
7632
|
+
* controllers (object values) will be bound. See {@link ng.$compile#-require- `require`}.
|
7633
|
+
* - `$...` – additional properties to attach to the directive factory function and the controller
|
7634
|
+
* constructor function. (This is used by the component router to annotate)
|
7547
7635
|
*
|
7548
7636
|
* @returns {ng.$compileProvider} the compile provider itself, for chaining of function calls.
|
7549
7637
|
* @description
|
@@ -7575,7 +7663,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7575
7663
|
*
|
7576
7664
|
* myMod.component('myComp', {
|
7577
7665
|
* templateUrl: 'views/my-comp.html',
|
7578
|
-
* controller: 'MyCtrl
|
7666
|
+
* controller: 'MyCtrl',
|
7667
|
+
* controllerAs: 'ctrl',
|
7579
7668
|
* bindings: {name: '@'}
|
7580
7669
|
* });
|
7581
7670
|
*
|
@@ -7600,7 +7689,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7600
7689
|
}
|
7601
7690
|
|
7602
7691
|
var template = (!options.template && !options.templateUrl ? '' : options.template);
|
7603
|
-
|
7692
|
+
var ddo = {
|
7604
7693
|
controller: controller,
|
7605
7694
|
controllerAs: identifierForController(options.controller) || options.controllerAs || '$ctrl',
|
7606
7695
|
template: makeInjectable(template),
|
@@ -7611,13 +7700,27 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7611
7700
|
restrict: 'E',
|
7612
7701
|
require: options.require
|
7613
7702
|
};
|
7703
|
+
|
7704
|
+
// Copy annotations (starting with $) over to the DDO
|
7705
|
+
forEach(options, function(val, key) {
|
7706
|
+
if (key.charAt(0) === '$') ddo[key] = val;
|
7707
|
+
});
|
7708
|
+
|
7709
|
+
return ddo;
|
7614
7710
|
}
|
7615
7711
|
|
7616
|
-
//
|
7712
|
+
// TODO(pete) remove the following `forEach` before we release 1.6.0
|
7713
|
+
// The component-router@0.2.0 looks for the annotations on the controller constructor
|
7714
|
+
// Nothing in Angular looks for annotations on the factory function but we can't remove
|
7715
|
+
// it from 1.5.x yet.
|
7716
|
+
|
7717
|
+
// Copy any annotation properties (starting with $) over to the factory and controller constructor functions
|
7617
7718
|
// These could be used by libraries such as the new component router
|
7618
7719
|
forEach(options, function(val, key) {
|
7619
7720
|
if (key.charAt(0) === '$') {
|
7620
7721
|
factory[key] = val;
|
7722
|
+
// Don't try to copy over annotations to named controller
|
7723
|
+
if (isFunction(controller)) controller[key] = val;
|
7621
7724
|
}
|
7622
7725
|
});
|
7623
7726
|
|
@@ -7717,6 +7820,36 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7717
7820
|
return debugInfoEnabled;
|
7718
7821
|
};
|
7719
7822
|
|
7823
|
+
|
7824
|
+
var TTL = 10;
|
7825
|
+
/**
|
7826
|
+
* @ngdoc method
|
7827
|
+
* @name $compileProvider#onChangesTtl
|
7828
|
+
* @description
|
7829
|
+
*
|
7830
|
+
* Sets the number of times `$onChanges` hooks can trigger new changes before giving up and
|
7831
|
+
* assuming that the model is unstable.
|
7832
|
+
*
|
7833
|
+
* The current default is 10 iterations.
|
7834
|
+
*
|
7835
|
+
* In complex applications it's possible that dependencies between `$onChanges` hooks and bindings will result
|
7836
|
+
* in several iterations of calls to these hooks. However if an application needs more than the default 10
|
7837
|
+
* iterations to stabilize then you should investigate what is causing the model to continuously change during
|
7838
|
+
* the `$onChanges` hook execution.
|
7839
|
+
*
|
7840
|
+
* Increasing the TTL could have performance implications, so you should not change it without proper justification.
|
7841
|
+
*
|
7842
|
+
* @param {number} limit The number of `$onChanges` hook iterations.
|
7843
|
+
* @returns {number|object} the current limit (or `this` if called as a setter for chaining)
|
7844
|
+
*/
|
7845
|
+
this.onChangesTtl = function(value) {
|
7846
|
+
if (arguments.length) {
|
7847
|
+
TTL = value;
|
7848
|
+
return this;
|
7849
|
+
}
|
7850
|
+
return TTL;
|
7851
|
+
};
|
7852
|
+
|
7720
7853
|
this.$get = [
|
7721
7854
|
'$injector', '$interpolate', '$exceptionHandler', '$templateRequest', '$parse',
|
7722
7855
|
'$controller', '$rootScope', '$sce', '$animate', '$$sanitizeUri',
|
@@ -7724,8 +7857,38 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7724
7857
|
$controller, $rootScope, $sce, $animate, $$sanitizeUri) {
|
7725
7858
|
|
7726
7859
|
var SIMPLE_ATTR_NAME = /^\w/;
|
7727
|
-
var specialAttrHolder = document.createElement('div');
|
7728
|
-
|
7860
|
+
var specialAttrHolder = window.document.createElement('div');
|
7861
|
+
|
7862
|
+
|
7863
|
+
|
7864
|
+
var onChangesTtl = TTL;
|
7865
|
+
// The onChanges hooks should all be run together in a single digest
|
7866
|
+
// When changes occur, the call to trigger their hooks will be added to this queue
|
7867
|
+
var onChangesQueue;
|
7868
|
+
|
7869
|
+
// This function is called in a $$postDigest to trigger all the onChanges hooks in a single digest
|
7870
|
+
function flushOnChangesQueue() {
|
7871
|
+
try {
|
7872
|
+
if (!(--onChangesTtl)) {
|
7873
|
+
// We have hit the TTL limit so reset everything
|
7874
|
+
onChangesQueue = undefined;
|
7875
|
+
throw $compileMinErr('infchng', '{0} $onChanges() iterations reached. Aborting!\n', TTL);
|
7876
|
+
}
|
7877
|
+
// We must run this hook in an apply since the $$postDigest runs outside apply
|
7878
|
+
$rootScope.$apply(function() {
|
7879
|
+
for (var i = 0, ii = onChangesQueue.length; i < ii; ++i) {
|
7880
|
+
onChangesQueue[i]();
|
7881
|
+
}
|
7882
|
+
// Reset the queue to trigger a new schedule next time there is a change
|
7883
|
+
onChangesQueue = undefined;
|
7884
|
+
});
|
7885
|
+
} finally {
|
7886
|
+
onChangesTtl++;
|
7887
|
+
}
|
7888
|
+
}
|
7889
|
+
|
7890
|
+
|
7891
|
+
function Attributes(element, attributesToCopy) {
|
7729
7892
|
if (attributesToCopy) {
|
7730
7893
|
var keys = Object.keys(attributesToCopy);
|
7731
7894
|
var i, l, key;
|
@@ -7739,7 +7902,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
7739
7902
|
}
|
7740
7903
|
|
7741
7904
|
this.$$element = element;
|
7742
|
-
}
|
7905
|
+
}
|
7743
7906
|
|
7744
7907
|
Attributes.prototype = {
|
7745
7908
|
/**
|
@@ -8020,6 +8183,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
8020
8183
|
safeAddClass($element, isolated ? 'ng-isolate-scope' : 'ng-scope');
|
8021
8184
|
} : noop;
|
8022
8185
|
|
8186
|
+
compile.$$createComment = function(directiveName, comment) {
|
8187
|
+
var content = '';
|
8188
|
+
if (debugInfoEnabled) {
|
8189
|
+
content = ' ' + (directiveName || '') + ': ' + (comment || '') + ' ';
|
8190
|
+
}
|
8191
|
+
return window.document.createComment(content);
|
8192
|
+
};
|
8193
|
+
|
8023
8194
|
return compile;
|
8024
8195
|
|
8025
8196
|
//================================
|
@@ -8040,7 +8211,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
8040
8211
|
var domNode = $compileNodes[i];
|
8041
8212
|
|
8042
8213
|
if (domNode.nodeType === NODE_TYPE_TEXT && domNode.nodeValue.match(NOT_EMPTY) /* non-empty */) {
|
8043
|
-
jqLiteWrapNode(domNode, $compileNodes[i] = document.createElement('span'));
|
8214
|
+
jqLiteWrapNode(domNode, $compileNodes[i] = window.document.createElement('span'));
|
8044
8215
|
}
|
8045
8216
|
}
|
8046
8217
|
|
@@ -8233,8 +8404,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
8233
8404
|
}
|
8234
8405
|
|
8235
8406
|
function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) {
|
8236
|
-
|
8237
|
-
var boundTranscludeFn = function(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) {
|
8407
|
+
function boundTranscludeFn(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) {
|
8238
8408
|
|
8239
8409
|
if (!transcludedScope) {
|
8240
8410
|
transcludedScope = scope.$new(false, containingScope);
|
@@ -8246,7 +8416,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
8246
8416
|
transcludeControllers: controllers,
|
8247
8417
|
futureParentElement: futureParentElement
|
8248
8418
|
});
|
8249
|
-
}
|
8419
|
+
}
|
8250
8420
|
|
8251
8421
|
// We need to attach the transclusion slots onto the `boundTranscludeFn`
|
8252
8422
|
// so that they are available inside the `controllersBoundTransclude` function
|
@@ -8411,7 +8581,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
8411
8581
|
* @returns {Function}
|
8412
8582
|
*/
|
8413
8583
|
function groupElementsLinkFnWrapper(linkFn, attrStart, attrEnd) {
|
8414
|
-
return function(scope, element, attrs, controllers, transcludeFn) {
|
8584
|
+
return function groupedElementsLink(scope, element, attrs, controllers, transcludeFn) {
|
8415
8585
|
element = groupScan(element[0], attrStart, attrEnd);
|
8416
8586
|
return linkFn(scope, element, attrs, controllers, transcludeFn);
|
8417
8587
|
};
|
@@ -8429,23 +8599,21 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
8429
8599
|
* @returns {Function}
|
8430
8600
|
*/
|
8431
8601
|
function compilationGenerator(eager, $compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext) {
|
8432
|
-
|
8433
|
-
return compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);
|
8434
|
-
}
|
8602
|
+
var compiled;
|
8435
8603
|
|
8436
|
-
|
8437
|
-
|
8438
|
-
|
8439
|
-
|
8440
|
-
|
8441
|
-
|
8442
|
-
// Null out all of these references in order to make them eligible for garbage collection
|
8443
|
-
// since this is a potentially long lived closure
|
8444
|
-
$compileNodes = transcludeFn = previousCompileContext = null;
|
8445
|
-
}
|
8604
|
+
if (eager) {
|
8605
|
+
return compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);
|
8606
|
+
}
|
8607
|
+
return function lazyCompilation() {
|
8608
|
+
if (!compiled) {
|
8609
|
+
compiled = compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext);
|
8446
8610
|
|
8447
|
-
|
8448
|
-
|
8611
|
+
// Null out all of these references in order to make them eligible for garbage collection
|
8612
|
+
// since this is a potentially long lived closure
|
8613
|
+
$compileNodes = transcludeFn = previousCompileContext = null;
|
8614
|
+
}
|
8615
|
+
return compiled.apply(this, arguments);
|
8616
|
+
};
|
8449
8617
|
}
|
8450
8618
|
|
8451
8619
|
/**
|
@@ -8581,11 +8749,21 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
8581
8749
|
terminalPriority = directive.priority;
|
8582
8750
|
$template = $compileNode;
|
8583
8751
|
$compileNode = templateAttrs.$$element =
|
8584
|
-
jqLite(
|
8585
|
-
templateAttrs[directiveName] + ' '));
|
8752
|
+
jqLite(compile.$$createComment(directiveName, templateAttrs[directiveName]));
|
8586
8753
|
compileNode = $compileNode[0];
|
8587
8754
|
replaceWith(jqCollection, sliceArgs($template), compileNode);
|
8588
8755
|
|
8756
|
+
// Support: Chrome < 50
|
8757
|
+
// https://github.com/angular/angular.js/issues/14041
|
8758
|
+
|
8759
|
+
// In the versions of V8 prior to Chrome 50, the document fragment that is created
|
8760
|
+
// in the `replaceWith` function is improperly garbage collected despite still
|
8761
|
+
// being referenced by the `parentNode` property of all of the child nodes. By adding
|
8762
|
+
// a reference to the fragment via a different property, we can avoid that incorrect
|
8763
|
+
// behavior.
|
8764
|
+
// TODO: remove this line after Chrome 50 has been released
|
8765
|
+
$template[0].$$parentNode = $template[0].parentNode;
|
8766
|
+
|
8589
8767
|
childTranscludeFn = compilationGenerator(mightHaveMultipleTransclusionError, $template, transcludeFn, terminalPriority,
|
8590
8768
|
replaceDirective && replaceDirective.name, {
|
8591
8769
|
// Don't pass in:
|
@@ -8726,7 +8904,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
8726
8904
|
replaceDirective = directive;
|
8727
8905
|
}
|
8728
8906
|
|
8907
|
+
/* jshint -W021 */
|
8729
8908
|
nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode,
|
8909
|
+
/* jshint +W021 */
|
8730
8910
|
templateAttrs, jqCollection, hasTranscludeDirective && childTranscludeFn, preLinkFns, postLinkFns, {
|
8731
8911
|
controllerDirectives: controllerDirectives,
|
8732
8912
|
newScopeDirective: (newScopeDirective !== directive) && newScopeDirective,
|
@@ -8788,85 +8968,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
8788
8968
|
}
|
8789
8969
|
}
|
8790
8970
|
|
8791
|
-
|
8792
|
-
function getControllers(directiveName, require, $element, elementControllers) {
|
8793
|
-
var value;
|
8794
|
-
|
8795
|
-
if (isString(require)) {
|
8796
|
-
var match = require.match(REQUIRE_PREFIX_REGEXP);
|
8797
|
-
var name = require.substring(match[0].length);
|
8798
|
-
var inheritType = match[1] || match[3];
|
8799
|
-
var optional = match[2] === '?';
|
8800
|
-
|
8801
|
-
//If only parents then start at the parent element
|
8802
|
-
if (inheritType === '^^') {
|
8803
|
-
$element = $element.parent();
|
8804
|
-
//Otherwise attempt getting the controller from elementControllers in case
|
8805
|
-
//the element is transcluded (and has no data) and to avoid .data if possible
|
8806
|
-
} else {
|
8807
|
-
value = elementControllers && elementControllers[name];
|
8808
|
-
value = value && value.instance;
|
8809
|
-
}
|
8810
|
-
|
8811
|
-
if (!value) {
|
8812
|
-
var dataName = '$' + name + 'Controller';
|
8813
|
-
value = inheritType ? $element.inheritedData(dataName) : $element.data(dataName);
|
8814
|
-
}
|
8815
|
-
|
8816
|
-
if (!value && !optional) {
|
8817
|
-
throw $compileMinErr('ctreq',
|
8818
|
-
"Controller '{0}', required by directive '{1}', can't be found!",
|
8819
|
-
name, directiveName);
|
8820
|
-
}
|
8821
|
-
} else if (isArray(require)) {
|
8822
|
-
value = [];
|
8823
|
-
for (var i = 0, ii = require.length; i < ii; i++) {
|
8824
|
-
value[i] = getControllers(directiveName, require[i], $element, elementControllers);
|
8825
|
-
}
|
8826
|
-
} else if (isObject(require)) {
|
8827
|
-
value = {};
|
8828
|
-
forEach(require, function(controller, property) {
|
8829
|
-
value[property] = getControllers(directiveName, controller, $element, elementControllers);
|
8830
|
-
});
|
8831
|
-
}
|
8832
|
-
|
8833
|
-
return value || null;
|
8834
|
-
}
|
8835
|
-
|
8836
|
-
function setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope) {
|
8837
|
-
var elementControllers = createMap();
|
8838
|
-
for (var controllerKey in controllerDirectives) {
|
8839
|
-
var directive = controllerDirectives[controllerKey];
|
8840
|
-
var locals = {
|
8841
|
-
$scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
|
8842
|
-
$element: $element,
|
8843
|
-
$attrs: attrs,
|
8844
|
-
$transclude: transcludeFn
|
8845
|
-
};
|
8846
|
-
|
8847
|
-
var controller = directive.controller;
|
8848
|
-
if (controller == '@') {
|
8849
|
-
controller = attrs[directive.name];
|
8850
|
-
}
|
8851
|
-
|
8852
|
-
var controllerInstance = $controller(controller, locals, true, directive.controllerAs);
|
8853
|
-
|
8854
|
-
// For directives with element transclusion the element is a comment,
|
8855
|
-
// but jQuery .data doesn't support attaching data to comment nodes as it's hard to
|
8856
|
-
// clean up (http://bugs.jquery.com/ticket/8335).
|
8857
|
-
// Instead, we save the controllers for the element in a local hash and attach to .data
|
8858
|
-
// later, once we have the actual element.
|
8859
|
-
elementControllers[directive.name] = controllerInstance;
|
8860
|
-
if (!hasElementTranscludeDirective) {
|
8861
|
-
$element.data('$' + directive.name + 'Controller', controllerInstance.instance);
|
8862
|
-
}
|
8863
|
-
}
|
8864
|
-
return elementControllers;
|
8865
|
-
}
|
8866
|
-
|
8867
8971
|
function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {
|
8868
8972
|
var i, ii, linkFn, isolateScope, controllerScope, elementControllers, transcludeFn, $element,
|
8869
|
-
attrs,
|
8973
|
+
attrs, scopeBindingInfo;
|
8870
8974
|
|
8871
8975
|
if (compileNode === linkNode) {
|
8872
8976
|
attrs = templateAttrs;
|
@@ -8895,7 +8999,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
8895
8999
|
}
|
8896
9000
|
|
8897
9001
|
if (controllerDirectives) {
|
8898
|
-
elementControllers = setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope);
|
9002
|
+
elementControllers = setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope, newIsolateScopeDirective);
|
8899
9003
|
}
|
8900
9004
|
|
8901
9005
|
if (newIsolateScopeDirective) {
|
@@ -8905,11 +9009,11 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
8905
9009
|
compile.$$addScopeClass($element, true);
|
8906
9010
|
isolateScope.$$isolateBindings =
|
8907
9011
|
newIsolateScopeDirective.$$isolateBindings;
|
8908
|
-
|
9012
|
+
scopeBindingInfo = initializeDirectiveBindings(scope, attrs, isolateScope,
|
8909
9013
|
isolateScope.$$isolateBindings,
|
8910
9014
|
newIsolateScopeDirective);
|
8911
|
-
if (
|
8912
|
-
isolateScope.$on('$destroy',
|
9015
|
+
if (scopeBindingInfo.removeWatches) {
|
9016
|
+
isolateScope.$on('$destroy', scopeBindingInfo.removeWatches);
|
8913
9017
|
}
|
8914
9018
|
}
|
8915
9019
|
|
@@ -8920,8 +9024,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
8920
9024
|
var bindings = controllerDirective.$$bindings.bindToController;
|
8921
9025
|
|
8922
9026
|
if (controller.identifier && bindings) {
|
8923
|
-
|
9027
|
+
controller.bindingInfo =
|
8924
9028
|
initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);
|
9029
|
+
} else {
|
9030
|
+
controller.bindingInfo = {};
|
8925
9031
|
}
|
8926
9032
|
|
8927
9033
|
var controllerResult = controller();
|
@@ -8930,8 +9036,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
8930
9036
|
// from setupControllers
|
8931
9037
|
controller.instance = controllerResult;
|
8932
9038
|
$element.data('$' + controllerDirective.name + 'Controller', controllerResult);
|
8933
|
-
|
8934
|
-
|
9039
|
+
controller.bindingInfo.removeWatches && controller.bindingInfo.removeWatches();
|
9040
|
+
controller.bindingInfo =
|
8935
9041
|
initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);
|
8936
9042
|
}
|
8937
9043
|
}
|
@@ -8944,10 +9050,19 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
8944
9050
|
}
|
8945
9051
|
});
|
8946
9052
|
|
8947
|
-
//
|
9053
|
+
// Handle the init and destroy lifecycle hooks on all controllers that have them
|
8948
9054
|
forEach(elementControllers, function(controller) {
|
8949
|
-
|
8950
|
-
|
9055
|
+
var controllerInstance = controller.instance;
|
9056
|
+
if (isFunction(controllerInstance.$onChanges)) {
|
9057
|
+
controllerInstance.$onChanges(controller.bindingInfo.initialChanges);
|
9058
|
+
}
|
9059
|
+
if (isFunction(controllerInstance.$onInit)) {
|
9060
|
+
controllerInstance.$onInit();
|
9061
|
+
}
|
9062
|
+
if (isFunction(controllerInstance.$onDestroy)) {
|
9063
|
+
controllerScope.$on('$destroy', function callOnDestroyHook() {
|
9064
|
+
controllerInstance.$onDestroy();
|
9065
|
+
});
|
8951
9066
|
}
|
8952
9067
|
});
|
8953
9068
|
|
@@ -8984,6 +9099,14 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
8984
9099
|
);
|
8985
9100
|
}
|
8986
9101
|
|
9102
|
+
// Trigger $postLink lifecycle hooks
|
9103
|
+
forEach(elementControllers, function(controller) {
|
9104
|
+
var controllerInstance = controller.instance;
|
9105
|
+
if (isFunction(controllerInstance.$postLink)) {
|
9106
|
+
controllerInstance.$postLink();
|
9107
|
+
}
|
9108
|
+
});
|
9109
|
+
|
8987
9110
|
// This is the function that is injected as `$transclude`.
|
8988
9111
|
// Note: all arguments are optional!
|
8989
9112
|
function controllersBoundTransclude(scope, cloneAttachFn, futureParentElement, slotName) {
|
@@ -9023,6 +9146,78 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
9023
9146
|
}
|
9024
9147
|
}
|
9025
9148
|
|
9149
|
+
function getControllers(directiveName, require, $element, elementControllers) {
|
9150
|
+
var value;
|
9151
|
+
|
9152
|
+
if (isString(require)) {
|
9153
|
+
var match = require.match(REQUIRE_PREFIX_REGEXP);
|
9154
|
+
var name = require.substring(match[0].length);
|
9155
|
+
var inheritType = match[1] || match[3];
|
9156
|
+
var optional = match[2] === '?';
|
9157
|
+
|
9158
|
+
//If only parents then start at the parent element
|
9159
|
+
if (inheritType === '^^') {
|
9160
|
+
$element = $element.parent();
|
9161
|
+
//Otherwise attempt getting the controller from elementControllers in case
|
9162
|
+
//the element is transcluded (and has no data) and to avoid .data if possible
|
9163
|
+
} else {
|
9164
|
+
value = elementControllers && elementControllers[name];
|
9165
|
+
value = value && value.instance;
|
9166
|
+
}
|
9167
|
+
|
9168
|
+
if (!value) {
|
9169
|
+
var dataName = '$' + name + 'Controller';
|
9170
|
+
value = inheritType ? $element.inheritedData(dataName) : $element.data(dataName);
|
9171
|
+
}
|
9172
|
+
|
9173
|
+
if (!value && !optional) {
|
9174
|
+
throw $compileMinErr('ctreq',
|
9175
|
+
"Controller '{0}', required by directive '{1}', can't be found!",
|
9176
|
+
name, directiveName);
|
9177
|
+
}
|
9178
|
+
} else if (isArray(require)) {
|
9179
|
+
value = [];
|
9180
|
+
for (var i = 0, ii = require.length; i < ii; i++) {
|
9181
|
+
value[i] = getControllers(directiveName, require[i], $element, elementControllers);
|
9182
|
+
}
|
9183
|
+
} else if (isObject(require)) {
|
9184
|
+
value = {};
|
9185
|
+
forEach(require, function(controller, property) {
|
9186
|
+
value[property] = getControllers(directiveName, controller, $element, elementControllers);
|
9187
|
+
});
|
9188
|
+
}
|
9189
|
+
|
9190
|
+
return value || null;
|
9191
|
+
}
|
9192
|
+
|
9193
|
+
function setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope, newIsolateScopeDirective) {
|
9194
|
+
var elementControllers = createMap();
|
9195
|
+
for (var controllerKey in controllerDirectives) {
|
9196
|
+
var directive = controllerDirectives[controllerKey];
|
9197
|
+
var locals = {
|
9198
|
+
$scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
|
9199
|
+
$element: $element,
|
9200
|
+
$attrs: attrs,
|
9201
|
+
$transclude: transcludeFn
|
9202
|
+
};
|
9203
|
+
|
9204
|
+
var controller = directive.controller;
|
9205
|
+
if (controller == '@') {
|
9206
|
+
controller = attrs[directive.name];
|
9207
|
+
}
|
9208
|
+
|
9209
|
+
var controllerInstance = $controller(controller, locals, true, directive.controllerAs);
|
9210
|
+
|
9211
|
+
// For directives with element transclusion the element is a comment.
|
9212
|
+
// In this case .data will not attach any data.
|
9213
|
+
// Instead, we save the controllers for the element in a local hash and attach to .data
|
9214
|
+
// later, once we have the actual element.
|
9215
|
+
elementControllers[directive.name] = controllerInstance;
|
9216
|
+
$element.data('$' + directive.name + 'Controller', controllerInstance.instance);
|
9217
|
+
}
|
9218
|
+
return elementControllers;
|
9219
|
+
}
|
9220
|
+
|
9026
9221
|
// Depending upon the context in which a directive finds itself it might need to have a new isolated
|
9027
9222
|
// or child scope created. For instance:
|
9028
9223
|
// * if the directive has been pulled into a template because another directive with a higher priority
|
@@ -9063,6 +9258,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
9063
9258
|
if (startAttrName) {
|
9064
9259
|
directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName});
|
9065
9260
|
}
|
9261
|
+
if (!directive.$$bindings) {
|
9262
|
+
var bindings = directive.$$bindings =
|
9263
|
+
parseDirectiveBindings(directive, directive.name);
|
9264
|
+
if (isObject(bindings.isolateScope)) {
|
9265
|
+
directive.$$isolateBindings = bindings.isolateScope;
|
9266
|
+
}
|
9267
|
+
}
|
9066
9268
|
tDirectives.push(directive);
|
9067
9269
|
match = directive;
|
9068
9270
|
}
|
@@ -9310,7 +9512,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
9310
9512
|
switch (type) {
|
9311
9513
|
case 'svg':
|
9312
9514
|
case 'math':
|
9313
|
-
var wrapper = document.createElement('div');
|
9515
|
+
var wrapper = window.document.createElement('div');
|
9314
9516
|
wrapper.innerHTML = '<' + type + '>' + template + '</' + type + '>';
|
9315
9517
|
return wrapper.childNodes[0].childNodes;
|
9316
9518
|
default:
|
@@ -9454,7 +9656,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
9454
9656
|
// - remove them from the DOM
|
9455
9657
|
// - allow them to still be traversed with .nextSibling
|
9456
9658
|
// - allow a single fragment.qSA to fetch all elements being removed
|
9457
|
-
var fragment = document.createDocumentFragment();
|
9659
|
+
var fragment = window.document.createDocumentFragment();
|
9458
9660
|
for (i = 0; i < removeCount; i++) {
|
9459
9661
|
fragment.appendChild(elementsToRemove[i]);
|
9460
9662
|
}
|
@@ -9500,7 +9702,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
9500
9702
|
// only occurs for isolate scopes and new scopes with controllerAs.
|
9501
9703
|
function initializeDirectiveBindings(scope, attrs, destination, bindings, directive) {
|
9502
9704
|
var removeWatchCollection = [];
|
9503
|
-
|
9705
|
+
var initialChanges = {};
|
9706
|
+
var changes;
|
9707
|
+
forEach(bindings, function initializeBinding(definition, scopeName) {
|
9504
9708
|
var attrName = definition.attrName,
|
9505
9709
|
optional = definition.optional,
|
9506
9710
|
mode = definition.mode, // @, =, or &
|
@@ -9514,7 +9718,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
9514
9718
|
destination[scopeName] = attrs[attrName] = void 0;
|
9515
9719
|
}
|
9516
9720
|
attrs.$observe(attrName, function(value) {
|
9517
|
-
if (isString(value)) {
|
9721
|
+
if (isString(value) || isBoolean(value)) {
|
9722
|
+
var oldValue = destination[scopeName];
|
9723
|
+
recordChanges(scopeName, value, oldValue);
|
9518
9724
|
destination[scopeName] = value;
|
9519
9725
|
}
|
9520
9726
|
});
|
@@ -9529,6 +9735,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
9529
9735
|
// the value to boolean rather than a string, so we special case this situation
|
9530
9736
|
destination[scopeName] = lastValue;
|
9531
9737
|
}
|
9738
|
+
initialChanges[scopeName] = new SimpleChange(_UNINITIALIZED_VALUE, destination[scopeName]);
|
9532
9739
|
break;
|
9533
9740
|
|
9534
9741
|
case '=':
|
@@ -9542,7 +9749,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
9542
9749
|
if (parentGet.literal) {
|
9543
9750
|
compare = equals;
|
9544
9751
|
} else {
|
9545
|
-
compare = function(a, b) { return a === b || (a !== a && b !== b); };
|
9752
|
+
compare = function simpleCompare(a, b) { return a === b || (a !== a && b !== b); };
|
9546
9753
|
}
|
9547
9754
|
parentSet = parentGet.assign || function() {
|
9548
9755
|
// reset the change, or we will throw this exception on every $digest
|
@@ -9584,9 +9791,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
9584
9791
|
parentGet = $parse(attrs[attrName]);
|
9585
9792
|
|
9586
9793
|
destination[scopeName] = parentGet(scope);
|
9794
|
+
initialChanges[scopeName] = new SimpleChange(_UNINITIALIZED_VALUE, destination[scopeName]);
|
9587
9795
|
|
9588
|
-
removeWatch = scope.$watch(parentGet, function parentValueWatchAction(
|
9589
|
-
|
9796
|
+
removeWatch = scope.$watch(parentGet, function parentValueWatchAction(newValue, oldValue) {
|
9797
|
+
if (newValue === oldValue) {
|
9798
|
+
// If the new and old values are identical then this is the first time the watch has been triggered
|
9799
|
+
// So instead we use the current value on the destination as the old value
|
9800
|
+
oldValue = destination[scopeName];
|
9801
|
+
}
|
9802
|
+
recordChanges(scopeName, newValue, oldValue);
|
9803
|
+
destination[scopeName] = newValue;
|
9590
9804
|
}, parentGet.literal);
|
9591
9805
|
|
9592
9806
|
removeWatchCollection.push(removeWatch);
|
@@ -9606,15 +9820,52 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
|
|
9606
9820
|
}
|
9607
9821
|
});
|
9608
9822
|
|
9609
|
-
|
9610
|
-
|
9611
|
-
|
9823
|
+
function recordChanges(key, currentValue, previousValue) {
|
9824
|
+
if (isFunction(destination.$onChanges) && currentValue !== previousValue) {
|
9825
|
+
// If we have not already scheduled the top level onChangesQueue handler then do so now
|
9826
|
+
if (!onChangesQueue) {
|
9827
|
+
scope.$$postDigest(flushOnChangesQueue);
|
9828
|
+
onChangesQueue = [];
|
9829
|
+
}
|
9830
|
+
// If we have not already queued a trigger of onChanges for this controller then do so now
|
9831
|
+
if (!changes) {
|
9832
|
+
changes = {};
|
9833
|
+
onChangesQueue.push(triggerOnChangesHook);
|
9834
|
+
}
|
9835
|
+
// If the has been a change on this property already then we need to reuse the previous value
|
9836
|
+
if (changes[key]) {
|
9837
|
+
previousValue = changes[key].previousValue;
|
9838
|
+
}
|
9839
|
+
// Store this change
|
9840
|
+
changes[key] = new SimpleChange(previousValue, currentValue);
|
9841
|
+
}
|
9842
|
+
}
|
9843
|
+
|
9844
|
+
function triggerOnChangesHook() {
|
9845
|
+
destination.$onChanges(changes);
|
9846
|
+
// Now clear the changes so that we schedule onChanges when more changes arrive
|
9847
|
+
changes = undefined;
|
9848
|
+
}
|
9849
|
+
|
9850
|
+
return {
|
9851
|
+
initialChanges: initialChanges,
|
9852
|
+
removeWatches: removeWatchCollection.length && function removeWatches() {
|
9853
|
+
for (var i = 0, ii = removeWatchCollection.length; i < ii; ++i) {
|
9854
|
+
removeWatchCollection[i]();
|
9855
|
+
}
|
9612
9856
|
}
|
9613
9857
|
};
|
9614
9858
|
}
|
9615
9859
|
}];
|
9616
9860
|
}
|
9617
9861
|
|
9862
|
+
function SimpleChange(previous, current) {
|
9863
|
+
this.previousValue = previous;
|
9864
|
+
this.currentValue = current;
|
9865
|
+
}
|
9866
|
+
SimpleChange.prototype.isFirstChange = function() { return this.previousValue === _UNINITIALIZED_VALUE; };
|
9867
|
+
|
9868
|
+
|
9618
9869
|
var PREFIX_REGEXP = /^((?:x|data)[\:\-_])/i;
|
9619
9870
|
/**
|
9620
9871
|
* Converts all accepted directives format into proper directive name.
|
@@ -9744,6 +9995,15 @@ function $ControllerProvider() {
|
|
9744
9995
|
var controllers = {},
|
9745
9996
|
globals = false;
|
9746
9997
|
|
9998
|
+
/**
|
9999
|
+
* @ngdoc method
|
10000
|
+
* @name $controllerProvider#has
|
10001
|
+
* @param {string} name Controller name to check.
|
10002
|
+
*/
|
10003
|
+
this.has = function(name) {
|
10004
|
+
return controllers.hasOwnProperty(name);
|
10005
|
+
};
|
10006
|
+
|
9747
10007
|
/**
|
9748
10008
|
* @ngdoc method
|
9749
10009
|
* @name $controllerProvider#register
|
@@ -9800,7 +10060,7 @@ function $ControllerProvider() {
|
|
9800
10060
|
* It's just a simple call to {@link auto.$injector $injector}, but extracted into
|
9801
10061
|
* a service, so that one can override this service with [BC version](https://gist.github.com/1649788).
|
9802
10062
|
*/
|
9803
|
-
return function(expression, locals, later, ident) {
|
10063
|
+
return function $controller(expression, locals, later, ident) {
|
9804
10064
|
// PRIVATE API:
|
9805
10065
|
// param `later` --- indicates that the controller's constructor is invoked at a later time.
|
9806
10066
|
// If true, $controller will allocate the object with the correct
|
@@ -9851,7 +10111,7 @@ function $ControllerProvider() {
|
|
9851
10111
|
}
|
9852
10112
|
|
9853
10113
|
var instantiate;
|
9854
|
-
return instantiate = extend(function() {
|
10114
|
+
return instantiate = extend(function $controllerInit() {
|
9855
10115
|
var result = $injector.invoke(expression, instance, locals, constructor);
|
9856
10116
|
if (result !== instance && (isObject(result) || isFunction(result))) {
|
9857
10117
|
instance = result;
|
@@ -10037,7 +10297,7 @@ function $HttpParamSerializerProvider() {
|
|
10037
10297
|
forEachSorted(params, function(value, key) {
|
10038
10298
|
if (value === null || isUndefined(value)) return;
|
10039
10299
|
if (isArray(value)) {
|
10040
|
-
forEach(value, function(v
|
10300
|
+
forEach(value, function(v) {
|
10041
10301
|
parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(serializeValue(v)));
|
10042
10302
|
});
|
10043
10303
|
} else {
|
@@ -10247,10 +10507,9 @@ function $HttpProvider() {
|
|
10247
10507
|
*
|
10248
10508
|
* Object containing default values for all {@link ng.$http $http} requests.
|
10249
10509
|
*
|
10250
|
-
* - **`defaults.cache`** - {Object} -
|
10251
|
-
*
|
10252
|
-
*
|
10253
|
-
* cache object will be cached. See {@link $http#caching $http Caching} for more information.
|
10510
|
+
* - **`defaults.cache`** - {boolean|Object} - A boolean value or object created with
|
10511
|
+
* {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of HTTP responses
|
10512
|
+
* by default. See {@link $http#caching $http Caching} for more information.
|
10254
10513
|
*
|
10255
10514
|
* - **`defaults.xsrfCookieName`** - {string} - Name of cookie containing the XSRF token.
|
10256
10515
|
* Defaults value is `'XSRF-TOKEN'`.
|
@@ -10541,6 +10800,15 @@ function $HttpProvider() {
|
|
10541
10800
|
* the transformed value (`function(data, headersGetter, status)`) or an array of such transformation functions,
|
10542
10801
|
* which allows you to `push` or `unshift` a new transformation function into the transformation chain.
|
10543
10802
|
*
|
10803
|
+
* <div class="alert alert-warning">
|
10804
|
+
* **Note:** Angular does not make a copy of the `data` parameter before it is passed into the `transformRequest` pipeline.
|
10805
|
+
* That means changes to the properties of `data` are not local to the transform function (since Javascript passes objects by reference).
|
10806
|
+
* For example, when calling `$http.get(url, $scope.myObject)`, modifications to the object's properties in a transformRequest
|
10807
|
+
* function will be reflected on the scope and in any templates where the object is data-bound.
|
10808
|
+
* To prevent this, transform functions should have no side-effects.
|
10809
|
+
* If you need to modify properties, it is recommended to make a copy of the data, or create new object to return.
|
10810
|
+
* </div>
|
10811
|
+
*
|
10544
10812
|
* ### Default Transformations
|
10545
10813
|
*
|
10546
10814
|
* The `$httpProvider` provider and `$http` service expose `defaults.transformRequest` and
|
@@ -10598,26 +10866,35 @@ function $HttpProvider() {
|
|
10598
10866
|
*
|
10599
10867
|
* ## Caching
|
10600
10868
|
*
|
10601
|
-
*
|
10602
|
-
* cache
|
10603
|
-
*
|
10604
|
-
*
|
10605
|
-
*
|
10869
|
+
* {@link ng.$http `$http`} responses are not cached by default. To enable caching, you must
|
10870
|
+
* set the config.cache value or the default cache value to TRUE or to a cache object (created
|
10871
|
+
* with {@link ng.$cacheFactory `$cacheFactory`}). If defined, the value of config.cache takes
|
10872
|
+
* precedence over the default cache value.
|
10873
|
+
*
|
10874
|
+
* In order to:
|
10875
|
+
* * cache all responses - set the default cache value to TRUE or to a cache object
|
10876
|
+
* * cache a specific response - set config.cache value to TRUE or to a cache object
|
10877
|
+
*
|
10878
|
+
* If caching is enabled, but neither the default cache nor config.cache are set to a cache object,
|
10879
|
+
* then the default `$cacheFactory($http)` object is used.
|
10606
10880
|
*
|
10607
|
-
*
|
10608
|
-
*
|
10881
|
+
* The default cache value can be set by updating the
|
10882
|
+
* {@link ng.$http#defaults `$http.defaults.cache`} property or the
|
10883
|
+
* {@link $httpProvider#defaults `$httpProvider.defaults.cache`} property.
|
10609
10884
|
*
|
10610
|
-
*
|
10611
|
-
*
|
10612
|
-
* the
|
10885
|
+
* When caching is enabled, {@link ng.$http `$http`} stores the response from the server using
|
10886
|
+
* the relevant cache object. The next time the same request is made, the response is returned
|
10887
|
+
* from the cache without sending a request to the server.
|
10613
10888
|
*
|
10614
|
-
*
|
10615
|
-
*
|
10616
|
-
*
|
10617
|
-
*
|
10889
|
+
* Take note that:
|
10890
|
+
*
|
10891
|
+
* * Only GET and JSONP requests are cached.
|
10892
|
+
* * The cache key is the request URL including search parameters; headers are not considered.
|
10893
|
+
* * Cached responses are returned asynchronously, in the same way as responses from the server.
|
10894
|
+
* * If multiple identical requests are made using the same cache, which is not yet populated,
|
10895
|
+
* one request will be made to the server and remaining requests will return the same response.
|
10896
|
+
* * A cache-control header on the response does not affect if or how responses are cached.
|
10618
10897
|
*
|
10619
|
-
* If you set the default cache to `false` then only requests that specify their own custom
|
10620
|
-
* cache object will be cached.
|
10621
10898
|
*
|
10622
10899
|
* ## Interceptors
|
10623
10900
|
*
|
@@ -10774,6 +11051,12 @@ function $HttpProvider() {
|
|
10774
11051
|
* - **headers** – `{Object}` – Map of strings or functions which return strings representing
|
10775
11052
|
* HTTP headers to send to the server. If the return value of a function is null, the
|
10776
11053
|
* header will not be sent. Functions accept a config object as an argument.
|
11054
|
+
* - **eventHandlers** - `{Object}` - Event listeners to be bound to the XMLHttpRequest object.
|
11055
|
+
* To bind events to the XMLHttpRequest upload object, use `uploadEventHandlers`.
|
11056
|
+
* The handler will be called in the context of a `$apply` block.
|
11057
|
+
* - **uploadEventHandlers** - `{Object}` - Event listeners to be bound to the XMLHttpRequest upload
|
11058
|
+
* object. To bind events to the XMLHttpRequest object, use `eventHandlers`.
|
11059
|
+
* The handler will be called in the context of a `$apply` block.
|
10777
11060
|
* - **xsrfHeaderName** – `{string}` – Name of HTTP header to populate with the XSRF token.
|
10778
11061
|
* - **xsrfCookieName** – `{string}` – Name of cookie containing the XSRF token.
|
10779
11062
|
* - **transformRequest** –
|
@@ -10787,7 +11070,7 @@ function $HttpProvider() {
|
|
10787
11070
|
* transform function or an array of such functions. The transform function takes the http
|
10788
11071
|
* response body, headers and status and returns its transformed (typically deserialized) version.
|
10789
11072
|
* See {@link ng.$http#overriding-the-default-transformations-per-request
|
10790
|
-
* Overriding the Default
|
11073
|
+
* Overriding the Default Transformations}
|
10791
11074
|
* - **paramSerializer** - `{string|function(Object<string,string>):string}` - A function used to
|
10792
11075
|
* prepare the string representation of request parameters (specified as an object).
|
10793
11076
|
* If specified as string, it is interpreted as function registered with the
|
@@ -10795,10 +11078,9 @@ function $HttpProvider() {
|
|
10795
11078
|
* by registering it as a {@link auto.$provide#service service}.
|
10796
11079
|
* The default serializer is the {@link $httpParamSerializer $httpParamSerializer};
|
10797
11080
|
* alternatively, you can use the {@link $httpParamSerializerJQLike $httpParamSerializerJQLike}
|
10798
|
-
* - **cache** – `{boolean|
|
10799
|
-
*
|
10800
|
-
* {@link
|
10801
|
-
* caching.
|
11081
|
+
* - **cache** – `{boolean|Object}` – A boolean value or object created with
|
11082
|
+
* {@link ng.$cacheFactory `$cacheFactory`} to enable or disable caching of the HTTP response.
|
11083
|
+
* See {@link $http#caching $http Caching} for more information.
|
10802
11084
|
* - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise}
|
10803
11085
|
* that should abort the request when resolved.
|
10804
11086
|
* - **withCredentials** - `{boolean}` - whether to set the `withCredentials` flag on the
|
@@ -11233,11 +11515,35 @@ function $HttpProvider() {
|
|
11233
11515
|
}
|
11234
11516
|
|
11235
11517
|
$httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout,
|
11236
|
-
config.withCredentials, config.responseType
|
11518
|
+
config.withCredentials, config.responseType,
|
11519
|
+
createApplyHandlers(config.eventHandlers),
|
11520
|
+
createApplyHandlers(config.uploadEventHandlers));
|
11237
11521
|
}
|
11238
11522
|
|
11239
11523
|
return promise;
|
11240
11524
|
|
11525
|
+
function createApplyHandlers(eventHandlers) {
|
11526
|
+
if (eventHandlers) {
|
11527
|
+
var applyHandlers = {};
|
11528
|
+
forEach(eventHandlers, function(eventHandler, key) {
|
11529
|
+
applyHandlers[key] = function(event) {
|
11530
|
+
if (useApplyAsync) {
|
11531
|
+
$rootScope.$applyAsync(callEventHandler);
|
11532
|
+
} else if ($rootScope.$$phase) {
|
11533
|
+
callEventHandler();
|
11534
|
+
} else {
|
11535
|
+
$rootScope.$apply(callEventHandler);
|
11536
|
+
}
|
11537
|
+
|
11538
|
+
function callEventHandler() {
|
11539
|
+
eventHandler(event);
|
11540
|
+
}
|
11541
|
+
};
|
11542
|
+
});
|
11543
|
+
return applyHandlers;
|
11544
|
+
}
|
11545
|
+
}
|
11546
|
+
|
11241
11547
|
|
11242
11548
|
/**
|
11243
11549
|
* Callback registered to $httpBackend():
|
@@ -11358,7 +11664,7 @@ function $HttpBackendProvider() {
|
|
11358
11664
|
|
11359
11665
|
function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDocument) {
|
11360
11666
|
// TODO(vojta): fix the signature
|
11361
|
-
return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
|
11667
|
+
return function(method, url, post, callback, headers, timeout, withCredentials, responseType, eventHandlers, uploadEventHandlers) {
|
11362
11668
|
$browser.$$incOutstandingRequestCount();
|
11363
11669
|
url = url || $browser.url();
|
11364
11670
|
|
@@ -11418,6 +11724,14 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
|
|
11418
11724
|
xhr.onerror = requestError;
|
11419
11725
|
xhr.onabort = requestError;
|
11420
11726
|
|
11727
|
+
forEach(eventHandlers, function(value, key) {
|
11728
|
+
xhr.addEventListener(key, value);
|
11729
|
+
});
|
11730
|
+
|
11731
|
+
forEach(uploadEventHandlers, function(value, key) {
|
11732
|
+
xhr.upload.addEventListener(key, value);
|
11733
|
+
});
|
11734
|
+
|
11421
11735
|
if (withCredentials) {
|
11422
11736
|
xhr.withCredentials = true;
|
11423
11737
|
}
|
@@ -13396,7 +13710,7 @@ Lexer.prototype = {
|
|
13396
13710
|
this.readString(ch);
|
13397
13711
|
} else if (this.isNumber(ch) || ch === '.' && this.isNumber(this.peek())) {
|
13398
13712
|
this.readNumber();
|
13399
|
-
} else if (this.
|
13713
|
+
} else if (this.isIdentifierStart(this.peekMultichar())) {
|
13400
13714
|
this.readIdent();
|
13401
13715
|
} else if (this.is(ch, '(){}[].,;:?')) {
|
13402
13716
|
this.tokens.push({index: this.index, text: ch});
|
@@ -13440,12 +13754,49 @@ Lexer.prototype = {
|
|
13440
13754
|
ch === '\n' || ch === '\v' || ch === '\u00A0');
|
13441
13755
|
},
|
13442
13756
|
|
13443
|
-
|
13757
|
+
isIdentifierStart: function(ch) {
|
13758
|
+
return this.options.isIdentifierStart ?
|
13759
|
+
this.options.isIdentifierStart(ch, this.codePointAt(ch)) :
|
13760
|
+
this.isValidIdentifierStart(ch);
|
13761
|
+
},
|
13762
|
+
|
13763
|
+
isValidIdentifierStart: function(ch) {
|
13444
13764
|
return ('a' <= ch && ch <= 'z' ||
|
13445
13765
|
'A' <= ch && ch <= 'Z' ||
|
13446
13766
|
'_' === ch || ch === '$');
|
13447
13767
|
},
|
13448
13768
|
|
13769
|
+
isIdentifierContinue: function(ch) {
|
13770
|
+
return this.options.isIdentifierContinue ?
|
13771
|
+
this.options.isIdentifierContinue(ch, this.codePointAt(ch)) :
|
13772
|
+
this.isValidIdentifierContinue(ch);
|
13773
|
+
},
|
13774
|
+
|
13775
|
+
isValidIdentifierContinue: function(ch, cp) {
|
13776
|
+
return this.isValidIdentifierStart(ch, cp) || this.isNumber(ch);
|
13777
|
+
},
|
13778
|
+
|
13779
|
+
codePointAt: function(ch) {
|
13780
|
+
if (ch.length === 1) return ch.charCodeAt(0);
|
13781
|
+
/*jshint bitwise: false*/
|
13782
|
+
return (ch.charCodeAt(0) << 10) + ch.charCodeAt(1) - 0x35FDC00;
|
13783
|
+
/*jshint bitwise: true*/
|
13784
|
+
},
|
13785
|
+
|
13786
|
+
peekMultichar: function() {
|
13787
|
+
var ch = this.text.charAt(this.index);
|
13788
|
+
var peek = this.peek();
|
13789
|
+
if (!peek) {
|
13790
|
+
return ch;
|
13791
|
+
}
|
13792
|
+
var cp1 = ch.charCodeAt(0);
|
13793
|
+
var cp2 = peek.charCodeAt(0);
|
13794
|
+
if (cp1 >= 0xD800 && cp1 <= 0xDBFF && cp2 >= 0xDC00 && cp2 <= 0xDFFF) {
|
13795
|
+
return ch + peek;
|
13796
|
+
}
|
13797
|
+
return ch;
|
13798
|
+
},
|
13799
|
+
|
13449
13800
|
isExpOperator: function(ch) {
|
13450
13801
|
return (ch === '-' || ch === '+' || this.isNumber(ch));
|
13451
13802
|
},
|
@@ -13494,12 +13845,13 @@ Lexer.prototype = {
|
|
13494
13845
|
|
13495
13846
|
readIdent: function() {
|
13496
13847
|
var start = this.index;
|
13848
|
+
this.index += this.peekMultichar().length;
|
13497
13849
|
while (this.index < this.text.length) {
|
13498
|
-
var ch = this.
|
13499
|
-
if (!
|
13850
|
+
var ch = this.peekMultichar();
|
13851
|
+
if (!this.isIdentifierContinue(ch)) {
|
13500
13852
|
break;
|
13501
13853
|
}
|
13502
|
-
this.index
|
13854
|
+
this.index += ch.length;
|
13503
13855
|
}
|
13504
13856
|
this.tokens.push({
|
13505
13857
|
index: start,
|
@@ -13709,8 +14061,10 @@ AST.prototype = {
|
|
13709
14061
|
primary = this.arrayDeclaration();
|
13710
14062
|
} else if (this.expect('{')) {
|
13711
14063
|
primary = this.object();
|
13712
|
-
} else if (this.
|
13713
|
-
primary = copy(this.
|
14064
|
+
} else if (this.selfReferential.hasOwnProperty(this.peek().text)) {
|
14065
|
+
primary = copy(this.selfReferential[this.consume().text]);
|
14066
|
+
} else if (this.options.literals.hasOwnProperty(this.peek().text)) {
|
14067
|
+
primary = { type: AST.Literal, value: this.options.literals[this.consume().text]};
|
13714
14068
|
} else if (this.peek().identifier) {
|
13715
14069
|
primary = this.identifier();
|
13716
14070
|
} else if (this.peek().constant) {
|
@@ -13862,15 +14216,7 @@ AST.prototype = {
|
|
13862
14216
|
return false;
|
13863
14217
|
},
|
13864
14218
|
|
13865
|
-
|
13866
|
-
/* `undefined` is not a constant, it is an identifier,
|
13867
|
-
* but using it as an identifier is not supported
|
13868
|
-
*/
|
13869
|
-
constants: {
|
13870
|
-
'true': { type: AST.Literal, value: true },
|
13871
|
-
'false': { type: AST.Literal, value: false },
|
13872
|
-
'null': { type: AST.Literal, value: null },
|
13873
|
-
'undefined': {type: AST.Literal, value: undefined },
|
14219
|
+
selfReferential: {
|
13874
14220
|
'this': {type: AST.ThisExpression },
|
13875
14221
|
'$locals': {type: AST.LocalsExpression }
|
13876
14222
|
}
|
@@ -14435,7 +14781,13 @@ ASTCompiler.prototype = {
|
|
14435
14781
|
},
|
14436
14782
|
|
14437
14783
|
nonComputedMember: function(left, right) {
|
14438
|
-
|
14784
|
+
var SAFE_IDENTIFIER = /[$_a-zA-Z][$_a-zA-Z0-9]*/;
|
14785
|
+
var UNSAFE_CHARACTERS = /[^$_a-zA-Z0-9]/g;
|
14786
|
+
if (SAFE_IDENTIFIER.test(right)) {
|
14787
|
+
return left + '.' + right;
|
14788
|
+
} else {
|
14789
|
+
return left + '["' + right.replace(UNSAFE_CHARACTERS, this.stringEscapeFn) + '"]';
|
14790
|
+
}
|
14439
14791
|
},
|
14440
14792
|
|
14441
14793
|
computedMember: function(left, right) {
|
@@ -14560,7 +14912,7 @@ ASTInterpreter.prototype = {
|
|
14560
14912
|
forEach(ast.body, function(expression) {
|
14561
14913
|
expressions.push(self.recurse(expression.expression));
|
14562
14914
|
});
|
14563
|
-
var fn = ast.body.length === 0 ?
|
14915
|
+
var fn = ast.body.length === 0 ? noop :
|
14564
14916
|
ast.body.length === 1 ? expressions[0] :
|
14565
14917
|
function(scope, locals) {
|
14566
14918
|
var lastValue;
|
@@ -14701,7 +15053,7 @@ ASTInterpreter.prototype = {
|
|
14701
15053
|
return context ? {value: locals} : locals;
|
14702
15054
|
};
|
14703
15055
|
case AST.NGValueParameter:
|
14704
|
-
return function(scope, locals, assign
|
15056
|
+
return function(scope, locals, assign) {
|
14705
15057
|
return context ? {value: assign} : assign;
|
14706
15058
|
};
|
14707
15059
|
}
|
@@ -14915,7 +15267,7 @@ var Parser = function(lexer, $filter, options) {
|
|
14915
15267
|
this.lexer = lexer;
|
14916
15268
|
this.$filter = $filter;
|
14917
15269
|
this.options = options;
|
14918
|
-
this.ast = new AST(
|
15270
|
+
this.ast = new AST(lexer, options);
|
14919
15271
|
this.astCompiler = options.csp ? new ASTInterpreter(this.ast, $filter) :
|
14920
15272
|
new ASTCompiler(this.ast, $filter);
|
14921
15273
|
};
|
@@ -14992,16 +15344,73 @@ function getValueOf(value) {
|
|
14992
15344
|
function $ParseProvider() {
|
14993
15345
|
var cacheDefault = createMap();
|
14994
15346
|
var cacheExpensive = createMap();
|
15347
|
+
var literals = {
|
15348
|
+
'true': true,
|
15349
|
+
'false': false,
|
15350
|
+
'null': null,
|
15351
|
+
'undefined': undefined
|
15352
|
+
};
|
15353
|
+
var identStart, identContinue;
|
15354
|
+
|
15355
|
+
/**
|
15356
|
+
* @ngdoc method
|
15357
|
+
* @name $parseProvider#addLiteral
|
15358
|
+
* @description
|
15359
|
+
*
|
15360
|
+
* Configure $parse service to add literal values that will be present as literal at expressions.
|
15361
|
+
*
|
15362
|
+
* @param {string} literalName Token for the literal value. The literal name value must be a valid literal name.
|
15363
|
+
* @param {*} literalValue Value for this literal. All literal values must be primitives or `undefined`.
|
15364
|
+
*
|
15365
|
+
**/
|
15366
|
+
this.addLiteral = function(literalName, literalValue) {
|
15367
|
+
literals[literalName] = literalValue;
|
15368
|
+
};
|
15369
|
+
|
15370
|
+
/**
|
15371
|
+
* @ngdoc method
|
15372
|
+
* @name $parseProvider#setIdentifierFns
|
15373
|
+
* @description
|
15374
|
+
*
|
15375
|
+
* Allows defining the set of characters that are allowed in Angular expressions. The function
|
15376
|
+
* `identifierStart` will get called to know if a given character is a valid character to be the
|
15377
|
+
* first character for an identifier. The function `identifierContinue` will get called to know if
|
15378
|
+
* a given character is a valid character to be a follow-up identifier character. The functions
|
15379
|
+
* `identifierStart` and `identifierContinue` will receive as arguments the single character to be
|
15380
|
+
* identifier and the character code point. These arguments will be `string` and `numeric`. Keep in
|
15381
|
+
* mind that the `string` parameter can be two characters long depending on the character
|
15382
|
+
* representation. It is expected for the function to return `true` or `false`, whether that
|
15383
|
+
* character is allowed or not.
|
15384
|
+
*
|
15385
|
+
* Since this function will be called extensivelly, keep the implementation of these functions fast,
|
15386
|
+
* as the performance of these functions have a direct impact on the expressions parsing speed.
|
15387
|
+
*
|
15388
|
+
* @param {function=} identifierStart The function that will decide whether the given character is
|
15389
|
+
* a valid identifier start character.
|
15390
|
+
* @param {function=} identifierContinue The function that will decide whether the given character is
|
15391
|
+
* a valid identifier continue character.
|
15392
|
+
*/
|
15393
|
+
this.setIdentifierFns = function(identifierStart, identifierContinue) {
|
15394
|
+
identStart = identifierStart;
|
15395
|
+
identContinue = identifierContinue;
|
15396
|
+
return this;
|
15397
|
+
};
|
14995
15398
|
|
14996
15399
|
this.$get = ['$filter', function($filter) {
|
14997
15400
|
var noUnsafeEval = csp().noUnsafeEval;
|
14998
15401
|
var $parseOptions = {
|
14999
15402
|
csp: noUnsafeEval,
|
15000
|
-
expensiveChecks: false
|
15403
|
+
expensiveChecks: false,
|
15404
|
+
literals: copy(literals),
|
15405
|
+
isIdentifierStart: isFunction(identStart) && identStart,
|
15406
|
+
isIdentifierContinue: isFunction(identContinue) && identContinue
|
15001
15407
|
},
|
15002
15408
|
$parseOptionsExpensive = {
|
15003
15409
|
csp: noUnsafeEval,
|
15004
|
-
expensiveChecks: true
|
15410
|
+
expensiveChecks: true,
|
15411
|
+
literals: copy(literals),
|
15412
|
+
isIdentifierStart: isFunction(identStart) && identStart,
|
15413
|
+
isIdentifierContinue: isFunction(identContinue) && identContinue
|
15005
15414
|
};
|
15006
15415
|
var runningChecksEnabled = false;
|
15007
15416
|
|
@@ -15250,15 +15659,15 @@ function $ParseProvider() {
|
|
15250
15659
|
* [Kris Kowal's Q](https://github.com/kriskowal/q).
|
15251
15660
|
*
|
15252
15661
|
* $q can be used in two fashions --- one which is more similar to Kris Kowal's Q or jQuery's Deferred
|
15253
|
-
* implementations, and the other which resembles ES6 promises to some degree.
|
15662
|
+
* implementations, and the other which resembles ES6 (ES2015) promises to some degree.
|
15254
15663
|
*
|
15255
15664
|
* # $q constructor
|
15256
15665
|
*
|
15257
15666
|
* The streamlined ES6 style promise is essentially just using $q as a constructor which takes a `resolver`
|
15258
|
-
* function as the first argument. This is similar to the native Promise implementation from ES6
|
15667
|
+
* function as the first argument. This is similar to the native Promise implementation from ES6,
|
15259
15668
|
* see [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).
|
15260
15669
|
*
|
15261
|
-
* While the constructor-style use is supported, not all of the supporting methods from ES6
|
15670
|
+
* While the constructor-style use is supported, not all of the supporting methods from ES6 promises are
|
15262
15671
|
* available yet.
|
15263
15672
|
*
|
15264
15673
|
* It can be used like so:
|
@@ -15423,7 +15832,7 @@ function $ParseProvider() {
|
|
15423
15832
|
* - Q has many more features than $q, but that comes at a cost of bytes. $q is tiny, but contains
|
15424
15833
|
* all the important functionality needed for common async tasks.
|
15425
15834
|
*
|
15426
|
-
*
|
15835
|
+
* # Testing
|
15427
15836
|
*
|
15428
15837
|
* ```js
|
15429
15838
|
* it('should simulate promise', inject(function($q, $rootScope) {
|
@@ -16611,7 +17020,7 @@ function $RootScopeProvider() {
|
|
16611
17020
|
dirty, ttl = TTL,
|
16612
17021
|
next, current, target = this,
|
16613
17022
|
watchLog = [],
|
16614
|
-
logIdx,
|
17023
|
+
logIdx, asyncTask;
|
16615
17024
|
|
16616
17025
|
beginPhase('$digest');
|
16617
17026
|
// Check for changes to browser url that happened in sync before the call to $digest
|
@@ -18396,6 +18805,10 @@ function $SceProvider() {
|
|
18396
18805
|
function $SnifferProvider() {
|
18397
18806
|
this.$get = ['$window', '$document', function($window, $document) {
|
18398
18807
|
var eventSupport = {},
|
18808
|
+
// Chrome Packaged Apps are not allowed to access `history.pushState`. They can be detected by
|
18809
|
+
// the presence of `chrome.app.runtime` (see https://developer.chrome.com/apps/api_index)
|
18810
|
+
isChromePackagedApp = $window.chrome && $window.chrome.app && $window.chrome.app.runtime,
|
18811
|
+
hasHistoryPushState = !isChromePackagedApp && $window.history && $window.history.pushState,
|
18399
18812
|
android =
|
18400
18813
|
toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),
|
18401
18814
|
boxee = /Boxee/i.test(($window.navigator || {}).userAgent),
|
@@ -18440,7 +18853,7 @@ function $SnifferProvider() {
|
|
18440
18853
|
// so let's not use the history API also
|
18441
18854
|
// We are purposefully using `!(android < 4)` to cover the case when `android` is undefined
|
18442
18855
|
// jshint -W018
|
18443
|
-
history: !!(
|
18856
|
+
history: !!(hasHistoryPushState && !(android < 4) && !boxee),
|
18444
18857
|
// jshint +W018
|
18445
18858
|
hasEvent: function(event) {
|
18446
18859
|
// IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
|
@@ -18466,7 +18879,7 @@ function $SnifferProvider() {
|
|
18466
18879
|
}];
|
18467
18880
|
}
|
18468
18881
|
|
18469
|
-
var $
|
18882
|
+
var $templateRequestMinErr = minErr('$compile');
|
18470
18883
|
|
18471
18884
|
/**
|
18472
18885
|
* @ngdoc provider
|
@@ -18562,7 +18975,7 @@ function $TemplateRequestProvider() {
|
|
18562
18975
|
|
18563
18976
|
function handleError(resp) {
|
18564
18977
|
if (!ignoreRequestError) {
|
18565
|
-
throw $
|
18978
|
+
throw $templateRequestMinErr('tpload', 'Failed to load template: {0} (HTTP status: {1} {2})',
|
18566
18979
|
tpl, resp.status, resp.statusText);
|
18567
18980
|
}
|
18568
18981
|
return $q.reject(resp);
|
@@ -18792,7 +19205,7 @@ function $TimeoutProvider() {
|
|
18792
19205
|
// doesn't know about mocked locations and resolves URLs to the real document - which is
|
18793
19206
|
// exactly the behavior needed here. There is little value is mocking these out for this
|
18794
19207
|
// service.
|
18795
|
-
var urlParsingNode = document.createElement("a");
|
19208
|
+
var urlParsingNode = window.document.createElement("a");
|
18796
19209
|
var originUrl = urlResolve(window.location.href);
|
18797
19210
|
|
18798
19211
|
|
@@ -19484,7 +19897,7 @@ function currencyFilter($locale) {
|
|
19484
19897
|
* Formats a number as text.
|
19485
19898
|
*
|
19486
19899
|
* If the input is null or undefined, it will just be returned.
|
19487
|
-
* If the input is infinite (Infinity
|
19900
|
+
* If the input is infinite (Infinity or -Infinity), the Infinity symbol '∞' or '-∞' is returned, respectively.
|
19488
19901
|
* If the input is not a number an empty string is returned.
|
19489
19902
|
*
|
19490
19903
|
*
|
@@ -19492,7 +19905,9 @@ function currencyFilter($locale) {
|
|
19492
19905
|
* @param {(number|string)=} fractionSize Number of decimal places to round the number to.
|
19493
19906
|
* If this is not provided then the fraction size is computed from the current locale's number
|
19494
19907
|
* formatting pattern. In the case of the default locale, it will be 3.
|
19495
|
-
* @returns {string} Number rounded to fractionSize
|
19908
|
+
* @returns {string} Number rounded to `fractionSize` appropriately formatted based on the current
|
19909
|
+
* locale (e.g., in the en_US locale it will have "." as the decimal separator and
|
19910
|
+
* include "," group separators after each third digit).
|
19496
19911
|
*
|
19497
19912
|
* @example
|
19498
19913
|
<example module="numberFilterExample">
|
@@ -19574,7 +19989,7 @@ function parse(numStr) {
|
|
19574
19989
|
}
|
19575
19990
|
|
19576
19991
|
// Count the number of leading zeros.
|
19577
|
-
for (i = 0; numStr.charAt(i) == ZERO_CHAR; i++)
|
19992
|
+
for (i = 0; numStr.charAt(i) == ZERO_CHAR; i++) {/* jshint noempty: false */}
|
19578
19993
|
|
19579
19994
|
if (i == (zeros = numStr.length)) {
|
19580
19995
|
// The digits are all zero.
|
@@ -19620,18 +20035,37 @@ function roundNumber(parsedNumber, fractionSize, minFrac, maxFrac) {
|
|
19620
20035
|
var digit = digits[roundAt];
|
19621
20036
|
|
19622
20037
|
if (roundAt > 0) {
|
19623
|
-
digits
|
20038
|
+
// Drop fractional digits beyond `roundAt`
|
20039
|
+
digits.splice(Math.max(parsedNumber.i, roundAt));
|
20040
|
+
|
20041
|
+
// Set non-fractional digits beyond `roundAt` to 0
|
20042
|
+
for (var j = roundAt; j < digits.length; j++) {
|
20043
|
+
digits[j] = 0;
|
20044
|
+
}
|
19624
20045
|
} else {
|
19625
20046
|
// We rounded to zero so reset the parsedNumber
|
20047
|
+
fractionLen = Math.max(0, fractionLen);
|
19626
20048
|
parsedNumber.i = 1;
|
19627
|
-
digits.length = roundAt = fractionSize + 1;
|
19628
|
-
|
20049
|
+
digits.length = Math.max(1, roundAt = fractionSize + 1);
|
20050
|
+
digits[0] = 0;
|
20051
|
+
for (var i = 1; i < roundAt; i++) digits[i] = 0;
|
19629
20052
|
}
|
19630
20053
|
|
19631
|
-
if (digit >= 5)
|
20054
|
+
if (digit >= 5) {
|
20055
|
+
if (roundAt - 1 < 0) {
|
20056
|
+
for (var k = 0; k > roundAt; k--) {
|
20057
|
+
digits.unshift(0);
|
20058
|
+
parsedNumber.i++;
|
20059
|
+
}
|
20060
|
+
digits.unshift(1);
|
20061
|
+
parsedNumber.i++;
|
20062
|
+
} else {
|
20063
|
+
digits[roundAt - 1]++;
|
20064
|
+
}
|
20065
|
+
}
|
19632
20066
|
|
19633
20067
|
// Pad out with zeros to get the required fraction length
|
19634
|
-
for (; fractionLen < fractionSize; fractionLen++) digits.push(0);
|
20068
|
+
for (; fractionLen < Math.max(0, fractionSize); fractionLen++) digits.push(0);
|
19635
20069
|
|
19636
20070
|
|
19637
20071
|
// Do any carrying, e.g. a digit was rounded up to 10
|
@@ -19703,7 +20137,7 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
|
|
19703
20137
|
|
19704
20138
|
// format the integer digits with grouping separators
|
19705
20139
|
var groups = [];
|
19706
|
-
if (digits.length
|
20140
|
+
if (digits.length >= pattern.lgSize) {
|
19707
20141
|
groups.unshift(digits.splice(-pattern.lgSize).join(''));
|
19708
20142
|
}
|
19709
20143
|
while (digits.length > pattern.gSize) {
|
@@ -19730,11 +20164,15 @@ function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
|
|
19730
20164
|
}
|
19731
20165
|
}
|
19732
20166
|
|
19733
|
-
function padNumber(num, digits, trim) {
|
20167
|
+
function padNumber(num, digits, trim, negWrap) {
|
19734
20168
|
var neg = '';
|
19735
|
-
if (num < 0) {
|
19736
|
-
|
19737
|
-
|
20169
|
+
if (num < 0 || (negWrap && num <= 0)) {
|
20170
|
+
if (negWrap) {
|
20171
|
+
num = -num + 1;
|
20172
|
+
} else {
|
20173
|
+
num = -num;
|
20174
|
+
neg = '-';
|
20175
|
+
}
|
19738
20176
|
}
|
19739
20177
|
num = '' + num;
|
19740
20178
|
while (num.length < digits) num = ZERO_CHAR + num;
|
@@ -19745,7 +20183,7 @@ function padNumber(num, digits, trim) {
|
|
19745
20183
|
}
|
19746
20184
|
|
19747
20185
|
|
19748
|
-
function dateGetter(name, size, offset, trim) {
|
20186
|
+
function dateGetter(name, size, offset, trim, negWrap) {
|
19749
20187
|
offset = offset || 0;
|
19750
20188
|
return function(date) {
|
19751
20189
|
var value = date['get' + name]();
|
@@ -19753,14 +20191,15 @@ function dateGetter(name, size, offset, trim) {
|
|
19753
20191
|
value += offset;
|
19754
20192
|
}
|
19755
20193
|
if (value === 0 && offset == -12) value = 12;
|
19756
|
-
return padNumber(value, size, trim);
|
20194
|
+
return padNumber(value, size, trim, negWrap);
|
19757
20195
|
};
|
19758
20196
|
}
|
19759
20197
|
|
19760
|
-
function dateStrGetter(name, shortForm) {
|
20198
|
+
function dateStrGetter(name, shortForm, standAlone) {
|
19761
20199
|
return function(date, formats) {
|
19762
20200
|
var value = date['get' + name]();
|
19763
|
-
var
|
20201
|
+
var propPrefix = (standAlone ? 'STANDALONE' : '') + (shortForm ? 'SHORT' : '');
|
20202
|
+
var get = uppercase(propPrefix + name);
|
19764
20203
|
|
19765
20204
|
return formats[get][value];
|
19766
20205
|
};
|
@@ -19815,13 +20254,14 @@ function longEraGetter(date, formats) {
|
|
19815
20254
|
}
|
19816
20255
|
|
19817
20256
|
var DATE_FORMATS = {
|
19818
|
-
yyyy: dateGetter('FullYear', 4),
|
19819
|
-
yy: dateGetter('FullYear', 2, 0, true),
|
19820
|
-
y: dateGetter('FullYear', 1),
|
20257
|
+
yyyy: dateGetter('FullYear', 4, 0, false, true),
|
20258
|
+
yy: dateGetter('FullYear', 2, 0, true, true),
|
20259
|
+
y: dateGetter('FullYear', 1, 0, false, true),
|
19821
20260
|
MMMM: dateStrGetter('Month'),
|
19822
20261
|
MMM: dateStrGetter('Month', true),
|
19823
20262
|
MM: dateGetter('Month', 2, 1),
|
19824
20263
|
M: dateGetter('Month', 1, 1),
|
20264
|
+
LLLL: dateStrGetter('Month', false, true),
|
19825
20265
|
dd: dateGetter('Date', 2),
|
19826
20266
|
d: dateGetter('Date', 1),
|
19827
20267
|
HH: dateGetter('Hours', 2),
|
@@ -19847,7 +20287,7 @@ var DATE_FORMATS = {
|
|
19847
20287
|
GGGG: longEraGetter
|
19848
20288
|
};
|
19849
20289
|
|
19850
|
-
var DATE_FORMATS_SPLIT = /((?:[^
|
20290
|
+
var DATE_FORMATS_SPLIT = /((?:[^yMLdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|L+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,
|
19851
20291
|
NUMBER_STRING = /^\-?\d+$/;
|
19852
20292
|
|
19853
20293
|
/**
|
@@ -19867,6 +20307,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|
|
|
19867
20307
|
* * `'MMM'`: Month in year (Jan-Dec)
|
19868
20308
|
* * `'MM'`: Month in year, padded (01-12)
|
19869
20309
|
* * `'M'`: Month in year (1-12)
|
20310
|
+
* * `'LLLL'`: Stand-alone month in year (January-December)
|
19870
20311
|
* * `'dd'`: Day in month, padded (01-31)
|
19871
20312
|
* * `'d'`: Day in month (1-31)
|
19872
20313
|
* * `'EEEE'`: Day in Week,(Sunday-Saturday)
|
@@ -21548,8 +21989,8 @@ var ngFormDirective = formDirectiveFactory(true);
|
|
21548
21989
|
ngModelMinErr: false,
|
21549
21990
|
*/
|
21550
21991
|
|
21551
|
-
// Regex code
|
21552
|
-
var ISO_DATE_REGEXP =
|
21992
|
+
// Regex code was initially obtained from SO prior to modification: https://stackoverflow.com/questions/3143070/javascript-regex-iso-datetime#answer-3143231
|
21993
|
+
var ISO_DATE_REGEXP = /^\d{4,}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+(?:[+-][0-2]\d:[0-5]\d|Z)$/;
|
21553
21994
|
// See valid URLs in RFC3987 (http://tools.ietf.org/html/rfc3987)
|
21554
21995
|
// Note: We are being more lenient, because browsers are too.
|
21555
21996
|
// 1. Scheme
|
@@ -21565,12 +22006,18 @@ var ISO_DATE_REGEXP = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-
|
|
21565
22006
|
var URL_REGEXP = /^[a-z][a-z\d.+-]*:\/*(?:[^:@]+(?::[^@]+)?@)?(?:[^\s:/?#]+|\[[a-f\d:]+\])(?::\d+)?(?:\/[^?#]*)?(?:\?[^#]*)?(?:#.*)?$/i;
|
21566
22007
|
var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
|
21567
22008
|
var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/;
|
21568
|
-
var DATE_REGEXP = /^(\d{4})-(\d{2})-(\d{2})$/;
|
21569
|
-
var DATETIMELOCAL_REGEXP = /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
|
21570
|
-
var WEEK_REGEXP = /^(\d{4})-W(\d\d)$/;
|
21571
|
-
var MONTH_REGEXP = /^(\d{4})-(\d\d)$/;
|
22009
|
+
var DATE_REGEXP = /^(\d{4,})-(\d{2})-(\d{2})$/;
|
22010
|
+
var DATETIMELOCAL_REGEXP = /^(\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
|
22011
|
+
var WEEK_REGEXP = /^(\d{4,})-W(\d\d)$/;
|
22012
|
+
var MONTH_REGEXP = /^(\d{4,})-(\d\d)$/;
|
21572
22013
|
var TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
|
21573
22014
|
|
22015
|
+
var PARTIAL_VALIDATION_EVENTS = 'keydown wheel mousedown';
|
22016
|
+
var PARTIAL_VALIDATION_TYPES = createMap();
|
22017
|
+
forEach('date,datetime-local,month,time,week'.split(','), function(type) {
|
22018
|
+
PARTIAL_VALIDATION_TYPES[type] = true;
|
22019
|
+
});
|
22020
|
+
|
21574
22021
|
var inputType = {
|
21575
22022
|
|
21576
22023
|
/**
|
@@ -21926,7 +22373,7 @@ var inputType = {
|
|
21926
22373
|
}]);
|
21927
22374
|
</script>
|
21928
22375
|
<form name="myForm" ng-controller="DateController as dateCtrl">
|
21929
|
-
<label for="exampleInput">Pick a between 8am and 5pm:</label>
|
22376
|
+
<label for="exampleInput">Pick a time between 8am and 5pm:</label>
|
21930
22377
|
<input type="time" id="exampleInput" name="input" ng-model="example.value"
|
21931
22378
|
placeholder="HH:mm:ss" min="08:00:00" max="17:00:00" required />
|
21932
22379
|
<div role="alert">
|
@@ -22647,7 +23094,7 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|
22647
23094
|
if (!$sniffer.android) {
|
22648
23095
|
var composing = false;
|
22649
23096
|
|
22650
|
-
element.on('compositionstart', function(
|
23097
|
+
element.on('compositionstart', function() {
|
22651
23098
|
composing = true;
|
22652
23099
|
});
|
22653
23100
|
|
@@ -22657,6 +23104,8 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|
22657
23104
|
});
|
22658
23105
|
}
|
22659
23106
|
|
23107
|
+
var timeout;
|
23108
|
+
|
22660
23109
|
var listener = function(ev) {
|
22661
23110
|
if (timeout) {
|
22662
23111
|
$browser.defer.cancel(timeout);
|
@@ -22686,8 +23135,6 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|
22686
23135
|
if ($sniffer.hasEvent('input')) {
|
22687
23136
|
element.on('input', listener);
|
22688
23137
|
} else {
|
22689
|
-
var timeout;
|
22690
|
-
|
22691
23138
|
var deferListener = function(ev, input, origValue) {
|
22692
23139
|
if (!timeout) {
|
22693
23140
|
timeout = $browser.defer(function() {
|
@@ -22719,6 +23166,26 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|
22719
23166
|
// or form autocomplete on newer browser, we need "change" event to catch it
|
22720
23167
|
element.on('change', listener);
|
22721
23168
|
|
23169
|
+
// Some native input types (date-family) have the ability to change validity without
|
23170
|
+
// firing any input/change events.
|
23171
|
+
// For these event types, when native validators are present and the browser supports the type,
|
23172
|
+
// check for validity changes on various DOM events.
|
23173
|
+
if (PARTIAL_VALIDATION_TYPES[type] && ctrl.$$hasNativeValidators && type === attr.type) {
|
23174
|
+
element.on(PARTIAL_VALIDATION_EVENTS, function(ev) {
|
23175
|
+
if (!timeout) {
|
23176
|
+
var validity = this[VALIDITY_STATE_PROPERTY];
|
23177
|
+
var origBadInput = validity.badInput;
|
23178
|
+
var origTypeMismatch = validity.typeMismatch;
|
23179
|
+
timeout = $browser.defer(function() {
|
23180
|
+
timeout = null;
|
23181
|
+
if (validity.badInput !== origBadInput || validity.typeMismatch !== origTypeMismatch) {
|
23182
|
+
listener(ev);
|
23183
|
+
}
|
23184
|
+
});
|
23185
|
+
}
|
23186
|
+
});
|
23187
|
+
}
|
23188
|
+
|
22722
23189
|
ctrl.$render = function() {
|
22723
23190
|
// Workaround for Firefox validation #12102.
|
22724
23191
|
var value = ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue;
|
@@ -23669,7 +24136,11 @@ function classDirective(name, selector) {
|
|
23669
24136
|
updateClasses(oldClasses, newClasses);
|
23670
24137
|
}
|
23671
24138
|
}
|
23672
|
-
|
24139
|
+
if (isArray(newVal)) {
|
24140
|
+
oldVal = newVal.map(function(v) { return shallowCopy(v); });
|
24141
|
+
} else {
|
24142
|
+
oldVal = shallowCopy(newVal);
|
24143
|
+
}
|
23673
24144
|
}
|
23674
24145
|
}
|
23675
24146
|
};
|
@@ -23739,9 +24210,10 @@ function classDirective(name, selector) {
|
|
23739
24210
|
* new classes added.
|
23740
24211
|
*
|
23741
24212
|
* @animations
|
23742
|
-
*
|
23743
|
-
*
|
23744
|
-
*
|
24213
|
+
* | Animation | Occurs |
|
24214
|
+
* |----------------------------------|-------------------------------------|
|
24215
|
+
* | {@link ng.$animate#addClass addClass} | just before the class is applied to the element |
|
24216
|
+
* | {@link ng.$animate#removeClass removeClass} | just before the class is removed from the element |
|
23745
24217
|
*
|
23746
24218
|
* @element ANY
|
23747
24219
|
* @param {expression} ngClass {@link guide/expression Expression} to eval. The result
|
@@ -25000,8 +25472,10 @@ forEach(
|
|
25000
25472
|
* and `leave` effects.
|
25001
25473
|
*
|
25002
25474
|
* @animations
|
25003
|
-
*
|
25004
|
-
*
|
25475
|
+
* | Animation | Occurs |
|
25476
|
+
* |----------------------------------|-------------------------------------|
|
25477
|
+
* | {@link ng.$animate#enter enter} | just after the `ngIf` contents change and a new DOM element is created and injected into the `ngIf` container |
|
25478
|
+
* | {@link ng.$animate#leave leave} | just before the `ngIf` contents are removed from the DOM |
|
25005
25479
|
*
|
25006
25480
|
* @element ANY
|
25007
25481
|
* @scope
|
@@ -25042,7 +25516,7 @@ forEach(
|
|
25042
25516
|
</file>
|
25043
25517
|
</example>
|
25044
25518
|
*/
|
25045
|
-
var ngIfDirective = ['$animate', function($animate) {
|
25519
|
+
var ngIfDirective = ['$animate', '$compile', function($animate, $compile) {
|
25046
25520
|
return {
|
25047
25521
|
multiElement: true,
|
25048
25522
|
transclude: 'element',
|
@@ -25058,7 +25532,7 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
25058
25532
|
if (!childScope) {
|
25059
25533
|
$transclude(function(clone, newScope) {
|
25060
25534
|
childScope = newScope;
|
25061
|
-
clone[clone.length++] =
|
25535
|
+
clone[clone.length++] = $compile.$$createComment('end ngIf', $attr.ngIf);
|
25062
25536
|
// Note: We only need the first/last node of the cloned nodes.
|
25063
25537
|
// However, we need to keep the reference to the jqlite wrapper as it might be changed later
|
25064
25538
|
// by a directive with templateUrl when its template arrives.
|
@@ -25113,8 +25587,10 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
25113
25587
|
* access on some browsers.
|
25114
25588
|
*
|
25115
25589
|
* @animations
|
25116
|
-
*
|
25117
|
-
*
|
25590
|
+
* | Animation | Occurs |
|
25591
|
+
* |----------------------------------|-------------------------------------|
|
25592
|
+
* | {@link ng.$animate#enter enter} | when the expression changes, on the new include |
|
25593
|
+
* | {@link ng.$animate#leave leave} | when the expression changes, on the old include |
|
25118
25594
|
*
|
25119
25595
|
* The enter and leave animation occur concurrently.
|
25120
25596
|
*
|
@@ -25380,7 +25856,7 @@ var ngIncludeFillContentDirective = ['$compile',
|
|
25380
25856
|
// support innerHTML, so detect this here and try to generate the contents
|
25381
25857
|
// specially.
|
25382
25858
|
$element.empty();
|
25383
|
-
$compile(jqLiteBuildFragment(ctrl.template, document).childNodes)(scope,
|
25859
|
+
$compile(jqLiteBuildFragment(ctrl.template, window.document).childNodes)(scope,
|
25384
25860
|
function namespaceAdaptedClone(clone) {
|
25385
25861
|
$element.append(clone);
|
25386
25862
|
}, {futureParentElement: $element});
|
@@ -25855,9 +26331,9 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
25855
26331
|
};
|
25856
26332
|
ngModelSet = function($scope, newValue) {
|
25857
26333
|
if (isFunction(parsedNgModel($scope))) {
|
25858
|
-
invokeModelSetter($scope, {$$$p:
|
26334
|
+
invokeModelSetter($scope, {$$$p: newValue});
|
25859
26335
|
} else {
|
25860
|
-
parsedNgModelAssign($scope,
|
26336
|
+
parsedNgModelAssign($scope, newValue);
|
25861
26337
|
}
|
25862
26338
|
};
|
25863
26339
|
} else if (!parsedNgModel.assign) {
|
@@ -25882,7 +26358,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
25882
26358
|
* the `$viewValue` are different from last time.
|
25883
26359
|
*
|
25884
26360
|
* Since `ng-model` does not do a deep watch, `$render()` is only invoked if the values of
|
25885
|
-
* `$modelValue` and `$viewValue` are actually different from their previous
|
26361
|
+
* `$modelValue` and `$viewValue` are actually different from their previous values. If `$modelValue`
|
25886
26362
|
* or `$viewValue` are objects (rather than a string or number) then `$render()` will not be
|
25887
26363
|
* invoked if you only change a property on the objects.
|
25888
26364
|
*/
|
@@ -26234,7 +26710,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
26234
26710
|
setValidity(name, undefined);
|
26235
26711
|
validatorPromises.push(promise.then(function() {
|
26236
26712
|
setValidity(name, true);
|
26237
|
-
}, function(
|
26713
|
+
}, function() {
|
26238
26714
|
allValid = false;
|
26239
26715
|
setValidity(name, false);
|
26240
26716
|
}));
|
@@ -26708,7 +27184,7 @@ var ngModelDirective = ['$rootScope', function($rootScope) {
|
|
26708
27184
|
});
|
26709
27185
|
}
|
26710
27186
|
|
26711
|
-
element.on('blur', function(
|
27187
|
+
element.on('blur', function() {
|
26712
27188
|
if (modelCtrl.$touched) return;
|
26713
27189
|
|
26714
27190
|
if ($rootScope.$$phase) {
|
@@ -27294,7 +27770,7 @@ var NG_OPTIONS_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s
|
|
27294
27770
|
// jshint maxlen: 100
|
27295
27771
|
|
27296
27772
|
|
27297
|
-
var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
|
27773
|
+
var ngOptionsDirective = ['$compile', '$document', '$parse', function($compile, $document, $parse) {
|
27298
27774
|
|
27299
27775
|
function parseOptionsExpression(optionsExp, selectElement, scope) {
|
27300
27776
|
|
@@ -27391,8 +27867,8 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
27391
27867
|
var key = (optionValues === optionValuesKeys) ? index : optionValuesKeys[index];
|
27392
27868
|
var value = optionValues[key];
|
27393
27869
|
|
27394
|
-
var locals = getLocals(
|
27395
|
-
var selectValue = getTrackByValueFn(
|
27870
|
+
var locals = getLocals(value, key);
|
27871
|
+
var selectValue = getTrackByValueFn(value, locals);
|
27396
27872
|
watchedArray.push(selectValue);
|
27397
27873
|
|
27398
27874
|
// Only need to watch the displayFn if there is a specific label expression
|
@@ -27455,8 +27931,8 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
27455
27931
|
|
27456
27932
|
// we can't just jqLite('<option>') since jqLite is not smart enough
|
27457
27933
|
// to create it in <select> and IE barfs otherwise.
|
27458
|
-
var optionTemplate = document.createElement('option'),
|
27459
|
-
optGroupTemplate = document.createElement('optgroup');
|
27934
|
+
var optionTemplate = window.document.createElement('option'),
|
27935
|
+
optGroupTemplate = window.document.createElement('optgroup');
|
27460
27936
|
|
27461
27937
|
function ngOptionsPostLink(scope, selectElement, attr, ctrls) {
|
27462
27938
|
|
@@ -27481,7 +27957,10 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
27481
27957
|
|
27482
27958
|
var options;
|
27483
27959
|
var ngOptions = parseOptionsExpression(attr.ngOptions, selectElement, scope);
|
27484
|
-
|
27960
|
+
// This stores the newly created options before they are appended to the select.
|
27961
|
+
// Since the contents are removed from the fragment when it is appended,
|
27962
|
+
// we only need to create it once.
|
27963
|
+
var listFragment = $document[0].createDocumentFragment();
|
27485
27964
|
|
27486
27965
|
var renderEmptyOption = function() {
|
27487
27966
|
if (!providedEmptyOption) {
|
@@ -27516,15 +27995,21 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
27516
27995
|
selectCtrl.writeValue = function writeNgOptionsValue(value) {
|
27517
27996
|
var option = options.getOptionFromViewValue(value);
|
27518
27997
|
|
27519
|
-
if (option
|
27998
|
+
if (option) {
|
27999
|
+
// Don't update the option when it is already selected.
|
28000
|
+
// For example, the browser will select the first option by default. In that case,
|
28001
|
+
// most properties are set automatically - except the `selected` attribute, which we
|
28002
|
+
// set always
|
28003
|
+
|
27520
28004
|
if (selectElement[0].value !== option.selectValue) {
|
27521
28005
|
removeUnknownOption();
|
27522
28006
|
removeEmptyOption();
|
27523
28007
|
|
27524
28008
|
selectElement[0].value = option.selectValue;
|
27525
28009
|
option.element.selected = true;
|
27526
|
-
option.element.setAttribute('selected', 'selected');
|
27527
28010
|
}
|
28011
|
+
|
28012
|
+
option.element.setAttribute('selected', 'selected');
|
27528
28013
|
} else {
|
27529
28014
|
if (value === null || providedEmptyOption) {
|
27530
28015
|
removeUnknownOption();
|
@@ -27572,7 +28057,7 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
27572
28057
|
if (value) {
|
27573
28058
|
value.forEach(function(item) {
|
27574
28059
|
var option = options.getOptionFromViewValue(item);
|
27575
|
-
if (option
|
28060
|
+
if (option) option.element.selected = true;
|
27576
28061
|
});
|
27577
28062
|
}
|
27578
28063
|
};
|
@@ -27624,6 +28109,8 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
27624
28109
|
emptyOption = jqLite(optionTemplate.cloneNode(false));
|
27625
28110
|
}
|
27626
28111
|
|
28112
|
+
selectElement.empty();
|
28113
|
+
|
27627
28114
|
// We need to do this here to ensure that the options object is defined
|
27628
28115
|
// when we first hit it in writeNgOptionsValue
|
27629
28116
|
updateOptions();
|
@@ -27633,6 +28120,12 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
27633
28120
|
|
27634
28121
|
// ------------------------------------------------------------------ //
|
27635
28122
|
|
28123
|
+
function addOptionElement(option, parent) {
|
28124
|
+
var optionElement = optionTemplate.cloneNode(false);
|
28125
|
+
parent.appendChild(optionElement);
|
28126
|
+
updateOptionElement(option, optionElement);
|
28127
|
+
}
|
28128
|
+
|
27636
28129
|
|
27637
28130
|
function updateOptionElement(option, element) {
|
27638
28131
|
option.element = element;
|
@@ -27649,133 +28142,66 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
27649
28142
|
if (option.value !== element.value) element.value = option.selectValue;
|
27650
28143
|
}
|
27651
28144
|
|
27652
|
-
function
|
27653
|
-
var
|
27654
|
-
// Check whether we can reuse the next element
|
27655
|
-
if (current && lowercase(current.nodeName) === type) {
|
27656
|
-
// The next element is the right type so reuse it
|
27657
|
-
element = current;
|
27658
|
-
} else {
|
27659
|
-
// The next element is not the right type so create a new one
|
27660
|
-
element = templateElement.cloneNode(false);
|
27661
|
-
if (!current) {
|
27662
|
-
// There are no more elements so just append it to the select
|
27663
|
-
parent.appendChild(element);
|
27664
|
-
} else {
|
27665
|
-
// The next element is not a group so insert the new one
|
27666
|
-
parent.insertBefore(element, current);
|
27667
|
-
}
|
27668
|
-
}
|
27669
|
-
return element;
|
27670
|
-
}
|
27671
|
-
|
27672
|
-
|
27673
|
-
function removeExcessElements(current) {
|
27674
|
-
var next;
|
27675
|
-
while (current) {
|
27676
|
-
next = current.nextSibling;
|
27677
|
-
jqLiteRemove(current);
|
27678
|
-
current = next;
|
27679
|
-
}
|
27680
|
-
}
|
27681
|
-
|
27682
|
-
|
27683
|
-
function skipEmptyAndUnknownOptions(current) {
|
27684
|
-
var emptyOption_ = emptyOption && emptyOption[0];
|
27685
|
-
var unknownOption_ = unknownOption && unknownOption[0];
|
28145
|
+
function updateOptions() {
|
28146
|
+
var previousValue = options && selectCtrl.readValue();
|
27686
28147
|
|
27687
|
-
// We
|
27688
|
-
//
|
27689
|
-
//
|
27690
|
-
|
27691
|
-
|
27692
|
-
|
27693
|
-
|
27694
|
-
|
27695
|
-
|
27696
|
-
|
28148
|
+
// We must remove all current options, but cannot simply set innerHTML = null
|
28149
|
+
// since the providedEmptyOption might have an ngIf on it that inserts comments which we
|
28150
|
+
// must preserve.
|
28151
|
+
// Instead, iterate over the current option elements and remove them or their optgroup
|
28152
|
+
// parents
|
28153
|
+
if (options) {
|
28154
|
+
|
28155
|
+
for (var i = options.items.length - 1; i >= 0; i--) {
|
28156
|
+
var option = options.items[i];
|
28157
|
+
if (option.group) {
|
28158
|
+
jqLiteRemove(option.element.parentNode);
|
28159
|
+
} else {
|
28160
|
+
jqLiteRemove(option.element);
|
28161
|
+
}
|
27697
28162
|
}
|
27698
28163
|
}
|
27699
|
-
return current;
|
27700
|
-
}
|
27701
|
-
|
27702
|
-
|
27703
|
-
function updateOptions() {
|
27704
|
-
|
27705
|
-
var previousValue = options && selectCtrl.readValue();
|
27706
28164
|
|
27707
28165
|
options = ngOptions.getOptions();
|
27708
28166
|
|
27709
|
-
var
|
27710
|
-
var currentElement = selectElement[0].firstChild;
|
28167
|
+
var groupElementMap = {};
|
27711
28168
|
|
27712
28169
|
// Ensure that the empty option is always there if it was explicitly provided
|
27713
28170
|
if (providedEmptyOption) {
|
27714
28171
|
selectElement.prepend(emptyOption);
|
27715
28172
|
}
|
27716
28173
|
|
27717
|
-
|
27718
|
-
|
27719
|
-
options.items.forEach(function updateOption(option) {
|
27720
|
-
var group;
|
28174
|
+
options.items.forEach(function addOption(option) {
|
27721
28175
|
var groupElement;
|
27722
|
-
var optionElement;
|
27723
28176
|
|
27724
28177
|
if (isDefined(option.group)) {
|
27725
28178
|
|
27726
28179
|
// This option is to live in a group
|
27727
28180
|
// See if we have already created this group
|
27728
|
-
|
28181
|
+
groupElement = groupElementMap[option.group];
|
27729
28182
|
|
27730
|
-
if (!
|
28183
|
+
if (!groupElement) {
|
27731
28184
|
|
27732
|
-
|
27733
|
-
groupElement
|
27734
|
-
currentElement,
|
27735
|
-
'optgroup',
|
27736
|
-
optGroupTemplate);
|
27737
|
-
// Move to the next element
|
27738
|
-
currentElement = groupElement.nextSibling;
|
28185
|
+
groupElement = optGroupTemplate.cloneNode(false);
|
28186
|
+
listFragment.appendChild(groupElement);
|
27739
28187
|
|
27740
28188
|
// Update the label on the group element
|
27741
28189
|
groupElement.label = option.group;
|
27742
28190
|
|
27743
28191
|
// Store it for use later
|
27744
|
-
|
27745
|
-
groupElement: groupElement,
|
27746
|
-
currentOptionElement: groupElement.firstChild
|
27747
|
-
};
|
27748
|
-
|
28192
|
+
groupElementMap[option.group] = groupElement;
|
27749
28193
|
}
|
27750
28194
|
|
27751
|
-
|
27752
|
-
optionElement = addOrReuseElement(group.groupElement,
|
27753
|
-
group.currentOptionElement,
|
27754
|
-
'option',
|
27755
|
-
optionTemplate);
|
27756
|
-
updateOptionElement(option, optionElement);
|
27757
|
-
// Move to the next element
|
27758
|
-
group.currentOptionElement = optionElement.nextSibling;
|
28195
|
+
addOptionElement(option, groupElement);
|
27759
28196
|
|
27760
28197
|
} else {
|
27761
28198
|
|
27762
28199
|
// This option is not in a group
|
27763
|
-
|
27764
|
-
currentElement,
|
27765
|
-
'option',
|
27766
|
-
optionTemplate);
|
27767
|
-
updateOptionElement(option, optionElement);
|
27768
|
-
// Move to the next element
|
27769
|
-
currentElement = optionElement.nextSibling;
|
28200
|
+
addOptionElement(option, listFragment);
|
27770
28201
|
}
|
27771
28202
|
});
|
27772
28203
|
|
27773
|
-
|
27774
|
-
// Now remove all excess options and group
|
27775
|
-
Object.keys(groupMap).forEach(function(key) {
|
27776
|
-
removeExcessElements(groupMap[key].currentOptionElement);
|
27777
|
-
});
|
27778
|
-
removeExcessElements(currentElement);
|
28204
|
+
selectElement[0].appendChild(listFragment);
|
27779
28205
|
|
27780
28206
|
ngModelCtrl.$render();
|
27781
28207
|
|
@@ -28083,17 +28509,23 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
|
|
28083
28509
|
* <div ng-repeat="(key, value) in myObj"> ... </div>
|
28084
28510
|
* ```
|
28085
28511
|
*
|
28086
|
-
*
|
28087
|
-
*
|
28088
|
-
*
|
28512
|
+
* However, there are a limitations compared to array iteration:
|
28513
|
+
*
|
28514
|
+
* - The JavaScript specification does not define the order of keys
|
28515
|
+
* returned for an object, so Angular relies on the order returned by the browser
|
28516
|
+
* when running `for key in myObj`. Browsers generally follow the strategy of providing
|
28517
|
+
* keys in the order in which they were defined, although there are exceptions when keys are deleted
|
28518
|
+
* and reinstated. See the
|
28519
|
+
* [MDN page on `delete` for more info](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete#Cross-browser_notes).
|
28520
|
+
*
|
28521
|
+
* - `ngRepeat` will silently *ignore* object keys starting with `$`, because
|
28522
|
+
* it's a prefix used by Angular for public (`$`) and private (`$$`) properties.
|
28089
28523
|
*
|
28090
|
-
*
|
28091
|
-
*
|
28092
|
-
* keys in the order in which they were defined, although there are exceptions when keys are deleted
|
28093
|
-
* and reinstated. See the [MDN page on `delete` for more info](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete#Cross-browser_notes).
|
28524
|
+
* - The built-in filters {@link ng.orderBy orderBy} and {@link ng.filter filter} do not work with
|
28525
|
+
* objects, and will throw if used with one.
|
28094
28526
|
*
|
28095
|
-
* If
|
28096
|
-
* that is sorted into the order that you prefer before providing it to `ngRepeat`.
|
28527
|
+
* If you are hitting any of these limitations, the recommended workaround is to convert your object into an array
|
28528
|
+
* that is sorted into the order that you prefer before providing it to `ngRepeat`. You could
|
28097
28529
|
* do this with a filter such as [toArrayFilter](http://ngmodules.org/modules/angular-toArrayFilter)
|
28098
28530
|
* or implement a `$watch` on the object yourself.
|
28099
28531
|
*
|
@@ -28211,11 +28643,11 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
|
|
28211
28643
|
* as **data-ng-repeat-start**, **x-ng-repeat-start** and **ng:repeat-start**).
|
28212
28644
|
*
|
28213
28645
|
* @animations
|
28214
|
-
*
|
28215
|
-
*
|
28216
|
-
*
|
28217
|
-
*
|
28218
|
-
*
|
28646
|
+
* | Animation | Occurs |
|
28647
|
+
* |----------------------------------|-------------------------------------|
|
28648
|
+
* | {@link ng.$animate#enter enter} | when a new item is added to the list or when an item is revealed after a filter |
|
28649
|
+
* | {@link ng.$animate#leave leave} | when an item is removed from the list or when an item is filtered out |
|
28650
|
+
* | {@link ng.$animate#move move } | when an adjacent item is filtered out causing a reorder or when the item contents are reordered |
|
28219
28651
|
*
|
28220
28652
|
* See the example below for defining CSS animations with ngRepeat.
|
28221
28653
|
*
|
@@ -28363,7 +28795,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', '$log', function($locale,
|
|
28363
28795
|
</file>
|
28364
28796
|
</example>
|
28365
28797
|
*/
|
28366
|
-
var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
28798
|
+
var ngRepeatDirective = ['$parse', '$animate', '$compile', function($parse, $animate, $compile) {
|
28367
28799
|
var NG_REMOVED = '$$NG_REMOVED';
|
28368
28800
|
var ngRepeatMinErr = minErr('ngRepeat');
|
28369
28801
|
|
@@ -28398,7 +28830,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
28398
28830
|
$$tlb: true,
|
28399
28831
|
compile: function ngRepeatCompile($element, $attr) {
|
28400
28832
|
var expression = $attr.ngRepeat;
|
28401
|
-
var ngRepeatEndComment =
|
28833
|
+
var ngRepeatEndComment = $compile.$$createComment('end ngRepeat', expression);
|
28402
28834
|
|
28403
28835
|
var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
|
28404
28836
|
|
@@ -28562,7 +28994,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
28562
28994
|
|
28563
28995
|
if (getBlockStart(block) != nextNode) {
|
28564
28996
|
// existing item which got moved
|
28565
|
-
$animate.move(getBlockNodes(block.clone), null,
|
28997
|
+
$animate.move(getBlockNodes(block.clone), null, previousNode);
|
28566
28998
|
}
|
28567
28999
|
previousNode = getBlockEnd(block);
|
28568
29000
|
updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength);
|
@@ -28574,8 +29006,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
28574
29006
|
var endNode = ngRepeatEndComment.cloneNode(false);
|
28575
29007
|
clone[clone.length++] = endNode;
|
28576
29008
|
|
28577
|
-
|
28578
|
-
$animate.enter(clone, null, jqLite(previousNode));
|
29009
|
+
$animate.enter(clone, null, previousNode);
|
28579
29010
|
previousNode = endNode;
|
28580
29011
|
// Note: We only need the first/last node of the cloned nodes.
|
28581
29012
|
// However, we need to keep the reference to the jqlite wrapper as it might be changed later
|
@@ -28678,12 +29109,14 @@ var NG_HIDE_IN_PROGRESS_CLASS = 'ng-hide-animate';
|
|
28678
29109
|
* .my-element.ng-hide-remove.ng-hide-remove-active { ... }
|
28679
29110
|
* ```
|
28680
29111
|
*
|
28681
|
-
* Keep in mind that, as of AngularJS version 1.3
|
29112
|
+
* Keep in mind that, as of AngularJS version 1.3, there is no need to change the display
|
28682
29113
|
* property to block during animation states--ngAnimate will handle the style toggling automatically for you.
|
28683
29114
|
*
|
28684
29115
|
* @animations
|
28685
|
-
*
|
28686
|
-
*
|
29116
|
+
* | Animation | Occurs |
|
29117
|
+
* |----------------------------------|-------------------------------------|
|
29118
|
+
* | {@link $animate#addClass addClass} `.ng-hide` | after the `ngShow` expression evaluates to a non truthy value and just before the contents are set to hidden |
|
29119
|
+
* | {@link $animate#removeClass removeClass} `.ng-hide` | after the `ngShow` expression evaluates to a truthy value and just before contents are set to visible |
|
28687
29120
|
*
|
28688
29121
|
* @element ANY
|
28689
29122
|
* @param {expression} ngShow If the {@link guide/expression expression} is truthy
|
@@ -28842,12 +29275,15 @@ var ngShowDirective = ['$animate', function($animate) {
|
|
28842
29275
|
* .my-element.ng-hide-remove.ng-hide-remove-active { ... }
|
28843
29276
|
* ```
|
28844
29277
|
*
|
28845
|
-
* Keep in mind that, as of AngularJS version 1.3
|
29278
|
+
* Keep in mind that, as of AngularJS version 1.3, there is no need to change the display
|
28846
29279
|
* property to block during animation states--ngAnimate will handle the style toggling automatically for you.
|
28847
29280
|
*
|
28848
29281
|
* @animations
|
28849
|
-
*
|
28850
|
-
*
|
29282
|
+
* | Animation | Occurs |
|
29283
|
+
* |----------------------------------|-------------------------------------|
|
29284
|
+
* | {@link $animate#addClass addClass} `.ng-hide` | after the `ngHide` expression evaluates to a truthy value and just before the contents are set to hidden |
|
29285
|
+
* | {@link $animate#removeClass removeClass} `.ng-hide` | after the `ngHide` expression evaluates to a non truthy value and just before contents are set to visible |
|
29286
|
+
*
|
28851
29287
|
*
|
28852
29288
|
* @element ANY
|
28853
29289
|
* @param {expression} ngHide If the {@link guide/expression expression} is truthy then
|
@@ -29009,8 +29445,10 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
|
|
29009
29445
|
* </div>
|
29010
29446
|
|
29011
29447
|
* @animations
|
29012
|
-
*
|
29013
|
-
*
|
29448
|
+
* | Animation | Occurs |
|
29449
|
+
* |----------------------------------|-------------------------------------|
|
29450
|
+
* | {@link ng.$animate#enter enter} | after the ngSwitch contents change and the matched child element is placed inside the container |
|
29451
|
+
* | {@link ng.$animate#leave leave} | after the ngSwitch contents change and just before the former contents are removed from the DOM |
|
29014
29452
|
*
|
29015
29453
|
* @usage
|
29016
29454
|
*
|
@@ -29109,7 +29547,7 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
|
|
29109
29547
|
</file>
|
29110
29548
|
</example>
|
29111
29549
|
*/
|
29112
|
-
var ngSwitchDirective = ['$animate', function($animate) {
|
29550
|
+
var ngSwitchDirective = ['$animate', '$compile', function($animate, $compile) {
|
29113
29551
|
return {
|
29114
29552
|
require: 'ngSwitch',
|
29115
29553
|
|
@@ -29150,7 +29588,7 @@ var ngSwitchDirective = ['$animate', function($animate) {
|
|
29150
29588
|
selectedTransclude.transclude(function(caseElement, selectedScope) {
|
29151
29589
|
selectedScopes.push(selectedScope);
|
29152
29590
|
var anchor = selectedTransclude.element;
|
29153
|
-
caseElement[caseElement.length++] =
|
29591
|
+
caseElement[caseElement.length++] = $compile.$$createComment('end ngSwitchWhen');
|
29154
29592
|
var block = { clone: caseElement };
|
29155
29593
|
|
29156
29594
|
selectedElements.push(block);
|
@@ -29444,7 +29882,7 @@ function chromeHack(optionElement) {
|
|
29444
29882
|
* added `<option>` elements, perhaps by an `ngRepeat` directive.
|
29445
29883
|
*/
|
29446
29884
|
var SelectController =
|
29447
|
-
['$element', '$scope',
|
29885
|
+
['$element', '$scope', function($element, $scope) {
|
29448
29886
|
|
29449
29887
|
var self = this,
|
29450
29888
|
optionsMap = new HashMap();
|
@@ -29458,7 +29896,7 @@ var SelectController =
|
|
29458
29896
|
//
|
29459
29897
|
// We can't just jqLite('<option>') since jqLite is not smart enough
|
29460
29898
|
// to create it in <select> and IE barfs otherwise.
|
29461
|
-
self.unknownOption = jqLite(document.createElement('option'));
|
29899
|
+
self.unknownOption = jqLite(window.document.createElement('option'));
|
29462
29900
|
self.renderUnknownOption = function(val) {
|
29463
29901
|
var unknownVal = '? ' + hashKey(val) + ' ?';
|
29464
29902
|
self.unknownOption.val(unknownVal);
|
@@ -30266,7 +30704,9 @@ var minlengthDirective = function() {
|
|
30266
30704
|
|
30267
30705
|
if (window.angular.bootstrap) {
|
30268
30706
|
//AngularJS is already loaded, so we can return here...
|
30269
|
-
|
30707
|
+
if (window.console) {
|
30708
|
+
console.log('WARNING: Tried to load angular more than once.');
|
30709
|
+
}
|
30270
30710
|
return;
|
30271
30711
|
}
|
30272
30712
|
|
@@ -30419,10 +30859,10 @@ $provide.value("$locale", {
|
|
30419
30859
|
});
|
30420
30860
|
}]);
|
30421
30861
|
|
30422
|
-
jqLite(document).ready(function() {
|
30423
|
-
angularInit(document, bootstrap);
|
30862
|
+
jqLite(window.document).ready(function() {
|
30863
|
+
angularInit(window.document, bootstrap);
|
30424
30864
|
});
|
30425
30865
|
|
30426
|
-
})(window
|
30866
|
+
})(window);
|
30427
30867
|
|
30428
30868
|
!window.angular.$$csp().noInlineStyle && window.angular.element(document.head).prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\\:form{display:block;}.ng-animate-shim{visibility:hidden;}.ng-anchor{position:absolute;}</style>');
|