"use strict"; // Base features for all components Toolkit.Component = class Component { // Object constructor constructor(application, tagname, options) { options = options || {}; // Configure instance fields this.application = application; this.containers = [ this ]; this.display = null; this.element = document.createElement(tagname); this.id = this.element.id = Toolkit.id(); this.parent = null; this.properties = {}; this.resizeListeners = []; this.resizeObserver = null; this.visible = "visible" in options ? !!options.visible : true; // Configure component this.element.component = this; this.setVisible(this.visible); } ///////////////////////////// Public Methods ////////////////////////////// // Add a callback for resize events addResizeListener(listener) { if (this.resizeListeners.indexOf(listener) != -1) return; if (this.resizeObserver == null) { this.resizeObserver = new ResizeObserver(()=>this.onresized()); this.resizeObserver.observe(this.element); } this.resizeListeners.push(listener); } // Remove the component from its parent remove() { this.parent && this.parent.remove(this); } // Retrieve the bounding box of the element getBounds() { return this.element.getBoundingClientRect(); } // Retrieve the display CSS property of the visible element getDisplay() { return this.display; } // Determine whether the component is visible isVisible() { for (let comp = this; comp != null; comp = comp.parent) if (!comp.visible) return false; return true; } // Specify the display CSS property of the visible element setDisplay(display) { this.display = display || null; this.setVisible(this.visible); } // Specify the height of the element setHeight(height) { if (height === null) this.element.style.removeProperty("height"); else this.element.style.height = typeof height == "number" ? height + "px" : height } // Specify the horizontal position of the component setLeft(left) { if (left === null) this.element.style.removeProperty("left"); else this.element.style.left = typeof left == "number" ? left + "px" : left ; } // Specify the absolute position of the component setLocation(left, top) { this.setLeft(left); this.setTop (top ); } // Specify both the width and the height of the component setSize(width, height) { this.setHeight(height); this.setWidth (width ); } // Specify the vertical position of the component setTop(top) { if (top === null) this.element.style.removeProperty("top"); else this.element.style.top = typeof top == "number" ? top + "px" : top ; } // Specify whether the component is visible setVisible(visible) { this.visible = visible = !!visible; if (visible) { if (this.display == null) this.element.style.removeProperty("display"); else this.element.style.display = this.display; } else this.element.style.display = "none"; } // Specify the width of the element setWidth(width) { if (width === null) this.element.style.removeProperty("width"); else this.element.style.width = typeof width == "number" ? width + "px" : width ; } ///////////////////////////// Package Methods ///////////////////////////// // Determine whether this component contains another contains(comp) { if (comp == null) return false; if (comp instanceof Toolkit.Component) comp = comp.element; for (let cont of this.containers) if ((cont instanceof Toolkit.Component ? cont.element : cont) .contains(comp)) return true; return false; } ///////////////////////////// Private Methods ///////////////////////////// // Resize event handler onresized() { let bounds = this.getBounds(); for (let listener of this.resizeListeners) listener(bounds, this); } };