Skip to content

Commit

Permalink
More efficient array management in Polymer.DomApi.
Browse files Browse the repository at this point in the history
  • Loading branch information
Steven Orvell committed Oct 30, 2015
1 parent e35c4e9 commit 320d5c7
Showing 1 changed file with 48 additions and 20 deletions.
68 changes: 48 additions & 20 deletions src/lib/dom-api.html
Expand Up @@ -356,7 +356,7 @@
if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
// NOTE: the act of setting this info can affect patched nodes
// getters; therefore capture childNodes before patching.
var c$ = Array.prototype.slice.call(node.childNodes);
var c$ = arrayCopyNodes(node.childNodes);
for (var i=0, n; (i<c$.length) && (n=c$[i]); i++) {
children.splice(index++, 0, n);
n._lightParent = container;
Expand Down Expand Up @@ -585,7 +585,7 @@
childNodes: {
get: function() {
var c$ = getLightChildren(this.node);
return Array.isArray(c$) ? c$ : Array.prototype.slice.call(c$);
return Array.isArray(c$) ? c$ : arrayCopyNodes(c$);
},
configurable: true
},
Expand Down Expand Up @@ -722,7 +722,9 @@
this._clear();
var d = document.createElement('div');
d.innerHTML = text;
var c$ = Array.prototype.slice.call(d.childNodes);
// here, appendChild may move nodes async so we cannot rely
// on node position when copying
var c$ = arrayCopyNodes(d.childNodes);
for (var i=0; i < c$.length; i++) {
this.appendChild(c$[i]);
}
Expand All @@ -740,17 +742,22 @@

} else {

var forwardMethods = ['cloneNode', 'appendChild', 'insertBefore',
'removeChild', 'replaceChild'];

forwardMethods.forEach(function(name) {
function forwardMethods(m$) {
for (var i=0; i < m$.length; i++) {
fowardMethod(m$[i]);
}
}
function forwardMethod(method) {
DomApi.prototype[name] = function() {
return this.node[name].apply(this.node, arguments);
}
});
}

forwardMethods(['cloneNode', 'appendChild', 'insertBefore',
'removeChild', 'replaceChild'])

DomApi.prototype.querySelectorAll = function(selector) {
return Array.prototype.slice.call(this.node.querySelectorAll(selector));
return arrayCopyNodes(this.node.querySelectorAll(selector));
};

DomApi.prototype.getOwnerRoot = function() {
Expand All @@ -772,13 +779,13 @@
DomApi.prototype.getDestinationInsertionPoints = function() {
var n$ = this.node.getDestinationInsertionPoints &&
this.node.getDestinationInsertionPoints();
return n$ ? Array.prototype.slice.call(n$) : [];
return n$ ? arrayCopy(n$) : [];
};

DomApi.prototype.getDistributedNodes = function() {
var n$ = this.node.getDistributedNodes &&
this.node.getDistributedNodes();
return n$ ? Array.prototype.slice.call(n$) : [];
return n$ ? arrayCopy(n$) : [];
};

DomApi.prototype._distributeParent = function() {};
Expand All @@ -796,14 +803,14 @@

childNodes: {
get: function() {
return Array.prototype.slice.call(this.node.childNodes);
return arrayCopyNodes(this.node.childNodes);
},
configurable: true
},

children: {
get: function() {
return Array.prototype.slice.call(this.node.children);
return arrayCopyNodes(this.node.children);
},
configurable: true
},
Expand Down Expand Up @@ -831,18 +838,22 @@

});

var forwardProperties = ['parentNode', 'firstChild', 'lastChild',
'nextSibling', 'previousSibling', 'firstElementChild', 'lastElementChild',
'nextElementSibling', 'previousElementSibling'];

forwardProperties.forEach(function(name) {
function forwardProperties(f$) {
for (var i=0; i < f$.length; i++) {
forwardProperty(f$[i]);
}
}
function forwardProperty(name) {
Object.defineProperty(DomApi.prototype, name, {
get: function() {
return this.node[name];
},
configurable: true
});
});
}
forwardProperties(['parentNode', 'firstChild', 'lastChild',
'nextSibling', 'previousSibling', 'firstElementChild', 'lastElementChild',
'nextElementSibling', 'previousElementSibling']);

}

Expand Down Expand Up @@ -878,7 +889,7 @@

function getComposedChildren(node) {
if (!node._composedChildren) {
node._composedChildren = Array.prototype.slice.call(node.childNodes);
node._composedChildren = arrayCopyNodes(node.childNodes);
}
return node._composedChildren;
}
Expand Down Expand Up @@ -939,6 +950,23 @@
}
}

// sad but faster than slice...
function arrayCopyNodes(childNodes) {
var copy=[], i=0;
for (var n=childNodes.firstChild; n; n=n.nextSibling) {
copy[i++] = n;
}
return copy;
}

function arrayCopy(a$) {
var copy = new Array(a$.length);
for (var i=0; i < a$.length; i++) {
copy[i] = a$[i];
}
return copy;
}

function hasInsertionPoint(root) {
return Boolean(root && root._insertionPoints.length);
}
Expand Down

0 comments on commit 320d5c7

Please sign in to comment.