2021-08-23 23:56:36 +00:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
// Base features for all components
|
|
|
|
Toolkit.Component = class Component {
|
|
|
|
|
|
|
|
// Object constructor
|
2021-08-26 19:23:18 +00:00
|
|
|
constructor(application, tagname, options) {
|
|
|
|
options = options || {};
|
2021-08-23 23:56:36 +00:00
|
|
|
|
|
|
|
// Configure instance fields
|
|
|
|
this.application = application;
|
|
|
|
this.containers = [ this ];
|
2021-08-26 19:23:18 +00:00
|
|
|
this.display = null;
|
2021-08-23 23:56:36 +00:00
|
|
|
this.element = document.createElement(tagname);
|
|
|
|
this.id = this.element.id = Toolkit.id();
|
|
|
|
this.parent = null;
|
|
|
|
this.properties = {};
|
|
|
|
this.resizeListeners = [];
|
2021-08-26 19:23:18 +00:00
|
|
|
this.resizeObserver = null;
|
|
|
|
this.visible = "visible" in options ? !!options.visible : true;
|
2021-08-23 23:56:36 +00:00
|
|
|
|
|
|
|
// Configure component
|
|
|
|
this.element.component = this;
|
2021-08-26 19:23:18 +00:00
|
|
|
this.setVisible(this.visible);
|
2021-08-23 23:56:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////// Public Methods //////////////////////////////
|
|
|
|
|
|
|
|
// Add a callback for resize events
|
|
|
|
addResizeListener(listener) {
|
|
|
|
if (this.resizeListeners.indexOf(listener) != -1)
|
|
|
|
return;
|
2021-08-26 19:23:18 +00:00
|
|
|
if (this.resizeObserver == null) {
|
|
|
|
this.resizeObserver = new ResizeObserver(()=>this.onresized());
|
|
|
|
this.resizeObserver.observe(this.element);
|
|
|
|
}
|
2021-08-23 23:56:36 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2021-08-26 19:23:18 +00:00
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
|
2021-08-23 23:56:36 +00:00
|
|
|
// Specify the height of the element
|
|
|
|
setHeight(height) {
|
|
|
|
if (height === null)
|
|
|
|
this.element.style.removeProperty("height");
|
2021-08-26 19:23:18 +00:00
|
|
|
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";
|
2021-08-23 23:56:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Specify the width of the element
|
|
|
|
setWidth(width) {
|
|
|
|
if (width === null)
|
|
|
|
this.element.style.removeProperty("width");
|
2021-08-26 19:23:18 +00:00
|
|
|
else this.element.style.width =
|
|
|
|
typeof width == "number" ? width + "px" : width ;
|
2021-08-23 23:56:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////// 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
|
2021-08-26 19:23:18 +00:00
|
|
|
onresized() {
|
2021-08-23 23:56:36 +00:00
|
|
|
let bounds = this.getBounds();
|
|
|
|
for (let listener of this.resizeListeners)
|
|
|
|
listener(bounds, this);
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|