Skip to content

Commit

Permalink
feat: Add a function for getting descendants from components (#6519)
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonocasey authored Mar 30, 2020
1 parent 668c7f4 commit 47ba704
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
31 changes: 31 additions & 0 deletions src/js/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,37 @@ class Component {
return this.childNameIndex_[name];
}

/**
* Returns the descendant `Component` following the givent
* descendant `names`. For instance ['foo', 'bar', 'baz'] would
* try to get 'foo' on the current component, 'bar' on the 'foo'
* component and 'baz' on the 'bar' component and return undefined
* if any of those don't exist.
*
* @param {...string[]|...string} names
* The name of the child `Component` to get.
*
* @return {Component|undefined}
* The descendant `Component` following the given descendant
* `names` or undefined.
*/
getDescendant(...names) {
// flatten array argument into the main array
names = names.reduce((acc, n) => acc.concat(n), []);

let currentChild = this;

for (let i = 0; i < names.length; i++) {
currentChild = currentChild.getChild(names[i]);

if (!currentChild || !currentChild.getChild) {
return;
}
}

return currentChild;
}

/**
* Add a child `Component` inside the current `Component`.
*
Expand Down
21 changes: 21 additions & 0 deletions test/unit/component.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1203,3 +1203,24 @@ QUnit.test('should remove child when the child moves to the other parent', funct
parentComponent2.dispose();
childComponent.dispose();
});

QUnit.test('getDescendant should work as expected', function(assert) {
const comp = new Component(getFakePlayer(), {name: 'component'});
const descendant1 = new Component(getFakePlayer(), {name: 'descendant1'});
const descendant2 = new Component(getFakePlayer(), {name: 'descendant2'});
const descendant3 = new Component(getFakePlayer(), {name: 'descendant3'});

comp.addChild(descendant1);
descendant1.addChild(descendant2);
descendant2.addChild(descendant3);

assert.equal(comp.getDescendant('descendant1', 'descendant2', 'descendant3'), descendant3, 'can pass as args');
assert.equal(comp.getDescendant(['descendant1', 'descendant2', 'descendant3']), descendant3, 'can pass as array');
assert.equal(comp.getDescendant('descendant1'), descendant1, 'can pass as single string');
assert.equal(comp.getDescendant(), comp, 'no args returns base component');
assert.notOk(comp.getDescendant('descendant5'), 'undefined descendant returned');
assert.notOk(comp.getDescendant('descendant1', 'descendant5'), 'undefined descendant returned');
assert.notOk(comp.getDescendant(['descendant1', 'descendant5']), 'undefined descendant returned');

comp.dispose();
});

0 comments on commit 47ba704

Please sign in to comment.