angularjs-rails 1.5.0 → 1.5.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/angularjs-rails/version.rb +2 -2
- data/vendor/assets/javascripts/angular-animate.js +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>');
|