Skip to content

Commit 85e12c9

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 somewhere in the children of a transcluding directive like `ng-repeat`. Fixes angular#9344 Related to angular#8808
1 parent 1064443 commit 85e12c9

File tree

2 files changed

+15
-14
lines changed

2 files changed

+15
-14
lines changed

src/ng/compile.js

+14-13
Original file line numberDiff line numberDiff line change
@@ -1047,27 +1047,28 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
10471047
maxPriority, ignoreDirective, previousCompileContext);
10481048
compile.$$addScopeClass($compileNodes);
10491049
var namespace = null;
1050-
var namespaceAdaptedCompileNodes = $compileNodes;
1051-
var lastCompileNode;
10521050
return function publicLinkFn(scope, cloneConnectFn, transcludeControllers, parentBoundTranscludeFn, futureParentElement){
10531051
assertArg(scope, 'scope');
10541052
if (!namespace) {
10551053
namespace = detectNamespaceForChildElements(futureParentElement);
10561054
}
1057-
if (namespace !== 'html' && $compileNodes[0] !== lastCompileNode) {
1058-
namespaceAdaptedCompileNodes = jqLite(
1055+
var $linkNode;
1056+
if (namespace !== 'html') {
1057+
// When using a directive with replace:true and templateUrl the $compileNodes
1058+
// (or a child element inside of them)
1059+
// might change, so we need to recreate the namespace adapted compileNodes
1060+
// for call to the link function.
1061+
// Note: This will already clone the nodes...
1062+
$linkNode = jqLite(
10591063
wrapTemplate(namespace, jqLite('<div>').append($compileNodes).html())
10601064
);
1065+
} else if (cloneConnectFn) {
1066+
// important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart
1067+
// and sometimes changes the structure of the DOM.
1068+
$linkNode = JQLitePrototype.clone.call($compileNodes);
1069+
} else {
1070+
$linkNode = $compileNodes;
10611071
}
1062-
// When using a directive with replace:true and templateUrl the $compileNodes
1063-
// might change, so we need to recreate the namespace adapted compileNodes.
1064-
lastCompileNode = $compileNodes[0];
1065-
1066-
// important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart
1067-
// and sometimes changes the structure of the DOM.
1068-
var $linkNode = cloneConnectFn
1069-
? JQLitePrototype.clone.call(namespaceAdaptedCompileNodes) // IMPORTANT!!!
1070-
: namespaceAdaptedCompileNodes;
10711072

10721073
if (transcludeControllers) {
10731074
for (var controllerName in transcludeControllers) {

test/ng/compileSpec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ describe('$compile', function() {
300300
});
301301
inject(function($compile, $rootScope, $httpBackend) {
302302
$httpBackend.expect('GET', 'template.html').respond('<circle></circle>');
303-
element = $compile('<svg><svg-circle-url ng-repeat="l in list"/></svg>')($rootScope);
303+
element = $compile('<svg><g ng-repeat="l in list"><svg-circle-url></svg-circle-url></g></svg>')($rootScope);
304304

305305
// initially the template is not yet loaded
306306
$rootScope.$apply(function() {

0 commit comments

Comments
 (0)