angular-rails-engine 1.2.0.2 → 1.2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/app/assets/javascripts/angular/angular-animate.js +105 -37
- data/app/assets/javascripts/angular/angular-animate.min.js +18 -17
- data/app/assets/javascripts/angular/angular-cookies.js +2 -2
- data/app/assets/javascripts/angular/angular-cookies.min.js +2 -2
- data/app/assets/javascripts/angular/angular-loader.js +93 -6
- data/app/assets/javascripts/angular/angular-loader.min.js +5 -4
- data/app/assets/javascripts/angular/angular-mocks.js +187 -202
- data/app/assets/javascripts/angular/angular-resource.js +31 -63
- data/app/assets/javascripts/angular/angular-resource.min.js +8 -8
- data/app/assets/javascripts/angular/angular-route.js +42 -31
- data/app/assets/javascripts/angular/angular-route.min.js +10 -10
- data/app/assets/javascripts/angular/angular-sanitize.js +66 -28
- data/app/assets/javascripts/angular/angular-sanitize.min.js +10 -10
- data/app/assets/javascripts/angular/angular-scenario.js +599 -348
- data/app/assets/javascripts/angular/angular-touch.js +2 -2
- data/app/assets/javascripts/angular/angular-touch.min.js +2 -2
- data/app/assets/javascripts/angular/angular.js +603 -352
- data/app/assets/javascripts/angular/angular.min.js +197 -196
- data/app/assets/stylesheets/angular-csp.css +4 -4
- data/lib/angular-rails-engine.rb +1 -1
- data/lib/angular-rails-engine/version.rb +1 -1
- metadata +2 -2
- metadata.gz.sig +0 -0
@@ -1,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>');
|