diff --git a/buildoz.css b/buildoz.css index 0a556b4..8916695 100644 --- a/buildoz.css +++ b/buildoz.css @@ -204,3 +204,38 @@ bz-graflow .bzgf-main-container{ position: relative; box-sizing: border-box; } + +/* BZGRAFLOW_CORE_START */ +/* bz-graflow internal layout rules (used in light DOM, and injected into shadow DOM when isolated) */ +bz-graflow .bzgf-wires-container, +bz-graflow .bzgf-nodes-container{ + position: absolute; + inset: 0; + width: 100%; + height: 100%; +} +bz-graflow .bzgf-nodes-container .bzgf-node{ position:absolute; } +bz-graflow .bzgf-nodes-container .bzgf-fake-node{ + position: absolute; + width: 5px; + height: 5px; + background: transparent; + border-style: none; +} +bz-graflow .bzgf-nodes-container button.bzgf-zoom-in{ + z-index: 999; + position: absolute; + top: -0.5em; + right: -1em; + color: black; + width: 2em; + height: 2em; + padding: 0; +} +bz-graflow button.bzgf-zoom-out{ + z-index: 999; + position: absolute; + left: 5px; + top: 5px; +} +/* BZGRAFLOW_CORE_END */ diff --git a/bzGraflow.js b/bzGraflow.js index b7f7176..249bffd 100644 --- a/bzGraflow.js +++ b/bzGraflow.js @@ -34,6 +34,32 @@ class BZgraflow extends Buildoz{ this.currentOrientation = null } + static _coreCssPromise = null + + static async getCoreCss(){ + if(BZgraflow._coreCssPromise) return(await BZgraflow._coreCssPromise) + BZgraflow._coreCssPromise = (async() => { + const res = await fetch('/app/thirdparty/buildoz/buildoz.css') + const css = await res.text() + const m = css.match(/\/\*\s*BZGRAFLOW_CORE_START\s*\*\/([\s\S]*?)\/\*\s*BZGRAFLOW_CORE_END\s*\*\//) + const core = m ? m[1] : '' + return(core) + })() + return(await BZgraflow._coreCssPromise) + } + + async ensureIsolatedCoreStyles(){ + if(!this.hasAttribute('isolated')) return + if(this._isolatedCoreInjected) return + this._isolatedCoreInjected = true + const core = await BZgraflow.getCoreCss() + // Convert light-dom selectors (`bz-graflow ...`) to shadow-dom selectors (`:host ...`) + const shadowCss = core.replaceAll('bz-graflow', ':host') + const style = document.createElement('style') + style.textContent = shadowCss + this.mainContainer.appendChild(style) + } + addIcon(el, name) { el.innerHTML = `` } @@ -41,10 +67,7 @@ class BZgraflow extends Buildoz{ connectedCallback() { super.connectedCallback() const flowUrl = this.getBZAttribute('flow') - if(!flowUrl) { - console.warn('BZgraflow: No flow URL !?') - return - } + if(!flowUrl) return // Be tolerant: maybe injected later from JS above // If attribute "isolated" is present, render inside a shadow root. // Otherwise, render in light DOM (no shadow DOM). this.hostContainer = document.createElement('div') @@ -52,37 +75,7 @@ class BZgraflow extends Buildoz{ this.mainContainer = this.hasAttribute('isolated') ? this.hostContainer.attachShadow({ mode: 'open' }) : this.hostContainer - const style = document.createElement('style') - //TODO kick this wart somewhere under a carpet - style.textContent = ` - .bzgf-wires-container, - .bzgf-nodes-container{ position: absolute; inset: 0; width: 100%; height: 100%; } - .bzgf-nodes-container .bzgf-node{ position:absolute; } - .bzgf-nodes-container .bzgf-fake-node{ - position: absolute; - width: 5px; - height: 5px; - backgrround: transparent; - border-style: none; - } - .bzgf-nodes-container button.bzgf-zoom-in{ - z-index: 999; - position: absolute; - top: -0.5em; - right: -1em; - color: black; - width: 2em; - height: 2em; - padding: 0; - } - bz-graflow button.bzgf-zoom-out{ - z-index: 999; - position: absolute; - left: 5px; - top: 5px; - } - ` - this.mainContainer.appendChild(style) + this.ensureIsolatedCoreStyles() this.nodesContainer = document.createElement('div') this.nodesContainer.classList.add('bzgf-nodes-container') this.wiresContainer = document.createElementNS('http://www.w3.org/2000/svg', 'svg') @@ -91,9 +84,13 @@ class BZgraflow extends Buildoz{ this.mainContainer.append(this.wiresContainer) this.mainContainer.append(this.nodesContainer) this.append(this.hostContainer) - this.loadFlow(flowUrl) // Let it load async + this.loadFlow(flowUrl).then(() => { + if(this.hasAttribute('editable')){ + this.dnd = new MovingNodes(this) + this.dnd.enableMovingNodes('.bzgf-node') } + }) // Let it load async } - + error(msg, err){ this.innerHTML = `