diff --git a/src/ng/directive/ngTransclude.js b/src/ng/directive/ngTransclude.js index f19c251fc3b6..4f48f5ee0bbf 100644 --- a/src/ng/directive/ngTransclude.js +++ b/src/ng/directive/ngTransclude.js @@ -13,8 +13,8 @@ * * If the transcluded content is not empty (i.e. contains one or more DOM nodes, including whitespace text nodes), any existing * content of this element will be removed before the transcluded content is inserted. - * If the transcluded content is empty, the existing content is left intact. This lets you provide fallback content in the case - * that no transcluded content is provided. + * If the transcluded content is empty (or only whitespace), the existing content is left intact. This lets you provide fallback + * content in the case that no transcluded content is provided. * * @element ANY * @@ -195,7 +195,7 @@ var ngTranscludeDirective = ['$compile', function($compile) { } function ngTranscludeCloneAttachFn(clone, transcludedScope) { - if (clone.length) { + if (clone.length && notWhitespace(clone)) { $element.append(clone); } else { useFallbackContent(); @@ -212,6 +212,15 @@ var ngTranscludeDirective = ['$compile', function($compile) { $element.append(clone); }); } + + function notWhitespace(nodes) { + for (var i = 0, ii = nodes.length; i < ii; i++) { + var node = nodes[i]; + if (node.nodeType !== NODE_TYPE_TEXT || node.nodeValue.trim()) { + return true; + } + } + } }; } }; diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 70112d14a82f..a9659524fd21 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -8728,6 +8728,60 @@ describe('$compile', function() { }); }); + it('should compile and link the fallback content if only whitespace transcluded content is provided', function() { + var linkSpy = jasmine.createSpy('postlink'); + + module(function() { + directive('inner', function() { + return { + restrict: 'E', + template: 'old stuff! ', + link: linkSpy + }; + }); + + directive('trans', function() { + return { + transclude: true, + template: '
' + }; + }); + }); + inject(function(log, $rootScope, $compile) { + element = $compile('
\n \n
')($rootScope); + $rootScope.$apply(); + expect(sortedHtml(element.html())).toEqual('
old stuff!
'); + expect(linkSpy).toHaveBeenCalled(); + }); + }); + + it('should not link the fallback content if only whitespace and comments are provided as transclude content', function() { + var linkSpy = jasmine.createSpy('postlink'); + + module(function() { + directive('inner', function() { + return { + restrict: 'E', + template: 'old stuff! ', + link: linkSpy + }; + }); + + directive('trans', function() { + return { + transclude: true, + template: '
' + }; + }); + }); + inject(function(log, $rootScope, $compile) { + element = $compile('
\n \n
')($rootScope); + $rootScope.$apply(); + expect(sortedHtml(element.html())).toEqual('
\n \n
'); + expect(linkSpy).not.toHaveBeenCalled(); + }); + }); + it('should compile and link the fallback content if an optional transclusion slot is not provided', function() { var linkSpy = jasmine.createSpy('postlink');