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

Commit cb73a37

Browse files
committed
fix($compile): use the correct namespace for transcluded svg elements
This fixes the case when a directive that uses `templateUrl` is used inside of a transcluding directive like `ng-repeat`. Fixes #8808 Closes #8816
1 parent 49455a7 commit cb73a37

File tree

2 files changed

+46
-11
lines changed

2 files changed

+46
-11
lines changed

src/ng/compile.js

+13-11
Original file line numberDiff line numberDiff line change
@@ -955,26 +955,29 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
955955
var compositeLinkFn =
956956
compileNodes($compileNodes, transcludeFn, $compileNodes,
957957
maxPriority, ignoreDirective, previousCompileContext);
958-
959958
compile.$$addScopeClass($compileNodes);
960-
959+
var namespace = null;
960+
var namespaceAdaptedCompileNodes = $compileNodes;
961+
var lastCompileNode;
961962
return function publicLinkFn(scope, cloneConnectFn, transcludeControllers, parentBoundTranscludeFn, futureParentElement){
962-
var namespace = null;
963963
assertArg(scope, 'scope');
964964
if (!namespace) {
965965
namespace = detectNamespaceForChildElements(futureParentElement);
966-
if (namespace !== 'html') {
967-
$compileNodes = jqLite(
968-
wrapTemplate(namespace, jqLite('<div>').append($compileNodes).html())
969-
);
970-
}
971966
}
967+
if (namespace !== 'html' && $compileNodes[0] !== lastCompileNode) {
968+
namespaceAdaptedCompileNodes = jqLite(
969+
wrapTemplate(namespace, jqLite('<div>').append($compileNodes).html())
970+
);
971+
}
972+
// When using a directive with replace:true and templateUrl the $compileNodes
973+
// might change, so we need to recreate the namespace adapted compileNodes.
974+
lastCompileNode = $compileNodes[0];
972975

973976
// important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart
974977
// and sometimes changes the structure of the DOM.
975978
var $linkNode = cloneConnectFn
976-
? JQLitePrototype.clone.call($compileNodes) // IMPORTANT!!!
977-
: $compileNodes;
979+
? JQLitePrototype.clone.call(namespaceAdaptedCompileNodes) // IMPORTANT!!!
980+
: namespaceAdaptedCompileNodes;
978981

979982
if (transcludeControllers) {
980983
for (var controllerName in transcludeControllers) {
@@ -1940,7 +1943,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
19401943
// it was cloned therefore we have to clone as well.
19411944
linkNode = jqLiteClone(compileNode);
19421945
}
1943-
19441946
replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);
19451947

19461948
// Copy in CSS classes from original node

test/ng/compileSpec.js

+33
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,39 @@ describe('$compile', function() {
289289

290290
}));
291291

292+
it('should support directives with SVG templates and a slow url '+
293+
'that are stamped out later by a transcluding directive', function() {
294+
module(function() {
295+
directive('svgCircleUrl', valueFn({
296+
replace: true,
297+
templateUrl: 'template.html',
298+
templateNamespace: 'SVG',
299+
}));
300+
});
301+
inject(function($compile, $rootScope, $httpBackend) {
302+
$httpBackend.expect('GET', 'template.html').respond('<circle></circle>');
303+
element = $compile('<svg><svg-circle-url ng-repeat="l in list"/></svg>')($rootScope);
304+
305+
// initially the template is not yet loaded
306+
$rootScope.$apply(function() {
307+
$rootScope.list = [1];
308+
});
309+
expect(element.find('svg-circle-url').length).toBe(1);
310+
expect(element.find('circle').length).toBe(0);
311+
312+
// template is loaded and replaces the existing nodes
313+
$httpBackend.flush();
314+
expect(element.find('svg-circle-url').length).toBe(0);
315+
expect(element.find('circle').length).toBe(1);
316+
317+
// new entry should immediately use the loaded template
318+
$rootScope.$apply(function() {
319+
$rootScope.list.push(2);
320+
});
321+
expect(element.find('svg-circle-url').length).toBe(0);
322+
expect(element.find('circle').length).toBe(2);
323+
});
324+
});
292325
});
293326

294327

0 commit comments

Comments
 (0)