diff options
author | Florrie <towerofnix@gmail.com> | 2019-09-16 10:34:40 -0300 |
---|---|---|
committer | Florrie <towerofnix@gmail.com> | 2019-09-16 10:34:40 -0300 |
commit | eb3b83fa2d56f3c85ac0d5c9b62223f6bd297940 (patch) | |
tree | 19b44f8249b56ec6d71f91ae83ce71c27a37be25 /ui/Element.js | |
parent | 3b94a56ecad81980448cb1f7f78acd8e58ab0c67 (diff) |
Add basic Element class
Diffstat (limited to 'ui/Element.js')
-rw-r--r-- | ui/Element.js | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/ui/Element.js b/ui/Element.js new file mode 100644 index 0000000..c5beb59 --- /dev/null +++ b/ui/Element.js @@ -0,0 +1,80 @@ +const EventEmitter = require('events') + +module.exports = class Element extends EventEmitter { + // The basic class containing methods for working with an element hierarchy. + // Generally speaking, you usually want to extend DisplayElement instead of + // this class. + + constructor() { + super() + + this.children = [] + this.parent = null + } + + eachDescendant(fn) { + // Run a function on this element, all of its children, all of their + // children, etc. + fn(this) + for (const child of this.children) { + child.eachDescendant(fn) + } + } + + addChild(child, afterIndex = this.children.length, {fixLayout = true} = {}) { + // TODO Don't let a direct ancestor of this be added as a child. Don't + // let itself be one of its childs either! + + if (child === this) { + throw exception( + 'EINVALIDHIERARCHY', 'An element cannot be a child of itself') + } + + child.parent = this + + if (afterIndex === this.children.length) { + this.children.push(child) + } else { + this.children.splice(afterIndex, 0, child) + } + + if (fixLayout) { + child.fixLayout() + } + } + + removeChild(child, {fixLayout = true} = {}) { + // Removes the given child element from the children list of this + // element. It won't be rendered in the future. If the given element + // isn't a direct child of this element, nothing will happen. + + if (child.parent !== this) { + return + } + + child.parent = null + this.children.splice(this.children.indexOf(child), 1) + + if (fixLayout) { + this.fixLayout() + } + } + + get root() { + let el = this + while (el.parent) { + el = el.parent + } + return el + } + + get directAncestors() { + const ancestors = [] + let el = this + while (el.parent) { + el = el.parent + ancestors.push(el) + } + return ancestors + } +} |