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

Commit 19af039

Browse files
petebacondarwinvojtajina
authored andcommittedMay 29, 2014
fix($compile): don't pass transclude to template of non-transclude directive
If a directive provides a template but is not explicitly requesting transclusion then the compiler should not pass a transclusion function to the directives within the template.
1 parent 6e15462 commit 19af039

File tree

2 files changed

+50
-8
lines changed

2 files changed

+50
-8
lines changed
 

‎src/ng/compile.js

+17-8
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
924924
!childNodes.length)
925925
? null
926926
: compileNodes(childNodes,
927-
nodeLinkFn ? nodeLinkFn.transclude : transcludeFn);
927+
nodeLinkFn ? (
928+
(nodeLinkFn.transcludeOnThisElement || !nodeLinkFn.templateOnThisElement)
929+
&& nodeLinkFn.transclude) : transcludeFn);
928930

929931
linkFns.push(nodeLinkFn, childLinkFn);
930932
linkFnFound = linkFnFound || nodeLinkFn || childLinkFn;
@@ -959,14 +961,17 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
959961
childScope = scope;
960962
}
961963

962-
// We need to create a new boundTranscludeFn if
963-
// - a directive on this element wants to transclude
964-
// or
965-
// - there is no parentBoundTranscludeFn already and a transcludeFn was passed in
966-
if ( nodeLinkFn.transcludeOnThisElement || (!parentBoundTranscludeFn && transcludeFn) ) {
967-
childBoundTranscludeFn = createBoundTranscludeFn(scope, nodeLinkFn.transclude || transcludeFn, parentBoundTranscludeFn);
968-
} else {
964+
if ( nodeLinkFn.transcludeOnThisElement ) {
965+
childBoundTranscludeFn = createBoundTranscludeFn(scope, nodeLinkFn.transclude, parentBoundTranscludeFn);
966+
967+
} else if (!nodeLinkFn.templateOnThisElement && parentBoundTranscludeFn) {
969968
childBoundTranscludeFn = parentBoundTranscludeFn;
969+
970+
} else if (!parentBoundTranscludeFn && transcludeFn) {
971+
childBoundTranscludeFn = createBoundTranscludeFn(scope, transcludeFn);
972+
973+
} else {
974+
childBoundTranscludeFn = null;
970975
}
971976

972977
nodeLinkFn(childLinkFn, childScope, node, $rootElement, childBoundTranscludeFn);
@@ -1181,6 +1186,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
11811186
templateDirective = previousCompileContext.templateDirective,
11821187
nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective,
11831188
hasTranscludeDirective = false,
1189+
hasTemplate = false,
11841190
hasElementTranscludeDirective = previousCompileContext.hasElementTranscludeDirective,
11851191
$compileNode = templateAttrs.$$element = jqLite(compileNode),
11861192
directive,
@@ -1271,6 +1277,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
12711277
}
12721278

12731279
if (directive.template) {
1280+
hasTemplate = true;
12741281
assertNoDuplicate('template', templateDirective, directive, $compileNode);
12751282
templateDirective = directive;
12761283

@@ -1320,6 +1327,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
13201327
}
13211328

13221329
if (directive.templateUrl) {
1330+
hasTemplate = true;
13231331
assertNoDuplicate('template', templateDirective, directive, $compileNode);
13241332
templateDirective = directive;
13251333

@@ -1357,6 +1365,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
13571365

13581366
nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true;
13591367
nodeLinkFn.transcludeOnThisElement = hasTranscludeDirective;
1368+
nodeLinkFn.templateOnThisElement = hasTemplate;
13601369
nodeLinkFn.transclude = childTranscludeFn;
13611370

13621371
previousCompileContext.hasElementTranscludeDirective = hasElementTranscludeDirective;

‎test/ng/compileSpec.js

+33
Original file line numberDiff line numberDiff line change
@@ -3988,6 +3988,39 @@ describe('$compile', function() {
39883988
});
39893989

39903990

3991+
it('should not pass transclusion into a template directive when the directive didn\'t request transclusion', function() {
3992+
3993+
module(function($compileProvider) {
3994+
3995+
$compileProvider.directive('transFoo', valueFn({
3996+
template: '<div>' +
3997+
'<div no-trans-bar></div>' +
3998+
'<div ng-transclude>this one should get replaced with content</div>' +
3999+
'<div class="foo" ng-transclude></div>' +
4000+
'</div>',
4001+
transclude: true
4002+
4003+
}));
4004+
4005+
$compileProvider.directive('noTransBar', valueFn({
4006+
template: '<div>' +
4007+
// This ng-transclude is invalid. It should throw an error.
4008+
'<div class="bar" ng-transclude></div>' +
4009+
'</div>',
4010+
transclude: false
4011+
4012+
}));
4013+
});
4014+
4015+
inject(function($compile, $rootScope) {
4016+
expect(function() {
4017+
$compile('<div trans-foo>content</div>')($rootScope);
4018+
}).toThrowMinErr('ngTransclude', 'orphan',
4019+
'Illegal use of ngTransclude directive in the template! No parent directive that requires a transclusion found. Element: <div class="bar" ng-transclude="">');
4020+
});
4021+
});
4022+
4023+
39914024
it('should make the result of a transclusion available to the parent directive in post-linking phase' +
39924025
'(template)', function() {
39934026
module(function() {

0 commit comments

Comments
 (0)
This repository has been archived.