angular-rails-engine 1.2.0.2 → 1.2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,14 +1,14 @@
|
|
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
|
-
(function(
|
7
|
-
c}}var b,f
|
8
|
-
a.substring(b[0].length),b[0].replace(
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
6
|
+
(function(n,h,q){'use strict';function F(a){var e=[];t(e,h.noop).chars(a);return e.join("")}function k(a){var e={};a=a.split(",");var d;for(d=0;d<a.length;d++)e[a[d]]=!0;return e}function G(a,e){function d(a,b,d,g){b=h.lowercase(b);if(u[b])for(;f.last()&&v[f.last()];)c("",f.last());w[b]&&f.last()==b&&c("",b);(g=x[b]||!!g)||f.push(b);var l={};d.replace(H,function(a,b,e,c,m){l[b]=r(e||c||m||"")});e.start&&e.start(b,l,g)}function c(a,b){var c=0,d;if(b=h.lowercase(b))for(c=f.length-1;0<=c&&f[c]!=b;c--);
|
7
|
+
if(0<=c){for(d=f.length-1;d>=c;d--)e.end&&e.end(f[d]);f.length=c}}var b,g,f=[],l=a;for(f.last=function(){return f[f.length-1]};a;){g=!0;if(f.last()&&y[f.last()])a=a.replace(RegExp("(.*)<\\s*\\/\\s*"+f.last()+"[^>]*>","i"),function(a,b){b=b.replace(I,"$1").replace(J,"$1");e.chars&&e.chars(r(b));return""}),c("",f.last());else{if(0===a.indexOf("\x3c!--"))b=a.indexOf("--",4),0<=b&&a.lastIndexOf("--\x3e",b)===b&&(e.comment&&e.comment(a.substring(4,b)),a=a.substring(b+3),g=!1);else if(z.test(a)){if(b=a.match(z))a=
|
8
|
+
a.replace(b[0],""),g=!1}else if(K.test(a)){if(b=a.match(A))a=a.substring(b[0].length),b[0].replace(A,c),g=!1}else L.test(a)&&(b=a.match(B))&&(a=a.substring(b[0].length),b[0].replace(B,d),g=!1);g&&(b=a.indexOf("<"),g=0>b?a:a.substring(0,b),a=0>b?"":a.substring(b),e.chars&&e.chars(r(g)))}if(a==l)throw M("badparse",a);l=a}c()}function r(a){if(!a)return"";a=/^(\s*)([\s\S]*?)(\s*)$/.exec(a);a[0]="";a[2]&&(s.innerHTML=a[2].replace(/</g,"<"),a[2]=s.innerText||s.textContent);return a.join("")}function C(a){return a.replace(/&/g,
|
9
|
+
"&").replace(N,function(a){return"&#"+a.charCodeAt(0)+";"}).replace(/</g,"<").replace(/>/g,">")}function t(a,e){var d=!1,c=h.bind(a,a.push);return{start:function(a,g,f){a=h.lowercase(a);!d&&y[a]&&(d=a);d||!0!==D[a]||(c("<"),c(a),h.forEach(g,function(d,f){var g=h.lowercase(f),k="img"===a&&"src"===g||"background"===g;!0!==O[g]||!0===E[g]&&!e(d,k)||(c(" "),c(f),c('="'),c(C(d)),c('"'))}),c(f?"/>":">"))},end:function(a){a=h.lowercase(a);d||!0!==D[a]||(c("</"),c(a),c(">"));a==d&&(d=!1)},chars:function(a){d||
|
10
|
+
c(C(a))}}}var M=h.$$minErr("$sanitize"),B=/^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,A=/^<\s*\/\s*([\w:-]+)[^>]*>/,H=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,L=/^</,K=/^<\s*\//,I=/\x3c!--(.*?)--\x3e/g,z=/<!DOCTYPE([^>]*?)>/i,J=/<!\[CDATA\[(.*?)]]\x3e/g,N=/([^\#-~| |!])/g,x=k("area,br,col,hr,img,wbr");n=k("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr");q=k("rp,rt");var w=h.extend({},q,n),u=h.extend({},n,k("address,article,aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul")),
|
11
|
+
v=h.extend({},q,k("a,abbr,acronym,b,bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,samp,small,span,strike,strong,sub,sup,time,tt,u,var")),y=k("script,style"),D=h.extend({},x,u,v,w),E=k("background,cite,href,longdesc,src,usemap"),O=h.extend({},E,k("abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,scope,scrolling,shape,span,start,summary,target,title,type,valign,value,vspace,width")),
|
12
|
+
s=document.createElement("pre");h.module("ngSanitize",[]).provider("$sanitize",function(){this.$get=["$$sanitizeUri",function(a){return function(e){var d=[];G(e,t(d,function(c,b){return!/^unsafe/.test(a(c,b))}));return d.join("")}}]});h.module("ngSanitize").filter("linky",["$sanitize",function(a){var e=/((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>]/,d=/^mailto:/;return function(c,b){function g(a){a&&m.push(F(a))}function f(a,c){m.push("<a ");h.isDefined(b)&&(m.push('target="'),
|
13
|
+
m.push(b),m.push('" '));m.push('href="');m.push(a);m.push('">');g(c);m.push("</a>")}if(!c)return c;for(var l,k=c,m=[],p,n;l=k.match(e);)p=l[0],l[2]==l[3]&&(p="mailto:"+p),n=l.index,g(k.substr(0,n)),f(p,l[0].replace(d,"")),k=k.substring(n+l[0].length);g(k);return a(m.join(""))}}])})(window,window.angular);
|
14
14
|
//# sourceMappingURL=angular-sanitize.min.js.map
|
@@ -9790,8 +9790,8 @@ if ( typeof module === "object" && module && typeof module.exports === "object"
|
|
9790
9790
|
})( window );
|
9791
9791
|
|
9792
9792
|
/**
|
9793
|
-
* @license AngularJS v1.2.
|
9794
|
-
* (c) 2010-
|
9793
|
+
* @license AngularJS v1.2.3
|
9794
|
+
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
9795
9795
|
* License: MIT
|
9796
9796
|
*/
|
9797
9797
|
(function(window, document){
|
@@ -9832,11 +9832,11 @@ function minErr(module) {
|
|
9832
9832
|
template = arguments[1],
|
9833
9833
|
templateArgs = arguments,
|
9834
9834
|
stringify = function (obj) {
|
9835
|
-
if (
|
9835
|
+
if (typeof obj === 'function') {
|
9836
9836
|
return obj.toString().replace(/ \{[\s\S]*$/, '');
|
9837
|
-
} else if (
|
9837
|
+
} else if (typeof obj === 'undefined') {
|
9838
9838
|
return 'undefined';
|
9839
|
-
} else if (
|
9839
|
+
} else if (typeof obj !== 'string') {
|
9840
9840
|
return JSON.stringify(obj);
|
9841
9841
|
}
|
9842
9842
|
return obj;
|
@@ -9848,11 +9848,11 @@ function minErr(module) {
|
|
9848
9848
|
|
9849
9849
|
if (index + 2 < templateArgs.length) {
|
9850
9850
|
arg = templateArgs[index + 2];
|
9851
|
-
if (
|
9851
|
+
if (typeof arg === 'function') {
|
9852
9852
|
return arg.toString().replace(/ ?\{[\s\S]*$/, '');
|
9853
|
-
} else if (
|
9853
|
+
} else if (typeof arg === 'undefined') {
|
9854
9854
|
return 'undefined';
|
9855
|
-
} else if (
|
9855
|
+
} else if (typeof arg !== 'string') {
|
9856
9856
|
return toJson(arg);
|
9857
9857
|
}
|
9858
9858
|
return arg;
|
@@ -9860,7 +9860,7 @@ function minErr(module) {
|
|
9860
9860
|
return match;
|
9861
9861
|
});
|
9862
9862
|
|
9863
|
-
message = message + '\nhttp://errors.angularjs.org/
|
9863
|
+
message = message + '\nhttp://errors.angularjs.org/1.2.3/' +
|
9864
9864
|
(module ? module + '/' : '') + code;
|
9865
9865
|
for (i = 2; i < arguments.length; i++) {
|
9866
9866
|
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
|
@@ -9951,7 +9951,7 @@ function minErr(module) {
|
|
9951
9951
|
-assertArgFn,
|
9952
9952
|
-assertNotHasOwnProperty,
|
9953
9953
|
-getter,
|
9954
|
-
-getBlockElements
|
9954
|
+
-getBlockElements,
|
9955
9955
|
|
9956
9956
|
*/
|
9957
9957
|
|
@@ -10415,7 +10415,7 @@ var trim = (function() {
|
|
10415
10415
|
// TODO: we should move this into IE/ES5 polyfill
|
10416
10416
|
if (!String.prototype.trim) {
|
10417
10417
|
return function(value) {
|
10418
|
-
return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
|
10418
|
+
return isString(value) ? value.replace(/^\s\s*/, '').replace(/\s\s*$/, '') : value;
|
10419
10419
|
};
|
10420
10420
|
}
|
10421
10421
|
return function(value) {
|
@@ -10973,26 +10973,38 @@ function encodeUriQuery(val, pctEncodeSpaces) {
|
|
10973
10973
|
*
|
10974
10974
|
* @description
|
10975
10975
|
*
|
10976
|
-
* Use this directive to auto-bootstrap an application.
|
10977
|
-
*
|
10978
|
-
*
|
10979
|
-
* at the root of the page.
|
10976
|
+
* Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive
|
10977
|
+
* designates the **root element** of the application and is typically placed near the root element
|
10978
|
+
* of the page - e.g. on the `<body>` or `<html>` tags.
|
10980
10979
|
*
|
10981
|
-
*
|
10982
|
-
*
|
10983
|
-
*
|
10980
|
+
* Only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp`
|
10981
|
+
* found in the document will be used to define the root element to auto-bootstrap as an
|
10982
|
+
* application. To run multiple applications in an HTML document you must manually bootstrap them using
|
10983
|
+
* {@link angular.bootstrap} instead. AngularJS applications cannot be nested within each other.
|
10984
10984
|
*
|
10985
|
-
*
|
10986
|
-
*
|
10987
|
-
*
|
10985
|
+
* You can specify an **AngularJS module** to be used as the root module for the application. This
|
10986
|
+
* module will be loaded into the {@link AUTO.$injector} when the application is bootstrapped and
|
10987
|
+
* should contain the application code needed or have dependencies on other modules that will
|
10988
|
+
* contain the code. See {@link angular.module} for more information.
|
10988
10989
|
*
|
10989
|
-
* `ngApp`
|
10990
|
+
* In the example below if the `ngApp` directive were not placed on the `html` element then the
|
10991
|
+
* document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}`
|
10992
|
+
* would not be resolved to `3`.
|
10990
10993
|
*
|
10991
|
-
|
10992
|
-
|
10993
|
-
|
10994
|
-
|
10995
|
-
|
10994
|
+
* `ngApp` is the easiest, and most common, way to bootstrap an application.
|
10995
|
+
*
|
10996
|
+
<example module="ngAppDemo">
|
10997
|
+
<file name="index.html">
|
10998
|
+
<div ng-controller="ngAppDemoController">
|
10999
|
+
I can add: {{a}} + {{b}} = {{ a+b }}
|
11000
|
+
</file>
|
11001
|
+
<file name="script.js">
|
11002
|
+
angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) {
|
11003
|
+
$scope.a = 1;
|
11004
|
+
$scope.b = 2;
|
11005
|
+
});
|
11006
|
+
</file>
|
11007
|
+
</example>
|
10996
11008
|
*
|
10997
11009
|
*/
|
10998
11010
|
function angularInit(element, bootstrap) {
|
@@ -11221,12 +11233,18 @@ function getBlockElements(block) {
|
|
11221
11233
|
function setupModuleLoader(window) {
|
11222
11234
|
|
11223
11235
|
var $injectorMinErr = minErr('$injector');
|
11236
|
+
var ngMinErr = minErr('ng');
|
11224
11237
|
|
11225
11238
|
function ensure(obj, name, factory) {
|
11226
11239
|
return obj[name] || (obj[name] = factory());
|
11227
11240
|
}
|
11228
11241
|
|
11229
|
-
|
11242
|
+
var angular = ensure(window, 'angular', Object);
|
11243
|
+
|
11244
|
+
// We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
|
11245
|
+
angular.$$minErr = angular.$$minErr || minErr;
|
11246
|
+
|
11247
|
+
return ensure(angular, 'module', function() {
|
11230
11248
|
/** @type {Object.<string, angular.Module>} */
|
11231
11249
|
var modules = {};
|
11232
11250
|
|
@@ -11281,6 +11299,12 @@ function setupModuleLoader(window) {
|
|
11281
11299
|
* @returns {module} new module with the {@link angular.Module} api.
|
11282
11300
|
*/
|
11283
11301
|
return function module(name, requires, configFn) {
|
11302
|
+
var assertNotHasOwnProperty = function(name, context) {
|
11303
|
+
if (name === 'hasOwnProperty') {
|
11304
|
+
throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
|
11305
|
+
}
|
11306
|
+
};
|
11307
|
+
|
11284
11308
|
assertNotHasOwnProperty(name, 'module');
|
11285
11309
|
if (requires && modules.hasOwnProperty(name)) {
|
11286
11310
|
modules[name] = null;
|
@@ -11570,6 +11594,7 @@ function setupModuleLoader(window) {
|
|
11570
11594
|
$ParseProvider,
|
11571
11595
|
$RootScopeProvider,
|
11572
11596
|
$QProvider,
|
11597
|
+
$$SanitizeUriProvider,
|
11573
11598
|
$SceProvider,
|
11574
11599
|
$SceDelegateProvider,
|
11575
11600
|
$SnifferProvider,
|
@@ -11593,11 +11618,11 @@ function setupModuleLoader(window) {
|
|
11593
11618
|
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
|
11594
11619
|
*/
|
11595
11620
|
var version = {
|
11596
|
-
full: '1.2.
|
11621
|
+
full: '1.2.3', // all of these placeholder strings will be replaced by grunt's
|
11597
11622
|
major: 1, // package task
|
11598
|
-
minor:
|
11599
|
-
dot:
|
11600
|
-
codeName: '
|
11623
|
+
minor: 2,
|
11624
|
+
dot: 3,
|
11625
|
+
codeName: 'unicorn-zapper'
|
11601
11626
|
};
|
11602
11627
|
|
11603
11628
|
|
@@ -11641,6 +11666,10 @@ function publishExternalAPI(angular){
|
|
11641
11666
|
|
11642
11667
|
angularModule('ng', ['ngLocale'], ['$provide',
|
11643
11668
|
function ngModule($provide) {
|
11669
|
+
// $$sanitizeUriProvider needs to be before $compileProvider as it is used by it.
|
11670
|
+
$provide.provider({
|
11671
|
+
$$sanitizeUri: $$SanitizeUriProvider
|
11672
|
+
});
|
11644
11673
|
$provide.provider('$compile', $CompileProvider).
|
11645
11674
|
directive({
|
11646
11675
|
a: htmlAnchorDirective,
|
@@ -13144,11 +13173,11 @@ function annotate(fn) {
|
|
13144
13173
|
* @example
|
13145
13174
|
* Here are some examples of creating value services.
|
13146
13175
|
* <pre>
|
13147
|
-
* $provide.
|
13176
|
+
* $provide.value('ADMIN_USER', 'admin');
|
13148
13177
|
*
|
13149
|
-
* $provide.
|
13178
|
+
* $provide.value('RoleLookup', { admin: 0, writer: 1, reader: 2 });
|
13150
13179
|
*
|
13151
|
-
* $provide.
|
13180
|
+
* $provide.value('halfOf', function(value) {
|
13152
13181
|
* return value / 2;
|
13153
13182
|
* });
|
13154
13183
|
* </pre>
|
@@ -13634,13 +13663,14 @@ var $AnimateProvider = ['$provide', function($provide) {
|
|
13634
13663
|
* inserted into the DOM
|
13635
13664
|
*/
|
13636
13665
|
enter : function(element, parent, after, done) {
|
13637
|
-
|
13638
|
-
|
13639
|
-
|
13640
|
-
|
13641
|
-
|
13642
|
-
|
13643
|
-
|
13666
|
+
if (after) {
|
13667
|
+
after.after(element);
|
13668
|
+
} else {
|
13669
|
+
if (!parent || !parent[0]) {
|
13670
|
+
parent = after.parent();
|
13671
|
+
}
|
13672
|
+
parent.append(element);
|
13673
|
+
}
|
13644
13674
|
done && $timeout(done, 0, false);
|
13645
13675
|
},
|
13646
13676
|
|
@@ -14488,8 +14518,9 @@ function $TemplateCacheProvider() {
|
|
14488
14518
|
* When there are multiple directives defined on a single DOM element, sometimes it
|
14489
14519
|
* is necessary to specify the order in which the directives are applied. The `priority` is used
|
14490
14520
|
* to sort the directives before their `compile` functions get called. Priority is defined as a
|
14491
|
-
* number. Directives with greater numerical `priority` are compiled first.
|
14492
|
-
*
|
14521
|
+
* number. Directives with greater numerical `priority` are compiled first. Pre-link functions
|
14522
|
+
* are also run in priority order, but post-link functions are run in reverse order. The order
|
14523
|
+
* of directives with the same priority is undefined. The default priority is `0`.
|
14493
14524
|
*
|
14494
14525
|
* #### `terminal`
|
14495
14526
|
* If set to true then the current `priority` will be the last set of directives
|
@@ -14550,8 +14581,9 @@ function $TemplateCacheProvider() {
|
|
14550
14581
|
* * `$scope` - Current scope associated with the element
|
14551
14582
|
* * `$element` - Current element
|
14552
14583
|
* * `$attrs` - Current attributes object for the element
|
14553
|
-
* * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope
|
14554
|
-
*
|
14584
|
+
* * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope.
|
14585
|
+
* The scope can be overridden by an optional first argument.
|
14586
|
+
* `function([scope], cloneLinkingFn)`.
|
14555
14587
|
*
|
14556
14588
|
*
|
14557
14589
|
* #### `require`
|
@@ -14644,7 +14676,7 @@ function $TemplateCacheProvider() {
|
|
14644
14676
|
* * `tAttrs` - template attributes - Normalized list of attributes declared on this element shared
|
14645
14677
|
* between all directive compile functions.
|
14646
14678
|
*
|
14647
|
-
* * `transclude` - A transclude linking function: `function(scope, cloneLinkingFn)
|
14679
|
+
* * `transclude` - [*DEPRECATED*!] A transclude linking function: `function(scope, cloneLinkingFn)`
|
14648
14680
|
*
|
14649
14681
|
* <div class="alert alert-warning">
|
14650
14682
|
* **Note:** The template instance and the link instance may be different objects if the template has
|
@@ -14653,6 +14685,12 @@ function $TemplateCacheProvider() {
|
|
14653
14685
|
* should be done in a linking function rather than in a compile function.
|
14654
14686
|
* </div>
|
14655
14687
|
*
|
14688
|
+
* <div class="alert alert-error">
|
14689
|
+
* **Note:** The `transclude` function that is passed to the compile function is deprecated, as it
|
14690
|
+
* e.g. does not know about the right outer scope. Please use the transclude function that is passed
|
14691
|
+
* to the link function instead.
|
14692
|
+
* </div>
|
14693
|
+
|
14656
14694
|
* A compile function can have a return value which can be either a function or an object.
|
14657
14695
|
*
|
14658
14696
|
* * returning a (post-link) function - is equivalent to registering the linking function via the
|
@@ -14667,7 +14705,7 @@ function $TemplateCacheProvider() {
|
|
14667
14705
|
* This property is used only if the `compile` property is not defined.
|
14668
14706
|
*
|
14669
14707
|
* <pre>
|
14670
|
-
* function link(scope, iElement, iAttrs, controller) { ... }
|
14708
|
+
* function link(scope, iElement, iAttrs, controller, transcludeFn) { ... }
|
14671
14709
|
* </pre>
|
14672
14710
|
*
|
14673
14711
|
* The link function is responsible for registering DOM listeners as well as updating the DOM. It is
|
@@ -14688,6 +14726,10 @@ function $TemplateCacheProvider() {
|
|
14688
14726
|
* element defines a controller. The controller is shared among all the directives, which allows
|
14689
14727
|
* the directives to use the controllers as a communication channel.
|
14690
14728
|
*
|
14729
|
+
* * `transcludeFn` - A transclude linking function pre-bound to the correct transclusion scope.
|
14730
|
+
* The scope can be overridden by an optional first argument. This is the same as the `$transclude`
|
14731
|
+
* parameter of directive controllers.
|
14732
|
+
* `function([scope], cloneLinkingFn)`.
|
14691
14733
|
*
|
14692
14734
|
*
|
14693
14735
|
* #### Pre-linking function
|
@@ -14854,14 +14896,12 @@ var $compileMinErr = minErr('$compile');
|
|
14854
14896
|
*
|
14855
14897
|
* @description
|
14856
14898
|
*/
|
14857
|
-
$CompileProvider.$inject = ['$provide'];
|
14858
|
-
function $CompileProvider($provide) {
|
14899
|
+
$CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider'];
|
14900
|
+
function $CompileProvider($provide, $$sanitizeUriProvider) {
|
14859
14901
|
var hasDirectives = {},
|
14860
14902
|
Suffix = 'Directive',
|
14861
14903
|
COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,
|
14862
|
-
CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)
|
14863
|
-
aHrefSanitizationWhitelist = /^\s*(https?|ftp|mailto|tel|file):/,
|
14864
|
-
imgSrcSanitizationWhitelist = /^\s*(https?|ftp|file):|data:image\//;
|
14904
|
+
CLASS_DIRECTIVE_REGEXP = /(([\d\w\-_]+)(?:\:([^;]+))?;?)/;
|
14865
14905
|
|
14866
14906
|
// Ref: http://developers.whatwg.org/webappapis.html#event-handler-idl-attributes
|
14867
14907
|
// The assumption is that future DOM event attribute names will begin with
|
@@ -14945,10 +14985,11 @@ function $CompileProvider($provide) {
|
|
14945
14985
|
*/
|
14946
14986
|
this.aHrefSanitizationWhitelist = function(regexp) {
|
14947
14987
|
if (isDefined(regexp)) {
|
14948
|
-
aHrefSanitizationWhitelist
|
14988
|
+
$$sanitizeUriProvider.aHrefSanitizationWhitelist(regexp);
|
14949
14989
|
return this;
|
14990
|
+
} else {
|
14991
|
+
return $$sanitizeUriProvider.aHrefSanitizationWhitelist();
|
14950
14992
|
}
|
14951
|
-
return aHrefSanitizationWhitelist;
|
14952
14993
|
};
|
14953
14994
|
|
14954
14995
|
|
@@ -14975,18 +15016,18 @@ function $CompileProvider($provide) {
|
|
14975
15016
|
*/
|
14976
15017
|
this.imgSrcSanitizationWhitelist = function(regexp) {
|
14977
15018
|
if (isDefined(regexp)) {
|
14978
|
-
imgSrcSanitizationWhitelist
|
15019
|
+
$$sanitizeUriProvider.imgSrcSanitizationWhitelist(regexp);
|
14979
15020
|
return this;
|
15021
|
+
} else {
|
15022
|
+
return $$sanitizeUriProvider.imgSrcSanitizationWhitelist();
|
14980
15023
|
}
|
14981
|
-
return imgSrcSanitizationWhitelist;
|
14982
15024
|
};
|
14983
15025
|
|
14984
|
-
|
14985
15026
|
this.$get = [
|
14986
15027
|
'$injector', '$interpolate', '$exceptionHandler', '$http', '$templateCache', '$parse',
|
14987
|
-
'$controller', '$rootScope', '$document', '$sce', '$animate',
|
15028
|
+
'$controller', '$rootScope', '$document', '$sce', '$animate', '$$sanitizeUri',
|
14988
15029
|
function($injector, $interpolate, $exceptionHandler, $http, $templateCache, $parse,
|
14989
|
-
$controller, $rootScope, $document, $sce, $animate) {
|
15030
|
+
$controller, $rootScope, $document, $sce, $animate, $$sanitizeUri) {
|
14990
15031
|
|
14991
15032
|
var Attributes = function(element, attr) {
|
14992
15033
|
this.$$element = element;
|
@@ -15033,6 +15074,24 @@ function $CompileProvider($provide) {
|
|
15033
15074
|
}
|
15034
15075
|
},
|
15035
15076
|
|
15077
|
+
/**
|
15078
|
+
* @ngdoc function
|
15079
|
+
* @name ng.$compile.directive.Attributes#$updateClass
|
15080
|
+
* @methodOf ng.$compile.directive.Attributes
|
15081
|
+
* @function
|
15082
|
+
*
|
15083
|
+
* @description
|
15084
|
+
* Adds and removes the appropriate CSS class values to the element based on the difference
|
15085
|
+
* between the new and old CSS class values (specified as newClasses and oldClasses).
|
15086
|
+
*
|
15087
|
+
* @param {string} newClasses The current CSS className value
|
15088
|
+
* @param {string} oldClasses The former CSS className value
|
15089
|
+
*/
|
15090
|
+
$updateClass : function(newClasses, oldClasses) {
|
15091
|
+
this.$removeClass(tokenDifference(oldClasses, newClasses));
|
15092
|
+
this.$addClass(tokenDifference(newClasses, oldClasses));
|
15093
|
+
},
|
15094
|
+
|
15036
15095
|
/**
|
15037
15096
|
* Set a normalized attribute on the element in a way such that all directives
|
15038
15097
|
* can share the attribute. This function properly handles boolean attributes.
|
@@ -15043,59 +15102,44 @@ function $CompileProvider($provide) {
|
|
15043
15102
|
* @param {string=} attrName Optional none normalized name. Defaults to key.
|
15044
15103
|
*/
|
15045
15104
|
$set: function(key, value, writeAttr, attrName) {
|
15046
|
-
//
|
15047
|
-
//
|
15048
|
-
//
|
15049
|
-
if(key == 'class') {
|
15050
|
-
value = value || '';
|
15051
|
-
var current = this.$$element.attr('class') || '';
|
15052
|
-
this.$removeClass(tokenDifference(current, value).join(' '));
|
15053
|
-
this.$addClass(tokenDifference(value, current).join(' '));
|
15054
|
-
} else {
|
15055
|
-
var booleanKey = getBooleanAttrName(this.$$element[0], key),
|
15056
|
-
normalizedVal,
|
15057
|
-
nodeName;
|
15105
|
+
// TODO: decide whether or not to throw an error if "class"
|
15106
|
+
//is set through this function since it may cause $updateClass to
|
15107
|
+
//become unstable.
|
15058
15108
|
|
15059
|
-
|
15060
|
-
|
15061
|
-
|
15062
|
-
}
|
15109
|
+
var booleanKey = getBooleanAttrName(this.$$element[0], key),
|
15110
|
+
normalizedVal,
|
15111
|
+
nodeName;
|
15063
15112
|
|
15064
|
-
|
15113
|
+
if (booleanKey) {
|
15114
|
+
this.$$element.prop(key, value);
|
15115
|
+
attrName = booleanKey;
|
15116
|
+
}
|
15065
15117
|
|
15066
|
-
|
15067
|
-
if (attrName) {
|
15068
|
-
this.$attr[key] = attrName;
|
15069
|
-
} else {
|
15070
|
-
attrName = this.$attr[key];
|
15071
|
-
if (!attrName) {
|
15072
|
-
this.$attr[key] = attrName = snake_case(key, '-');
|
15073
|
-
}
|
15074
|
-
}
|
15118
|
+
this[key] = value;
|
15075
15119
|
|
15076
|
-
|
15077
|
-
|
15078
|
-
|
15079
|
-
|
15080
|
-
|
15081
|
-
|
15082
|
-
|
15083
|
-
normalizedVal = urlResolve(value).href;
|
15084
|
-
if (normalizedVal !== '') {
|
15085
|
-
if ((key === 'href' && !normalizedVal.match(aHrefSanitizationWhitelist)) ||
|
15086
|
-
(key === 'src' && !normalizedVal.match(imgSrcSanitizationWhitelist))) {
|
15087
|
-
this[key] = value = 'unsafe:' + normalizedVal;
|
15088
|
-
}
|
15089
|
-
}
|
15090
|
-
}
|
15120
|
+
// translate normalized key to actual key
|
15121
|
+
if (attrName) {
|
15122
|
+
this.$attr[key] = attrName;
|
15123
|
+
} else {
|
15124
|
+
attrName = this.$attr[key];
|
15125
|
+
if (!attrName) {
|
15126
|
+
this.$attr[key] = attrName = snake_case(key, '-');
|
15091
15127
|
}
|
15128
|
+
}
|
15092
15129
|
|
15093
|
-
|
15094
|
-
|
15095
|
-
|
15096
|
-
|
15097
|
-
|
15098
|
-
|
15130
|
+
nodeName = nodeName_(this.$$element);
|
15131
|
+
|
15132
|
+
// sanitize a[href] and img[src] values
|
15133
|
+
if ((nodeName === 'A' && key === 'href') ||
|
15134
|
+
(nodeName === 'IMG' && key === 'src')) {
|
15135
|
+
this[key] = value = $$sanitizeUri(value, key === 'src');
|
15136
|
+
}
|
15137
|
+
|
15138
|
+
if (writeAttr !== false) {
|
15139
|
+
if (value === null || value === undefined) {
|
15140
|
+
this.$$element.removeAttr(attrName);
|
15141
|
+
} else {
|
15142
|
+
this.$$element.attr(attrName, value);
|
15099
15143
|
}
|
15100
15144
|
}
|
15101
15145
|
|
@@ -15108,22 +15152,6 @@ function $CompileProvider($provide) {
|
|
15108
15152
|
$exceptionHandler(e);
|
15109
15153
|
}
|
15110
15154
|
});
|
15111
|
-
|
15112
|
-
function tokenDifference(str1, str2) {
|
15113
|
-
var values = [],
|
15114
|
-
tokens1 = str1.split(/\s+/),
|
15115
|
-
tokens2 = str2.split(/\s+/);
|
15116
|
-
|
15117
|
-
outer:
|
15118
|
-
for(var i=0;i<tokens1.length;i++) {
|
15119
|
-
var token = tokens1[i];
|
15120
|
-
for(var j=0;j<tokens2.length;j++) {
|
15121
|
-
if(token == tokens2[j]) continue outer;
|
15122
|
-
}
|
15123
|
-
values.push(token);
|
15124
|
-
}
|
15125
|
-
return values;
|
15126
|
-
}
|
15127
15155
|
},
|
15128
15156
|
|
15129
15157
|
|
@@ -15193,7 +15221,7 @@ function $CompileProvider($provide) {
|
|
15193
15221
|
var compositeLinkFn =
|
15194
15222
|
compileNodes($compileNodes, transcludeFn, $compileNodes,
|
15195
15223
|
maxPriority, ignoreDirective, previousCompileContext);
|
15196
|
-
return function publicLinkFn(scope, cloneConnectFn){
|
15224
|
+
return function publicLinkFn(scope, cloneConnectFn, transcludeControllers){
|
15197
15225
|
assertArg(scope, 'scope');
|
15198
15226
|
// important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart
|
15199
15227
|
// and sometimes changes the structure of the DOM.
|
@@ -15201,6 +15229,10 @@ function $CompileProvider($provide) {
|
|
15201
15229
|
? JQLitePrototype.clone.call($compileNodes) // IMPORTANT!!!
|
15202
15230
|
: $compileNodes;
|
15203
15231
|
|
15232
|
+
forEach(transcludeControllers, function(instance, name) {
|
15233
|
+
$linkNode.data('$' + name + 'Controller', instance);
|
15234
|
+
});
|
15235
|
+
|
15204
15236
|
// Attach scope only to non-text nodes.
|
15205
15237
|
for(var i = 0, ii = $linkNode.length; i<ii; i++) {
|
15206
15238
|
var node = $linkNode[i];
|
@@ -15299,15 +15331,7 @@ function $CompileProvider($provide) {
|
|
15299
15331
|
childTranscludeFn = nodeLinkFn.transclude;
|
15300
15332
|
if (childTranscludeFn || (!boundTranscludeFn && transcludeFn)) {
|
15301
15333
|
nodeLinkFn(childLinkFn, childScope, node, $rootElement,
|
15302
|
-
|
15303
|
-
return function(cloneFn) {
|
15304
|
-
var transcludeScope = scope.$new();
|
15305
|
-
transcludeScope.$$transcluded = true;
|
15306
|
-
|
15307
|
-
return transcludeFn(transcludeScope, cloneFn).
|
15308
|
-
on('$destroy', bind(transcludeScope, transcludeScope.$destroy));
|
15309
|
-
};
|
15310
|
-
})(childTranscludeFn || transcludeFn)
|
15334
|
+
createBoundTranscludeFn(scope, childTranscludeFn || transcludeFn)
|
15311
15335
|
);
|
15312
15336
|
} else {
|
15313
15337
|
nodeLinkFn(childLinkFn, childScope, node, undefined, boundTranscludeFn);
|
@@ -15319,6 +15343,23 @@ function $CompileProvider($provide) {
|
|
15319
15343
|
}
|
15320
15344
|
}
|
15321
15345
|
|
15346
|
+
function createBoundTranscludeFn(scope, transcludeFn) {
|
15347
|
+
return function boundTranscludeFn(transcludedScope, cloneFn, controllers) {
|
15348
|
+
var scopeCreated = false;
|
15349
|
+
|
15350
|
+
if (!transcludedScope) {
|
15351
|
+
transcludedScope = scope.$new();
|
15352
|
+
transcludedScope.$$transcluded = true;
|
15353
|
+
scopeCreated = true;
|
15354
|
+
}
|
15355
|
+
|
15356
|
+
var clone = transcludeFn(transcludedScope, cloneFn, controllers);
|
15357
|
+
if (scopeCreated) {
|
15358
|
+
clone.on('$destroy', bind(transcludedScope, transcludedScope.$destroy));
|
15359
|
+
}
|
15360
|
+
return clone;
|
15361
|
+
};
|
15362
|
+
}
|
15322
15363
|
|
15323
15364
|
/**
|
15324
15365
|
* Looks for directives on the given node and adds them to the directive collection which is
|
@@ -15456,9 +15497,9 @@ function $CompileProvider($provide) {
|
|
15456
15497
|
* @returns {Function}
|
15457
15498
|
*/
|
15458
15499
|
function groupElementsLinkFnWrapper(linkFn, attrStart, attrEnd) {
|
15459
|
-
return function(scope, element, attrs, controllers) {
|
15500
|
+
return function(scope, element, attrs, controllers, transcludeFn) {
|
15460
15501
|
element = groupScan(element[0], attrStart, attrEnd);
|
15461
|
-
return linkFn(scope, element, attrs, controllers);
|
15502
|
+
return linkFn(scope, element, attrs, controllers, transcludeFn);
|
15462
15503
|
};
|
15463
15504
|
}
|
15464
15505
|
|
@@ -15495,7 +15536,9 @@ function $CompileProvider($provide) {
|
|
15495
15536
|
controllerDirectives = previousCompileContext.controllerDirectives,
|
15496
15537
|
newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective,
|
15497
15538
|
templateDirective = previousCompileContext.templateDirective,
|
15498
|
-
|
15539
|
+
nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective,
|
15540
|
+
hasTranscludeDirective = false,
|
15541
|
+
hasElementTranscludeDirective = false,
|
15499
15542
|
$compileNode = templateAttrs.$$element = jqLite(compileNode),
|
15500
15543
|
directive,
|
15501
15544
|
directiveName,
|
@@ -15546,15 +15589,18 @@ function $CompileProvider($provide) {
|
|
15546
15589
|
}
|
15547
15590
|
|
15548
15591
|
if (directiveValue = directive.transclude) {
|
15592
|
+
hasTranscludeDirective = true;
|
15593
|
+
|
15549
15594
|
// Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion.
|
15550
15595
|
// This option should only be used by directives that know how to how to safely handle element transclusion,
|
15551
15596
|
// where the transcluded nodes are added or replaced after linking.
|
15552
15597
|
if (!directive.$$tlb) {
|
15553
|
-
assertNoDuplicate('transclusion',
|
15554
|
-
|
15598
|
+
assertNoDuplicate('transclusion', nonTlbTranscludeDirective, directive, $compileNode);
|
15599
|
+
nonTlbTranscludeDirective = directive;
|
15555
15600
|
}
|
15556
15601
|
|
15557
15602
|
if (directiveValue == 'element') {
|
15603
|
+
hasElementTranscludeDirective = true;
|
15558
15604
|
terminalPriority = directive.priority;
|
15559
15605
|
$template = groupScan(compileNode, attrStart, attrEnd);
|
15560
15606
|
$compileNode = templateAttrs.$$element =
|
@@ -15570,9 +15616,9 @@ function $CompileProvider($provide) {
|
|
15570
15616
|
// - newIsolateScopeDirective or templateDirective - combining templates with
|
15571
15617
|
// element transclusion doesn't make sense.
|
15572
15618
|
//
|
15573
|
-
// We need only
|
15619
|
+
// We need only nonTlbTranscludeDirective so that we prevent putting transclusion
|
15574
15620
|
// on the same element more than once.
|
15575
|
-
|
15621
|
+
nonTlbTranscludeDirective: nonTlbTranscludeDirective
|
15576
15622
|
});
|
15577
15623
|
} else {
|
15578
15624
|
$template = jqLite(jqLiteClone(compileNode)).contents();
|
@@ -15641,7 +15687,7 @@ function $CompileProvider($provide) {
|
|
15641
15687
|
controllerDirectives: controllerDirectives,
|
15642
15688
|
newIsolateScopeDirective: newIsolateScopeDirective,
|
15643
15689
|
templateDirective: templateDirective,
|
15644
|
-
|
15690
|
+
nonTlbTranscludeDirective: nonTlbTranscludeDirective
|
15645
15691
|
});
|
15646
15692
|
ii = directives.length;
|
15647
15693
|
} else if (directive.compile) {
|
@@ -15665,7 +15711,7 @@ function $CompileProvider($provide) {
|
|
15665
15711
|
}
|
15666
15712
|
|
15667
15713
|
nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true;
|
15668
|
-
nodeLinkFn.transclude =
|
15714
|
+
nodeLinkFn.transclude = hasTranscludeDirective && childTranscludeFn;
|
15669
15715
|
|
15670
15716
|
// might be normal or delayed nodeLinkFn depending on if templateUrl is present
|
15671
15717
|
return nodeLinkFn;
|
@@ -15692,7 +15738,7 @@ function $CompileProvider($provide) {
|
|
15692
15738
|
}
|
15693
15739
|
|
15694
15740
|
|
15695
|
-
function getControllers(require, $element) {
|
15741
|
+
function getControllers(require, $element, elementControllers) {
|
15696
15742
|
var value, retrievalMethod = 'data', optional = false;
|
15697
15743
|
if (isString(require)) {
|
15698
15744
|
while((value = require.charAt(0)) == '^' || value == '?') {
|
@@ -15702,13 +15748,12 @@ function $CompileProvider($provide) {
|
|
15702
15748
|
}
|
15703
15749
|
optional = optional || value == '?';
|
15704
15750
|
}
|
15751
|
+
value = null;
|
15705
15752
|
|
15706
|
-
|
15707
|
-
|
15708
|
-
if ($element[0].nodeType == 8 && $element[0].$$controller) { // Transclusion comment node
|
15709
|
-
value = value || $element[0].$$controller;
|
15710
|
-
$element[0].$$controller = null;
|
15753
|
+
if (elementControllers && retrievalMethod === 'data') {
|
15754
|
+
value = elementControllers[require];
|
15711
15755
|
}
|
15756
|
+
value = value || $element[retrievalMethod]('$' + require + 'Controller');
|
15712
15757
|
|
15713
15758
|
if (!value && !optional) {
|
15714
15759
|
throw $compileMinErr('ctreq',
|
@@ -15719,7 +15764,7 @@ function $CompileProvider($provide) {
|
|
15719
15764
|
} else if (isArray(require)) {
|
15720
15765
|
value = [];
|
15721
15766
|
forEach(require, function(require) {
|
15722
|
-
value.push(getControllers(require, $element));
|
15767
|
+
value.push(getControllers(require, $element, elementControllers));
|
15723
15768
|
});
|
15724
15769
|
}
|
15725
15770
|
return value;
|
@@ -15727,7 +15772,7 @@ function $CompileProvider($provide) {
|
|
15727
15772
|
|
15728
15773
|
|
15729
15774
|
function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {
|
15730
|
-
var attrs, $element, i, ii, linkFn, controller, isolateScope;
|
15775
|
+
var attrs, $element, i, ii, linkFn, controller, isolateScope, elementControllers = {}, transcludeFn;
|
15731
15776
|
|
15732
15777
|
if (compileNode === linkNode) {
|
15733
15778
|
attrs = templateAttrs;
|
@@ -15821,14 +15866,14 @@ function $CompileProvider($provide) {
|
|
15821
15866
|
}
|
15822
15867
|
});
|
15823
15868
|
}
|
15824
|
-
|
15869
|
+
transcludeFn = boundTranscludeFn && controllersBoundTransclude;
|
15825
15870
|
if (controllerDirectives) {
|
15826
15871
|
forEach(controllerDirectives, function(directive) {
|
15827
15872
|
var locals = {
|
15828
15873
|
$scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
|
15829
15874
|
$element: $element,
|
15830
15875
|
$attrs: attrs,
|
15831
|
-
$transclude:
|
15876
|
+
$transclude: transcludeFn
|
15832
15877
|
}, controllerInstance;
|
15833
15878
|
|
15834
15879
|
controller = directive.controller;
|
@@ -15837,16 +15882,16 @@ function $CompileProvider($provide) {
|
|
15837
15882
|
}
|
15838
15883
|
|
15839
15884
|
controllerInstance = $controller(controller, locals);
|
15840
|
-
|
15841
|
-
//
|
15842
|
-
//
|
15843
|
-
//
|
15844
|
-
//
|
15845
|
-
|
15846
|
-
|
15847
|
-
} else {
|
15885
|
+
// For directives with element transclusion the element is a comment,
|
15886
|
+
// but jQuery .data doesn't support attaching data to comment nodes as it's hard to
|
15887
|
+
// clean up (http://bugs.jquery.com/ticket/8335).
|
15888
|
+
// Instead, we save the controllers for the element in a local hash and attach to .data
|
15889
|
+
// later, once we have the actual element.
|
15890
|
+
elementControllers[directive.name] = controllerInstance;
|
15891
|
+
if (!hasElementTranscludeDirective) {
|
15848
15892
|
$element.data('$' + directive.name + 'Controller', controllerInstance);
|
15849
15893
|
}
|
15894
|
+
|
15850
15895
|
if (directive.controllerAs) {
|
15851
15896
|
locals.$scope[directive.controllerAs] = controllerInstance;
|
15852
15897
|
}
|
@@ -15858,7 +15903,7 @@ function $CompileProvider($provide) {
|
|
15858
15903
|
try {
|
15859
15904
|
linkFn = preLinkFns[i];
|
15860
15905
|
linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs,
|
15861
|
-
linkFn.require && getControllers(linkFn.require, $element));
|
15906
|
+
linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn);
|
15862
15907
|
} catch (e) {
|
15863
15908
|
$exceptionHandler(e, startingTag($element));
|
15864
15909
|
}
|
@@ -15878,11 +15923,28 @@ function $CompileProvider($provide) {
|
|
15878
15923
|
try {
|
15879
15924
|
linkFn = postLinkFns[i];
|
15880
15925
|
linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs,
|
15881
|
-
linkFn.require && getControllers(linkFn.require, $element));
|
15926
|
+
linkFn.require && getControllers(linkFn.require, $element, elementControllers), transcludeFn);
|
15882
15927
|
} catch (e) {
|
15883
15928
|
$exceptionHandler(e, startingTag($element));
|
15884
15929
|
}
|
15885
15930
|
}
|
15931
|
+
|
15932
|
+
// This is the function that is injected as `$transclude`.
|
15933
|
+
function controllersBoundTransclude(scope, cloneAttachFn) {
|
15934
|
+
var transcludeControllers;
|
15935
|
+
|
15936
|
+
// no scope passed
|
15937
|
+
if (arguments.length < 2) {
|
15938
|
+
cloneAttachFn = scope;
|
15939
|
+
scope = undefined;
|
15940
|
+
}
|
15941
|
+
|
15942
|
+
if (hasElementTranscludeDirective) {
|
15943
|
+
transcludeControllers = elementControllers;
|
15944
|
+
}
|
15945
|
+
|
15946
|
+
return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers);
|
15947
|
+
}
|
15886
15948
|
}
|
15887
15949
|
}
|
15888
15950
|
|
@@ -15961,6 +16023,7 @@ function $CompileProvider($provide) {
|
|
15961
16023
|
dst['class'] = (dst['class'] ? dst['class'] + ' ' : '') + value;
|
15962
16024
|
} else if (key == 'style') {
|
15963
16025
|
$element.attr('style', $element.attr('style') + ';' + value);
|
16026
|
+
dst['style'] = (dst['style'] ? dst['style'] + ';' : '') + value;
|
15964
16027
|
// `dst` will never contain hasOwnProperty as DOM parser won't let it.
|
15965
16028
|
// You will get an "InvalidCharacterError: DOM Exception 5" error if you
|
15966
16029
|
// have an attribute like "has-own-property" or "data-has-own-property", etc.
|
@@ -15991,7 +16054,7 @@ function $CompileProvider($provide) {
|
|
15991
16054
|
|
15992
16055
|
$http.get($sce.getTrustedResourceUrl(templateUrl), {cache: $templateCache}).
|
15993
16056
|
success(function(content) {
|
15994
|
-
var compileNode, tempTemplateAttrs, $template;
|
16057
|
+
var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn;
|
15995
16058
|
|
15996
16059
|
content = denormalizeTemplate(content);
|
15997
16060
|
|
@@ -16036,7 +16099,7 @@ function $CompileProvider($provide) {
|
|
16036
16099
|
var scope = linkQueue.shift(),
|
16037
16100
|
beforeTemplateLinkNode = linkQueue.shift(),
|
16038
16101
|
linkRootElement = linkQueue.shift(),
|
16039
|
-
|
16102
|
+
boundTranscludeFn = linkQueue.shift(),
|
16040
16103
|
linkNode = $compileNode[0];
|
16041
16104
|
|
16042
16105
|
if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {
|
@@ -16044,9 +16107,13 @@ function $CompileProvider($provide) {
|
|
16044
16107
|
linkNode = jqLiteClone(compileNode);
|
16045
16108
|
replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);
|
16046
16109
|
}
|
16047
|
-
|
16110
|
+
if (afterTemplateNodeLinkFn.transclude) {
|
16111
|
+
childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude);
|
16112
|
+
} else {
|
16113
|
+
childBoundTranscludeFn = boundTranscludeFn;
|
16114
|
+
}
|
16048
16115
|
afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement,
|
16049
|
-
|
16116
|
+
childBoundTranscludeFn);
|
16050
16117
|
}
|
16051
16118
|
linkQueue = null;
|
16052
16119
|
}).
|
@@ -16054,14 +16121,14 @@ function $CompileProvider($provide) {
|
|
16054
16121
|
throw $compileMinErr('tpload', 'Failed to load template: {0}', config.url);
|
16055
16122
|
});
|
16056
16123
|
|
16057
|
-
return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement,
|
16124
|
+
return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, boundTranscludeFn) {
|
16058
16125
|
if (linkQueue) {
|
16059
16126
|
linkQueue.push(scope);
|
16060
16127
|
linkQueue.push(node);
|
16061
16128
|
linkQueue.push(rootElement);
|
16062
|
-
linkQueue.push(
|
16129
|
+
linkQueue.push(boundTranscludeFn);
|
16063
16130
|
} else {
|
16064
|
-
afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement,
|
16131
|
+
afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, boundTranscludeFn);
|
16065
16132
|
}
|
16066
16133
|
};
|
16067
16134
|
}
|
@@ -16106,10 +16173,15 @@ function $CompileProvider($provide) {
|
|
16106
16173
|
|
16107
16174
|
|
16108
16175
|
function getTrustedContext(node, attrNormalizedName) {
|
16176
|
+
if (attrNormalizedName == "srcdoc") {
|
16177
|
+
return $sce.HTML;
|
16178
|
+
}
|
16179
|
+
var tag = nodeName_(node);
|
16109
16180
|
// maction[xlink:href] can source SVG. It's not limited to <maction>.
|
16110
16181
|
if (attrNormalizedName == "xlinkHref" ||
|
16111
|
-
(
|
16112
|
-
|
16182
|
+
(tag == "FORM" && attrNormalizedName == "action") ||
|
16183
|
+
(tag != "IMG" && (attrNormalizedName == "src" ||
|
16184
|
+
attrNormalizedName == "ngSrc"))) {
|
16113
16185
|
return $sce.RESOURCE_URL;
|
16114
16186
|
}
|
16115
16187
|
}
|
@@ -16154,9 +16226,19 @@ function $CompileProvider($provide) {
|
|
16154
16226
|
attr[name] = interpolateFn(scope);
|
16155
16227
|
($$observers[name] || ($$observers[name] = [])).$$inter = true;
|
16156
16228
|
(attr.$$observers && attr.$$observers[name].$$scope || scope).
|
16157
|
-
|
16158
|
-
|
16159
|
-
|
16229
|
+
$watch(interpolateFn, function interpolateFnWatchAction(newValue, oldValue) {
|
16230
|
+
//special case for class attribute addition + removal
|
16231
|
+
//so that class changes can tap into the animation
|
16232
|
+
//hooks provided by the $animate service. Be sure to
|
16233
|
+
//skip animations when the first digest occurs (when
|
16234
|
+
//both the new and the old values are the same) since
|
16235
|
+
//the CSS classes are the non-interpolated values
|
16236
|
+
if(name === 'class' && newValue != oldValue) {
|
16237
|
+
attr.$updateClass(newValue, oldValue);
|
16238
|
+
} else {
|
16239
|
+
attr.$set(name, newValue);
|
16240
|
+
}
|
16241
|
+
});
|
16160
16242
|
}
|
16161
16243
|
};
|
16162
16244
|
}
|
@@ -16297,6 +16379,22 @@ function directiveLinkingFn(
|
|
16297
16379
|
/* function(Function) */ boundTranscludeFn
|
16298
16380
|
){}
|
16299
16381
|
|
16382
|
+
function tokenDifference(str1, str2) {
|
16383
|
+
var values = '',
|
16384
|
+
tokens1 = str1.split(/\s+/),
|
16385
|
+
tokens2 = str2.split(/\s+/);
|
16386
|
+
|
16387
|
+
outer:
|
16388
|
+
for(var i = 0; i < tokens1.length; i++) {
|
16389
|
+
var token = tokens1[i];
|
16390
|
+
for(var j = 0; j < tokens2.length; j++) {
|
16391
|
+
if(token == tokens2[j]) continue outer;
|
16392
|
+
}
|
16393
|
+
values += (values.length > 0 ? ' ' : '') + token;
|
16394
|
+
}
|
16395
|
+
return values;
|
16396
|
+
}
|
16397
|
+
|
16300
16398
|
/**
|
16301
16399
|
* @ngdoc object
|
16302
16400
|
* @name ng.$controllerProvider
|
@@ -16766,9 +16864,11 @@ function $HttpProvider() {
|
|
16766
16864
|
*
|
16767
16865
|
* # Caching
|
16768
16866
|
*
|
16769
|
-
* To enable caching, set the configuration
|
16770
|
-
*
|
16771
|
-
*
|
16867
|
+
* To enable caching, set the request configuration `cache` property to `true` (to use default
|
16868
|
+
* cache) or to a custom cache object (built with {@link ng.$cacheFactory `$cacheFactory`}).
|
16869
|
+
* When the cache is enabled, `$http` stores the response from the server in the specified
|
16870
|
+
* cache. The next time the same request is made, the response is served from the cache without
|
16871
|
+
* sending a request to the server.
|
16772
16872
|
*
|
16773
16873
|
* Note that even if the response is served from cache, delivery of the data is asynchronous in
|
16774
16874
|
* the same way that real requests are.
|
@@ -16777,9 +16877,13 @@ function $HttpProvider() {
|
|
16777
16877
|
* cache, but the cache is not populated yet, only one request to the server will be made and
|
16778
16878
|
* the remaining requests will be fulfilled using the response from the first request.
|
16779
16879
|
*
|
16780
|
-
*
|
16781
|
-
*
|
16880
|
+
* You can change the default cache to a new object (built with
|
16881
|
+
* {@link ng.$cacheFactory `$cacheFactory`}) by updating the
|
16882
|
+
* {@link ng.$http#properties_defaults `$http.defaults.cache`} property. All requests who set
|
16883
|
+
* their `cache` property to `true` will now use this cache object.
|
16782
16884
|
*
|
16885
|
+
* If you set the default cache to `false` then only requests that specify their own custom
|
16886
|
+
* cache object will be cached.
|
16783
16887
|
*
|
16784
16888
|
* # Interceptors
|
16785
16889
|
*
|
@@ -17501,12 +17605,13 @@ var XHR = window.XMLHttpRequest || function() {
|
|
17501
17605
|
*/
|
17502
17606
|
function $HttpBackendProvider() {
|
17503
17607
|
this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) {
|
17504
|
-
return createHttpBackend($browser, XHR, $browser.defer, $window.angular.callbacks,
|
17505
|
-
$document[0], $window.location.protocol.replace(':', ''));
|
17608
|
+
return createHttpBackend($browser, XHR, $browser.defer, $window.angular.callbacks, $document[0]);
|
17506
17609
|
}];
|
17507
17610
|
}
|
17508
17611
|
|
17509
|
-
function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument
|
17612
|
+
function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument) {
|
17613
|
+
var ABORTED = -1;
|
17614
|
+
|
17510
17615
|
// TODO(vojta): fix the signature
|
17511
17616
|
return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
|
17512
17617
|
var status;
|
@@ -17542,13 +17647,19 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
|
|
17542
17647
|
// always async
|
17543
17648
|
xhr.onreadystatechange = function() {
|
17544
17649
|
if (xhr.readyState == 4) {
|
17545
|
-
var responseHeaders =
|
17650
|
+
var responseHeaders = null,
|
17651
|
+
response = null;
|
17652
|
+
|
17653
|
+
if(status !== ABORTED) {
|
17654
|
+
responseHeaders = xhr.getAllResponseHeaders();
|
17655
|
+
response = xhr.responseType ? xhr.response : xhr.responseText;
|
17656
|
+
}
|
17546
17657
|
|
17547
17658
|
// responseText is the old-school way of retrieving response (supported by IE8 & 9)
|
17548
17659
|
// response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
|
17549
17660
|
completeRequest(callback,
|
17550
17661
|
status || xhr.status,
|
17551
|
-
|
17662
|
+
response,
|
17552
17663
|
responseHeaders);
|
17553
17664
|
}
|
17554
17665
|
};
|
@@ -17572,20 +17683,20 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
|
|
17572
17683
|
|
17573
17684
|
|
17574
17685
|
function timeoutRequest() {
|
17575
|
-
status =
|
17686
|
+
status = ABORTED;
|
17576
17687
|
jsonpDone && jsonpDone();
|
17577
17688
|
xhr && xhr.abort();
|
17578
17689
|
}
|
17579
17690
|
|
17580
17691
|
function completeRequest(callback, status, response, headersString) {
|
17581
|
-
var protocol =
|
17692
|
+
var protocol = urlResolve(url).protocol;
|
17582
17693
|
|
17583
17694
|
// cancel timeout and subsequent timeout promise resolution
|
17584
17695
|
timeoutId && $browserDefer.cancel(timeoutId);
|
17585
17696
|
jsonpDone = xhr = null;
|
17586
17697
|
|
17587
17698
|
// fix status code for file protocol (it's always 0)
|
17588
|
-
status = (protocol == 'file') ? (response ? 200 : 404) : status;
|
17699
|
+
status = (protocol == 'file' && status === 0) ? (response ? 200 : 404) : status;
|
17589
17700
|
|
17590
17701
|
// normalize IE bug (http://bugs.jquery.com/ticket/1450)
|
17591
17702
|
status = status == 1223 ? 204 : status;
|
@@ -17601,6 +17712,7 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
|
|
17601
17712
|
// - adds and immediately removes script elements from the document
|
17602
17713
|
var script = rawDocument.createElement('script'),
|
17603
17714
|
doneWrapper = function() {
|
17715
|
+
script.onreadystatechange = script.onload = script.onerror = null;
|
17604
17716
|
rawDocument.body.removeChild(script);
|
17605
17717
|
if (done) done();
|
17606
17718
|
};
|
@@ -17608,12 +17720,16 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
|
|
17608
17720
|
script.type = 'text/javascript';
|
17609
17721
|
script.src = url;
|
17610
17722
|
|
17611
|
-
if (msie) {
|
17723
|
+
if (msie && msie <= 8) {
|
17612
17724
|
script.onreadystatechange = function() {
|
17613
|
-
if (/loaded|complete/.test(script.readyState))
|
17725
|
+
if (/loaded|complete/.test(script.readyState)) {
|
17726
|
+
doneWrapper();
|
17727
|
+
}
|
17614
17728
|
};
|
17615
17729
|
} else {
|
17616
|
-
script.onload = script.onerror =
|
17730
|
+
script.onload = script.onerror = function() {
|
17731
|
+
doneWrapper();
|
17732
|
+
};
|
17617
17733
|
}
|
17618
17734
|
|
17619
17735
|
rawDocument.body.appendChild(script);
|
@@ -18043,8 +18159,8 @@ function encodePath(path) {
|
|
18043
18159
|
return segments.join('/');
|
18044
18160
|
}
|
18045
18161
|
|
18046
|
-
function parseAbsoluteUrl(absoluteUrl, locationObj) {
|
18047
|
-
var parsedUrl = urlResolve(absoluteUrl);
|
18162
|
+
function parseAbsoluteUrl(absoluteUrl, locationObj, appBase) {
|
18163
|
+
var parsedUrl = urlResolve(absoluteUrl, appBase);
|
18048
18164
|
|
18049
18165
|
locationObj.$$protocol = parsedUrl.protocol;
|
18050
18166
|
locationObj.$$host = parsedUrl.hostname;
|
@@ -18052,12 +18168,12 @@ function parseAbsoluteUrl(absoluteUrl, locationObj) {
|
|
18052
18168
|
}
|
18053
18169
|
|
18054
18170
|
|
18055
|
-
function parseAppUrl(relativeUrl, locationObj) {
|
18171
|
+
function parseAppUrl(relativeUrl, locationObj, appBase) {
|
18056
18172
|
var prefixed = (relativeUrl.charAt(0) !== '/');
|
18057
18173
|
if (prefixed) {
|
18058
18174
|
relativeUrl = '/' + relativeUrl;
|
18059
18175
|
}
|
18060
|
-
var match = urlResolve(relativeUrl);
|
18176
|
+
var match = urlResolve(relativeUrl, appBase);
|
18061
18177
|
locationObj.$$path = decodeURIComponent(prefixed && match.pathname.charAt(0) === '/' ?
|
18062
18178
|
match.pathname.substring(1) : match.pathname);
|
18063
18179
|
locationObj.$$search = parseKeyValue(match.search);
|
@@ -18112,7 +18228,7 @@ function LocationHtml5Url(appBase, basePrefix) {
|
|
18112
18228
|
this.$$html5 = true;
|
18113
18229
|
basePrefix = basePrefix || '';
|
18114
18230
|
var appBaseNoFile = stripFile(appBase);
|
18115
|
-
parseAbsoluteUrl(appBase, this);
|
18231
|
+
parseAbsoluteUrl(appBase, this, appBase);
|
18116
18232
|
|
18117
18233
|
|
18118
18234
|
/**
|
@@ -18127,7 +18243,7 @@ function LocationHtml5Url(appBase, basePrefix) {
|
|
18127
18243
|
appBaseNoFile);
|
18128
18244
|
}
|
18129
18245
|
|
18130
|
-
parseAppUrl(pathUrl, this);
|
18246
|
+
parseAppUrl(pathUrl, this, appBase);
|
18131
18247
|
|
18132
18248
|
if (!this.$$path) {
|
18133
18249
|
this.$$path = '/';
|
@@ -18179,7 +18295,7 @@ function LocationHtml5Url(appBase, basePrefix) {
|
|
18179
18295
|
function LocationHashbangUrl(appBase, hashPrefix) {
|
18180
18296
|
var appBaseNoFile = stripFile(appBase);
|
18181
18297
|
|
18182
|
-
parseAbsoluteUrl(appBase, this);
|
18298
|
+
parseAbsoluteUrl(appBase, this, appBase);
|
18183
18299
|
|
18184
18300
|
|
18185
18301
|
/**
|
@@ -18199,8 +18315,48 @@ function LocationHashbangUrl(appBase, hashPrefix) {
|
|
18199
18315
|
throw $locationMinErr('ihshprfx', 'Invalid url "{0}", missing hash prefix "{1}".', url,
|
18200
18316
|
hashPrefix);
|
18201
18317
|
}
|
18202
|
-
parseAppUrl(withoutHashUrl, this);
|
18318
|
+
parseAppUrl(withoutHashUrl, this, appBase);
|
18319
|
+
|
18320
|
+
this.$$path = removeWindowsDriveName(this.$$path, withoutHashUrl, appBase);
|
18321
|
+
|
18203
18322
|
this.$$compose();
|
18323
|
+
|
18324
|
+
/*
|
18325
|
+
* In Windows, on an anchor node on documents loaded from
|
18326
|
+
* the filesystem, the browser will return a pathname
|
18327
|
+
* prefixed with the drive name ('/C:/path') when a
|
18328
|
+
* pathname without a drive is set:
|
18329
|
+
* * a.setAttribute('href', '/foo')
|
18330
|
+
* * a.pathname === '/C:/foo' //true
|
18331
|
+
*
|
18332
|
+
* Inside of Angular, we're always using pathnames that
|
18333
|
+
* do not include drive names for routing.
|
18334
|
+
*/
|
18335
|
+
function removeWindowsDriveName (path, url, base) {
|
18336
|
+
/*
|
18337
|
+
Matches paths for file protocol on windows,
|
18338
|
+
such as /C:/foo/bar, and captures only /foo/bar.
|
18339
|
+
*/
|
18340
|
+
var windowsFilePathExp = /^\/?.*?:(\/.*)/;
|
18341
|
+
|
18342
|
+
var firstPathSegmentMatch;
|
18343
|
+
|
18344
|
+
//Get the relative path from the input URL.
|
18345
|
+
if (url.indexOf(base) === 0) {
|
18346
|
+
url = url.replace(base, '');
|
18347
|
+
}
|
18348
|
+
|
18349
|
+
/*
|
18350
|
+
* The input URL intentionally contains a
|
18351
|
+
* first path segment that ends with a colon.
|
18352
|
+
*/
|
18353
|
+
if (windowsFilePathExp.exec(url)) {
|
18354
|
+
return path;
|
18355
|
+
}
|
18356
|
+
|
18357
|
+
firstPathSegmentMatch = windowsFilePathExp.exec(path);
|
18358
|
+
return firstPathSegmentMatch ? firstPathSegmentMatch[1] : path;
|
18359
|
+
}
|
18204
18360
|
};
|
18205
18361
|
|
18206
18362
|
/**
|
@@ -18690,7 +18846,7 @@ function $LocationProvider(){
|
|
18690
18846
|
*
|
18691
18847
|
* The main purpose of this service is to simplify debugging and troubleshooting.
|
18692
18848
|
*
|
18693
|
-
* The default is
|
18849
|
+
* The default is to log `debug` messages. You can use
|
18694
18850
|
* {@link ng.$logProvider ng.$logProvider#debugEnabled} to change this.
|
18695
18851
|
*
|
18696
18852
|
* @example
|
@@ -18847,23 +19003,18 @@ var promiseWarning;
|
|
18847
19003
|
// ------------------------------
|
18848
19004
|
// Angular expressions are generally considered safe because these expressions only have direct
|
18849
19005
|
// access to $scope and locals. However, one can obtain the ability to execute arbitrary JS code by
|
18850
|
-
// obtaining a reference to native JS functions such as the Function constructor
|
18851
|
-
// or Document object. In addition, many powerful functions for use by JavaScript code are
|
18852
|
-
// published on scope that shouldn't be available from within an Angular expression.
|
19006
|
+
// obtaining a reference to native JS functions such as the Function constructor.
|
18853
19007
|
//
|
18854
19008
|
// As an example, consider the following Angular expression:
|
18855
19009
|
//
|
18856
19010
|
// {}.toString.constructor(alert("evil JS code"))
|
18857
19011
|
//
|
18858
19012
|
// We want to prevent this type of access. For the sake of performance, during the lexing phase we
|
18859
|
-
// disallow any "dotted" access to any member named "constructor"
|
18860
|
-
// or ends with an underscore. The latter allows one to exclude the private / JavaScript only API
|
18861
|
-
// available on the scope and controllers from the context of an Angular expression.
|
19013
|
+
// disallow any "dotted" access to any member named "constructor".
|
18862
19014
|
//
|
18863
|
-
// For reflective calls (a[b])
|
18864
|
-
//
|
18865
|
-
//
|
18866
|
-
// to static dereferencing.
|
19015
|
+
// For reflective calls (a[b]) we check that the value of the lookup is not the Function constructor
|
19016
|
+
// while evaluating the expression, which is a stronger but more expensive test. Since reflective
|
19017
|
+
// calls are expensive anyway, this is not such a big deal compared to static dereferencing.
|
18867
19018
|
//
|
18868
19019
|
// This sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits
|
18869
19020
|
// against the expression language, but not to prevent exploits that were enabled by exposing
|
@@ -18877,20 +19028,12 @@ var promiseWarning;
|
|
18877
19028
|
// In general, it is not possible to access a Window object from an angular expression unless a
|
18878
19029
|
// window or some DOM object that has a reference to window is published onto a Scope.
|
18879
19030
|
|
18880
|
-
function ensureSafeMemberName(name, fullExpression
|
18881
|
-
if (
|
18882
|
-
return name;
|
18883
|
-
}
|
18884
|
-
if (name === "constructor" && !allowConstructor) {
|
19031
|
+
function ensureSafeMemberName(name, fullExpression) {
|
19032
|
+
if (name === "constructor") {
|
18885
19033
|
throw $parseMinErr('isecfld',
|
18886
19034
|
'Referencing "constructor" field in Angular expressions is disallowed! Expression: {0}',
|
18887
19035
|
fullExpression);
|
18888
19036
|
}
|
18889
|
-
if (name.charAt(0) === '_' || name.charAt(name.length-1) === '_') {
|
18890
|
-
throw $parseMinErr('isecprv',
|
18891
|
-
'Referencing private fields in Angular expressions is disallowed! Expression: {0}',
|
18892
|
-
fullExpression);
|
18893
|
-
}
|
18894
19037
|
return name;
|
18895
19038
|
}
|
18896
19039
|
|
@@ -19574,10 +19717,7 @@ Parser.prototype = {
|
|
19574
19717
|
|
19575
19718
|
return extend(function(self, locals) {
|
19576
19719
|
var o = obj(self, locals),
|
19577
|
-
|
19578
|
-
// constructors. However, if value looked up is the Function constructor, we will still block it in the
|
19579
|
-
// ensureSafeObject call right after we look up o[i] (a few lines below.)
|
19580
|
-
i = ensureSafeMemberName(indexFn(self, locals), parser.text, true /* allowConstructor */),
|
19720
|
+
i = indexFn(self, locals),
|
19581
19721
|
v, p;
|
19582
19722
|
|
19583
19723
|
if (!o) return undefined;
|
@@ -19593,7 +19733,7 @@ Parser.prototype = {
|
|
19593
19733
|
return v;
|
19594
19734
|
}, {
|
19595
19735
|
assign: function(self, value, locals) {
|
19596
|
-
var key =
|
19736
|
+
var key = indexFn(self, locals);
|
19597
19737
|
// prevent overwriting of Function.constructor which would break ensureSafeObject check
|
19598
19738
|
var safe = ensureSafeObject(obj(self, locals), parser.text);
|
19599
19739
|
return safe[key] = value;
|
@@ -19872,7 +20012,7 @@ function getterFn(path, options, fullExp) {
|
|
19872
20012
|
: '((k&&k.hasOwnProperty("' + key + '"))?k:s)') + '["' + key + '"]' + ';\n' +
|
19873
20013
|
(options.unwrapPromises
|
19874
20014
|
? 'if (s && s.then) {\n' +
|
19875
|
-
' pw("' + fullExp.replace(
|
20015
|
+
' pw("' + fullExp.replace(/(["\r\n])/g, '\\$1') + '");\n' +
|
19876
20016
|
' if (!("$$v" in s)) {\n' +
|
19877
20017
|
' p=s;\n' +
|
19878
20018
|
' p.$$v = undefined;\n' +
|
@@ -20253,7 +20393,7 @@ function $ParseProvider() {
|
|
20253
20393
|
* // Propagate promise resolution to 'then' functions using $apply().
|
20254
20394
|
* $rootScope.$apply();
|
20255
20395
|
* expect(resolvedValue).toEqual(123);
|
20256
|
-
* });
|
20396
|
+
* }));
|
20257
20397
|
* </pre>
|
20258
20398
|
*/
|
20259
20399
|
function $QProvider() {
|
@@ -21643,6 +21783,79 @@ function $RootScopeProvider(){
|
|
21643
21783
|
}];
|
21644
21784
|
}
|
21645
21785
|
|
21786
|
+
/**
|
21787
|
+
* @description
|
21788
|
+
* Private service to sanitize uris for links and images. Used by $compile and $sanitize.
|
21789
|
+
*/
|
21790
|
+
function $$SanitizeUriProvider() {
|
21791
|
+
var aHrefSanitizationWhitelist = /^\s*(https?|ftp|mailto|tel|file):/,
|
21792
|
+
imgSrcSanitizationWhitelist = /^\s*(https?|ftp|file):|data:image\//;
|
21793
|
+
|
21794
|
+
/**
|
21795
|
+
* @description
|
21796
|
+
* Retrieves or overrides the default regular expression that is used for whitelisting of safe
|
21797
|
+
* urls during a[href] sanitization.
|
21798
|
+
*
|
21799
|
+
* The sanitization is a security measure aimed at prevent XSS attacks via html links.
|
21800
|
+
*
|
21801
|
+
* Any url about to be assigned to a[href] via data-binding is first normalized and turned into
|
21802
|
+
* an absolute url. Afterwards, the url is matched against the `aHrefSanitizationWhitelist`
|
21803
|
+
* regular expression. If a match is found, the original url is written into the dom. Otherwise,
|
21804
|
+
* the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
|
21805
|
+
*
|
21806
|
+
* @param {RegExp=} regexp New regexp to whitelist urls with.
|
21807
|
+
* @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
|
21808
|
+
* chaining otherwise.
|
21809
|
+
*/
|
21810
|
+
this.aHrefSanitizationWhitelist = function(regexp) {
|
21811
|
+
if (isDefined(regexp)) {
|
21812
|
+
aHrefSanitizationWhitelist = regexp;
|
21813
|
+
return this;
|
21814
|
+
}
|
21815
|
+
return aHrefSanitizationWhitelist;
|
21816
|
+
};
|
21817
|
+
|
21818
|
+
|
21819
|
+
/**
|
21820
|
+
* @description
|
21821
|
+
* Retrieves or overrides the default regular expression that is used for whitelisting of safe
|
21822
|
+
* urls during img[src] sanitization.
|
21823
|
+
*
|
21824
|
+
* The sanitization is a security measure aimed at prevent XSS attacks via html links.
|
21825
|
+
*
|
21826
|
+
* Any url about to be assigned to img[src] via data-binding is first normalized and turned into
|
21827
|
+
* an absolute url. Afterwards, the url is matched against the `imgSrcSanitizationWhitelist`
|
21828
|
+
* regular expression. If a match is found, the original url is written into the dom. Otherwise,
|
21829
|
+
* the absolute url is prefixed with `'unsafe:'` string and only then is it written into the DOM.
|
21830
|
+
*
|
21831
|
+
* @param {RegExp=} regexp New regexp to whitelist urls with.
|
21832
|
+
* @returns {RegExp|ng.$compileProvider} Current RegExp if called without value or self for
|
21833
|
+
* chaining otherwise.
|
21834
|
+
*/
|
21835
|
+
this.imgSrcSanitizationWhitelist = function(regexp) {
|
21836
|
+
if (isDefined(regexp)) {
|
21837
|
+
imgSrcSanitizationWhitelist = regexp;
|
21838
|
+
return this;
|
21839
|
+
}
|
21840
|
+
return imgSrcSanitizationWhitelist;
|
21841
|
+
};
|
21842
|
+
|
21843
|
+
this.$get = function() {
|
21844
|
+
return function sanitizeUri(uri, isImage) {
|
21845
|
+
var regex = isImage ? imgSrcSanitizationWhitelist : aHrefSanitizationWhitelist;
|
21846
|
+
var normalizedVal;
|
21847
|
+
// NOTE: urlResolve() doesn't support IE < 8 so we don't sanitize for that case.
|
21848
|
+
if (!msie || msie >= 8 ) {
|
21849
|
+
normalizedVal = urlResolve(uri).href;
|
21850
|
+
if (normalizedVal !== '' && !normalizedVal.match(regex)) {
|
21851
|
+
return 'unsafe:'+normalizedVal;
|
21852
|
+
}
|
21853
|
+
}
|
21854
|
+
return uri;
|
21855
|
+
};
|
21856
|
+
};
|
21857
|
+
}
|
21858
|
+
|
21646
21859
|
var $sceMinErr = minErr('$sce');
|
21647
21860
|
|
21648
21861
|
var SCE_CONTEXTS = {
|
@@ -21842,8 +22055,7 @@ function $SceDelegateProvider() {
|
|
21842
22055
|
return resourceUrlBlacklist;
|
21843
22056
|
};
|
21844
22057
|
|
21845
|
-
this.$get = ['$
|
21846
|
-
$log, $document, $injector) {
|
22058
|
+
this.$get = ['$injector', function($injector) {
|
21847
22059
|
|
21848
22060
|
var htmlSanitizer = function htmlSanitizer(html) {
|
21849
22061
|
throw $sceMinErr('unsafe', 'Attempting to use an unsafe value in a safe context.');
|
@@ -22070,10 +22282,10 @@ function $SceDelegateProvider() {
|
|
22070
22282
|
*
|
22071
22283
|
* <pre class="prettyprint">
|
22072
22284
|
* <input ng-model="userHtml">
|
22073
|
-
* <div ng-bind-html="
|
22285
|
+
* <div ng-bind-html="userHtml">
|
22074
22286
|
* </pre>
|
22075
22287
|
*
|
22076
|
-
* Notice that `ng-bind-html` is bound to `
|
22288
|
+
* Notice that `ng-bind-html` is bound to `userHtml` controlled by the user. With SCE
|
22077
22289
|
* disabled, this application allows the user to render arbitrary HTML into the DIV.
|
22078
22290
|
* In a more realistic example, one may be rendering user comments, blog articles, etc. via
|
22079
22291
|
* bindings. (HTML is just one example of a context where rendering user controlled input creates
|
@@ -22374,18 +22586,15 @@ function $SceProvider() {
|
|
22374
22586
|
* sce.js and sceSpecs.js would need to be aware of this detail.
|
22375
22587
|
*/
|
22376
22588
|
|
22377
|
-
this.$get = ['$parse', '$
|
22378
|
-
$parse, $
|
22589
|
+
this.$get = ['$parse', '$sniffer', '$sceDelegate', function(
|
22590
|
+
$parse, $sniffer, $sceDelegate) {
|
22379
22591
|
// Prereq: Ensure that we're not running in IE8 quirks mode. In that mode, IE allows
|
22380
22592
|
// the "expression(javascript expression)" syntax which is insecure.
|
22381
|
-
if (enabled && msie) {
|
22382
|
-
|
22383
|
-
|
22384
|
-
|
22385
|
-
|
22386
|
-
'mode. You can fix this by adding the text <!doctype html> to the top of your HTML ' +
|
22387
|
-
'document. See http://docs.angularjs.org/api/ng.$sce for more information.');
|
22388
|
-
}
|
22593
|
+
if (enabled && $sniffer.msie && $sniffer.msieDocumentMode < 8) {
|
22594
|
+
throw $sceMinErr('iequirks',
|
22595
|
+
'Strict Contextual Escaping does not support Internet Explorer version < 9 in quirks ' +
|
22596
|
+
'mode. You can fix this by adding the text <!doctype html> to the top of your HTML ' +
|
22597
|
+
'document. See http://docs.angularjs.org/api/ng.$sce for more information.');
|
22389
22598
|
}
|
22390
22599
|
|
22391
22600
|
var sce = copy(SCE_CONTEXTS);
|
@@ -22747,6 +22956,7 @@ function $SnifferProvider() {
|
|
22747
22956
|
int((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]),
|
22748
22957
|
boxee = /Boxee/i.test(($window.navigator || {}).userAgent),
|
22749
22958
|
document = $document[0] || {},
|
22959
|
+
documentMode = document.documentMode,
|
22750
22960
|
vendorPrefix,
|
22751
22961
|
vendorRegex = /^(Moz|webkit|O|ms)(?=[A-Z])/,
|
22752
22962
|
bodyStyle = document.body && document.body.style,
|
@@ -22791,7 +23001,7 @@ function $SnifferProvider() {
|
|
22791
23001
|
// jshint +W018
|
22792
23002
|
hashchange: 'onhashchange' in $window &&
|
22793
23003
|
// IE8 compatible mode lies
|
22794
|
-
(!
|
23004
|
+
(!documentMode || documentMode > 7),
|
22795
23005
|
hasEvent: function(event) {
|
22796
23006
|
// IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
|
22797
23007
|
// it. In particular the event is not fired when backspace or delete key are pressed or
|
@@ -22809,7 +23019,8 @@ function $SnifferProvider() {
|
|
22809
23019
|
vendorPrefix: vendorPrefix,
|
22810
23020
|
transitions : transitions,
|
22811
23021
|
animations : animations,
|
22812
|
-
msie : msie
|
23022
|
+
msie : msie,
|
23023
|
+
msieDocumentMode: documentMode
|
22813
23024
|
};
|
22814
23025
|
}];
|
22815
23026
|
}
|
@@ -22996,6 +23207,7 @@ function $TimeoutProvider() {
|
|
22996
23207
|
var urlParsingNode = document.createElement("a");
|
22997
23208
|
var originUrl = urlResolve(window.location.href, true);
|
22998
23209
|
|
23210
|
+
|
22999
23211
|
/**
|
23000
23212
|
*
|
23001
23213
|
* Implementation Notes for non-IE browsers
|
@@ -23014,7 +23226,7 @@ var originUrl = urlResolve(window.location.href, true);
|
|
23014
23226
|
* browsers. However, the parsed components will not be set if the URL assigned did not specify
|
23015
23227
|
* them. (e.g. if you assign a.href = "foo", then a.protocol, a.host, etc. will be empty.) We
|
23016
23228
|
* work around that by performing the parsing in a 2nd step by taking a previously normalized
|
23017
|
-
* URL (e.g. by
|
23229
|
+
* URL (e.g. by assigning to a.href) and assigning it a.href again. This correctly populates the
|
23018
23230
|
* properties such as protocol, hostname, port, etc.
|
23019
23231
|
*
|
23020
23232
|
* IE7 does not normalize the URL when assigned to an anchor node. (Apparently, it does, if one
|
@@ -23048,8 +23260,9 @@ var originUrl = urlResolve(window.location.href, true);
|
|
23048
23260
|
* | pathname | The pathname, beginning with "/"
|
23049
23261
|
*
|
23050
23262
|
*/
|
23051
|
-
function urlResolve(url) {
|
23263
|
+
function urlResolve(url, base) {
|
23052
23264
|
var href = url;
|
23265
|
+
|
23053
23266
|
if (msie) {
|
23054
23267
|
// Normalize before parse. Refer Implementation Notes on why this is
|
23055
23268
|
// done in two steps on IE.
|
@@ -23059,7 +23272,7 @@ function urlResolve(url) {
|
|
23059
23272
|
|
23060
23273
|
urlParsingNode.setAttribute('href', href);
|
23061
23274
|
|
23062
|
-
//
|
23275
|
+
// urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
|
23063
23276
|
return {
|
23064
23277
|
href: urlParsingNode.href,
|
23065
23278
|
protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
|
@@ -23068,12 +23281,12 @@ function urlResolve(url) {
|
|
23068
23281
|
hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
|
23069
23282
|
hostname: urlParsingNode.hostname,
|
23070
23283
|
port: urlParsingNode.port,
|
23071
|
-
pathname: urlParsingNode.pathname
|
23072
|
-
|
23284
|
+
pathname: (urlParsingNode.pathname.charAt(0) === '/')
|
23285
|
+
? urlParsingNode.pathname
|
23286
|
+
: '/' + urlParsingNode.pathname
|
23073
23287
|
};
|
23074
23288
|
}
|
23075
23289
|
|
23076
|
-
|
23077
23290
|
/**
|
23078
23291
|
* Parse a request URL and determine whether this is a same-origin request as the application document.
|
23079
23292
|
*
|
@@ -24382,8 +24595,11 @@ var htmlAnchorDirective = valueFn({
|
|
24382
24595
|
*
|
24383
24596
|
* The HTML specification does not require browsers to preserve the values of boolean attributes
|
24384
24597
|
* such as disabled. (Their presence means true and their absence means false.)
|
24385
|
-
*
|
24598
|
+
* If we put an Angular interpolation expression into such an attribute then the
|
24599
|
+
* binding information would be lost when the browser removes the attribute.
|
24386
24600
|
* The `ngDisabled` directive solves this problem for the `disabled` attribute.
|
24601
|
+
* This complementary directive is not removed by the browser and so provides
|
24602
|
+
* a permanent reliable place to store the binding information.
|
24387
24603
|
*
|
24388
24604
|
* @example
|
24389
24605
|
<doc:example>
|
@@ -24414,8 +24630,11 @@ var htmlAnchorDirective = valueFn({
|
|
24414
24630
|
* @description
|
24415
24631
|
* The HTML specification does not require browsers to preserve the values of boolean attributes
|
24416
24632
|
* such as checked. (Their presence means true and their absence means false.)
|
24417
|
-
*
|
24633
|
+
* If we put an Angular interpolation expression into such an attribute then the
|
24634
|
+
* binding information would be lost when the browser removes the attribute.
|
24418
24635
|
* The `ngChecked` directive solves this problem for the `checked` attribute.
|
24636
|
+
* This complementary directive is not removed by the browser and so provides
|
24637
|
+
* a permanent reliable place to store the binding information.
|
24419
24638
|
* @example
|
24420
24639
|
<doc:example>
|
24421
24640
|
<doc:source>
|
@@ -24445,8 +24664,12 @@ var htmlAnchorDirective = valueFn({
|
|
24445
24664
|
* @description
|
24446
24665
|
* The HTML specification does not require browsers to preserve the values of boolean attributes
|
24447
24666
|
* such as readonly. (Their presence means true and their absence means false.)
|
24448
|
-
*
|
24667
|
+
* If we put an Angular interpolation expression into such an attribute then the
|
24668
|
+
* binding information would be lost when the browser removes the attribute.
|
24449
24669
|
* The `ngReadonly` directive solves this problem for the `readonly` attribute.
|
24670
|
+
* This complementary directive is not removed by the browser and so provides
|
24671
|
+
* a permanent reliable place to store the binding information.
|
24672
|
+
|
24450
24673
|
* @example
|
24451
24674
|
<doc:example>
|
24452
24675
|
<doc:source>
|
@@ -24476,8 +24699,11 @@ var htmlAnchorDirective = valueFn({
|
|
24476
24699
|
* @description
|
24477
24700
|
* The HTML specification does not require browsers to preserve the values of boolean attributes
|
24478
24701
|
* such as selected. (Their presence means true and their absence means false.)
|
24479
|
-
*
|
24702
|
+
* If we put an Angular interpolation expression into such an attribute then the
|
24703
|
+
* binding information would be lost when the browser removes the attribute.
|
24480
24704
|
* The `ngSelected` directive solves this problem for the `selected` atttribute.
|
24705
|
+
* This complementary directive is not removed by the browser and so provides
|
24706
|
+
* a permanent reliable place to store the binding information.
|
24481
24707
|
* @example
|
24482
24708
|
<doc:example>
|
24483
24709
|
<doc:source>
|
@@ -24509,8 +24735,12 @@ var htmlAnchorDirective = valueFn({
|
|
24509
24735
|
* @description
|
24510
24736
|
* The HTML specification does not require browsers to preserve the values of boolean attributes
|
24511
24737
|
* such as open. (Their presence means true and their absence means false.)
|
24512
|
-
*
|
24738
|
+
* If we put an Angular interpolation expression into such an attribute then the
|
24739
|
+
* binding information would be lost when the browser removes the attribute.
|
24513
24740
|
* The `ngOpen` directive solves this problem for the `open` attribute.
|
24741
|
+
* This complementary directive is not removed by the browser and so provides
|
24742
|
+
* a permanent reliable place to store the binding information.
|
24743
|
+
|
24514
24744
|
*
|
24515
24745
|
* @example
|
24516
24746
|
<doc:example>
|
@@ -24603,7 +24833,7 @@ var nullFormCtrl = {
|
|
24603
24833
|
* @property {Object} $error Is an object hash, containing references to all invalid controls or
|
24604
24834
|
* forms, where:
|
24605
24835
|
*
|
24606
|
-
* - keys are validation tokens (error names) — such as `required`, `url` or `email
|
24836
|
+
* - keys are validation tokens (error names) — such as `required`, `url` or `email`,
|
24607
24837
|
* - values are arrays of controls or forms that are invalid with given error.
|
24608
24838
|
*
|
24609
24839
|
* @description
|
@@ -25340,8 +25570,21 @@ var inputType = {
|
|
25340
25570
|
|
25341
25571
|
|
25342
25572
|
function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
25573
|
+
// In composition mode, users are still inputing intermediate text buffer,
|
25574
|
+
// hold the listener until composition is done.
|
25575
|
+
// More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
|
25576
|
+
var composing = false;
|
25577
|
+
|
25578
|
+
element.on('compositionstart', function() {
|
25579
|
+
composing = true;
|
25580
|
+
});
|
25581
|
+
|
25582
|
+
element.on('compositionend', function() {
|
25583
|
+
composing = false;
|
25584
|
+
});
|
25343
25585
|
|
25344
25586
|
var listener = function() {
|
25587
|
+
if (composing) return;
|
25345
25588
|
var value = element.val();
|
25346
25589
|
|
25347
25590
|
// By default we will trim the value
|
@@ -25384,15 +25627,15 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|
25384
25627
|
deferListener();
|
25385
25628
|
});
|
25386
25629
|
|
25387
|
-
// if user paste into input using mouse, we need "change" event to catch it
|
25388
|
-
element.on('change', listener);
|
25389
|
-
|
25390
25630
|
// if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it
|
25391
25631
|
if ($sniffer.hasEvent('paste')) {
|
25392
25632
|
element.on('paste cut', deferListener);
|
25393
25633
|
}
|
25394
25634
|
}
|
25395
25635
|
|
25636
|
+
// if user paste into input using mouse on older browser
|
25637
|
+
// or form autocomplete on newer browser, we need "change" event to catch it
|
25638
|
+
element.on('change', listener);
|
25396
25639
|
|
25397
25640
|
ctrl.$render = function() {
|
25398
25641
|
element.val(ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue);
|
@@ -25788,6 +26031,11 @@ var VALID_CLASS = 'ng-valid',
|
|
25788
26031
|
* }
|
25789
26032
|
* ngModel.$formatters.push(formatter);
|
25790
26033
|
* </pre>
|
26034
|
+
*
|
26035
|
+
* @property {Array.<Function>} $viewChangeListeners Array of functions to execute whenever the
|
26036
|
+
* view value has changed. It is called with no arguments, and its return value is ignored.
|
26037
|
+
* This can be used in place of additional $watches against the model value.
|
26038
|
+
*
|
25791
26039
|
* @property {Object} $error An object hash with all errors as keys.
|
25792
26040
|
*
|
25793
26041
|
* @property {boolean} $pristine True if user has not interacted with the control yet.
|
@@ -26051,14 +26299,19 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
26051
26299
|
* @methodOf ng.directive:ngModel.NgModelController
|
26052
26300
|
*
|
26053
26301
|
* @description
|
26054
|
-
*
|
26302
|
+
* Update the view value.
|
26055
26303
|
*
|
26056
|
-
* This method should be called from within a DOM event handler.
|
26057
|
-
* For example {@link ng.directive:input input}
|
26304
|
+
* This method should be called when the view value changes, typically from within a DOM event handler.
|
26305
|
+
* For example {@link ng.directive:input input} and
|
26058
26306
|
* {@link ng.directive:select select} directives call it.
|
26059
26307
|
*
|
26060
|
-
* It
|
26061
|
-
*
|
26308
|
+
* It will update the $viewValue, then pass this value through each of the functions in `$parsers`,
|
26309
|
+
* which includes any validators. The value that comes out of this `$parsers` pipeline, be applied to
|
26310
|
+
* `$modelValue` and the **expression** specified in the `ng-model` attribute.
|
26311
|
+
*
|
26312
|
+
* Lastly, all the registered change listeners, in the `$viewChangeListeners` list, are called.
|
26313
|
+
*
|
26314
|
+
* Note that calling this function does not trigger a `$digest`.
|
26062
26315
|
*
|
26063
26316
|
* @param {string} value Value from the view.
|
26064
26317
|
*/
|
@@ -26560,27 +26813,33 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
|
|
26560
26813
|
* @param {expression} ngBindHtml {@link guide/expression Expression} to evaluate.
|
26561
26814
|
*
|
26562
26815
|
* @example
|
26563
|
-
|
26564
|
-
|
26565
|
-
|
26566
|
-
|
26567
|
-
angular.module('ngBindHtmlExample', ['ngSanitize'])
|
26568
|
-
|
26569
|
-
.controller('ngBindHtmlCtrl', ['$scope', function ngBindHtmlCtrl($scope) {
|
26570
|
-
$scope.myHTML = 'I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em>';
|
26571
|
-
}]);
|
26572
|
-
</script>
|
26816
|
+
Try it here: enter text in text box and watch the greeting change.
|
26817
|
+
|
26818
|
+
<example module="ngBindHtmlExample" deps="angular-sanitize.js">
|
26819
|
+
<file name="index.html">
|
26573
26820
|
<div ng-controller="ngBindHtmlCtrl">
|
26574
26821
|
<p ng-bind-html="myHTML"></p>
|
26575
26822
|
</div>
|
26576
|
-
</
|
26577
|
-
|
26823
|
+
</file>
|
26824
|
+
|
26825
|
+
<file name="script.js">
|
26826
|
+
angular.module('ngBindHtmlExample', ['ngSanitize'])
|
26827
|
+
|
26828
|
+
.controller('ngBindHtmlCtrl', ['$scope', function ngBindHtmlCtrl($scope) {
|
26829
|
+
$scope.myHTML =
|
26830
|
+
'I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em>';
|
26831
|
+
}]);
|
26832
|
+
</file>
|
26833
|
+
|
26834
|
+
<file name="scenario.js">
|
26578
26835
|
it('should check ng-bind-html', function() {
|
26579
26836
|
expect(using('.doc-example-live').binding('myHTML')).
|
26580
|
-
toBe(
|
26837
|
+
toBe(
|
26838
|
+
'I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em>'
|
26839
|
+
);
|
26581
26840
|
});
|
26582
|
-
</
|
26583
|
-
</
|
26841
|
+
</file>
|
26842
|
+
</example>
|
26584
26843
|
*/
|
26585
26844
|
var ngBindHtmlDirective = ['$sce', '$parse', function($sce, $parse) {
|
26586
26845
|
return function(scope, element, attr) {
|
@@ -26615,11 +26874,10 @@ function classDirective(name, selector) {
|
|
26615
26874
|
// jshint bitwise: false
|
26616
26875
|
var mod = $index & 1;
|
26617
26876
|
if (mod !== old$index & 1) {
|
26618
|
-
|
26619
|
-
|
26620
|
-
|
26621
|
-
removeClass(
|
26622
|
-
}
|
26877
|
+
var classes = flattenClasses(scope.$eval(attr[name]));
|
26878
|
+
mod === selector ?
|
26879
|
+
attr.$addClass(classes) :
|
26880
|
+
attr.$removeClass(classes);
|
26623
26881
|
}
|
26624
26882
|
});
|
26625
26883
|
}
|
@@ -26627,24 +26885,17 @@ function classDirective(name, selector) {
|
|
26627
26885
|
|
26628
26886
|
function ngClassWatchAction(newVal) {
|
26629
26887
|
if (selector === true || scope.$index % 2 === selector) {
|
26630
|
-
|
26631
|
-
|
26888
|
+
var newClasses = flattenClasses(newVal || '');
|
26889
|
+
if(!oldVal) {
|
26890
|
+
attr.$addClass(newClasses);
|
26891
|
+
} else if(!equals(newVal,oldVal)) {
|
26892
|
+
attr.$updateClass(newClasses, flattenClasses(oldVal));
|
26632
26893
|
}
|
26633
|
-
addClass(newVal);
|
26634
26894
|
}
|
26635
26895
|
oldVal = copy(newVal);
|
26636
26896
|
}
|
26637
26897
|
|
26638
26898
|
|
26639
|
-
function removeClass(classVal) {
|
26640
|
-
attr.$removeClass(flattenClasses(classVal));
|
26641
|
-
}
|
26642
|
-
|
26643
|
-
|
26644
|
-
function addClass(classVal) {
|
26645
|
-
attr.$addClass(flattenClasses(classVal));
|
26646
|
-
}
|
26647
|
-
|
26648
26899
|
function flattenClasses(classVal) {
|
26649
26900
|
if(isArray(classVal)) {
|
26650
26901
|
return classVal.join(' ');
|
@@ -26693,18 +26944,18 @@ function classDirective(name, selector) {
|
|
26693
26944
|
* @example Example that demonstrates basic bindings via ngClass directive.
|
26694
26945
|
<example>
|
26695
26946
|
<file name="index.html">
|
26696
|
-
<p ng-class="{strike:
|
26697
|
-
<input type="checkbox" ng-model="
|
26698
|
-
<input type="checkbox" ng-model="
|
26699
|
-
<input type="checkbox" ng-model="
|
26947
|
+
<p ng-class="{strike: deleted, bold: important, red: error}">Map Syntax Example</p>
|
26948
|
+
<input type="checkbox" ng-model="deleted"> deleted (apply "strike" class)<br>
|
26949
|
+
<input type="checkbox" ng-model="important"> important (apply "bold" class)<br>
|
26950
|
+
<input type="checkbox" ng-model="error"> error (apply "red" class)
|
26700
26951
|
<hr>
|
26701
26952
|
<p ng-class="style">Using String Syntax</p>
|
26702
26953
|
<input type="text" ng-model="style" placeholder="Type: bold strike red">
|
26703
26954
|
<hr>
|
26704
26955
|
<p ng-class="[style1, style2, style3]">Using Array Syntax</p>
|
26705
|
-
<input ng-model="style1" placeholder="Type: bold"><br>
|
26706
|
-
<input ng-model="style2" placeholder="Type: strike"><br>
|
26707
|
-
<input ng-model="style3" placeholder="Type: red"><br>
|
26956
|
+
<input ng-model="style1" placeholder="Type: bold, strike or red"><br>
|
26957
|
+
<input ng-model="style2" placeholder="Type: bold, strike or red"><br>
|
26958
|
+
<input ng-model="style3" placeholder="Type: bold, strike or red"><br>
|
26708
26959
|
</file>
|
26709
26960
|
<file name="style.css">
|
26710
26961
|
.strike {
|
@@ -26723,10 +26974,10 @@ function classDirective(name, selector) {
|
|
26723
26974
|
expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/bold/);
|
26724
26975
|
expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/red/);
|
26725
26976
|
|
26726
|
-
input('
|
26977
|
+
input('important').check();
|
26727
26978
|
expect(element('.doc-example-live p:first').prop('className')).toMatch(/bold/);
|
26728
26979
|
|
26729
|
-
input('
|
26980
|
+
input('error').check();
|
26730
26981
|
expect(element('.doc-example-live p:first').prop('className')).toMatch(/red/);
|
26731
26982
|
});
|
26732
26983
|
|
@@ -27122,7 +27373,8 @@ var ngCloakDirective = ngDirective({
|
|
27122
27373
|
var ngControllerDirective = [function() {
|
27123
27374
|
return {
|
27124
27375
|
scope: true,
|
27125
|
-
controller: '@'
|
27376
|
+
controller: '@',
|
27377
|
+
priority: 500
|
27126
27378
|
};
|
27127
27379
|
}];
|
27128
27380
|
|
@@ -27572,7 +27824,7 @@ forEach(
|
|
27572
27824
|
}
|
27573
27825
|
|
27574
27826
|
/*
|
27575
|
-
The transition styles can also be placed on the CSS base class above
|
27827
|
+
The transition styles can also be placed on the CSS base class above
|
27576
27828
|
*/
|
27577
27829
|
.animate-if.ng-enter, .animate-if.ng-leave {
|
27578
27830
|
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
|
@@ -27598,22 +27850,21 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
27598
27850
|
terminal: true,
|
27599
27851
|
restrict: 'A',
|
27600
27852
|
$$tlb: true,
|
27601
|
-
|
27602
|
-
return function ($scope, $element, $attr) {
|
27853
|
+
link: function ($scope, $element, $attr, ctrl, $transclude) {
|
27603
27854
|
var block, childScope;
|
27604
27855
|
$scope.$watch($attr.ngIf, function ngIfWatchAction(value) {
|
27605
27856
|
|
27606
27857
|
if (toBoolean(value)) {
|
27607
|
-
|
27608
|
-
|
27609
|
-
|
27610
|
-
|
27611
|
-
|
27612
|
-
|
27613
|
-
|
27614
|
-
|
27615
|
-
|
27616
|
-
|
27858
|
+
if (!childScope) {
|
27859
|
+
childScope = $scope.$new();
|
27860
|
+
$transclude(childScope, function (clone) {
|
27861
|
+
block = {
|
27862
|
+
startNode: clone[0],
|
27863
|
+
endNode: clone[clone.length++] = document.createComment(' end ngIf: ' + $attr.ngIf + ' ')
|
27864
|
+
};
|
27865
|
+
$animate.enter(clone, $element.parent(), $element);
|
27866
|
+
});
|
27867
|
+
}
|
27617
27868
|
} else {
|
27618
27869
|
|
27619
27870
|
if (childScope) {
|
@@ -27627,7 +27878,6 @@ var ngIfDirective = ['$animate', function($animate) {
|
|
27627
27878
|
}
|
27628
27879
|
}
|
27629
27880
|
});
|
27630
|
-
};
|
27631
27881
|
}
|
27632
27882
|
};
|
27633
27883
|
}];
|
@@ -27786,12 +28036,12 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
|
|
27786
28036
|
priority: 400,
|
27787
28037
|
terminal: true,
|
27788
28038
|
transclude: 'element',
|
27789
|
-
compile: function(element, attr
|
28039
|
+
compile: function(element, attr) {
|
27790
28040
|
var srcExp = attr.ngInclude || attr.src,
|
27791
28041
|
onloadExp = attr.onload || '',
|
27792
28042
|
autoScrollExp = attr.autoscroll;
|
27793
28043
|
|
27794
|
-
return function(scope, $element) {
|
28044
|
+
return function(scope, $element, $attr, ctrl, $transclude) {
|
27795
28045
|
var changeCounter = 0,
|
27796
28046
|
currentScope,
|
27797
28047
|
currentElement;
|
@@ -27820,18 +28070,23 @@ var ngIncludeDirective = ['$http', '$templateCache', '$anchorScroll', '$compile'
|
|
27820
28070
|
if (thisChangeId !== changeCounter) return;
|
27821
28071
|
var newScope = scope.$new();
|
27822
28072
|
|
27823
|
-
|
27824
|
-
|
27825
|
-
|
27826
|
-
|
27827
|
-
|
27828
|
-
|
27829
|
-
|
27830
|
-
|
27831
|
-
|
27832
|
-
|
27833
|
-
|
27834
|
-
|
28073
|
+
// Note: This will also link all children of ng-include that were contained in the original
|
28074
|
+
// html. If that content contains controllers, ... they could pollute/change the scope.
|
28075
|
+
// However, using ng-include on an element with additional content does not make sense...
|
28076
|
+
// Note: We can't remove them in the cloneAttchFn of $transclude as that
|
28077
|
+
// function is called before linking the content, which would apply child
|
28078
|
+
// directives to non existing elements.
|
28079
|
+
var clone = $transclude(newScope, noop);
|
28080
|
+
cleanupLastIncludeContent();
|
28081
|
+
|
28082
|
+
currentScope = newScope;
|
28083
|
+
currentElement = clone;
|
28084
|
+
|
28085
|
+
currentElement.html(response);
|
28086
|
+
$animate.enter(currentElement, null, $element, afterAnimation);
|
28087
|
+
$compile(currentElement.contents())(currentScope);
|
28088
|
+
currentScope.$emit('$includeContentLoaded');
|
28089
|
+
scope.$eval(onloadExp);
|
27835
28090
|
}).error(function() {
|
27836
28091
|
if (thisChangeId === changeCounter) cleanupLastIncludeContent();
|
27837
28092
|
});
|
@@ -27986,7 +28241,7 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
|
|
27986
28241
|
* other numbers, for example 12, so that instead of showing "12 people are viewing", you can
|
27987
28242
|
* show "a dozen people are viewing".
|
27988
28243
|
*
|
27989
|
-
* You can use a set of closed braces(`{}`) as a placeholder for the number that you want substituted
|
28244
|
+
* You can use a set of closed braces (`{}`) as a placeholder for the number that you want substituted
|
27990
28245
|
* into pluralized strings. In the previous example, Angular will replace `{}` with
|
27991
28246
|
* <span ng-non-bindable>`{{personCount}}`</span>. The closed braces `{}` is a placeholder
|
27992
28247
|
* for <span ng-non-bindable>{{numberExpression}}</span>.
|
@@ -28247,7 +28502,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
|
|
28247
28502
|
* For example: `item in items track by $id(item)`. A built in `$id()` function can be used to assign a unique
|
28248
28503
|
* `$$hashKey` property to each item in the array. This property is then used as a key to associated DOM elements
|
28249
28504
|
* with the corresponding item in the array by identity. Moving the same object in array would move the DOM
|
28250
|
-
* element in the same way
|
28505
|
+
* element in the same way in the DOM.
|
28251
28506
|
*
|
28252
28507
|
* For example: `item in items track by item.id` is a typical pattern when the items come from the database. In this
|
28253
28508
|
* case the object identity does not matter. Two objects are considered equivalent as long as their `id`
|
@@ -28349,8 +28604,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
28349
28604
|
priority: 1000,
|
28350
28605
|
terminal: true,
|
28351
28606
|
$$tlb: true,
|
28352
|
-
|
28353
|
-
return function($scope, $element, $attr){
|
28607
|
+
link: function($scope, $element, $attr, ctrl, $transclude){
|
28354
28608
|
var expression = $attr.ngRepeat;
|
28355
28609
|
var match = expression.match(/^\s*(.+)\s+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/),
|
28356
28610
|
trackByExp, trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn,
|
@@ -28512,7 +28766,7 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
28512
28766
|
// jshint bitwise: true
|
28513
28767
|
|
28514
28768
|
if (!block.startNode) {
|
28515
|
-
|
28769
|
+
$transclude(childScope, function(clone) {
|
28516
28770
|
clone[clone.length++] = document.createComment(' end ngRepeat: ' + expression + ' ');
|
28517
28771
|
$animate.enter(clone, null, jqLite(previousNode));
|
28518
28772
|
previousNode = clone;
|
@@ -28525,7 +28779,6 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
|
|
28525
28779
|
}
|
28526
28780
|
lastBlockMap = nextBlockMap;
|
28527
28781
|
});
|
28528
|
-
};
|
28529
28782
|
}
|
28530
28783
|
};
|
28531
28784
|
}];
|
@@ -29034,10 +29287,10 @@ var ngSwitchWhenDirective = ngDirective({
|
|
29034
29287
|
transclude: 'element',
|
29035
29288
|
priority: 800,
|
29036
29289
|
require: '^ngSwitch',
|
29037
|
-
compile: function(element, attrs
|
29038
|
-
return function(scope, element, attr, ctrl) {
|
29290
|
+
compile: function(element, attrs) {
|
29291
|
+
return function(scope, element, attr, ctrl, $transclude) {
|
29039
29292
|
ctrl.cases['!' + attrs.ngSwitchWhen] = (ctrl.cases['!' + attrs.ngSwitchWhen] || []);
|
29040
|
-
ctrl.cases['!' + attrs.ngSwitchWhen].push({ transclude: transclude, element: element });
|
29293
|
+
ctrl.cases['!' + attrs.ngSwitchWhen].push({ transclude: $transclude, element: element });
|
29041
29294
|
};
|
29042
29295
|
}
|
29043
29296
|
});
|
@@ -29046,12 +29299,10 @@ var ngSwitchDefaultDirective = ngDirective({
|
|
29046
29299
|
transclude: 'element',
|
29047
29300
|
priority: 800,
|
29048
29301
|
require: '^ngSwitch',
|
29049
|
-
|
29050
|
-
|
29051
|
-
|
29052
|
-
|
29053
|
-
};
|
29054
|
-
}
|
29302
|
+
link: function(scope, element, attr, ctrl, $transclude) {
|
29303
|
+
ctrl.cases['?'] = (ctrl.cases['?'] || []);
|
29304
|
+
ctrl.cases['?'].push({ transclude: $transclude, element: element });
|
29305
|
+
}
|
29055
29306
|
});
|
29056
29307
|
|
29057
29308
|
/**
|
@@ -32032,5 +32283,5 @@ if (config.autotest) {
|
|
32032
32283
|
})(window, document);
|
32033
32284
|
|
32034
32285
|
|
32035
|
-
!angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";\n\n[ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],\n.ng-cloak, .x-ng-cloak,\n.ng-hide {\n display: none !important;\n}\n\nng\\:form {\n display: block;\n}\n\n/* The styles below ensure that the CSS transition will ALWAYS\n * animate and close. A nasty bug occurs with CSS transitions where\n * when the active class isn\'t set, or if the active class doesn\'t\n * contain any styles to transition to, then, if ngAnimate is used,\n * it will appear as if the webpage is broken due to the forever hanging\n * animations. The
|
32286
|
+
!angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";\n\n[ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],\n.ng-cloak, .x-ng-cloak,\n.ng-hide {\n display: none !important;\n}\n\nng\\:form {\n display: block;\n}\n\n/* The styles below ensure that the CSS transition will ALWAYS\n * animate and close. A nasty bug occurs with CSS transitions where\n * when the active class isn\'t set, or if the active class doesn\'t\n * contain any styles to transition to, then, if ngAnimate is used,\n * it will appear as if the webpage is broken due to the forever hanging\n * animations. The border-spacing (!ie) and zoom (ie) CSS properties are\n * used below since they trigger a transition without making the browser\n * animate anything and they\'re both highly underused CSS properties */\n.ng-animate-start { border-spacing:1px 1px; -ms-zoom:1.0001; }\n.ng-animate-active { border-spacing:0px 0px; -ms-zoom:1; }\n</style>');
|
32036
32287
|
!angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">@charset "UTF-8";\n/* CSS Document */\n\n/** Structure */\nbody {\n font-family: Arial, sans-serif;\n margin: 0;\n font-size: 14px;\n}\n\n#system-error {\n font-size: 1.5em;\n text-align: center;\n}\n\n#json, #xml {\n display: none;\n}\n\n#header {\n position: fixed;\n width: 100%;\n}\n\n#specs {\n padding-top: 50px;\n}\n\n#header .angular {\n font-family: Courier New, monospace;\n font-weight: bold;\n}\n\n#header h1 {\n font-weight: normal;\n float: left;\n font-size: 30px;\n line-height: 30px;\n margin: 0;\n padding: 10px 10px;\n height: 30px;\n}\n\n#application h2,\n#specs h2 {\n margin: 0;\n padding: 0.5em;\n font-size: 1.1em;\n}\n\n#status-legend {\n margin-top: 10px;\n margin-right: 10px;\n}\n\n#header,\n#application,\n.test-info,\n.test-actions li {\n overflow: hidden;\n}\n\n#application {\n margin: 10px;\n}\n\n#application iframe {\n width: 100%;\n height: 758px;\n}\n\n#application .popout {\n float: right;\n}\n\n#application iframe {\n border: none;\n}\n\n.tests li,\n.test-actions li,\n.test-it li,\n.test-it ol,\n.status-display {\n list-style-type: none;\n}\n\n.tests,\n.test-it ol,\n.status-display {\n margin: 0;\n padding: 0;\n}\n\n.test-info {\n margin-left: 1em;\n margin-top: 0.5em;\n border-radius: 8px 0 0 8px;\n -webkit-border-radius: 8px 0 0 8px;\n -moz-border-radius: 8px 0 0 8px;\n cursor: pointer;\n}\n\n.test-info:hover .test-name {\n text-decoration: underline;\n}\n\n.test-info .closed:before {\n content: \'\\25b8\\00A0\';\n}\n\n.test-info .open:before {\n content: \'\\25be\\00A0\';\n font-weight: bold;\n}\n\n.test-it ol {\n margin-left: 2.5em;\n}\n\n.status-display,\n.status-display li {\n float: right;\n}\n\n.status-display li {\n padding: 5px 10px;\n}\n\n.timer-result,\n.test-title {\n display: inline-block;\n margin: 0;\n padding: 4px;\n}\n\n.test-actions .test-title,\n.test-actions .test-result {\n display: table-cell;\n padding-left: 0.5em;\n padding-right: 0.5em;\n}\n\n.test-actions {\n display: table;\n}\n\n.test-actions li {\n display: table-row;\n}\n\n.timer-result {\n width: 4em;\n padding: 0 10px;\n text-align: right;\n font-family: monospace;\n}\n\n.test-it pre,\n.test-actions pre {\n clear: left;\n color: black;\n margin-left: 6em;\n}\n\n.test-describe {\n padding-bottom: 0.5em;\n}\n\n.test-describe .test-describe {\n margin: 5px 5px 10px 2em;\n}\n\n.test-actions .status-pending .test-title:before {\n content: \'\\00bb\\00A0\';\n}\n\n.scrollpane {\n max-height: 20em;\n overflow: auto;\n}\n\n/** Colors */\n\n#header {\n background-color: #F2C200;\n}\n\n#specs h2 {\n border-top: 2px solid #BABAD1;\n}\n\n#specs h2,\n#application h2 {\n background-color: #efefef;\n}\n\n#application {\n border: 1px solid #BABAD1;\n}\n\n.test-describe .test-describe {\n border-left: 1px solid #BABAD1;\n border-right: 1px solid #BABAD1;\n border-bottom: 1px solid #BABAD1;\n}\n\n.status-display {\n border: 1px solid #777;\n}\n\n.status-display .status-pending,\n.status-pending .test-info {\n background-color: #F9EEBC;\n}\n\n.status-display .status-success,\n.status-success .test-info {\n background-color: #B1D7A1;\n}\n\n.status-display .status-failure,\n.status-failure .test-info {\n background-color: #FF8286;\n}\n\n.status-display .status-error,\n.status-error .test-info {\n background-color: black;\n color: white;\n}\n\n.test-actions .status-success .test-title {\n color: #30B30A;\n}\n\n.test-actions .status-failure .test-title {\n color: #DF0000;\n}\n\n.test-actions .status-error .test-title {\n color: black;\n}\n\n.test-actions .timer-result {\n color: #888;\n}\n</style>');
|