UNPKG

syntax-tree

Version:
180 lines (132 loc) 3.18 kB
/** * Node * @return {Node} */ function Node( properties ) { if( !(this instanceof Node) ) return new Node( properties ) this.type = 'Node' this.parent = null this.children = [] if( properties != null ) { Object.assign( this, properties ) } } /** * Node prototype * @type {Object} */ Node.prototype = { constructor: Node, get isRoot() { return this.parent === this }, get isParent() { return this.children.length > 0 }, get isChild() { return this.parent != null || !this.parent.hasChild( this ) }, get firstChild() { return this.children[0] }, get lastChild() { return this.children[ this.children.length - 1 ] }, get previousSibling() { if( this.isChild ) { var index = this.parent.children.indexOf( this ) if( index >= 1 ) { return this.parent.children[ index ] } } }, get nextSibling() { if( this.isChild ) { var index = this.parent.children.indexOf( this ) if( index >= 0 && index + 1 < this.parent.children.length ) { return this.parent.children[ index + 1 ] } } }, hasChild: function( node ) { return !!~this.children.indexOf( node ) }, prependChild: function( node ) { this.children.unshift( node ) node.remove() node.parent = this return this }, appendChild: function( node ) { this.children.push( node ) node.remove() node.parent = this return this }, insertBefore: function( node, previousNode ) { if( previousNode == null ) { return this.prependChild( node ) } var index = this.children.indexOf( previousNode ) if( index === 0 ) { this.children.unshift( node ) } else if( index > 0 ) { this.children.splice( index, 0, node )[0] } else { this.children.unshift( node ) } node.remove() node.parent = this return this }, insertAfter: function( node, nextNode ) { if( nextNode == null ) { return this.appendChild( node ) } var index = this.children.indexOf( nextNode ) if( index === this.children.length - 1 ) { this.children.push( node ) } else if( index >= 0 ) { this.children.splice( index + 1, 0, node )[0] } else { this.children.push( node ) } node.remove() node.parent = this return this }, replaceChild: function( oldNode, newNode ) { var child = null var index = this.children.indexOf( oldNode ) if( index >= 0 ) { child = this.children.splice( index, 1, newNode )[0] child.parent = null newNode.remove() newNode.parent = this } return this }, removeChild: function( node ) { var child = null var index = this.children.indexOf( node ) if( index >= 0 ) { child = this.children.splice( index, 1 )[0] child.parent = null } return child || node }, remove: function() { if( this.isRoot ) { throw new Error( 'Cannot remove root node' ) } if( this.parent ) { this.parent.removeChild( this ) this.parent = null } return this }, } // Exports module.exports = Node