UNPKG

extml

Version:

Converts html tagged templates to ExtJS component object.

152 lines (137 loc) 6.6 kB
import {htmlTags} from "./htmlTags.js"; export function defineExtClass(tag) { let className = 'html-' + tag; if (window.__extHtmlClass[className]) { return } window.__extHtmlClass[className] = window.Ext.define(className, { extend: 'Ext.Container', xtype: className, element: { tag, reference: 'element' }, template: [ { tag: 'ghost-tag', reference: 'bodyElement', cls: '', uiCls: '' } ], getInnerHtmlElement() { return this.getRenderTarget(); }, doHack() { { if (!this.el || !this.el.dom ) { return } //this.el.dom.className = ''; //this.innerElement.dom.className = ''; this.el.dom.removeAttribute('class'); // l'id mi serve per lo style if (!this.stylesheet) this.el.dom.removeAttribute('id'); this.el.dom.removeAttribute('data-componentid'); this.el.dom.removeAttribute('data-xid'); if (this._propsAttributes) { Object.keys(this._propsAttributes).forEach(attribute => { if (attribute === 'ref' && this._propsAttributes[attribute].$$isRef) { if (this._propsAttributes[attribute].$$isExtRef) { this._propsAttributes[attribute](this) } else { this._propsAttributes[attribute](this.el.dom) } } else if (this._propsAttributes[attribute].$$isState) { this.el.dom.setAttribute(attribute, String(this._propsAttributes[attribute]())); // o.$$stateListener = this._propsAttributes[attribute].$$subscribe(value => { this.$$stateListener = this._propsAttributes[attribute].$$subscribe(value => { this.el.dom.setAttribute(attribute, String(value)); }) } else if (attribute.startsWith('on') && typeof this._propsAttributes[attribute] === 'function') { this.el.dom.addEventListener(attribute.substring(2), this._propsAttributes[attribute]); } else { if (Array.isArray(this._propsAttributes[attribute]) && this._propsAttributes[attribute].$$hasState) { //console.log(this._propsAttributes[attribute]) // mi serve a costruire il valore dell'attributo concatenando i risultati degli state con le eventuali stringhe presenti let buildAttributeValue = () => this.el.dom.setAttribute(attribute, this._propsAttributes[attribute].map(item => { if (typeof item === 'function' && item.$$isState) { return item() } else { return item } }).join('')); buildAttributeValue(); // o.$$attributesStateListeners = []; this.$$attributesStateListeners = []; // per ogni state sottoscrivo un listener per ricostruire nuovamente il valore dell'attributo ad ogni cambiamento this._propsAttributes[attribute].forEach(item => { if (typeof item === 'function' && item.$$isState) { // o.$$attributesStateListeners.push(item.$$subscribe(value => { this.$$attributesStateListeners.push(item.$$subscribe(value => { buildAttributeValue(); })) } }) } else { this.el.dom.setAttribute(attribute, String(this._propsAttributes[attribute])); } } }); } } }, removeMonitorsElements() { // Rimuovo i due div del monitor, nodi dovrebbero essere sempre 3, quindi vado a colpo sicuro, // il primo è il bodyElement, quello che poi conterrà eventuali figli let sizeMonitorsEl = this.el.dom.childNodes[1]; let paintMonitorEl = this.el.dom.childNodes[2]; if (sizeMonitorsEl) sizeMonitorsEl.remove(); if (paintMonitorEl) paintMonitorEl.remove(); }, moveElementsToNewParent() { // sposto gli elementi dal ghost-tag al parent let newParent = this.el.dom; let oldParent = this.innerElement.dom; if (newParent && oldParent) { function move() { while (oldParent.childNodes.length > 0) { newParent.appendChild(oldParent.childNodes[0]); } } move(); this.innerElement.dom = this.el.dom; // Rimuovo ghost-tag oldParent.remove(); } }, listeners: [ { initialize() { requestAnimationFrame(() => this.doHack()); this.removeMonitorsElements(); this.moveElementsToNewParent(); } }, { destroy(o) { if(o.$$stateListener) { o.$$stateListener() } if (o.$$attributesStateListeners) { o.$$attributesStateListeners.forEach(listener => listener()); } } } ] }); } export function generateHtmlClass() { if (!window.__extHtmlClass) { window.__extHtmlClass = {}; htmlTags.forEach(tag => defineExtClass(tag)); } }