Skip to content

Commit

Permalink
Adds getEffectiveChildNodes, getEffectiveChildren, `getEffectiveT…
Browse files Browse the repository at this point in the history
…extContent`
  • Loading branch information
Steven Orvell committed Aug 3, 2015
1 parent 97944e4 commit f34fb45
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 24 deletions.
26 changes: 13 additions & 13 deletions src/lib/dom-api.html
Original file line number Diff line number Diff line change
Expand Up @@ -405,28 +405,28 @@
points.
*/
queryDistributedElements: function(selector) {
var c$ = this.childNodes;
var c$ = this.getEffectiveChildNodes();
var list = [];
this._distributedFilter(selector, c$, list);
for (var i=0, l=c$.length, c; (i<l) && (c=c$[i]); i++) {
if (c.localName === CONTENT) {
this._distributedFilter(selector, factory(c).getDistributedNodes(),
list);
if ((c.nodeType === Node.ELEMENT_NODE) &&
matchesSelector.call(c, selector)) {
list.push(c);
}
}
return list;
},

_distributedFilter: function(selector, list, results) {
results = results || [];
for (var i=0, l=list.length, d; (i<l) && (d=list[i]); i++) {
if ((d.nodeType === Node.ELEMENT_NODE) &&
(d.localName !== CONTENT) &&
matchesSelector.call(d, selector)) {
results.push(d);
getEffectiveChildNodes: function() {
var list = [];
var c$ = this.childNodes;
for (var i=0, l=c$.length, c; (i<l) && (c=c$[i]); i++) {
if (c.localName === CONTENT) {
list = list.concat(factory(c).getDistributedNodes().slice());
} else {
list.push(c);
}
}
return results;
return list;
},

_clear: function() {
Expand Down
57 changes: 57 additions & 0 deletions src/standard/utils.html
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,63 @@
}
},

/**
* Returns a list of nodes that are the effective childNodes. The effective
* childNodes list is the same as the element's childNodes except that
* any `<content>` elements are replaced with the list of nodes distributed
* to the `<content>`, the result of its `getDistributedNodes` method.
*
* @method getEffectiveChildNodes
* @return {Array<Node>} List of effctive child nodes.
*/
getEffectiveChildNodes: function() {
return Polymer.dom(this).getEffectiveChildNodes();
},

/**
* Returns a list of elements that are the effective children. The effective
* children list is the same as the element's children except that
* any `<content>` elements are replaced with the list of elements
* distributed to the `<content>`.
*
* @method getEffectiveChildren
* @return {Array<Node>} List of effctive children.
*/
getEffectiveChildren: function() {
var list = Polymer.dom(this).getEffectiveChildNodes();
return list.filter(function(n) {
return (n.nodeType === Node.ELEMENT_NODE);
});
},

/**
* Returns a string of text content that is the concatenation of the
* text content's of the element's effective childNodes (the elements
* returned by <a href="#getEffectiveChildNodes>getEffectiveChildNodes</a>.
*
* @method getEffectiveTextContent
* @return {Array<Node>} List of effctive children.
*/
getEffectiveTextContent: function() {
var cn = this.getEffectiveChildNodes();
var tc = [];
for (var i=0, c; c = cn[i]; i++) {
if (c.nodeType !== Node.COMMENT_NODE) {
tc.push(Polymer.dom(c).textContent);
}
}
return tc.join('');
},

queryEffectiveChildren: function(slctr) {
var e$ = Polymer.dom(this).queryDistributedElements(slctr);
return e$ && e$[0];
},

queryAllEffectiveChildren: function(slctr) {
return Polymer.dom(this).queryAllDistributedElements(slctr);
},

/**
* Returns a list of nodes distributed to this element's `<content>`.
*
Expand Down
9 changes: 9 additions & 0 deletions test/unit/polymer-dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,15 @@ suite('Polymer.dom', function() {

});

test('getEffectiveChildNodes', function() {
var rere = Polymer.dom(testElement.root).querySelector('x-rereproject');
var re = Polymer.dom(rere.root).querySelector('x-reproject');
var projected = Polymer.dom(testElement.root).querySelector('#projected');
var c$ = Polymer.dom(re).getEffectiveChildNodes();
assert.equal(c$.length, 3);
assert.equal(c$[1], projected);
});

test('Polymer.dom.querySelector', function() {
var test = Polymer.dom().querySelector('x-test');
var rere = Polymer.dom().querySelector('x-rereproject');
Expand Down
26 changes: 26 additions & 0 deletions test/unit/utils-content.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,19 @@
<span></span>
</x-content-multi>

<x-compose id="elt4">
<div class="b">b</div>
<div class="d">d</div>
</x-compose>

<script>

suite('content utils', function() {

var elt1 = document.querySelector('#elt1');
var elt2 = document.querySelector('#elt2');
var elt3 = document.querySelector('#elt3');
var elt4 = document.querySelector('#elt4');

test('getContentChildNodes (empty)', function() {
var nodes = elt1.getContentChildNodes();
Expand Down Expand Up @@ -88,6 +94,26 @@
var nodes = elt3.getContentChildren('[dne]');
assert.equal(nodes.length, 0, 'should find 0 nodes');
});

test('getEffectiveChildNodes', function() {
var nodes = elt4.$.content.getEffectiveChildNodes();
assert.equal(nodes.length, 14);
});

test('getEffectiveChildren', function() {
var nodes = elt4.$.content.getEffectiveChildren();
assert.equal(nodes.length, 5);
assert.ok(nodes[0].classList.contains('a'));
assert.ok(nodes[1].classList.contains('b'));
assert.ok(nodes[2].classList.contains('c'));
assert.ok(nodes[3].classList.contains('d'));
assert.ok(nodes[4].classList.contains('e'));
});

test('getEffectiveTextContent', function() {
var text = elt4.$.content.getEffectiveTextContent();
assert.equal(text.replace(/\s/g, ''), 'abcde');
});

});

Expand Down
40 changes: 29 additions & 11 deletions test/unit/utils-elements.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,44 @@
<template>
<content></content>
</template>
<script>
Polymer({
is: 'x-content'
});
</script>

</dom-module>

<script>
Polymer({
is: 'x-content'
});
</script>

<dom-module id="x-content-multi">

<template>
<content select="div"></content>
<content select="span"></content>
</template>

<script>
Polymer({
is: 'x-content-multi'
});
</script>

</dom-module>

<script>
Polymer({
is: 'x-content-multi'
});
</script>
<dom-module id="x-compose">

<template>
<x-content id="content">
<div class="a">a</div>
<content select=".b"></content>
<div class="c">c</div>
<content></content>
<div class="e">e</div>
</x-content>
</template>
<script>
Polymer({
is: 'x-compose'
});
</script>

</dom-module>

0 comments on commit f34fb45

Please sign in to comment.