Skip to content
Permalink
Browse files

Adds `querySelectorLocal` which returns matching nodes in `shadyRoot`…

…; fixes leaking clients list.
  • Loading branch information
sorvell committed Dec 19, 2014
1 parent e499588 commit 003123845d609de737d48b17a2f5aa681bcdaa88
Showing with 68 additions and 6 deletions.
  1. +40 −2 src/features/base/content.html
  2. +1 −3 src/features/base/ready.html
  3. +27 −1 test/unit/content.html
@@ -57,8 +57,8 @@
this._distributePool(this.contentRoot, this._collectPool());
}
// now fully distribute/compose "clients"
var l = this._clients.length;
for (var i=0, c; (i<l) && (c=this._clients[i]); i++) {
var c$ = this._getDistributionClients();
for (var i=0, l= c$.length, c; (i<l) && (c=c$[i]); i++) {
c.distributeContent();
}
// compose self
@@ -106,6 +106,36 @@
return matchesSelector.call(node, selector);
},

querySelectorLocal: function(selector) {
var self = this;
return this.queryLocal(function(n) {
return self.elementMatches(selector, n);
});
},

queryLocal: function(matcher) {
var c$ = this.children;
var list = [];
for (var i=0, l=c$.length, c; (i<l) && (c=c$[i]); i++) {
if (!c._destinationInsertionPoints) {
this._queryLocal(c, matcher, list);
}
}
return list;
},

_queryLocal: function(node, matcher, list) {
if (matcher(node)) {
list.push(node);
}
var c$ = getLightChildren(node);
for (var i=0, l=c$.length, c; (i<l) && (c=c$[i]); i++) {
if (c.nodeType === Node.ELEMENT_NODE) {
this._queryLocal(c, matcher, list);
}
}
},

// Many of the following methods are all conceptually static, but they are
// included here as "protected" methods to allow overriding.

@@ -174,6 +204,14 @@
}
},

_getDistributionClients: function() {
return this._clients ? this._clients :
this.queryLocal(function(n) {
// TODO(sorvell): need a better test here
return Boolean(n.distributeContent);
});
},

_composeTree: function(node) {
var children = this._composeNode(node);
for (var i = 0; i < children.length; i++) {
@@ -84,9 +84,7 @@
for (var i=0, l=n$.length, n; (i<l) && (n=n$[i]); i++) {
n._ready();
}
// TODO(sorvell): this leaks if we don't clean it up here, but
// it's currently needed for dynamic shadyDOM distribution... =(
//this._clients = [];
this._clients = null;
}
},

@@ -103,7 +103,6 @@
syncLightDOM(host);
setInnerHTML(host.contentRoot, '<x-content-test id="p"></x-content-test>');
var p = host.contentRoot.firstChild;
host._clients.push(p);
p.innerHTML = '<b></b><content></content>';
var b = p.firstChild;
var content = p.lastChild;
@@ -122,6 +121,8 @@
function testRender() {
// Simulate the correct ordering as "ready" would fire.
host.distributeContent();
// NOTE: needed only for this imperative test that needs
// to simulate distribution from `contentRoot`
p.distributeContent();

assert.strictEqual(host.innerHTML,
@@ -375,6 +376,31 @@
assert.strictEqual(host.innerHTML, '<b></b>');
});

test('querySelectorLocal', function() {
var host = document.createElement('x-content-test');
host.innerHTML = '<div id="main"></div>';
syncLightDOM(host);
setInnerHTML(host.contentRoot, '<content></content><span id="main"></span>' +
'<x-content-test></x-content-test>');
var hostLocalMain = host.contentRoot.firstChild.nextSibling;
var child = host.contentRoot.lastChild;
// force upgrade on polyfilled browsers
CustomElements.upgrade(child);
child.innerHTML = '<div id="sub"></div>';
var childLightSub = child.firstChild;
syncLightDOM(child);
setInnerHTML(child.contentRoot, '<content></content><span id="sub"></span>');
var childLocalSub = child.contentRoot.lastChild;
host.distributeContent();
// NOTE: needed only for this imperative test that needs
// to simulate distribution from `contentRoot`
child.distributeContent();

assert.deepEqual(host.querySelectorLocal('#main'), [hostLocalMain]);
assert.deepEqual(host.querySelectorLocal('#sub'), [childLightSub]);
assert.deepEqual(child.querySelectorLocal('#sub'), [childLocalSub]);
});

});

function setInnerHTML(node, value) {

0 comments on commit 0031238

Please sign in to comment.
You can’t perform that action at this time.