Skip to content
This repository has been archived by the owner on Mar 13, 2018. It is now read-only.

Commit

Permalink
Merge pull request #371 from arv/template-element-clone-node
Browse files Browse the repository at this point in the history
Template element clone node
  • Loading branch information
dfreedm committed Feb 3, 2014
2 parents 409fb08 + f2b87bb commit 308a7c2
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 18 deletions.
12 changes: 2 additions & 10 deletions src/wrappers/Document.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
var Selection = scope.wrappers.Selection;
var SelectorsInterface = scope.SelectorsInterface;
var ShadowRoot = scope.wrappers.ShadowRoot;
var cloneNode = scope.cloneNode;
var defineWrapGetter = scope.defineWrapGetter;
var elementFromPoint = scope.elementFromPoint;
var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
Expand Down Expand Up @@ -83,7 +84,6 @@
doc.adoptNode(oldShadowRoot);
}

var originalImportNode = document.importNode;
var originalGetSelection = document.getSelection;

mixin(Document.prototype, {
Expand All @@ -97,15 +97,7 @@
return elementFromPoint(this, this, x, y);
},
importNode: function(node, deep) {
// We need to manually walk the tree to ensure we do not include rendered
// shadow trees.
var clone = wrap(originalImportNode.call(this.impl, unwrap(node), false));
if (deep) {
for (var child = node.firstChild; child; child = child.nextSibling) {
clone.appendChild(this.importNode(child, true));
}
}
return clone;
return cloneNode(node, deep, this.impl);
},
getSelection: function() {
renderAllPending();
Expand Down
39 changes: 31 additions & 8 deletions src/wrappers/Node.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var wrapIfNeeded = scope.wrapIfNeeded;
var wrappers = scope.wrappers;

function assertIsNodeWrapper(node) {
assert(node instanceof Node);
Expand Down Expand Up @@ -235,6 +236,34 @@
}
}

var originalImportNode = document.importNode;
var originalCloneNode = window.Node.prototype.cloneNode;

function cloneNode(node, deep, opt_doc) {
var clone;
if (opt_doc)
clone = wrap(originalImportNode.call(opt_doc, node.impl, false));
else
clone = wrap(originalCloneNode.call(node.impl, false));

if (deep) {
for (var child = node.firstChild; child; child = child.nextSibling) {
clone.appendChild(cloneNode(child, true, opt_doc));
}

if (node instanceof wrappers.HTMLTemplateElement) {
var cloneContent = clone.content;
for (var child = node.content.firstChild;
child;
child = child.nextSibling) {
cloneContent.appendChild(cloneNode(child, true, opt_doc));
}
}
}
// TODO(arv): Some HTML elements also clone other data like value.
return clone;
}

var OriginalNode = window.Node;

/**
Expand Down Expand Up @@ -607,14 +636,7 @@
},

cloneNode: function(deep) {
var clone = wrap(this.impl.cloneNode(false));
if (deep) {
for (var child = this.firstChild; child; child = child.nextSibling) {
clone.appendChild(child.cloneNode(true));
}
}
// TODO(arv): Some HTML elements also clone other data like value.
return clone;
return cloneNode(this, deep);
},

contains: function(child) {
Expand Down Expand Up @@ -692,5 +714,6 @@
scope.nodesWereRemoved = nodesWereRemoved;
scope.snapshotNodeList = snapshotNodeList;
scope.wrappers.Node = Node;
scope.cloneNode = cloneNode;

})(window.ShadowDOMPolyfill);
27 changes: 27 additions & 0 deletions test/js/HTMLTemplateElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,31 @@ suite('HTML Template Element', function() {
assert.equal(count, 0);
});

test('cloneNode', function() {
var div = document.createElement('div');
div.innerHTML = '<template><a></a><b></b></template>';
var template = div.firstChild;

var clone = template.cloneNode(true);
assert.equal(clone.outerHTML, '<template><a></a><b></b></template>');

clone = div.cloneNode(true);
assert.equal(clone.outerHTML,
'<div><template><a></a><b></b></template></div>');
});

test('importNode', function() {
var doc2 = document.implementation.createHTMLDocument('');
var div = doc2.createElement('div');
div.innerHTML = '<template><a></a><b></b></template>';
var template = div.firstChild;

var clone = document.importNode(template, true);
assert.equal(clone.outerHTML, '<template><a></a><b></b></template>');

clone = document.importNode(div, true);
assert.equal(clone.outerHTML,
'<div><template><a></a><b></b></template></div>');
});

});

0 comments on commit 308a7c2

Please sign in to comment.