Skip to content

Commit

Permalink
Fixes #1888: add support for cloneNode and importNode to `Polymer…
Browse files Browse the repository at this point in the history
….dom`
  • Loading branch information
Steven Orvell committed Jul 8, 2015
1 parent f64b029 commit 699a3bc
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 2 deletions.
45 changes: 43 additions & 2 deletions src/lib/dom-api.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
var nativeInsertBefore = Element.prototype.insertBefore;
var nativeRemoveChild = Element.prototype.removeChild;
var nativeAppendChild = Element.prototype.appendChild;
var nativeCloneNode = Element.prototype.cloneNode;
var nativeImportNode = Document.prototype.importNode;

var dirtyRoots = [];

Expand Down Expand Up @@ -205,8 +207,8 @@

_tryRemoveUndistributedNode: function(node) {
if (this.node.shadyRoot) {
if (node.parentNode) {
nativeRemoveChild.call(node.parentNode, node);
if (node._composedParent) {
nativeRemoveChild.call(node._composedParent, node);
}
return true;
}
Expand Down Expand Up @@ -440,6 +442,35 @@
if (this._parentNeedsDistribution(this.parentNode)) {
this._lazyDistribute(this.parentNode);
}
},

cloneNode: function(deep) {
var n = nativeCloneNode.call(this.node, false);
if (deep) {
var c$ = this.childNodes;
var d = factory(n);
for (var i=0, nc; i < c$.length; i++) {
nc = factory(c$[i]).cloneNode(true);
d.appendChild(nc);
}
}
return n;
},

importNode: function(externalNode, deep) {
// for convenience use this node's ownerDoc if the node isn't a document
var doc = this.node instanceof HTMLDocument ? this.node :
this.node.ownerDocument;
var n = nativeImportNode.call(doc, externalNode, false);
if (deep) {
var c$ = factory(externalNode).childNodes;
var d = factory(n);
for (var i=0, nc; i < c$.length; i++) {
nc = factory(doc).importNode(c$[i], true);
d.appendChild(nc);
}
}
return n;
}

};
Expand Down Expand Up @@ -646,6 +677,16 @@
}
};

DomApi.prototype.cloneNode = function(deep) {
return this.node.cloneNode(deep);
}

DomApi.prototype.importNode = function(externalNode, deep) {
var doc = this.node instanceof HTMLDocument ? this.node :
this.node.ownerDocument;
return doc.importNode(externalNode, deep);
}

DomApi.prototype.getDestinationInsertionPoints = function() {
var n$ = this.node.getDestinationInsertionPoints();
return n$ ? Array.prototype.slice.call(n$) : [];
Expand Down
8 changes: 8 additions & 0 deletions test/unit/polymer-dom-elements.html
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,12 @@
</x-select-attr>
</template>
<script>Polymer({is: 'x-compose-select-attr'});</script>
</dom-module>


<dom-module id="x-clonate">
<template><span>[</span><content></content><span>]</span></template>
<script>Polymer({
is: 'x-clonate'
});</script>
</dom-module>
44 changes: 44 additions & 0 deletions test/unit/polymer-dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,50 @@ suite('Polymer.dom', function() {
assert.isTrue(Array.isArray(Polymer.dom(document.body).childNodes));
});

test('Polymer.dom cloneNode shallow', function() {
var a = document.createElement('div');
a.innerHTML = '<x-clonate><span>1</span><span>2</span></x-clonate>';
var b = Polymer.dom(Polymer.dom(a).firstElementChild).cloneNode();
Polymer.dom(document.body).appendChild(b);
assert.equal(Polymer.dom(b).childNodes.length, 0, 'shallow copy has incorrect children');
if (b.shadyRoot) {
assert.equal(b.children.length, 2, 'shallow copy has incorrect composed children');
}
});

test('Polymer.dom cloneNode deep', function() {
var a = document.createElement('div');
a.innerHTML = '<x-clonate><span>1</span><span>2</span></x-clonate>';
var b = Polymer.dom(a).cloneNode(true);
Polymer.dom(document.body).appendChild(b);
assert.equal(Polymer.dom(b.firstElementChild).childNodes.length, 2, 'deep copy has incorrect children');
if (b.shadyRoot) {
assert.equal(b.children.length, 4, 'deep copy has incorrect composed children');
}
});

test('Polymer.dom importNode shallow', function() {
var a = document.createElement('div');
a.innerHTML = '<x-clonate><span>1</span><span>2</span></x-clonate>';
var b = Polymer.dom(document).importNode(Polymer.dom(a).firstElementChild);
Polymer.dom(document.body).appendChild(b);
assert.equal(Polymer.dom(b).childNodes.length, 0, 'shallow import has incorrect children');
if (b.shadyRoot) {
assert.equal(b.children.length, 2, 'shallow import has incorrect composed children');
}
});

test('Polymer.dom importNode deep', function() {
var a = document.createElement('div');
a.innerHTML = '<x-clonate><span>1</span><span>2</span></x-clonate>';
var b = Polymer.dom(document).importNode(a, true);
Polymer.dom(document.body).appendChild(b);
assert.equal(Polymer.dom(b.firstElementChild).childNodes.length, 2, 'deep copy has incorrect children');
if (b.shadyRoot) {
assert.equal(b.children.length, 4, 'deep copy has incorrect composed children');
}
});

});

suite('Polymer.dom accessors', function() {
Expand Down

0 comments on commit 699a3bc

Please sign in to comment.