UNPKG

lovevanilla

Version:

Celebrating the Art of Simplicity in Web Development

299 lines (249 loc) 5.93 kB
import sanitizeHtml from "sanitize-html"; import { createDiv, createSpan } from "./createDiv"; import { murmurhash3_32_gc } from "./crypto"; import { getData, setData } from "./data"; import { Page } from "./page"; import { asyncDebounce } from "./utils"; export class Component { changedVisibility = async (visible) => {}; parent = null; children = []; $object = null; keys = []; constructor(id, props) { this.id = id; this.props = props; this.keys = [this.id]; for (let i = 0; i < this.props?.keys?.length; i++) { this.keys.push(this.props.keys[i]); } if (props?.parent) { this.parent = props.parent; } this.self = this; } getParent() { return this.parent; } init(props = {}) { this.props = props; for (const child of this.children) { if (child instanceof Component) { try { child.init(); } catch (e) { console.error(e); } } } } destroy() { window.removeEventListener("__init_state__", () => this.render()); window.removeEventListener("__popstate__", () => this.render()); } hide(delay = 0) { asyncDebounce(() => { if (this.isVisible()) { // this.obj.classList.add("hidden"); this.getObject().style.display = "none"; this.handleChangedVisibility(false); } }, delay)(); } show(delay = 0) { asyncDebounce(() => { this.getObject().style.display = "block"; // if (this.obj.classList.contains("love-vanilla-body")) { // this.obj.classList.add("fade-in visible"); // } // if (!this.isVisible()) { // this.obj.classList.remove("hidden"); // this.obj.removeAttribute("hidden"); // this.handleChangedVisibility(true); // } }, delay)(); } setText(text) { if (this.getObject()) { this.getObject().innerHTML = sanitizeHtml(text); } } reset() { this.obj.val = ""; } isVisible() { return this.getObject()?.style.display !== "none"; } handleChangedVisibility(visible) { this.changedVisibility(visible); } getChild(id) { for (let child of this.children) { if (child?.id == id) { return child; } } return null; } getChildren() { return this.children; } createChild(child) { child.setParent(this); this.children.push(child); return child; } setParent(parent) { this.parent = parent; } getParent() { return this.parent; } getObject() { if (this.$object) { return this.$object; } if (this.id === undefined) { this.$object = createSpan(); } else { this.$object = createDiv({ selector: this.id }); } return this.$object; } setHtml(html) { if (this.getObject() && this.getObject().innerHTML !== html) { this.getObject().innerHTML = html; } } remove() { this.children.forEach((child) => child.getObject()?.remove()); } getKeys() { return this.keys; } getHashCode() { return murmurhash3_32_gc(JSON.stringify(this.keys.join(""))); } disable() { this.getObject().disabled = true; } enable() { this.getObject().disabled = false; } setBeforeRender(beforeRender = () => {}) { if (beforeRender) { this.beforeRender = beforeRender; } return this; } setRender(render = () => {}) { if (this.render) { this.render = render; } return this; } setAfterRender(afterRender = () => {}) { if (this.afterRender) { this.afterRender = afterRender; } return this; } setUpdatedData(updatedData) { if (updatedData) { this.updatedData = updatedData; } return this; } beforeRender() { return this; } render() { for (var child in this.children) { if (this.children[child] instanceof Component) { this.children[child].render(); } } } afterRender() { return this; } updatedData() { return this; } getObjectPath() { let obj = this; let path = []; while (obj) { if (obj instanceof Component) { path.push(obj.id); obj = obj.getParent(); } else if (obj instanceof Page) { path.push(obj.getUrl()); break; } else { break; } } return path.reverse().join("|"); } setState(state) { setData({ [`${this.getObjectPath()}-${this.getHashCode()}`]: { ...getData()?.[this.getHashCode()], ...state, }, }); } getState() { return getData()?.[`${this.getObjectPath()}-${this.getHashCode()}`]; } getValue() { return this.getObject().value; } setClass(className) { this.getObject()?.classList.add(className); } removeClass(className) { this.getObject()?.classList.remove(className); } setAttribute(name, value) { this.getObject()?.setAttribute(name, value); } appendChild(child) { if (child instanceof Component) { child.setParent(this); this.children.push(child); if (this.getObject()) { this.getObject().prepend(child.getObject()); } } return child; } renderChild(newChild) { if (newChild instanceof Component) { if (this.getObject().children.length > 0) { this.getObject().replaceChild( newChild.render(), this.getObject().children[0] ); } else { this.getObject().appendChild(newChild.render()); } return this.getObject(); } if (newChild instanceof HTMLElement) { if (this.getObject().children.length > 0) { this.getObject().replaceChild(newChild, this.getObject().children[0]); } else { this.getObject().appendChild(newChild); } } return newChild; } add(newChild) { if (this.getObject()) { this.getObject().appendChild(newChild); } return this; } }