Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit b5af198

Browse files
committed
fix($compile): don't leak isolate scope state when replaced directive is used multiple times
When an isolate scope directive is also a "replace" directive and at the root of its template it has other directives, we need to keep track remember to use isolate scope when linking these. This commit fixes the leakage of this state when this directive is used again later inside or outside of the isolate directive template.
1 parent 3fe4491 commit b5af198

File tree

2 files changed

+48
-4
lines changed

2 files changed

+48
-4
lines changed

src/ng/compile.js

+11-2
Original file line numberDiff line numberDiff line change
@@ -1303,13 +1303,17 @@ function $CompileProvider($provide) {
13031303
if (pre) {
13041304
if (attrStart) pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd);
13051305
pre.require = directive.require;
1306-
if (newIsolateScopeDirective === directive || directive.$$isolateScope) pre.isolateScope = true;
1306+
if (newIsolateScopeDirective === directive || directive.$$isolateScope) {
1307+
pre = cloneAndAnnotateFn(pre, {isolateScope: true});
1308+
}
13071309
preLinkFns.push(pre);
13081310
}
13091311
if (post) {
13101312
if (attrStart) post = groupElementsLinkFnWrapper(post, attrStart, attrEnd);
13111313
post.require = directive.require;
1312-
if (newIsolateScopeDirective === directive || directive.$$isolateScope) post.isolateScope = true;
1314+
if (newIsolateScopeDirective === directive || directive.$$isolateScope) {
1315+
post = cloneAndAnnotateFn(post, {isolateScope: true});
1316+
}
13131317
postLinkFns.push(post);
13141318
}
13151319
}
@@ -1830,6 +1834,11 @@ function $CompileProvider($provide) {
18301834
elementsToRemove[0] = newNode;
18311835
elementsToRemove.length = 1;
18321836
}
1837+
1838+
1839+
function cloneAndAnnotateFn(fn, annotation) {
1840+
return extend(function() { return fn.apply(null, arguments); }, fn, annotation);
1841+
}
18331842
}];
18341843
}
18351844

test/ng/compileSpec.js

+37-2
Original file line numberDiff line numberDiff line change
@@ -2504,7 +2504,7 @@ describe('$compile', function() {
25042504
});
25052505

25062506

2507-
it('should share isolate scope with replaced directives', function() {
2507+
it('should share isolate scope with replaced directives (template)', function() {
25082508
var normalScope;
25092509
var isolateScope;
25102510

@@ -2540,7 +2540,7 @@ describe('$compile', function() {
25402540
});
25412541

25422542

2543-
it('should share isolate scope with replaced directives', function() {
2543+
it('should share isolate scope with replaced directives (templateUrl)', function() {
25442544
var normalScope;
25452545
var isolateScope;
25462546

@@ -2577,6 +2577,41 @@ describe('$compile', function() {
25772577
});
25782578

25792579

2580+
it('should not get confused about where to use isolate scope when a replaced directive is used multiple times',
2581+
function() {
2582+
2583+
module(function() {
2584+
directive('isolate', function() {
2585+
return {
2586+
replace: true,
2587+
scope: {},
2588+
template: '<span scope-tester="replaced"><span scope-tester="inside"></span></span>'
2589+
};
2590+
});
2591+
directive('scopeTester', function(log) {
2592+
return {
2593+
link: function($scope, $element) {
2594+
log($element.attr('scope-tester') + '=' + ($scope.$root === $scope ? 'non-isolate' : 'isolate'));
2595+
}
2596+
}
2597+
});
2598+
});
2599+
2600+
inject(function($compile, $rootScope, log) {
2601+
element = $compile('<div>' +
2602+
'<div isolate scope-tester="outside"></div>' +
2603+
'<span scope-tester="sibling"></span>' +
2604+
'</div>')($rootScope);
2605+
2606+
$rootScope.$digest();
2607+
expect(log).toEqual('inside=isolate; ' +
2608+
'outside replaced=non-isolate; ' + // outside
2609+
'outside replaced=isolate; ' + // replaced
2610+
'sibling=non-isolate')
2611+
});
2612+
});
2613+
2614+
25802615
it('should require controller of a non-isolate directive from an isolate directive on the ' +
25812616
'same element', function() {
25822617
var NonIsolateController = function() {};

0 commit comments

Comments
 (0)