infamous
Version:
A CSS3D/WebGL UI library.
150 lines (121 loc) • 3.98 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _lowclass = _interopRequireDefault(require("lowclass"));
var _native = _interopRequireDefault(require("lowclass/native"));
var _skatejs = require("@trusktr/skatejs");
var _Mixin = _interopRequireDefault(require("./Mixin"));
var _Utility = require("./Utility");
var _TreeNode = _interopRequireDefault(require("./TreeNode"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _default = (0, _Mixin.default)(Base => (0, _lowclass.default)('TreeNode').extends((0, _native.default)((0, _skatejs.withUpdate)(Base)), ({
Super,
Public: Private
}) => ({
// TODO, make Private work with Mixin+lowclass. The problem is when
// using `Private` on instance of the same class created by a different
// mixin application. We may have to do something similar to the
// hasInstance Mixin helper.
//private: {
_parent: null,
_children: null,
//},
constructor(...args) {
const self = Super(this).constructor(...args);
Private(self)._children = [];
return self;
},
/**
* @readonly
*/
get parent() {
return Private(this)._parent;
},
/**
* This is named "subnodes" to avoid conflict with HTML's Element.children
* @readonly
*/
get subnodes() {
// return a new array, so that the user modifying it doesn't affect
// this node's actual children.
return [...Private(this)._children];
},
/**
* Add a child node to this TreeNode.
*
* @param {TreeNode} childNode The child node to add.
*/
add(childNode) {
if (!(0, _Utility.isInstanceof)(childNode, _TreeNode.default)) throw new TypeError('TreeNode.add() expects the childNode argument to be a TreeNode instance.');
if (Private(childNode)._parent === this) throw new ReferenceError('childNode is already a child of this parent.');
if (Private(childNode)._parent) Private(childNode)._parent.remove(childNode);
Private(childNode)._parent = this;
Private(this)._children.push(childNode);
Promise.resolve().then(() => {
childNode.connected();
this.childConnected(childNode);
});
return this;
},
/**
* Add all the child nodes in the given array to this node.
*
* @param {Array.TreeNode} nodes The nodes to add.
*/
addChildren(nodes) {
nodes.forEach(node => this.add()(node));
return this;
},
/**
* Remove a child node from this node.
*
* @param {TreeNode} childNode The node to remove.
*/
remove(childNode) {
if (!(0, _Utility.isInstanceof)(childNode, _TreeNode.default)) throw new Error(`
TreeNode.remove expects the childNode argument to be an
instance of TreeNode. There should only be TreeNodes in the
tree.
`);
if (Private(childNode)._parent !== this) throw new ReferenceError('childNode is not a child of this parent.');
Private(childNode)._parent = null;
Private(this)._children.splice(Private(this)._children.indexOf(childNode), 1);
Promise.resolve().then(() => {
childNode.disconnected();
this.childDisconnected(childNode);
});
return this;
},
/**
* Remove all the child nodes in the given array from this node.
*
* @param {Array.TreeNode} nodes The nodes to remove.
*/
removeChildren(nodes) {
nodes.forEach(node => this.remove(node));
return this;
},
/**
* Shortcut to remove all children.
*/
removeAllChildren() {
this.removeChildren(Private(this)._children);
return this;
},
/**
* @readonly
* @return {number} How many children this TreeNode has.
*/
get childCount() {
return Private(this)._children.length;
},
// generic life cycle methods
connected() {},
disconnected() {},
childConnected(child) {},
childDisconnected(child) {},
propertyChanged() {}
})));
exports.default = _default;
;