This repository was archived by the owner on Apr 3, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathng-include-scope.js
More file actions
105 lines (94 loc) · 4.2 KB
/
ng-include-scope.js
File metadata and controls
105 lines (94 loc) · 4.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
angular.module('drg.ngIncludeScope', [])
.factory( 'ngIncludeScopeService', function() {
'use strict';
var keywords = [ 'this', 'constructor' ]
return function( scope, attrs, field, isolate ) {
var whitelist = [],
blacklist = angular.copy( keywords );
// initialize the local blacklist
var localBlacklist = angular.copy( blacklist );
localBlacklist.push( attrs[ field ] );
/**
* Set up the getter for the given key
* @param key {string}
*/
function defineGetter( key ) {
var propDesc = Object.getOwnPropertyDescriptor( scope, key );
// make sure there isn't already a getter defined
if( !propDesc || ( propDesc && !propDesc.get ) ) {
Object.defineProperty( scope, key, {
get: function () {
if ( !isolate || ( isolate && !!~whitelist.indexOf( key ) ) ) {
// get the current value evaluated on the included scope
var val = scope.$eval( attrs[ field ] + "['" + key.replace( "'", "\\'" ) + "']" );
if ( angular.isUndefined( val ) && !isolate ) {
// the value is not found and this is not an isolate scope so get the value on the parent scope
return scope.$parent[ key ];
}
return val;
}
return undefined;
}
} );
}
}
// find all the properties currently on the scope
for( var key in scope ) {
if( key.substr( 0, 1 ) === '$' || !!~localBlacklist.indexOf( key ) ) {
// the property is protected so add it to the blacklist
blacklist.push( key );
} else if( isolate ) {
// this is an isolate scope so define a getter to handle
defineGetter( key );
}
}
// watch the target scope
scope.$watchCollection( attrs[ field ], function( newScope ) {
if( newScope ) {
// build the blacklist
localBlacklist = angular.copy( blacklist );
localBlacklist.push( attrs[ field ] );
// build the whitelist
whitelist = Object.keys( newScope );
if( !isolate ) {
// this is not an isolate scope so we need to traverse up the parent scopes to find all the properties defined on them
for( var parent = newScope.$parent; parent; parent = parent.$parent ) {
// add each property in the parent scope to the whitelist if it's not already present
for( var key in newScope.$parent ) {
if( !~whitelist.indexOf( key ) ) {
whitelist.push( key );
}
}
}
}
// set getters
angular.forEach( whitelist, function(key) {
// add the given property to the scope as long as it's not in the blacklist
if( ( angular.isUndefined( scope[ key ] ) || !scope.hasOwnProperty( key ) ) && !~localBlacklist.indexOf( key ) ) {
defineGetter( key );
}
} );
}
} );
};
} )
.directive( 'ngIncludeScope', [ 'ngIncludeScopeService', function( ngIncludeScopeService ) {
'use strict';
return {
restrict: 'A',
scope: true,
link : function( scope, elem, attrs ) {
ngIncludeScopeService( scope, attrs, 'ngIncludeScope', false );
}
};
} ] )
.directive( 'ngIncludeIsolateScope', [ 'ngIncludeScopeService', function( ngIncludeScopeService ) {
'use strict';
return {
restrict: 'A',
scope: true,
link : function( scope, elem, attrs ) {
ngIncludeScopeService( scope, attrs, 'ngIncludeIsolateScope', true );
}
};
} ] );