angular-rails-engine 1.2.0.2 → 1.2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/app/assets/javascripts/angular/angular-animate.js +105 -37
- data/app/assets/javascripts/angular/angular-animate.min.js +18 -17
- data/app/assets/javascripts/angular/angular-cookies.js +2 -2
- data/app/assets/javascripts/angular/angular-cookies.min.js +2 -2
- data/app/assets/javascripts/angular/angular-loader.js +93 -6
- data/app/assets/javascripts/angular/angular-loader.min.js +5 -4
- data/app/assets/javascripts/angular/angular-mocks.js +187 -202
- data/app/assets/javascripts/angular/angular-resource.js +31 -63
- data/app/assets/javascripts/angular/angular-resource.min.js +8 -8
- data/app/assets/javascripts/angular/angular-route.js +42 -31
- data/app/assets/javascripts/angular/angular-route.min.js +10 -10
- data/app/assets/javascripts/angular/angular-sanitize.js +66 -28
- data/app/assets/javascripts/angular/angular-sanitize.min.js +10 -10
- data/app/assets/javascripts/angular/angular-scenario.js +599 -348
- data/app/assets/javascripts/angular/angular-touch.js +2 -2
- data/app/assets/javascripts/angular/angular-touch.min.js +2 -2
- data/app/assets/javascripts/angular/angular.js +603 -352
- data/app/assets/javascripts/angular/angular.min.js +197 -196
- data/app/assets/stylesheets/angular-csp.css +4 -4
- data/lib/angular-rails-engine.rb +1 -1
- data/lib/angular-rails-engine/version.rb +1 -1
- metadata +2 -2
- metadata.gz.sig +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
|
-
AngularJS v1.2.
|
3
|
-
(c) 2010-
|
2
|
+
AngularJS v1.2.3
|
3
|
+
(c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
License: MIT
|
5
5
|
*/
|
6
6
|
(function(y,v,z){'use strict';function t(g,a,b){q.directive(g,["$parse","$swipe",function(l,n){var r=75,h=0.3,d=30;return function(p,m,k){function e(e){if(!u)return!1;var c=Math.abs(e.y-u.y);e=(e.x-u.x)*a;return f&&c<r&&0<e&&e>d&&c/e<h}var c=l(k[g]),u,f;n.bind(m,{start:function(e,c){u=e;f=!0},cancel:function(e){f=!1},end:function(a,f){e(a)&&p.$apply(function(){m.triggerHandler(b);c(p,{$event:f})})}})}}])}var q=v.module("ngTouch",[]);q.factory("$swipe",[function(){function g(a){var b=a.touches&&a.touches.length?
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.2.
|
3
|
-
* (c) 2010-
|
2
|
+
* @license AngularJS v1.2.3
|
3
|
+
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
6
6
|
(function(window, document, undefined) {'use strict';
|
@@ -40,11 +40,11 @@ function minErr(module) {
|
|
40
40
|
template = arguments[1],
|
41
41
|
templateArgs = arguments,
|
42
42
|
stringify = function (obj) {
|
43
|
-
if (
|
43
|
+
if (typeof obj === 'function') {
|
44
44
|
return obj.toString().replace(/ \{[\s\S]*$/, '');
|
45
|
-
} else if (
|
45
|
+
} else if (typeof obj === 'undefined') {
|
46
46
|
return 'undefined';
|
47
|
-
} else if (
|
47
|
+
} else if (typeof obj !== 'string') {
|
48
48
|
return JSON.stringify(obj);
|
49
49
|
}
|
50
50
|
return obj;
|
@@ -56,11 +56,11 @@ function minErr(module) {
|
|
56
56
|
|
57
57
|
if (index + 2 < templateArgs.length) {
|
58
58
|
arg = templateArgs[index + 2];
|
59
|
-
if (
|
59
|
+
if (typeof arg === 'function') {
|
60
60
|
return arg.toString().replace(/ ?\{[\s\S]*$/, '');
|
61
|
-
} else if (
|
61
|
+
} else if (typeof arg === 'undefined') {
|
62
62
|
return 'undefined';
|
63
|
-
} else if (
|
63
|
+
} else if (typeof arg !== 'string') {
|
64
64
|
return toJson(arg);
|
65
65
|
}
|
66
66
|
return arg;
|
@@ -68,7 +68,7 @@ function minErr(module) {
|
|
68
68
|
return match;
|
69
69
|
});
|
70
70
|
|
71
|
-
message = message + '\nhttp://errors.angularjs.org/
|
71
|
+
message = message + '\nhttp://errors.angularjs.org/1.2.3/' +
|
72
72
|
(module ? module + '/' : '') + code;
|
73
73
|
for (i = 2; i < arguments.length; i++) {
|
74
74
|
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
|
@@ -159,7 +159,7 @@ function minErr(module) {
|
|
159
159
|
-assertArgFn,
|
160
160
|
-assertNotHasOwnProperty,
|
161
161
|
-getter,
|
162
|
-
-getBlockElements
|
162
|
+
-getBlockElements,
|
163
163
|
|
164
164
|
*/
|
165
165
|
|
@@ -623,7 +623,7 @@ var trim = (function() {
|
|
623
623
|
// TODO: we should move this into IE/ES5 polyfill
|
624
624
|
if (!String.prototype.trim) {
|
625
625
|
return function(value) {
|
626
|
-
return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
|
626
|
+
return isString(value) ? value.replace(/^\s\s*/, '').replace(/\s\s*$/, '') : value;
|
627
627
|
};
|
628
628
|
}
|
629
629
|
return function(value) {
|
@@ -1181,26 +1181,38 @@ function encodeUriQuery(val, pctEncodeSpaces) {
|
|
1181
1181
|
*
|
1182
1182
|
* @description
|
1183
1183
|
*
|
1184
|
-
* Use this directive to auto-bootstrap an application.
|
1185
|
-
*
|
1186
|
-
*
|
1187
|
-
*
|
1188
|
-
*
|
1189
|
-
*
|
1190
|
-
* an HTML document you must manually bootstrap them using
|
1191
|
-
*
|
1192
|
-
*
|
1193
|
-
*
|
1194
|
-
*
|
1195
|
-
*
|
1196
|
-
*
|
1197
|
-
*
|
1198
|
-
*
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1184
|
+
* Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive
|
1185
|
+
* designates the **root element** of the application and is typically placed near the root element
|
1186
|
+
* of the page - e.g. on the `<body>` or `<html>` tags.
|
1187
|
+
*
|
1188
|
+
* Only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp`
|
1189
|
+
* found in the document will be used to define the root element to auto-bootstrap as an
|
1190
|
+
* application. To run multiple applications in an HTML document you must manually bootstrap them using
|
1191
|
+
* {@link angular.bootstrap} instead. AngularJS applications cannot be nested within each other.
|
1192
|
+
*
|
1193
|
+
* You can specify an **AngularJS module** to be used as the root module for the application. This
|
1194
|
+
* module will be loaded into the {@link AUTO.$injector} when the application is bootstrapped and
|
1195
|
+
* should contain the application code needed or have dependencies on other modules that will
|
1196
|
+
* contain the code. See {@link angular.module} for more information.
|
1197
|
+
*
|
1198
|
+
* In the example below if the `ngApp` directive were not placed on the `html` element then the
|
1199
|
+
* document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}`
|
1200
|
+
* would not be resolved to `3`.
|
1201
|
+
*
|
1202
|
+
* `ngApp` is the easiest, and most common, way to bootstrap an application.
|
1203
|
+
*
|
1204
|
+
<example module="ngAppDemo">
|
1205
|
+
<file name="index.html">
|
1206
|
+
<div ng-controller="ngAppDemoController">
|
1207
|
+
I can add: {{a}} + {{b}} = {{ a+b }}
|
1208
|
+
</file>
|
1209
|
+
<file name="script.js">
|
1210
|
+
angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) {
|
1211
|
+
$scope.a = 1;
|
1212
|
+
$scope.b = 2;
|
1213
|
+
});
|
1214
|
+
</file>
|
1215
|
+
</example>
|
1204
1216
|
*
|
1205
1217
|
*/
|
1206
1218
|
function angularInit(element, bootstrap) {
|
@@ -1429,12 +1441,18 @@ function getBlockElements(block) {
|
|
1429
1441
|
function setupModuleLoader(window) {
|
1430
1442
|
|
1431
1443
|
var $injectorMinErr = minErr('$injector');
|
1444
|
+
var ngMinErr = minErr('ng');
|
1432
1445
|
|
1433
1446
|
function ensure(obj, name, factory) {
|
1434
1447
|
return obj[name] || (obj[name] = factory());
|
1435
1448
|
}
|
1436
1449
|
|
1437
|
-
|
1450
|
+
var angular = ensure(window, 'angular', Object);
|
1451
|
+
|
1452
|
+
// We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
|
1453
|
+
angular.$$minErr = angular.$$minErr || minErr;
|
1454
|
+
|
1455
|
+
return ensure(angular, 'module', function() {
|
1438
1456
|
/** @type {Object.<string, angular.Module>} */
|
1439
1457
|
var modules = {};
|
1440
1458
|
|
@@ -1489,6 +1507,12 @@ function setupModuleLoader(window) {
|
|
1489
1507
|
* @returns {module} new module with the {@link angular.Module} api.
|
1490
1508
|
*/
|
1491
1509
|
return function module(name, requires, configFn) {
|
1510
|
+
var assertNotHasOwnProperty = function(name, context) {
|
1511
|
+
if (name === 'hasOwnProperty') {
|
1512
|
+
throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
|
1513
|
+
}
|
1514
|
+
};
|
1515
|
+
|
1492
1516
|
assertNotHasOwnProperty(name, 'module');
|
1493
1517
|
if (requires && modules.hasOwnProperty(name)) {
|
1494
1518
|
modules[name] = null;
|
@@ -1778,6 +1802,7 @@ function setupModuleLoader(window) {
|
|
1778
1802
|
$ParseProvider,
|
1779
1803
|
$RootScopeProvider,
|
1780
1804
|
$QProvider,
|
1805
|
+
$$SanitizeUriProvider,
|
1781
1806
|
$SceProvider,
|
1782
1807
|
$SceDelegateProvider,
|
1783
1808
|
$SnifferProvider,
|
@@ -1801,11 +1826,11 @@ function setupModuleLoader(window) {
|
|
1801
1826
|
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
|
1802
1827
|
*/
|
1803
1828
|
var version = {
|
1804
|
-
full: '1.2.
|
1829
|
+
full: '1.2.3', // all of these placeholder strings will be replaced by grunt's
|
1805
1830
|
major: 1, // package task
|
1806
|
-
minor:
|
1807
|
-
dot:
|
1808
|
-
codeName: '
|
1831
|
+
minor: 2,
|
1832
|
+
dot: 3,
|
1833
|
+
codeName: 'unicorn-zapper'
|
1809
1834
|
};
|
1810
1835
|
|
1811
1836
|
|
@@ -1849,6 +1874,10 @@ function publishExternalAPI(angular){
|
|
1849
1874
|
|
1850
1875
|
angularModule('ng', ['ngLocale'], ['$provide',
|
1851
1876
|
function ngModule($provide) {
|
1877
|
+
// $$sanitizeUriProvider needs to be before $compileProvider as it is used by it.
|
1878
|
+
$provide.provider({
|
1879
|
+
$$sanitizeUri: $$SanitizeUriProvider
|
1880
|
+
});
|
1852
1881
|
$provide.provider('$compile', $CompileProvider).
|
1853
1882
|
directive({
|
1854
1883
|
a: htmlAnchorDirective,
|
@@ -3352,11 +3381,11 @@ function annotate(fn) {
|
|
3352
3381
|
* @example
|
3353
3382
|
* Here are some examples of creating value services.
|
3354
3383
|
* <pre>
|
3355
|
-
* $provide.
|
3384
|
+
* $provide.value('ADMIN_USER', 'admin');
|
3356
3385
|
*
|
3357
|
-
* $provide.
|
3386
|
+
* $provide.value('RoleLookup', { admin: 0, writer: 1, reader: 2 });
|
3358
3387
|
*
|
3359
|
-
* $provide.
|
3388
|
+
* $provide.value('halfOf', function(value) {
|
3360
3389
|
* return value / 2;
|
3361
3390
|
* });
|
3362
3391
|
* </pre>
|
@@ -3842,13 +3871,14 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
3842
3871
|
* inserted into the DOM
|
3843
3872
|
*/
|
3844
3873
|
enter : function(element, parent, after, done) {
|
3845
|
-
|
3846
|
-
|
3847
|
-
|
3848
|
-
|
3849
|
-
|
3850
|
-
|
3851
|
-
|
3874
|
+
if (after) {
|
3875
|
+
after.after(element);
|
3876
|
+
} else {
|
3877
|
+
if (!parent || !parent[0]) {
|
3878
|
+
parent = after.parent();
|
3879
|
+
}
|
3880
|
+
parent.append(element);
|
3881
|
+
}
|
3852
3882
|
done && $timeout(done, 0, false);
|
3853
3883
|
},
|
3854
3884
|
|
@@ -4696,8 +4726,9 @@ function $TemplateCacheProvider() {
|
|
4696
4726
|
* When there are multiple directives defined on a single DOM element, sometimes it
|
4697
4727
|
* is necessary to specify the order in which the directives are applied. The `priority` is used
|
4698
4728
|
* to sort the directives before their `compile` functions get called. Priority is defined as a
|
4699
|
-
* number. Directives with greater numerical `priority` are compiled first.
|
4700
|
-
*
|
4729
|
+
* number. Directives with greater numerical `priority` are compiled first. Pre-link functions
|
4730
|
+
* are also run in priority order, but post-link functions are run in reverse order. The order
|
4731
|
+
* of directives with the same priority is undefined. The default priority is `0`.
|
4701
4732
|
*
|
4702
4733
|
* #### `terminal`
|
4703
4734
|
* If set to true then the current `priority` will be the last set of directives
|
@@ -4758,8 +4789,9 @@ function $TemplateCacheProvider() {
|
|
4758
4789
|
* * `$scope` - Current scope associated with the element
|
4759
4790
|
* * `$element` - Current element
|
4760
4791
|
* * `$attrs` - Current attributes object for the element
|
4761
|
-
* * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope
|
4762
|
-
*
|
4792
|
+
* * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope.
|
4793
|
+
* The scope can be overridden by an optional first argument.
|
4794
|
+
* `function([scope], cloneLinkingFn)`.
|
4763
4795
|
*
|
4764
4796
|
*
|
4765
4797
|
* #### `require`
|
@@ -4852,7 +4884,7 @@ function $TemplateCacheProvider() {
|
|
4852
4884
|
* * `tAttrs` - template attributes - Normalized list of attributes declared on this element shared
|
4853
4885
|
* between all directive compile functions.
|
4854
4886
|
*
|
4855
|
-
* * `transclude` - A transclude linking function: `function(scope, cloneLinkingFn)
|
4887
|
+
* * `transclude` - [*DEPRECATED*!] A transclude linking function: `function(scope, cloneLinkingFn)`
|
4856
4888
|
*
|
4857
4889
|
* <div class="alert alert-warning">
|
4858
4890
|
* **Note:** The template instance and the link instance may be different objects if the template has
|
@@ -4861,6 +4893,12 @@ function $TemplateCacheProvider() {
|
|
4861
4893
|
* should be done in a linking function rather than in a compile function.
|
4862
4894
|
* </div>
|
4863
4895
|
*
|
4896
|
+
* <div class="alert alert-error">
|
4897
|
+
* **Note:** The `transclude` function that is passed to the compile function is deprecated, as it
|
4898
|
+
* e.g. does not know about the right outer scope. Please use the transclude function that is passed
|
4899
|
+
* to the link function instead.
|
4900
|
+
* </div>
|
4901
|
+
|
4864
4902
|
* A compile function can have a return value which can be either a function or an object.
|
4865
4903
|
*
|
4866
4904
|
* * returning a (post-link) function - is equivalent to registering the linking function via the
|
@@ -4875,7 +4913,7 @@ function $TemplateCacheProvider() {
|
|
4875
4913
|
* This property is used only if the `compile` property is not defined.
|
4876
4914
|
*
|
4877
4915
|
* <pre>
|
4878
|
-
* function link(scope, iElement, iAttrs, controller) { ... }
|
4916
|
+
* function link(scope, iElement, iAttrs, controller, transcludeFn) { ... }
|
4879
4917
|
* </pre>
|
4880
4918
|
*
|
4881
4919
|
* The link function is responsible for registering DOM listeners as well as updating the DOM. It is
|
@@ -4896,6 +4934,10 @@ function $TemplateCacheProvider() {
|
|
4896
4934
|
* element defines a controller. The controller is shared among all the directives, which allows
|
4897
4935
|
* the directives to use the controllers as a communication channel.
|
4898
4936
|
*
|
4937
|
+
* * `transcludeFn` - A transclude linking function pre-bound to the correct transclusion scope.
|
4938
|
+
* The scope can be overridden by an optional first argument. This is the same as the `$transclude`
|
4939
|
+
* parameter of directive controllers.
|
4940
|
+
* `function([scope], cloneLinkingFn)`.
|
4899
4941
|
*
|
4900
4942
|
*
|
4901
4943
|
* #### Pre-linking function
|
@@ -5062,14 +5104,12 @@ var $compileMinErr = minErr('$compile');
|
|
5062
5104
|
*
|
5063
5105
|
* @description
|
5064
5106
|
*/
|
5065
|
-
$CompileProvider.$inject = ['$provide'];
|
5066
|
-
function $CompileProvider($provide) {
|
5107
|
+
$CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider'];
|
5108
|
+
function $CompileProvider($provide, $$sanitizeUriProvider) {
|
5067
5109
|
var hasDirectives = {},
|
5068
5110
|
Suffix = 'Directive',
|
5069
5111
|
COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,
|
5070
|
-
CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)
|
5071
|
-
aHrefSanitizationWhitelist = /^\s*(https?|ftp|mailto|tel|file):/,
|
5072
|
-
imgSrcSanitizationWhitelist = /^\s*(https?|ftp|file):|data:image\//;
|
5112
|
+
CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/;
|
5073
5113
|
|
5074
5114
|
// Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes
|
5075
5115
|
// The assumption is that future DOM event attribute names will begin with
|
@@ -5153,10 +5193,11 @@ function $CompileProvider($provide) {
|
|
5153
5193
|
*/
|
5154
5194
|
this.aHrefSanitizationWhitelist = function(regexp) {
|
5155
5195
|
if (isDefined(regexp)) {
|
5156
|
-
aHrefSanitizationWhitelist
|
5196
|
+
$$sanitizeUriProvider.aHrefSanitizationWhitelist(regexp);
|
5157
5197
|
return this;
|
5198
|
+
} else {
|
5199
|
+
return $$sanitizeUriProvider.aHrefSanitizationWhitelist();
|
5158
5200
|
}
|
5159
|
-
return aHrefSanitizationWhitelist;
|
5160
5201
|
};
|
5161
5202
|
|
5162
5203
|
|
@@ -5183,18 +5224,18 @@ function $CompileProvider($provide) {
|
|
5183
5224
|
*/
|
5184
5225
|
this.imgSrcSanitizationWhitelist = function(regexp) {
|
5185
5226
|
if (isDefined(regexp)) {
|
5186
|
-
imgSrcSanitizationWhitelist
|
5227
|
+
$$sanitizeUriProvider.imgSrcSanitizationWhitelist(regexp);
|
5187
5228
|
return this;
|
5229
|
+
} else {
|
5230
|
+
return $$sanitizeUriProvider.imgSrcSanitizationWhitelist();
|
5188
5231
|
}
|
5189
|
-
return imgSrcSanitizationWhitelist;
|
5190
5232
|
};
|
5191
5233
|
|
5192
|
-
|
5193
5234
|
this.$get = [
|
5194
5235
|
'$injector', '$interpolate', '$exceptionHandler', '$http', '$templateCache', '$parse',
|
5195
|
-
'$controller', '$rootScope', '$document', '$sce', '$animate',
|
5236
|
+
'$controller', '$rootScope', '$document', '$sce', '$animate', '$$sanitizeUri',
|
5196
5237
|
function($injector, $interpolate, $exceptionHandler, $http, $templateCache, $parse,
|
5197
|
-
$controller, $rootScope, $document, $sce, $animate) {
|
5238
|
+
$controller, $rootScope, $document, $sce, $animate, $$sanitizeUri) {
|
5198
5239
|
|
5199
5240
|
var Attributes = function(element, attr) {
|
5200
5241
|
this.$$element = element;
|
@@ -5241,6 +5282,24 @@ function $CompileProvider($provide) {
|
|
5241
5282
|
}
|
5242
5283
|
},
|
5243
5284
|
|
5285
|
+
/**
|
5286
|
+
* @ngdoc function
|
5287
|
+
* @name ng.$compile.directive.Attributes#$updateClass
|
5288
|
+
* @methodOf ng.$compile.directive.Attributes
|
5289
|
+
* @function
|
5290
|
+
*
|
5291
|
+
* @description
|
5292
|
+
* Adds and removes the appropriate CSS class values to the element based on the difference
|
5293
|
+
* between the new and old CSS class values (specified as newClasses and oldClasses).
|
5294
|
+
*
|
5295
|
+
* @param {string} newClasses The current CSS className value
|
5296
|
+
* @param {string} oldClasses The former CSS className value
|
5297
|
+
*/
|
5298
|
+
$updateClass : function(newClasses, oldClasses) {
|
5299
|
+
this.$removeClass(tokenDifference(oldClasses, newClasses));
|
5300
|
+
this.$addClass(tokenDifference(newClasses, oldClasses));
|
5301
|
+
},
|
5302
|
+
|
5244
5303
|
/**
|
5245
5304
|
* Set a normalized attribute on the element in a way such that all directives
|
5246
5305
|
* can share the attribute. This function properly handles boolean attributes.
|
@@ -5251,59 +5310,44 @@ function $CompileProvider($provide) {
|
|
5251
5310
|
* @param {string=} attrName Optional none normalized name. Defaults to key.
|
5252
5311
|
*/
|
5253
5312
|
$set: function(key, value, writeAttr, attrName) {
|
5254
|
-
//
|
5255
|
-
//
|
5256
|
-
//
|
5257
|
-
if(key == 'class') {
|
5258
|
-
value = value || '';
|
5259
|
-
var current = this.$$element.attr('class') || '';
|
5260
|
-
this.$removeClass(tokenDifference(current, value).join(' '));
|
5261
|
-
this.$addClass(tokenDifference(value, current).join(' '));
|
5262
|
-
} else {
|
5263
|
-
var booleanKey = getBooleanAttrName(this.$$element[0], key),
|
5264
|
-
normalizedVal,
|
5265
|
-
nodeName;
|
5313
|
+
// TODO: decide whether or not to throw an error if "class"
|
5314
|
+
//is set through this function since it may cause $updateClass to
|
5315
|
+
//become unstable.
|
5266
5316
|
|
5267
|
-
|
5268
|
-
|
5269
|
-
|
5270
|
-
}
|
5317
|
+
var booleanKey = getBooleanAttrName(this.$$element[0], key),
|
5318
|
+
normalizedVal,
|
5319
|
+
nodeName;
|
5271
5320
|
|
5272
|
-
|
5321
|
+
if (booleanKey) {
|
5322
|
+
this.$$element.prop(key, value);
|
5323
|
+
attrName = booleanKey;
|
5324
|
+
}
|
5273
5325
|
|
5274
|
-
|
5275
|
-
if (attrName) {
|
5276
|
-
this.$attr[key] = attrName;
|
5277
|
-
} else {
|
5278
|
-
attrName = this.$attr[key];
|
5279
|
-
if (!attrName) {
|
5280
|
-
this.$attr[key] = attrName = snake_case(key, '-');
|
5281
|
-
}
|
5282
|
-
}
|
5326
|
+
this[key] = value;
|
5283
5327
|
|
5284
|
-
|
5285
|
-
|
5286
|
-
|
5287
|
-
|
5288
|
-
|
5289
|
-
|
5290
|
-
|
5291
|
-
normalizedVal = urlResolve(value).href;
|
5292
|
-
if (normalizedVal !== '') {
|
5293
|
-
if ((key === 'href' && !normalizedVal.match(aHrefSanitizationWhitelist)) ||
|
5294
|
-
(key === 'src' && !normalizedVal.match(imgSrcSanitizationWhitelist))) {
|
5295
|
-
this[key] = value = 'unsafe:' + normalizedVal;
|
5296
|
-
}
|
5297
|
-
}
|
5298
|
-
}
|
5328
|
+
// translate normalized key to actual key
|
5329
|
+
if (attrName) {
|
5330
|
+
this.$attr[key] = attrName;
|
5331
|
+
} else {
|
5332
|
+
attrName = this.$attr[key];
|
5333
|
+
if (!attrName) {
|
5334
|
+
this.$attr[key] = attrName = snake_case(key, '-');
|
5299
5335
|
}
|
5336
|
+
}
|
5300
5337
|
|
5301
|
-
|
5302
|
-
|
5303
|
-
|
5304
|
-
|
5305
|
-
|
5306
|
-
|
5338
|
+
nodeName = nodeName_(this.$$element);
|
5339
|
+
|
5340
|
+
// sanitize a[href] and img[src] values
|
5341
|
+
if ((nodeName === 'A' && key === 'href') ||
|
5342
|
+
(nodeName === 'IMG' && key === 'src')) {
|
5343
|
+
this[key] = value = $$sanitizeUri(value, key === 'src');
|
5344
|
+
}
|
5345
|
+
|
5346
|
+
if (writeAttr !== false) {
|
5347
|
+
if (value === null || value === undefined) {
|
5348
|
+
this.$$element.removeAttr(attrName);
|
5349
|
+
} else {
|
5350
|
+
this.$$element.attr(attrName, value);
|
5307
5351
|
}
|
5308
5352
|
}
|
5309
5353
|
|
@@ -5316,22 +5360,6 @@ function $CompileProvider($provide) {
|
|
5316
5360
|
$exceptionHandler(e);
|
5317
5361
|
}
|
5318
5362
|
});
|
5319
|
-
|
5320
|
-
function tokenDifference(str1, str2) {
|
5321
|
-
var values = [],
|
5322
|
-
tokens1 = str1.split(/\s+/),
|
5323
|
-
tokens2 = str2.split(/\s+/);
|
5324
|
-
|
5325
|
-
outer:
|
5326
|
-
for(var i=0;i<tokens1.length;i++) {
|
5327
|
-
var token = tokens1[i];
|
5328
|
-
for(var j=0;j<tokens2.length;j++) {
|
5329
|
-
if(token == tokens2[j]) continue outer;
|
5330
|
-
}
|
5331
|
-
values.push(token);
|
5332
|
-
}
|
5333
|
-
return values;
|
5334
|
-
}
|
5335
5363
|
},
|
5336
5364
|
|
5337
5365
|
|
@@ -5401,7 +5429,7 @@ function $CompileProvider($provide) {
|
|
5401
5429
|
var compositeLinkFn =
|
5402
5430
|
compileNodes($compileNodes, transcludeFn, $compileNodes,
|
5403
5431
|
maxPriority, ignoreDirective, previousCompileContext);
|
5404
|
-
return function publicLinkFn(scope, cloneConnectFn){
|
5432
|
+
return function publicLinkFn(scope, cloneConnectFn, transcludeControllers){
|
5405
5433
|
assertArg(scope, 'scope');
|
5406
5434
|
// important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart
|
5407
5435
|
// and sometimes changes the structure of the DOM.
|
@@ -5409,6 +5437,10 @@ function $CompileProvider($provide) {
|
|
5409
5437
|
? JQLitePrototype.clone.call($compileNodes) // IMPORTANT!!!
|
5410
5438
|
: $compileNodes;
|
5411
5439
|
|
5440
|
+
forEach(transcludeControllers, function(instance, name) {
|
5441
|
+
$linkNode.data('$' + name + 'Controller', instance);
|
5442
|
+
});
|
5443
|
+
|
5412
5444
|
// Attach scope only to non-text nodes.
|
5413
5445
|
for(var i = 0, ii = $linkNode.length; i<ii; i++) {
|
5414
5446
|
var node = $linkNode[i];
|
@@ -5507,15 +5539,7 @@ function $CompileProvider($provide) {
|
|
5507
5539
|
childTranscludeFn = nodeLinkFn.transclude;
|
5508
5540
|
if (childTranscludeFn || (!boundTranscludeFn && transcludeFn)) {
|
5509
5541
|
nodeLinkFn(childLinkFn, childScope, node, $rootElement,
|
5510
|
-
|
5511
|
-
return function(cloneFn) {
|
5512
|
-
var transcludeScope = scope.$new();
|
5513
|
-
transcludeScope.$$transcluded = true;
|
5514
|
-
|
5515
|
-
return transcludeFn(transcludeScope, cloneFn).
|
5516
|
-
on('$destroy', bind(transcludeScope, transcludeScope.$destroy));
|
5517
|
-
};
|
5518
|
-
})(childTranscludeFn || transcludeFn)
|
5542
|
+
createBoundTranscludeFn(scope, childTranscludeFn || transcludeFn)
|
5519
5543
|
);
|
5520
5544
|
} else {
|
5521
5545
|
nodeLinkFn(childLinkFn, childScope, node, undefined, boundTranscludeFn);
|
@@ -5527,6 +5551,23 @@ function $CompileProvider($provide) {
|
|
5527
5551
|
}
|
5528
5552
|
}
|
5529
5553
|
|
5554
|
+
function createBoundTranscludeFn(scope, transcludeFn) {
|
5555
|
+
return function boundTranscludeFn(transcludedScope, cloneFn, controllers) {
|
5556
|
+
var scopeCreated = false;
|
5557
|
+
|
5558
|
+
if (!transcludedScope) {
|
5559
|
+
transcludedScope = scope.$new();
|
5560
|
+
transcludedScope.$$transcluded = true;
|
5561
|
+
scopeCreated = true;
|
5562
|
+
}
|
5563
|
+
|
5564
|
+
var clone = transcludeFn(transcludedScope, cloneFn, controllers);
|
5565
|
+
if (scopeCreated) {
|
5566
|
+
clone.on('$destroy', bind(transcludedScope, transcludedScope.$destroy));
|
5567
|
+
}
|
5568
|
+
return clone;
|
5569
|
+
};
|
5570
|
+
}
|
5530
5571
|
|
5531
5572
|
/**
|
5532
5573
|
* Looks for directives on the given node and adds them to the directive collection which is
|
@@ -5664,9 +5705,9 @@ function $CompileProvider($provide) {
|
|
5664
5705
|
* @returns {Function}
|
5665
5706
|
*/
|
5666
5707
|
function groupElementsLinkFnWrapper(linkFn, attrStart, attrEnd) {
|
5667
|
-
return function(scope, element, attrs, controllers) {
|
5708
|
+
return function(scope, element, attrs, controllers, transcludeFn) {
|
5668
5709
|
element = groupScan(element[0], attrStart, attrEnd);
|
5669
|
-
return linkFn(scope, element, attrs, controllers);
|
5710
|
+
return linkFn(scope, element, attrs, controllers, transcludeFn);
|
5670
5711
|
};
|
5671
5712
|
}
|
5672
5713
|
|
@@ -5703,7 +5744,9 @@ function $CompileProvider($provide) {
|
|
5703
5744
|
controllerDirectives = previousCompileContext.controllerDirectives,
|
5704
5745
|
newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective,
|
5705
5746
|
templateDirective = previousCompileContext.templateDirective,
|
5706
|
-
|
5747
|
+
nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective,
|
5748
|
+
hasTranscludeDirective = false,
|
5749
|
+
hasElementTranscludeDirective = false,
|
5707
5750
|
$compileNode = templateAttrs.$$element = jqLite(compileNode),
|
5708
5751
|
directive,
|
5709
5752
|
directiveName,
|
@@ -5754,15 +5797,18 @@ function $CompileProvider($provide) {
|
|
5754
5797
|
}
|
5755
5798
|
|
5756
5799
|
if (directiveValue = directive.transclude) {
|
5800
|
+
hasTranscludeDirective = true;
|
5801
|
+
|
5757
5802
|
// Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion.
|
5758
5803
|
// This option should only be used by directives that know how to how to safely handle element transclusion,
|
5759
5804
|
// where the transcluded nodes are added or replaced after linking.
|
5760
5805
|
if (!directive.$$tlb) {
|
5761
|
-
assertNoDuplicate('transclusion',
|
5762
|
-
|
5806
|
+
assertNoDuplicate('transclusion', nonTlbTranscludeDirective, directive, $compileNode);
|
5807
|
+
nonTlbTranscludeDirective = directive;
|
5763
5808
|
}
|
5764
5809
|
|
5765
5810
|
if (directiveValue == 'element') {
|
5811
|
+
hasElementTranscludeDirective = true;
|
5766
5812
|
terminalPriority = directive.priority;
|
5767
5813
|
$template = groupScan(compileNode, attrStart, attrEnd);
|
5768
5814
|
$compileNode = templateAttrs.$$element =
|
@@ -5778,9 +5824,9 @@ function $CompileProvider($provide) {
|
|
5778
5824
|
// - newIsolateScopeDirective or templateDirective - combining templates with
|
5779
5825
|
// element transclusion doesn't make sense.
|
5780
5826
|
//
|
5781
|
-
// We need only
|
5827
|
+
// We need only nonTlbTranscludeDirective so that we prevent putting transclusion
|
5782
5828
|
// on the same element more than once.
|
5783
|
-
|
5829
|
+
nonTlbTranscludeDirective: nonTlbTranscludeDirective
|
5784
5830
|
});
|
5785
5831
|
} else {
|
5786
5832
|
$template = jqLite(jqLiteClone(compileNode)).contents();
|
@@ -5849,7 +5895,7 @@ function $CompileProvider($provide) {
|
|
5849
5895
|
controllerDirectives: controllerDirectives,
|
5850
5896
|
newIsolateScopeDirective: newIsolateScopeDirective,
|
5851
5897
|
templateDirective: templateDirective,
|
5852
|
-
|
5898
|
+
nonTlbTranscludeDirective: nonTlbTranscludeDirective
|
5853
5899
|
});
|
5854
5900
|
ii = directives.length;
|
5855
5901
|
} else if (directive.compile) {
|
@@ -5873,7 +5919,7 @@ function $CompileProvider($provide) {
|
|
5873
5919
|
}
|
5874
5920
|
|
5875
5921
|
nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true;
|
5876
|
-
nodeLinkFn.transclude =
|
5922
|
+
nodeLinkFn.transclude = hasTranscludeDirective && childTranscludeFn;
|
5877
5923
|
|
5878
5924
|
// might be normal or delayed nodeLinkFn depending on if templateUrl is present
|
5879
5925
|
return nodeLinkFn;
|
@@ -5900,7 +5946,7 @@ function $CompileProvider($provide) {
|
|
5900
5946
|
}
|
5901
5947
|
|
5902
5948
|
|
5903
|
-
function getControllers(require, $element) {
|
5949
|
+
function getControllers(require, $element, elementControllers) {
|
5904
5950
|
var value, retrievalMethod = 'data', optional = false;
|
5905
5951
|
if (isString(require)) {
|
5906
5952
|
while((value = require.charAt(0)) == '^' || value == '?') {
|
@@ -5910,13 +5956,12 @@ function $CompileProvider($provide) {
|
|
5910
5956
|
}
|
5911
5957
|
optional = optional || value == '?';
|
5912
5958
|
}
|
5959
|
+
value = null;
|
5913
5960
|
|
5914
|
-
|
5915
|
-
|
5916
|
-
if ($element[0].nodeType == 8 && $element[0].$$controller) { // Transclusion comment node
|
5917
|
-
value = value || $element[0].$$controller;
|
5918
|
-
$element[0].$$controller = null;
|
5961
|
+
if (elementControllers && retrievalMethod === 'data') {
|
5962
|
+
value = elementControllers[require];
|
5919
5963
|
}
|
5964
|
+
value = value || $element[retrievalMethod]('$' + require + 'Controller');
|
5920
5965
|
|
5921
5966
|
if (!value && !optional) {
|
5922
5967
|
throw $compileMinErr('ctreq',
|
@@ -5927,7 +5972,7 @@ function $CompileProvider($provide) {
|
|
5927
5972
|
} else if (isArray(require)) {
|
5928
5973
|
value = [];
|
5929
5974
|
forEach(require, function(require) {
|
5930
|
-
value.push(getControllers(require, $element));
|
5975
|
+
value.push(getControllers(require, $element, elementControllers));
|
5931
5976
|
});
|
5932
5977
|
}
|
5933
5978
|
return value;
|
@@ -5935,7 +5980,7 @@ function $CompileProvider($provide) {
|
|
5935
5980
|
|
5936
5981
|
|
5937
5982
|
function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {
|
5938
|
-
var attrs, $element, i, ii, linkFn, controller, isolateScope;
|
5983
|
+
var attrs, $element, i, ii, linkFn, controller, isolateScope, elementControllers = {}, transcludeFn;
|
5939
5984
|
|
5940
5985
|
if (compileNode === linkNode) {
|
5941
5986
|
attrs = templateAttrs;
|
@@ -6029,14 +6074,14 @@ function $CompileProvider($provide) {
|
|
6029
6074
|
}
|
6030
6075
|
});
|
6031
6076
|
}
|
6032
|
-
|
6077
|
+
transcludeFn = boundTranscludeFn && controllersBoundTransclude;
|
6033
6078
|
if (controllerDirectives) {
|
6034
6079
|
forEach(controllerDirectives, function(directive) {
|
6035
6080
|
var locals = {
|
6036
6081
|
$scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
|
6037
6082
|
$element: $element,
|
6038
6083
|
$attrs: attrs,
|
6039
|
-
$transclude:
|
6084
|
+
$transclude: transcludeFn
|
6040
6085
|
}, controllerInstance;
|
6041
6086
|
|
6042
6087
|
controller = directive.controller;
|
@@ -6045,16 +6090,16 @@ function $CompileProvider($provide) {
|
|
6045
6090
|
}
|
6046
6091
|
|
6047
6092
|
controllerInstance = $controller(controller, locals);
|
6048
|
-
|
6049
|
-
//
|
6050
|
-
//
|
6051
|
-
//
|
6052
|
-
//
|
6053
|
-
|
6054
|
-
|
6055
|
-
} else {
|
6093
|
+
// For directives with element transclusion the element is a comment,
|
6094
|
+
// but jQuery .data doesn't support attaching data to comment nodes as it's hard to
|
6095
|
+
// clean up (http://bugs.jquery.com/ticket/8335).
|
6096
|
+
// Instead, we save the controllers for the element in a local hash and attach to .data
|
6097
|
+
// later, once we have the actual element.
|
6098
|
+
elementControllers[directive.name] = controllerInstance;
|
6099
|
+
if (!hasElementTranscludeDirective) {
|
6056
6100
|
$element.data('$' + directive.name + 'Controller', controllerInstance);
|
6057
6101
|
}
|
6102
|
+
|
6058
6103
|
if (directive.controllerAs) {
|
6059
6104
|
locals.$scope[directive.controllerAs] = controllerInstance;
|
6060
6105
|
}
|
@@ -6066,7 +6111,7 @@ function $CompileProvider($provide) {
|
|
6066
6111
|
try {
|
6067
6112
|
linkFn = preLinkFns[i];
|
6068
6113
|
linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs,
|
6069
|
-
linkFn.require && getControllers(linkFn.require, $element));
|
6114
|
+
linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn);
|
6070
6115
|
} catch (e) {
|
6071
6116
|
$exceptionHandler(e, startingTag($element));
|
6072
6117
|
}
|
@@ -6086,11 +6131,28 @@ function $CompileProvider($provide) {
|
|
6086
6131
|
try {
|
6087
6132
|
linkFn = postLinkFns[i];
|
6088
6133
|
linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs,
|
6089
|
-
linkFn.require && getControllers(linkFn.require, $element));
|
6134
|
+
linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn);
|
6090
6135
|
} catch (e) {
|
6091
6136
|
$exceptionHandler(e, startingTag($element));
|
6092
6137
|
}
|
6093
6138
|
}
|
6139
|
+
|
6140
|
+
// This is the function that is injected as `$transclude`.
|
6141
|
+
function controllersBoundTransclude(scope, cloneAttachFn) {
|
6142
|
+
var transcludeControllers;
|
6143
|
+
|
6144
|
+
// no scope passed
|
6145
|
+
if (arguments.length < 2) {
|
6146
|
+
cloneAttachFn = scope;
|
6147
|
+
scope = undefined;
|
6148
|
+
}
|
6149
|
+
|
6150
|
+
if (hasElementTranscludeDirective) {
|
6151
|
+
transcludeControllers = elementControllers;
|
6152
|
+
}
|
6153
|
+
|
6154
|
+
return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers);
|
6155
|
+
}
|
6094
6156
|
}
|
6095
6157
|
}
|
6096
6158
|
|
@@ -6169,6 +6231,7 @@ function $CompileProvider($provide) {
|
|
6169
6231
|
dst['class'] = (dst['class'] ? dst['class'] + ' ' : '') + value;
|
6170
6232
|
} else if (key == 'style') {
|
6171
6233
|
$element.attr('style', $element.attr('style') + ';' + value);
|
6234
|
+
dst['style'] = (dst['style'] ? dst['style'] + ';' : '') + value;
|
6172
6235
|
// `dst` will never contain hasOwnProperty as DOM parser won't let it.
|
6173
6236
|
// You will get an "InvalidCharacterError: DOM Exception 5" error if you
|
6174
6237
|
// have an attribute like "has-own-property" or "data-has-own-property", etc.
|
@@ -6199,7 +6262,7 @@ function $CompileProvider($provide) {
|
|
6199
6262
|
|
6200
6263
|
$http.get($sce.getTrustedResourceUrl(templateUrl), {cache: $templateCache}).
|
6201
6264
|
success(function(content) {
|
6202
|
-
var compileNode, tempTemplateAttrs, $template;
|
6265
|
+
var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn;
|
6203
6266
|
|
6204
6267
|
content = denormalizeTemplate(content);
|
6205
6268
|
|
@@ -6244,7 +6307,7 @@ function $CompileProvider($provide) {
|
|
6244
6307
|
var scope = linkQueue.shift(),
|
6245
6308
|
beforeTemplateLinkNode = linkQueue.shift(),
|
6246
6309
|
linkRootElement = linkQueue.shift(),
|
6247
|
-
|
6310
|
+
boundTranscludeFn = linkQueue.shift(),
|
6248
6311
|
linkNode = $compileNode[0];
|
6249
6312
|
|
6250
6313
|
if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {
|
@@ -6252,9 +6315,13 @@ function $CompileProvider($provide) {
|
|
6252
6315
|
linkNode = jqLiteClone(compileNode);
|
6253
6316
|
replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);
|
6254
6317
|
}
|
6255
|
-
|
6318
|
+
if (afterTemplateNodeLinkFn.transclude) {
|
6319
|
+
childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude);
|
6320
|
+
} else {
|
6321
|
+
childBoundTranscludeFn = boundTranscludeFn;
|
6322
|
+
}
|
6256
6323
|
afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement,
|
6257
|
-
|
6324
|
+
childBoundTranscludeFn);
|
6258
6325
|
}
|
6259
6326
|
linkQueue = null;
|
6260
6327
|
}).
|
@@ -6262,14 +6329,14 @@ function $CompileProvider($provide) {
|
|
6262
6329
|
throw $compileMinErr('tpload', 'Failed to load template: {0}', config.url);
|
6263
6330
|
});
|
6264
6331
|
|
6265
|
-
return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement,
|
6332
|
+
return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, boundTranscludeFn) {
|
6266
6333
|
if (linkQueue) {
|
6267
6334
|
linkQueue.push(scope);
|
6268
6335
|
linkQueue.push(node);
|
6269
6336
|
linkQueue.push(rootElement);
|
6270
|
-
linkQueue.push(
|
6337
|
+
linkQueue.push(boundTranscludeFn);
|
6271
6338
|
} else {
|
6272
|
-
afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement,
|
6339
|
+
afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, boundTranscludeFn);
|
6273
6340
|
}
|
6274
6341
|
};
|
6275
6342
|
}
|
@@ -6314,10 +6381,15 @@ function $CompileProvider($provide) {
|
|
6314
6381
|
|
6315
6382
|
|
6316
6383
|
function getTrustedContext(node, attrNormalizedName) {
|
6384
|
+
if (attrNormalizedName == "srcdoc") {
|
6385
|
+
return $sce.HTML;
|
6386
|
+
}
|
6387
|
+
var tag = nodeName_(node);
|
6317
6388
|
// maction[xlink:href] can source SVG. It's not limited to <maction>.
|
6318
6389
|
if (attrNormalizedName == "xlinkHref" ||
|
6319
|
-
(
|
6320
|
-
|
6390
|
+
(tag == "FORM" && attrNormalizedName == "action") ||
|
6391
|
+
(tag != "IMG" && (attrNormalizedName == "src" ||
|
6392
|
+
attrNormalizedName == "ngSrc"))) {
|
6321
6393
|
return $sce.RESOURCE_URL;
|
6322
6394
|
}
|
6323
6395
|
}
|
@@ -6362,9 +6434,19 @@ function $CompileProvider($provide) {
|
|
6362
6434
|
attr[name] = interpolateFn(scope);
|
6363
6435
|
($$observers[name] || ($$observers[name] = [])).$$inter = true;
|
6364
6436
|
(attr.$$observers && attr.$$observers[name].$$scope || scope).
|
6365
|
-
|
6366
|
-
|
6367
|
-
|
6437
|
+
$watch(interpolateFn, function interpolateFnWatchAction(newValue, oldValue) {
|
6438
|
+
//special case for class attribute addition + removal
|
6439
|
+
//so that class changes can tap into the animation
|
6440
|
+
//hooks provided by the $animate service. Be sure to
|
6441
|
+
//skip animations when the first digest occurs (when
|
6442
|
+
//both the new and the old values are the same) since
|
6443
|
+
//the CSS classes are the non-interpolated values
|
6444
|
+
if(name === 'class' && newValue != oldValue) {
|
6445
|
+
attr.$updateClass(newValue, oldValue);
|
6446
|
+
} else {
|
6447
|
+
attr.$set(name, newValue);
|
6448
|
+
}
|
6449
|
+
});
|
6368
6450
|
}
|
6369
6451
|
};
|
6370
6452
|
}
|
@@ -6505,6 +6587,22 @@ function directiveLinkingFn(
|
|
6505
6587
|
/* function(Function) */ boundTranscludeFn
|
6506
6588
|
){}
|
6507
6589
|
|
6590
|
+
function tokenDifference(str1, str2) {
|
6591
|
+
var values = '',
|
6592
|
+
tokens1 = str1.split(/\s+/),
|
6593
|
+
tokens2 = str2.split(/\s+/);
|
6594
|
+
|
6595
|
+
outer:
|
6596
|
+
for(var i = 0; i < tokens1.length; i++) {
|
6597
|
+
var token = tokens1[i];
|
6598
|
+
for(var j = 0; j < tokens2.length; j++) {
|
6599
|
+
if(token == tokens2[j]) continue outer;
|
6600
|
+
}
|
6601
|
+
values += (values.length > 0 ? ' ' : '') + token;
|
6602
|
+
}
|
6603
|
+
return values;
|
6604
|
+
}
|
6605
|
+
|
6508
6606
|
/**
|
6509
6607
|
* @ngdoc object
|
6510
6608
|
* @name ng.$controllerProvider
|
@@ -6974,9 +7072,11 @@ function $HttpProvider() {
|
|
6974
7072
|
*
|
6975
7073
|
* # Caching
|
6976
7074
|
*
|
6977
|
-
* To enable caching, set the configuration
|
6978
|
-
*
|
6979
|
-
*
|
7075
|
+
* To enable caching, set the request configuration `cache` property to `true` (to use default
|
7076
|
+
* cache) or to a custom cache object (built with {@link ng.$cacheFactory `$cacheFactory`}).
|
7077
|
+
* When the cache is enabled, `$http` stores the response from the server in the specified
|
7078
|
+
* cache. The next time the same request is made, the response is served from the cache without
|
7079
|
+
* sending a request to the server.
|
6980
7080
|
*
|
6981
7081
|
* Note that even if the response is served from cache, delivery of the data is asynchronous in
|
6982
7082
|
* the same way that real requests are.
|
@@ -6985,9 +7085,13 @@ function $HttpProvider() {
|
|
6985
7085
|
* cache, but the cache is not populated yet, only one request to the server will be made and
|
6986
7086
|
* the remaining requests will be fulfilled using the response from the first request.
|
6987
7087
|
*
|
6988
|
-
*
|
6989
|
-
*
|
7088
|
+
* You can change the default cache to a new object (built with
|
7089
|
+
* {@link ng.$cacheFactory `$cacheFactory`}) by updating the
|
7090
|
+
* {@link ng.$http#properties_defaults `$http.defaults.cache`} property. All requests who set
|
7091
|
+
* their `cache` property to `true` will now use this cache object.
|
6990
7092
|
*
|
7093
|
+
* If you set the default cache to `false` then only requests that specify their own custom
|
7094
|
+
* cache object will be cached.
|
6991
7095
|
*
|
6992
7096
|
* # Interceptors
|
6993
7097
|
*
|
@@ -7709,12 +7813,13 @@ var XHR = window.XMLHttpRequest || function() {
|
|
7709
7813
|
*/
|
7710
7814
|
function $HttpBackendProvider() {
|
7711
7815
|
this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) {
|
7712
|
-
return createHttpBackend($browser, XHR, $browser.defer, $window.angular.callbacks,
|
7713
|
-
$document[0], $window.location.protocol.replace(':', ''));
|
7816
|
+
return createHttpBackend($browser, XHR, $browser.defer, $window.angular.callbacks, $document[0]);
|
7714
7817
|
}];
|
7715
7818
|
}
|
7716
7819
|
|
7717
|
-
function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument
|
7820
|
+
function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument) {
|
7821
|
+
var ABORTED = -1;
|
7822
|
+
|
7718
7823
|
// TODO(vojta): fix the signature
|
7719
7824
|
return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
|
7720
7825
|
var status;
|
@@ -7750,13 +7855,19 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
|
|
7750
7855
|
// always async
|
7751
7856
|
xhr.onreadystatechange = function() {
|
7752
7857
|
if (xhr.readyState == 4) {
|
7753
|
-
var responseHeaders =
|
7858
|
+
var responseHeaders = null,
|
7859
|
+
response = null;
|
7860
|
+
|
7861
|
+
if(status !== ABORTED) {
|
7862
|
+
responseHeaders = xhr.getAllResponseHeaders();
|
7863
|
+
response = xhr.responseType ? xhr.response : xhr.responseText;
|
7864
|
+
}
|
7754
7865
|
|
7755
7866
|
// responseText is the old-school way of retrieving response (supported by IE8 & 9)
|
7756
7867
|
// response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
|
7757
7868
|
completeRequest(callback,
|
7758
7869
|
status || xhr.status,
|
7759
|
-
|
7870
|
+
response,
|
7760
7871
|
responseHeaders);
|
7761
7872
|
}
|
7762
7873
|
};
|
@@ -7780,20 +7891,20 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
|
|
7780
7891
|
|
7781
7892
|
|
7782
7893
|
function timeoutRequest() {
|
7783
|
-
status =
|
7894
|
+
status = ABORTED;
|
7784
7895
|
jsonpDone && jsonpDone();
|
7785
7896
|
xhr && xhr.abort();
|
7786
7897
|
}
|
7787
7898
|
|
7788
7899
|
function completeRequest(callback, status, response, headersString) {
|
7789
|
-
var protocol =
|
7900
|
+
var protocol = urlResolve(url).protocol;
|
7790
7901
|
|
7791
7902
|
// cancel timeout and subsequent timeout promise resolution
|
7792
7903
|
timeoutId && $browserDefer.cancel(timeoutId);
|
7793
7904
|
jsonpDone = xhr = null;
|
7794
7905
|
|
7795
7906
|
// fix status code for file protocol (it's always 0)
|
7796
|
-
status = (protocol == 'file') ? (response ? 200 : 404) : status;
|
7907
|
+
status = (protocol == 'file' && status === 0) ? (response ? 200 : 404) : status;
|
7797
7908
|
|
7798
7909
|
// normalize IE bug (http://bugs.jquery.com/ticket/1450)
|
7799
7910
|
status = status == 1223 ? 204 : status;
|
@@ -7809,6 +7920,7 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
|
|
7809
7920
|
// - adds and immediately removes script elements from the document
|
7810
7921
|
var script = rawDocument.createElement('script'),
|
7811
7922
|
doneWrapper = function() {
|
7923
|
+
script.onreadystatechange = script.onload = script.onerror = null;
|
7812
7924
|
rawDocument.body.removeChild(script);
|
7813
7925
|
if (done) done();
|
7814
7926
|
};
|
@@ -7816,12 +7928,16 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
|
|
7816
7928
|
script.type = 'text/javascript';
|
7817
7929
|
script.src = url;
|
7818
7930
|
|
7819
|
-
if (msie) {
|
7931
|
+
if (msie && msie <= 8) {
|
7820
7932
|
script.onreadystatechange = function() {
|
7821
|
-
if (/loaded|complete/.test(script.readyState))
|
7933
|
+
if (/loaded|complete/.test(script.readyState)) {
|
7934
|
+
doneWrapper();
|
7935
|
+
}
|
7822
7936
|
};
|
7823
7937
|
} else {
|
7824
|
-
script.onload = script.onerror =
|
7938
|
+
script.onload = script.onerror = function() {
|
7939
|
+
doneWrapper();
|
7940
|
+
};
|
7825
7941
|
}
|
7826
7942
|
|
7827
7943
|
rawDocument.body.appendChild(script);
|
@@ -8251,8 +8367,8 @@ function encodePath(path) {
|
|
8251
8367
|
return segments.join('/');
|
8252
8368
|
}
|
8253
8369
|
|
8254
|
-
function parseAbsoluteUrl(absoluteUrl, locationObj) {
|
8255
|
-
var parsedUrl = urlResolve(absoluteUrl);
|
8370
|
+
function parseAbsoluteUrl(absoluteUrl, locationObj, appBase) {
|
8371
|
+
var parsedUrl = urlResolve(absoluteUrl, appBase);
|
8256
8372
|
|
8257
8373
|
locationObj.$$protocol = parsedUrl.protocol;
|
8258
8374
|
locationObj.$$host = parsedUrl.hostname;
|
@@ -8260,12 +8376,12 @@ function parseAbsoluteUrl(absoluteUrl, locationObj) {
|
|
8260
8376
|
}
|
8261
8377
|
|
8262
8378
|
|
8263
|
-
function parseAppUrl(relativeUrl, locationObj) {
|
8379
|
+
function parseAppUrl(relativeUrl, locationObj, appBase) {
|
8264
8380
|
var prefixed = (relativeUrl.charAt(0) !== '/');
|
8265
8381
|
if (prefixed) {
|
8266
8382
|
relativeUrl = '/' + relativeUrl;
|
8267
8383
|
}
|
8268
|
-
var match = urlResolve(relativeUrl);
|
8384
|
+
var match = urlResolve(relativeUrl, appBase);
|
8269
8385
|
locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ?
|
8270
8386
|
match.pathname.substring(1) : match.pathname);
|
8271
8387
|
locationObj.$$search = parseKeyValue(match.search);
|
@@ -8320,7 +8436,7 @@ function LocationHtml5Url(appBase, basePrefix) {
|
|
8320
8436
|
this.$$html5 = true;
|
8321
8437
|
basePrefix = basePrefix || '';
|
8322
8438
|
var appBaseNoFile = stripFile(appBase);
|
8323
|
-
parseAbsoluteUrl(appBase, this);
|
8439
|
+
parseAbsoluteUrl(appBase, this, appBase);
|
8324
8440
|
|
8325
8441
|
|
8326
8442
|
/**
|
@@ -8335,7 +8451,7 @@ function LocationHtml5Url(appBase, basePrefix) {
|
|
8335
8451
|
appBaseNoFile);
|
8336
8452
|
}
|
8337
8453
|
|
8338
|
-
parseAppUrl(pathUrl, this);
|
8454
|
+
parseAppUrl(pathUrl, this, appBase);
|
8339
8455
|
|
8340
8456
|
if (!this.$$path) {
|
8341
8457
|
this.$$path = '/';
|
@@ -8387,7 +8503,7 @@ function LocationHtml5Url(appBase, basePrefix) {
|
|
8387
8503
|
function LocationHashbangUrl(appBase, hashPrefix) {
|
8388
8504
|
var appBaseNoFile = stripFile(appBase);
|
8389
8505
|
|
8390
|
-
parseAbsoluteUrl(appBase, this);
|
8506
|
+
parseAbsoluteUrl(appBase, this, appBase);
|
8391
8507
|
|
8392
8508
|
|
8393
8509
|
/**
|
@@ -8407,8 +8523,48 @@ function LocationHashbangUrl(appBase, hashPrefix) {
|
|
8407
8523
|
throw $locationMinErr('ihshprfx', 'Invalid url "{0}", missing hash prefix "{1}".', url,
|
8408
8524
|
hashPrefix);
|
8409
8525
|
}
|
8410
|
-
parseAppUrl(withoutHashUrl, this);
|
8526
|
+
parseAppUrl(withoutHashUrl, this, appBase);
|
8527
|
+
|
8528
|
+
this.$$path = removeWindowsDriveName(this.$$path, withoutHashUrl, appBase);
|
8529
|
+
|
8411
8530
|
this.$$compose();
|
8531
|
+
|
8532
|
+
/*
|
8533
|
+
* In Windows, on an anchor node on documents loaded from
|
8534
|
+
* the filesystem, the browser will return a pathname
|
8535
|
+
* prefixed with the drive name ('/C:/path') when a
|
8536
|
+
* pathname without a drive is set:
|
8537
|
+
* * a.setAttribute('href', '/foo')
|
8538
|
+
* * a.pathname === '/C:/foo' //true
|
8539
|
+
*
|
8540
|
+
* Inside of Angular, we're always using pathnames that
|
8541
|
+
* do not include drive names for routing.
|
8542
|
+
*/
|
8543
|
+
function removeWindowsDriveName (path, url, base) {
|
8544
|
+
/*
|
8545
|
+
Matches paths for file protocol on windows,
|
8546
|
+
such as /C:/foo/bar, and captures only /foo/bar.
|
8547
|
+
*/
|
8548
|
+
var windowsFilePathExp = /^\/?.*?:(\/.*)/;
|
8549
|
+
|
8550
|
+
var firstPathSegmentMatch;
|
8551
|
+
|
8552
|
+
//Get the relative path from the input URL.
|
8553
|
+
if (url.indexOf(base) === 0) {
|
8554
|
+
url = url.replace(base, '');
|
8555
|
+
}
|
8556
|
+
|
8557
|
+
/*
|
8558
|
+
* The input URL intentionally contains a
|
8559
|
+
* first path segment that ends with a colon.
|
8560
|
+
*/
|
8561
|
+
if (windowsFilePathExp.exec(url)) {
|
8562
|
+
return path;
|
8563
|
+
}
|
8564
|
+
|
8565
|
+
firstPathSegmentMatch = windowsFilePathExp.exec(path);
|
8566
|
+
return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path;
|
8567
|
+
}
|
8412
8568
|
};
|
8413
8569
|
|
8414
8570
|
/**
|
@@ -8898,7 +9054,7 @@ function $LocationProvider(){
|
|
8898
9054
|
*
|
8899
9055
|
* The main purpose of this service is to simplify debugging and troubleshooting.
|
8900
9056
|
*
|
8901
|
-
* The default is
|
9057
|
+
* The default is to log `debug` messages. You can use
|
8902
9058
|
* {@link ng.$logProvider ng.$logProvider#debugEnabled} to change this.
|
8903
9059
|
*
|
8904
9060
|
* @example
|
@@ -9055,23 +9211,18 @@ var promiseWarning;
|
|
9055
9211
|
// ------------------------------
|
9056
9212
|
// Angular expressions are generally considered safe because these expressions only have direct
|
9057
9213
|
// access to $scope and locals. However, one can obtain the ability to execute arbitrary JS code by
|
9058
|
-
// obtaining a reference to native JS functions such as the Function constructor
|
9059
|
-
// or Document object. In addition, many powerful functions for use by JavaScript code are
|
9060
|
-
// published on scope that shouldn't be available from within an Angular expression.
|
9214
|
+
// obtaining a reference to native JS functions such as the Function constructor.
|
9061
9215
|
//
|
9062
9216
|
// As an example, consider the following Angular expression:
|
9063
9217
|
//
|
9064
9218
|
// {}.toString.constructor(alert("evil JS code"))
|
9065
9219
|
//
|
9066
9220
|
// We want to prevent this type of access. For the sake of performance, during the lexing phase we
|
9067
|
-
// disallow any "dotted" access to any member named "constructor"
|
9068
|
-
// or ends with an underscore. The latter allows one to exclude the private / JavaScript only API
|
9069
|
-
// available on the scope and controllers from the context of an Angular expression.
|
9221
|
+
// disallow any "dotted" access to any member named "constructor".
|
9070
9222
|
//
|
9071
|
-
// For reflective calls (a[b])
|
9072
|
-
//
|
9073
|
-
//
|
9074
|
-
// to static dereferencing.
|
9223
|
+
// For reflective calls (a[b]) we check that the value of the lookup is not the Function constructor
|
9224
|
+
// while evaluating the expression, which is a stronger but more expensive test. Since reflective
|
9225
|
+
// calls are expensive anyway, this is not such a big deal compared to static dereferencing.
|
9075
9226
|
//
|
9076
9227
|
// This sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits
|
9077
9228
|
// against the expression language, but not to prevent exploits that were enabled by exposing
|
@@ -9085,20 +9236,12 @@ var promiseWarning;
|
|
9085
9236
|
// In general, it is not possible to access a Window object from an angular expression unless a
|
9086
9237
|
// window or some DOM object that has a reference to window is published onto a Scope.
|
9087
9238
|
|
9088
|
-
function ensureSafeMemberName(name, fullExpression
|
9089
|
-
if (
|
9090
|
-
return name;
|
9091
|
-
}
|
9092
|
-
if (name === "constructor" && !allowConstructor) {
|
9239
|
+
function ensureSafeMemberName(name, fullExpression) {
|
9240
|
+
if (name === "constructor") {
|
9093
9241
|
throw $parseMinErr('isecfld',
|
9094
9242
|
'Referencing "constructor" field in Angular expressions is disallowed! Expression: {0}',
|
9095
9243
|
fullExpression);
|
9096
9244
|
}
|
9097
|
-
if (name.charAt(0) === '_' || name.charAt(name.length-1) === '_') {
|
9098
|
-
throw $parseMinErr('isecprv',
|
9099
|
-
'Referencing private fields in Angular expressions is disallowed! Expression: {0}',
|
9100
|
-
fullExpression);
|
9101
|
-
}
|
9102
9245
|
return name;
|
9103
9246
|
}
|
9104
9247
|
|
@@ -9782,10 +9925,7 @@ Parser.prototype = {
|
|
9782
9925
|
|
9783
9926
|
return extend(function(self, locals) {
|
9784
9927
|
var o = obj(self, locals),
|
9785
|
-
|
9786
|
-
// constructors. However, if value looked up is the Function constructor, we will still block it in the
|
9787
|
-
// ensureSafeObject call right after we look up o[i] (a few lines below.)
|
9788
|
-
i = ensureSafeMemberName(indexFn(self, locals), parser.text, true /* allowConstructor */),
|
9928
|
+
i = indexFn(self, locals),
|
9789
9929
|
v, p;
|
9790
9930
|
|
9791
9931
|
if (!o) return undefined;
|
@@ -9801,7 +9941,7 @@ Parser.prototype = {
|
|
9801
9941
|
return v;
|
9802
9942
|
}, {
|
9803
9943
|
assign: function(self, value, locals) {
|
9804
|
-
var key =
|
9944
|
+
var key = indexFn(self, locals);
|
9805
9945
|
// prevent overwriting of Function.constructor which would break ensureSafeObject check
|
9806
9946
|
var safe = ensureSafeObject(obj(self, locals), parser.text);
|
9807
9947
|
return safe[key] = value;
|
@@ -10080,7 +10220,7 @@ function getterFn(path, options, fullExp) {
|
|
10080
10220
|
: '((k&&k.hasOwnProperty("' + key + '"))?k:s)') + '["' + key + '"]' + ';\n' +
|
10081
10221
|
(options.unwrapPromises
|
10082
10222
|
? 'if (s && s.then) {\n' +
|
10083
|
-
' pw("' + fullExp.replace(
|
10223
|
+
' pw("' + fullExp.replace(/(["\r\n])/g, '\\$1') + '");\n' +
|
10084
10224
|
' if (!("$$v" in s)) {\n' +
|
10085
10225
|
' p=s;\n' +
|
10086
10226
|
' p.$$v = undefined;\n' +
|
@@ -10461,7 +10601,7 @@ function $ParseProvider() {
|
|
10461
10601
|
* // Propagate promise resolution to 'then' functions using $apply().
|
10462
10602
|
* $rootScope.$apply();
|
10463
10603
|
* expect(resolvedValue).toEqual(123);
|
10464
|
-
* });
|
10604
|
+
* }));
|
10465
10605
|
* </pre>
|
10466
10606
|
*/
|
10467
10607
|
function $QProvider() {
|
@@ -11851,6 +11991,79 @@ function $RootScopeProvider(){
|
|
11851
11991
|
}];
|
11852
11992
|
}
|
11853
11993
|
|
11994
|
+
/**
|
11995
|
+
* @description
|
11996
|
+
* Private service to sanitize uris for links and images. Used by $compile and $sanitize.
|
11997
|
+
*/
|
11998
|
+
function $$SanitizeUriProvider() {
|
11999
|
+
var aHrefSanitizationWhitelist = /^\s*(https?|ftp|mailto|tel|file):/,
|
12000
|
+
imgSrcSanitizationWhitelist = /^\s*(https?|ftp|file):|data:image\//;
|
12001
|
+
|
12002
|
+
/**
|
12003
|
+
* @description
|
12004
|
+
* Retrieves or overrides the default regular expression that is used for whitelisting of safe
|
12005
|
+
* urls during a[href] sanitization.
|
12006
|
+
*
|
12007
|
+
* The sanitization is a security measure aimed at prevent XSS attacks via html links.
|
12008
|
+
*
|
12009
|
+
* Any url about to be assigned to a[href] via data-binding is first normalized and turned into
|
12010
|
+
* an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`
|
12011
|
+
* regular expression. If a match is found, the original url is written into the dom. Otherwise,
|
12012
|
+
* the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
|
12013
|
+
*
|
12014
|
+
* @param {RegExp=} regexp New regexp to whitelist urls with.
|
12015
|
+
* @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
|
12016
|
+
* chaining otherwise.
|
12017
|
+
*/
|
12018
|
+
this.aHrefSanitizationWhitelist = function(regexp) {
|
12019
|
+
if (isDefined(regexp)) {
|
12020
|
+
aHrefSanitizationWhitelist = regexp;
|
12021
|
+
return this;
|
12022
|
+
}
|
12023
|
+
return aHrefSanitizationWhitelist;
|
12024
|
+
};
|
12025
|
+
|
12026
|
+
|
12027
|
+
/**
|
12028
|
+
* @description
|
12029
|
+
* Retrieves or overrides the default regular expression that is used for whitelisting of safe
|
12030
|
+
* urls during img[src] sanitization.
|
12031
|
+
*
|
12032
|
+
* The sanitization is a security measure aimed at prevent XSS attacks via html links.
|
12033
|
+
*
|
12034
|
+
* Any url about to be assigned to img[src] via data-binding is first normalized and turned into
|
12035
|
+
* an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist`
|
12036
|
+
* regular expression. If a match is found, the original url is written into the dom. Otherwise,
|
12037
|
+
* the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
|
12038
|
+
*
|
12039
|
+
* @param {RegExp=} regexp New regexp to whitelist urls with.
|
12040
|
+
* @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
|
12041
|
+
* chaining otherwise.
|
12042
|
+
*/
|
12043
|
+
this.imgSrcSanitizationWhitelist = function(regexp) {
|
12044
|
+
if (isDefined(regexp)) {
|
12045
|
+
imgSrcSanitizationWhitelist = regexp;
|
12046
|
+
return this;
|
12047
|
+
}
|
12048
|
+
return imgSrcSanitizationWhitelist;
|
12049
|
+
};
|
12050
|
+
|
12051
|
+
this.$get = function() {
|
12052
|
+
return function sanitizeUri(uri, isImage) {
|
12053
|
+
var regex = isImage ? imgSrcSanitizationWhitelist : aHrefSanitizationWhitelist;
|
12054
|
+
var normalizedVal;
|
12055
|
+
// NOTE: urlResolve() doesn't support IE < 8 so we don't sanitize for that case.
|
12056
|
+
if (!msie || msie >= 8 ) {
|
12057
|
+
normalizedVal = urlResolve(uri).href;
|
12058
|
+
if (normalizedVal !== '' && !normalizedVal.match(regex)) {
|
12059
|
+
return 'unsafe:'+normalizedVal;
|
12060
|
+
}
|
12061
|
+
}
|
12062
|
+
return uri;
|
12063
|
+
};
|
12064
|
+
};
|
12065
|
+
}
|
12066
|
+
|
11854
12067
|
var $sceMinErr = minErr('$sce');
|
11855
12068
|
|
11856
12069
|
var SCE_CONTEXTS = {
|
@@ -12050,8 +12263,7 @@ function $SceDelegateProvider() {
|
|
12050
12263
|
return resourceUrlBlacklist;
|
12051
12264
|
};
|
12052
12265
|
|
12053
|
-
this.$get = ['$
|
12054
|
-
$log, $document, $injector) {
|
12266
|
+
this.$get = ['$injector', function($injector) {
|
12055
12267
|
|
12056
12268
|
var htmlSanitizer = function htmlSanitizer(html) {
|
12057
12269
|
throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');
|
@@ -12278,10 +12490,10 @@ function $SceDelegateProvider() {
|
|
12278
12490
|
*
|
12279
12491
|
* <pre class="prettyprint">
|
12280
12492
|
* <input ng-model="userHtml">
|
12281
|
-
* <div ng-bind-html="
|
12493
|
+
* <div ng-bind-html="userHtml">
|
12282
12494
|
* </pre>
|
12283
12495
|
*
|
12284
|
-
* Notice that `ng-bind-html` is bound to `
|
12496
|
+
* Notice that `ng-bind-html` is bound to `userHtml` controlled by the user. With SCE
|
12285
12497
|
* disabled, this application allows the user to render arbitrary HTML into the DIV.
|
12286
12498
|
* In a more realistic example, one may be rendering user comments, blog articles, etc. via
|
12287
12499
|
* bindings. (HTML is just one example of a context where rendering user controlled input creates
|
@@ -12582,18 +12794,15 @@ function $SceProvider() {
|
|
12582
12794
|
* sce.js and sceSpecs.js would need to be aware of this detail.
|
12583
12795
|
*/
|
12584
12796
|
|
12585
|
-
this.$get = ['$parse', '$
|
12586
|
-
$parse, $
|
12797
|
+
this.$get = ['$parse', '$sniffer', '$sceDelegate', function(
|
12798
|
+
$parse, $sniffer, $sceDelegate) {
|
12587
12799
|
// Prereq: Ensure that we're not running in IE8 quirks mode. In that mode, IE allows
|
12588
12800
|
// the "expression(javascript expression)" syntax which is insecure.
|
12589
|
-
if (enabled && msie) {
|
12590
|
-
|
12591
|
-
|
12592
|
-
|
12593
|
-
|
12594
|
-
'mode. You can fix this by adding the text <!doctype html> to the top of your HTML ' +
|
12595
|
-
'document. See http://docs.angularjs.org/api/ng.$sce for more information.');
|
12596
|
-
}
|
12801
|
+
if (enabled && $sniffer.msie && $sniffer.msieDocumentMode < 8) {
|
12802
|
+
throw $sceMinErr('iequirks',
|
12803
|
+
'Strict Contextual Escaping does not support Internet Explorer version < 9 in quirks ' +
|
12804
|
+
'mode. You can fix this by adding the text <!doctype html> to the top of your HTML ' +
|
12805
|
+
'document. See http://docs.angularjs.org/api/ng.$sce for more information.');
|
12597
12806
|
}
|
12598
12807
|
|
12599
12808
|
var sce = copy(SCE_CONTEXTS);
|
@@ -12955,6 +13164,7 @@ function $SnifferProvider() {
|
|
12955
13164
|
int((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),
|
12956
13165
|
boxee = /Boxee/i.test(($window.navigator || {}).userAgent),
|
12957
13166
|
document = $document[0] || {},
|
13167
|
+
documentMode = document.documentMode,
|
12958
13168
|
vendorPrefix,
|
12959
13169
|
vendorRegex = /^(Moz|webkit|O|ms)(?=[A-Z])/,
|
12960
13170
|
bodyStyle = document.body && document.body.style,
|
@@ -12999,7 +13209,7 @@ function $SnifferProvider() {
|
|
12999
13209
|
// jshint +W018
|
13000
13210
|
hashchange: 'onhashchange' in $window &&
|
13001
13211
|
// IE8 compatible mode lies
|
13002
|
-
(!
|
13212
|
+
(!documentMode || documentMode > 7),
|
13003
13213
|
hasEvent: function(event) {
|
13004
13214
|
// IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
|
13005
13215
|
// it. In particular the event is not fired when backspace or delete key are pressed or
|
@@ -13017,7 +13227,8 @@ function $SnifferProvider() {
|
|
13017
13227
|
vendorPrefix: vendorPrefix,
|
13018
13228
|
transitions : transitions,
|
13019
13229
|
animations : animations,
|
13020
|
-
msie : msie
|
13230
|
+
msie : msie,
|
13231
|
+
msieDocumentMode: documentMode
|
13021
13232
|
};
|
13022
13233
|
}];
|
13023
13234
|
}
|
@@ -13204,6 +13415,7 @@ function $TimeoutProvider() {
|
|
13204
13415
|
var urlParsingNode = document.createElement("a");
|
13205
13416
|
var originUrl = urlResolve(window.location.href, true);
|
13206
13417
|
|
13418
|
+
|
13207
13419
|
/**
|
13208
13420
|
*
|
13209
13421
|
* Implementation Notes for non-IE browsers
|
@@ -13222,7 +13434,7 @@ var originUrl = urlResolve(window.location.href, true);
|
|
13222
13434
|
* browsers. However, the parsed components will not be set if the URL assigned did not specify
|
13223
13435
|
* them. (e.g. if you assign a.href = "foo", then a.protocol, a.host, etc. will be empty.) We
|
13224
13436
|
* work around that by performing the parsing in a 2nd step by taking a previously normalized
|
13225
|
-
* URL (e.g. by
|
13437
|
+
* URL (e.g. by assigning to a.href) and assigning it a.href again. This correctly populates the
|
13226
13438
|
* properties such as protocol, hostname, port, etc.
|
13227
13439
|
*
|
13228
13440
|
* IE7 does not normalize the URL when assigned to an anchor node. (Apparently, it does, if one
|
@@ -13256,8 +13468,9 @@ var originUrl = urlResolve(window.location.href, true);
|
|
13256
13468
|
* | pathname | The pathname, beginning with "/"
|
13257
13469
|
*
|
13258
13470
|
*/
|
13259
|
-
function urlResolve(url) {
|
13471
|
+
function urlResolve(url, base) {
|
13260
13472
|
var href = url;
|
13473
|
+
|
13261
13474
|
if (msie) {
|
13262
13475
|
// Normalize before parse. Refer Implementation Notes on why this is
|
13263
13476
|
// done in two steps on IE.
|
@@ -13267,7 +13480,7 @@ function urlResolve(url) {
|
|
13267
13480
|
|
13268
13481
|
urlParsingNode.setAttribute('href', href);
|
13269
13482
|
|
13270
|
-
//
|
13483
|
+
// urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
|
13271
13484
|
return {
|
13272
13485
|
href: urlParsingNode.href,
|
13273
13486
|
protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
|
@@ -13276,12 +13489,12 @@ function urlResolve(url) {
|
|
13276
13489
|
hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
|
13277
13490
|
hostname: urlParsingNode.hostname,
|
13278
13491
|
port: urlParsingNode.port,
|
13279
|
-
pathname: urlParsingNode.pathname
|
13280
|
-
|
13492
|
+
pathname: (urlParsingNode.pathname.charAt(0) === '/')
|
13493
|
+
? urlParsingNode.pathname
|
13494
|
+
: '/' + urlParsingNode.pathname
|
13281
13495
|
};
|
13282
13496
|
}
|
13283
13497
|
|
13284
|
-
|
13285
13498
|
/**
|
13286
13499
|
* Parse a request URL and determine whether this is a same-origin request as the application document.
|
13287
13500
|
*
|
@@ -14590,8 +14803,11 @@ var htmlAnchorDirective = valueFn({
|
|
14590
14803
|
*
|
14591
14804
|
* The HTML specification does not require browsers to preserve the values of boolean attributes
|
14592
14805
|
* such as disabled. (Their presence means true and their absence means false.)
|
14593
|
-
*
|
14806
|
+
* If we put an Angular interpolation expression into such an attribute then the
|
14807
|
+
* binding information would be lost when the browser removes the attribute.
|
14594
14808
|
* The `ngDisabled` directive solves this problem for the `disabled` attribute.
|
14809
|
+
* This complementary directive is not removed by the browser and so provides
|
14810
|
+
* a permanent reliable place to store the binding information.
|
14595
14811
|
*
|
14596
14812
|
* @example
|
14597
14813
|
<doc:example>
|
@@ -14622,8 +14838,11 @@ var htmlAnchorDirective = valueFn({
|
|
14622
14838
|
* @description
|
14623
14839
|
* The HTML specification does not require browsers to preserve the values of boolean attributes
|
14624
14840
|
* such as checked. (Their presence means true and their absence means false.)
|
14625
|
-
*
|
14841
|
+
* If we put an Angular interpolation expression into such an attribute then the
|
14842
|
+
* binding information would be lost when the browser removes the attribute.
|
14626
14843
|
* The `ngChecked` directive solves this problem for the `checked` attribute.
|
14844
|
+
* This complementary directive is not removed by the browser and so provides
|
14845
|
+
* a permanent reliable place to store the binding information.
|
14627
14846
|
* @example
|
14628
14847
|
<doc:example>
|
14629
14848
|
<doc:source>
|
@@ -14653,8 +14872,12 @@ var htmlAnchorDirective = valueFn({
|
|
14653
14872
|
* @description
|
14654
14873
|
* The HTML specification does not require browsers to preserve the values of boolean attributes
|
14655
14874
|
* such as readonly. (Their presence means true and their absence means false.)
|
14656
|
-
*
|
14875
|
+
* If we put an Angular interpolation expression into such an attribute then the
|
14876
|
+
* binding information would be lost when the browser removes the attribute.
|
14657
14877
|
* The `ngReadonly` directive solves this problem for the `readonly` attribute.
|
14878
|
+
* This complementary directive is not removed by the browser and so provides
|
14879
|
+
* a permanent reliable place to store the binding information.
|
14880
|
+
|
14658
14881
|
* @example
|
14659
14882
|
<doc:example>
|
14660
14883
|
<doc:source>
|
@@ -14684,8 +14907,11 @@ var htmlAnchorDirective = valueFn({
|
|
14684
14907
|
* @description
|
14685
14908
|
* The HTML specification does not require browsers to preserve the values of boolean attributes
|
14686
14909
|
* such as selected. (Their presence means true and their absence means false.)
|
14687
|
-
*
|
14910
|
+
* If we put an Angular interpolation expression into such an attribute then the
|
14911
|
+
* binding information would be lost when the browser removes the attribute.
|
14688
14912
|
* The `ngSelected` directive solves this problem for the `selected` atttribute.
|
14913
|
+
* This complementary directive is not removed by the browser and so provides
|
14914
|
+
* a permanent reliable place to store the binding information.
|
14689
14915
|
* @example
|
14690
14916
|
<doc:example>
|
14691
14917
|
<doc:source>
|
@@ -14717,8 +14943,12 @@ var htmlAnchorDirective = valueFn({
|
|
14717
14943
|
* @description
|
14718
14944
|
* The HTML specification does not require browsers to preserve the values of boolean attributes
|
14719
14945
|
* such as open. (Their presence means true and their absence means false.)
|
14720
|
-
*
|
14946
|
+
* If we put an Angular interpolation expression into such an attribute then the
|
14947
|
+
* binding information would be lost when the browser removes the attribute.
|
14721
14948
|
* The `ngOpen` directive solves this problem for the `open` attribute.
|
14949
|
+
* This complementary directive is not removed by the browser and so provides
|
14950
|
+
* a permanent reliable place to store the binding information.
|
14951
|
+
|
14722
14952
|
*
|
14723
14953
|
* @example
|
14724
14954
|
<doc:example>
|
@@ -14811,7 +15041,7 @@ var nullFormCtrl = {
|
|
14811
15041
|
* @property {Object} $error Is an object hash, containing references to all invalid controls or
|
14812
15042
|
* forms, where:
|
14813
15043
|
*
|
14814
|
-
* - keys are validation tokens (error names) — such as `required`, `url` or `email
|
15044
|
+
* - keys are validation tokens (error names) — such as `required`, `url` or `email`,
|
14815
15045
|
* - values are arrays of controls or forms that are invalid with given error.
|
14816
15046
|
*
|
14817
15047
|
* @description
|
@@ -15548,8 +15778,21 @@ var inputType = {
|
|
15548
15778
|
|
15549
15779
|
|
15550
15780
|
function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
15781
|
+
// In composition mode, users are still inputing intermediate text buffer,
|
15782
|
+
// hold the listener until composition is done.
|
15783
|
+
// More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
|
15784
|
+
var composing = false;
|
15785
|
+
|
15786
|
+
element.on('compositionstart', function() {
|
15787
|
+
composing = true;
|
15788
|
+
});
|
15789
|
+
|
15790
|
+
element.on('compositionend', function() {
|
15791
|
+
composing = false;
|
15792
|
+
});
|
15551
15793
|
|
15552
15794
|
var listener = function() {
|
15795
|
+
if (composing) return;
|
15553
15796
|
var value = element.val();
|
15554
15797
|
|
15555
15798
|
// By default we will trim the value
|
@@ -15592,15 +15835,15 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|
15592
15835
|
deferListener();
|
15593
15836
|
});
|
15594
15837
|
|
15595
|
-
// if user paste into input using mouse, we need "change" event to catch it
|
15596
|
-
element.on('change', listener);
|
15597
|
-
|
15598
15838
|
// if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it
|
15599
15839
|
if ($sniffer.hasEvent('paste')) {
|
15600
15840
|
element.on('paste cut', deferListener);
|
15601
15841
|
}
|
15602
15842
|
}
|
15603
15843
|
|
15844
|
+
// if user paste into input using mouse on older browser
|
15845
|
+
// or form autocomplete on newer browser, we need "change" event to catch it
|
15846
|
+
element.on('change', listener);
|
15604
15847
|
|
15605
15848
|
ctrl.$render = function() {
|
15606
15849
|
element.val(ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue);
|
@@ -15996,6 +16239,11 @@ var VALID_CLASS = 'ng-valid',
|
|
15996
16239
|
* }
|
15997
16240
|
* ngModel.$formatters.push(formatter);
|
15998
16241
|
* </pre>
|
16242
|
+
*
|
16243
|
+
* @property {Array.<Function>} $viewChangeListeners Array of functions to execute whenever the
|
16244
|
+
* view value has changed. It is called with no arguments, and its return value is ignored.
|
16245
|
+
* This can be used in place of additional $watches against the model value.
|
16246
|
+
*
|
15999
16247
|
* @property {Object} $error An object hash with all errors as keys.
|
16000
16248
|
*
|
16001
16249
|
* @property {boolean} $pristine True if user has not interacted with the control yet.
|
@@ -16259,14 +16507,19 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
16259
16507
|
* @methodOf ng.directive:ngModel.NgModelController
|
16260
16508
|
*
|
16261
16509
|
* @description
|
16262
|
-
*
|
16510
|
+
* Update the view value.
|
16263
16511
|
*
|
16264
|
-
* This method should be called from within a DOM event handler.
|
16265
|
-
* For example {@link ng.directive:input input}
|
16512
|
+
* This method should be called when the view value changes, typically from within a DOM event handler.
|
16513
|
+
* For example {@link ng.directive:input input} and
|
16266
16514
|
* {@link ng.directive:select select} directives call it.
|
16267
16515
|
*
|
16268
|
-
* It
|
16269
|
-
*
|
16516
|
+
* It will update the $viewValue, then pass this value through each of the functions in `$parsers`,
|
16517
|
+
* which includes any validators. The value that comes out of this `$parsers` pipeline, be applied to
|
16518
|
+
* `$modelValue` and the **expression** specified in the `ng-model` attribute.
|
16519
|
+
*
|
16520
|
+
* Lastly, all the registered change listeners, in the `$viewChangeListeners` list, are called.
|
16521
|
+
*
|
16522
|
+
* Note that calling this function does not trigger a `$digest`.
|
16270
16523
|
*
|
16271
16524
|
* @param {string} value Value from the view.
|
16272
16525
|
*/
|
@@ -16768,27 +17021,33 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
|
|
16768
17021
|
* @param {expression} ngBindHtml {@link guide/expression Expression} to evaluate.
|
16769
17022
|
*
|
16770
17023
|
* @example
|
16771
|
-
|
16772
|
-
|
16773
|
-
|
16774
|
-
|
16775
|
-
angular.module('ngBindHtmlExample', ['ngSanitize'])
|
16776
|
-
|
16777
|
-
.controller('ngBindHtmlCtrl', ['$scope', function ngBindHtmlCtrl($scope) {
|
16778
|
-
$scope.myHTML = 'I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em>';
|
16779
|
-
}]);
|
16780
|
-
</script>
|
17024
|
+
Try it here: enter text in text box and watch the greeting change.
|
17025
|
+
|
17026
|
+
<example module="ngBindHtmlExample" deps="angular-sanitize.js">
|
17027
|
+
<file name="index.html">
|
16781
17028
|
<div ng-controller="ngBindHtmlCtrl">
|
16782
17029
|
<p ng-bind-html="myHTML"></p>
|
16783
17030
|
</div>
|
16784
|
-
</
|
16785
|
-
|
17031
|
+
</file>
|
17032
|
+
|
17033
|
+
<file name="script.js">
|
17034
|
+
angular.module('ngBindHtmlExample', ['ngSanitize'])
|
17035
|
+
|
17036
|
+
.controller('ngBindHtmlCtrl', ['$scope', function ngBindHtmlCtrl($scope) {
|
17037
|
+
$scope.myHTML =
|
17038
|
+
'I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em>';
|
17039
|
+
}]);
|
17040
|
+
</file>
|
17041
|
+
|
17042
|
+
<file name="scenario.js">
|
16786
17043
|
it('should check ng-bind-html', function() {
|
16787
17044
|
expect(using('.doc-example-live').binding('myHTML')).
|
16788
|
-
toBe(
|
17045
|
+
toBe(
|
17046
|
+
'I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em>'
|
17047
|
+
);
|
16789
17048
|
});
|
16790
|
-
</
|
16791
|
-
</
|
17049
|
+
</file>
|
17050
|
+
</example>
|
16792
17051
|
*/
|
16793
17052
|
var ngBindHtmlDirective = ['$sce', '$parse', function($sce, $parse) {
|
16794
17053
|
return function(scope, element, attr) {
|
@@ -16823,11 +17082,10 @@ function classDirective(name, selector) {
|
|
16823
17082
|
// jshint bitwise: false
|
16824
17083
|
var mod = $index & 1;
|
16825
17084
|
if (mod !== old$index & 1) {
|
16826
|
-
|
16827
|
-
|
16828
|
-
|
16829
|
-
removeClass(
|
16830
|
-
}
|
17085
|
+
var classes = flattenClasses(scope.$eval(attr[name]));
|
17086
|
+
mod === selector ?
|
17087
|
+
attr.$addClass(classes) :
|
17088
|
+
attr.$removeClass(classes);
|
16831
17089
|
}
|
16832
17090
|
});
|
16833
17091
|
}
|
@@ -16835,24 +17093,17 @@ function classDirective(name, selector) {
|
|
16835
17093
|
|
16836
17094
|
function ngClassWatchAction(newVal) {
|
16837
17095
|
if (selector === true || scope.$index % 2 === selector) {
|
16838
|
-
|
16839
|
-
|
17096
|
+
var newClasses = flattenClasses(newVal || '');
|
17097
|
+
if(!oldVal) {
|
17098
|
+
attr.$addClass(newClasses);
|
17099
|
+
} else if(!equals(newVal,oldVal)) {
|
17100
|
+
attr.$updateClass(newClasses, flattenClasses(oldVal));
|
16840
17101
|
}
|
16841
|
-
addClass(newVal);
|
16842
17102
|
}
|
16843
17103
|
oldVal = copy(newVal);
|
16844
17104
|
}
|
16845
17105
|
|
16846
17106
|
|
16847
|
-
function removeClass(classVal) {
|
16848
|
-
attr.$removeClass(flattenClasses(classVal));
|
16849
|
-
}
|
16850
|
-
|
16851
|
-
|
16852
|
-
function addClass(classVal) {
|
16853
|
-
attr.$addClass(flattenClasses(classVal));
|
16854
|
-
}
|
16855
|
-
|
16856
17107
|
function flattenClasses(classVal) {
|
16857
17108
|
if(isArray(classVal)) {
|
16858
17109
|
return classVal.join(' ');
|
@@ -16901,18 +17152,18 @@ function classDirective(name, selector) {
|
|
16901
17152
|
* @example Example that demonstrates basic bindings via ngClass directive.
|
16902
17153
|
<example>
|
16903
17154
|
<file name="index.html">
|
16904
|
-
<p ng-class="{strike:
|
16905
|
-
<input type="checkbox" ng-model="
|
16906
|
-
<input type="checkbox" ng-model="
|
16907
|
-
<input type="checkbox" ng-model="
|
17155
|
+
<p ng-class="{strike: deleted, bold: important, red: error}">Map Syntax Example</p>
|
17156
|
+
<input type="checkbox" ng-model="deleted"> deleted (apply "strike" class)<br>
|
17157
|
+
<input type="checkbox" ng-model="important"> important (apply "bold" class)<br>
|
17158
|
+
<input type="checkbox" ng-model="error"> error (apply "red" class)
|
16908
17159
|
<hr>
|
16909
17160
|
<p ng-class="style">Using String Syntax</p>
|
16910
17161
|
<input type="text" ng-model="style" placeholder="Type: bold strike red">
|
16911
17162
|
<hr>
|
16912
17163
|
<p ng-class="[style1, style2, style3]">Using Array Syntax</p>
|
16913
|
-
<input ng-model="style1" placeholder="Type: bold"><br>
|
16914
|
-
<input ng-model="style2" placeholder="Type: strike"><br>
|
16915
|
-
<input ng-model="style3" placeholder="Type: red"><br>
|
17164
|
+
<input ng-model="style1" placeholder="Type: bold, strike or red"><br>
|
17165
|
+
<input ng-model="style2" placeholder="Type: bold, strike or red"><br>
|
17166
|
+
<input ng-model="style3" placeholder="Type: bold, strike or red"><br>
|
16916
17167
|
</file>
|
16917
17168
|
<file name="style.css">
|
16918
17169
|
.strike {
|
@@ -16931,10 +17182,10 @@ function classDirective(name, selector) {
|
|
16931
17182
|
expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/bold/);
|
16932
17183
|
expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/red/);
|
16933
17184
|
|
16934
|
-
input('
|
17185
|
+
input('important').check();
|
16935
17186
|
expect(element('.doc-example-live p:first').prop('className')).toMatch(/bold/);
|
16936
17187
|
|
16937
|
-
input('
|
17188
|
+
input('error').check();
|
16938
17189
|
expect(element('.doc-example-live p:first').prop('className')).toMatch(/red/);
|
16939
17190
|
});
|
16940
17191
|
|
@@ -17330,7 +17581,8 @@ var ngCloakDirective = ngDirective({
|
|
17330
17581
|
var ngControllerDirective = [function() {
|
17331
17582
|
return {
|
17332
17583
|
scope: true,
|
17333
|
-
controller: '@'
|
17584
|
+
controller: '@',
|
17585
|
+
priority: 500
|
17334
17586
|
};
|
17335
17587
|
}];
|
17336
17588
|
|
@@ -17780,7 +18032,7 @@ forEach(
|
|
17780
18032
|
}
|
17781
18033
|
|
17782
18034
|
/*
|
17783
|
-
The transition styles can also be placed on the CSS base class above
|
18035
|
+
The transition styles can also be placed on the CSS base class above
|
17784
18036
|
*/
|
17785
18037
|
.animate-if.ng-enter, .animate-if.ng-leave {
|
17786
18038
|
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
@@ -17806,22 +18058,21 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
17806
18058
|
terminal: true,
|
17807
18059
|
restrict: 'A',
|
17808
18060
|
$$tlb: true,
|
17809
|
-
|
17810
|
-
return function ($scope, $element, $attr) {
|
18061
|
+
link: function ($scope, $element, $attr, ctrl, $transclude) {
|
17811
18062
|
var block, childScope;
|
17812
18063
|
$scope.$watch($attr.ngIf, function ngIfWatchAction(value) {
|
17813
18064
|
|
17814
18065
|
if (toBoolean(value)) {
|
17815
|
-
|
17816
|
-
|
17817
|
-
|
17818
|
-
|
17819
|
-
|
17820
|
-
|
17821
|
-
|
17822
|
-
|
17823
|
-
|
17824
|
-
|
18066
|
+
if (!childScope) {
|
18067
|
+
childScope = $scope.$new();
|
18068
|
+
$transclude(childScope, function (clone) {
|
18069
|
+
block = {
|
18070
|
+
startNode: clone[0],
|
18071
|
+
endNode: clone[clone.length++] = document.createComment(' end ngIf: ' + $attr.ngIf + ' ')
|
18072
|
+
};
|
18073
|
+
$animate.enter(clone, $element.parent(), $element);
|
18074
|
+
});
|
18075
|
+
}
|
17825
18076
|
} else {
|
17826
18077
|
|
17827
18078
|
if (childScope) {
|
@@ -17835,7 +18086,6 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
17835
18086
|
}
|
17836
18087
|
}
|
17837
18088
|
});
|
17838
|
-
};
|
17839
18089
|
}
|
17840
18090
|
};
|
17841
18091
|
}];
|
@@ -17994,12 +18244,12 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
|
|
17994
18244
|
priority: 400,
|
17995
18245
|
terminal: true,
|
17996
18246
|
transclude: 'element',
|
17997
|
-
compile: function(element, attr
|
18247
|
+
compile: function(element, attr) {
|
17998
18248
|
var srcExp = attr.ngInclude || attr.src,
|
17999
18249
|
onloadExp = attr.onload || '',
|
18000
18250
|
autoScrollExp = attr.autoscroll;
|
18001
18251
|
|
18002
|
-
return function(scope, $element) {
|
18252
|
+
return function(scope, $element, $attr, ctrl, $transclude) {
|
18003
18253
|
var changeCounter = 0,
|
18004
18254
|
currentScope,
|
18005
18255
|
currentElement;
|
@@ -18028,18 +18278,23 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
|
|
18028
18278
|
if (thisChangeId !== changeCounter) return;
|
18029
18279
|
var newScope = scope.$new();
|
18030
18280
|
|
18031
|
-
|
18032
|
-
|
18033
|
-
|
18034
|
-
|
18035
|
-
|
18036
|
-
|
18037
|
-
|
18038
|
-
|
18039
|
-
|
18040
|
-
|
18041
|
-
|
18042
|
-
|
18281
|
+
// Note: This will also link all children of ng-include that were contained in the original
|
18282
|
+
// html. If that content contains controllers, ... they could pollute/change the scope.
|
18283
|
+
// However, using ng-include on an element with additional content does not make sense...
|
18284
|
+
// Note: We can't remove them in the cloneAttchFn of $transclude as that
|
18285
|
+
// function is called before linking the content, which would apply child
|
18286
|
+
// directives to non existing elements.
|
18287
|
+
var clone = $transclude(newScope, noop);
|
18288
|
+
cleanupLastIncludeContent();
|
18289
|
+
|
18290
|
+
currentScope = newScope;
|
18291
|
+
currentElement = clone;
|
18292
|
+
|
18293
|
+
currentElement.html(response);
|
18294
|
+
$animate.enter(currentElement, null, $element, afterAnimation);
|
18295
|
+
$compile(currentElement.contents())(currentScope);
|
18296
|
+
currentScope.$emit('$includeContentLoaded');
|
18297
|
+
scope.$eval(onloadExp);
|
18043
18298
|
}).error(function() {
|
18044
18299
|
if (thisChangeId === changeCounter) cleanupLastIncludeContent();
|
18045
18300
|
});
|
@@ -18194,7 +18449,7 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
|
|
18194
18449
|
* other numbers, for example 12, so that instead of showing "12 people are viewing", you can
|
18195
18450
|
* show "a dozen people are viewing".
|
18196
18451
|
*
|
18197
|
-
* You can use a set of closed braces(`{}`) as a placeholder for the number that you want substituted
|
18452
|
+
* You can use a set of closed braces (`{}`) as a placeholder for the number that you want substituted
|
18198
18453
|
* into pluralized strings. In the previous example, Angular will replace `{}` with
|
18199
18454
|
* <span ng-non-bindable>`{{personCount}}`</span>. The closed braces `{}` is a placeholder
|
18200
18455
|
* for <span ng-non-bindable>{{numberExpression}}</span>.
|
@@ -18455,7 +18710,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
|
|
18455
18710
|
* For example: `item in items track by $id(item)`. A built in `$id()` function can be used to assign a unique
|
18456
18711
|
* `$$hashKey` property to each item in the array. This property is then used as a key to associated DOM elements
|
18457
18712
|
* with the corresponding item in the array by identity. Moving the same object in array would move the DOM
|
18458
|
-
* element in the same way
|
18713
|
+
* element in the same way in the DOM.
|
18459
18714
|
*
|
18460
18715
|
* For example: `item in items track by item.id` is a typical pattern when the items come from the database. In this
|
18461
18716
|
* case the object identity does not matter. Two objects are considered equivalent as long as their `id`
|
@@ -18557,8 +18812,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
18557
18812
|
priority: 1000,
|
18558
18813
|
terminal: true,
|
18559
18814
|
$$tlb: true,
|
18560
|
-
|
18561
|
-
return function($scope, $element, $attr){
|
18815
|
+
link: function($scope, $element, $attr, ctrl, $transclude){
|
18562
18816
|
var expression = $attr.ngRepeat;
|
18563
18817
|
var match = expression.match(/^\s*(.+)\s+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/),
|
18564
18818
|
trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn,
|
@@ -18720,7 +18974,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
18720
18974
|
// jshint bitwise: true
|
18721
18975
|
|
18722
18976
|
if (!block.startNode) {
|
18723
|
-
|
18977
|
+
$transclude(childScope, function(clone) {
|
18724
18978
|
clone[clone.length++] = document.createComment(' end ngRepeat: ' + expression + ' ');
|
18725
18979
|
$animate.enter(clone, null, jqLite(previousNode));
|
18726
18980
|
previousNode = clone;
|
@@ -18733,7 +18987,6 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
18733
18987
|
}
|
18734
18988
|
lastBlockMap = nextBlockMap;
|
18735
18989
|
});
|
18736
|
-
};
|
18737
18990
|
}
|
18738
18991
|
};
|
18739
18992
|
}];
|
@@ -19242,10 +19495,10 @@ var ngSwitchWhenDirective = ngDirective({
|
|
19242
19495
|
transclude: 'element',
|
19243
19496
|
priority: 800,
|
19244
19497
|
require: '^ngSwitch',
|
19245
|
-
compile: function(element, attrs
|
19246
|
-
return function(scope, element, attr, ctrl) {
|
19498
|
+
compile: function(element, attrs) {
|
19499
|
+
return function(scope, element, attr, ctrl, $transclude) {
|
19247
19500
|
ctrl.cases['!' + attrs.ngSwitchWhen] = (ctrl.cases['!' + attrs.ngSwitchWhen] || []);
|
19248
|
-
ctrl.cases['!' + attrs.ngSwitchWhen].push({ transclude: transclude, element: element });
|
19501
|
+
ctrl.cases['!' + attrs.ngSwitchWhen].push({ transclude: $transclude, element: element });
|
19249
19502
|
};
|
19250
19503
|
}
|
19251
19504
|
});
|
@@ -19254,12 +19507,10 @@ var ngSwitchDefaultDirective = ngDirective({
|
|
19254
19507
|
transclude: 'element',
|
19255
19508
|
priority: 800,
|
19256
19509
|
require: '^ngSwitch',
|
19257
|
-
|
19258
|
-
|
19259
|
-
|
19260
|
-
|
19261
|
-
};
|
19262
|
-
}
|
19510
|
+
link: function(scope, element, attr, ctrl, $transclude) {
|
19511
|
+
ctrl.cases['?'] = (ctrl.cases['?'] || []);
|
19512
|
+
ctrl.cases['?'].push({ transclude: $transclude, element: element });
|
19513
|
+
}
|
19263
19514
|
});
|
19264
19515
|
|
19265
19516
|
/**
|
@@ -20028,4 +20279,4 @@ var styleDirective = valueFn({
|
|
20028
20279
|
|
20029
20280
|
})(window, document);
|
20030
20281
|
|
20031
|
-
!angular.$$csp() && angular.element(document).find('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{display:none !important;}ng\\:form{display:block;}.ng-animate-start{
|
20282
|
+
!angular.$$csp() && angular.element(document).find('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{display:none !important;}ng\\:form{display:block;}.ng-animate-start{border-spacing:1px 1px;-ms-zoom:1.0001;}.ng-animate-active{border-spacing:0px 0px;-ms-zoom:1;}</style>');
|