From c11b978faacfafa2b53dd59b7d7bdf8a3f569266 Mon Sep 17 00:00:00 2001 From: Gregg Tavares Date: Sun, 21 May 2023 12:10:40 +0900 Subject: [PATCH] use shadowdom --- examples/js/utils.js | 7 +++--- src/muigui.js | 54 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/examples/js/utils.js b/examples/js/utils.js index 406e24f..0ee237d 100644 --- a/examples/js/utils.js +++ b/examples/js/utils.js @@ -1,7 +1,8 @@ -export function getCSSRulesBySelector(selector) { +export function getCSSRulesBySelector(selector, styleSheet) { const rules = []; - for (let s = 0; s < document.styleSheets.length; ++s) { - const cssRules = document.styleSheets[s].cssRules; + const styleSheets = styleSheet ? [styleSheet] : document.styleSheets; + for (let s = 0; s < styleSheets.length; ++s) { + const cssRules = styleSheets[s].cssRules; for (let i = 0; i < cssRules.length; ++i) { const r = cssRules[i]; if (r.selectorText === selector) { diff --git a/src/muigui.js b/src/muigui.js index f7f3011..96f6fcc 100644 --- a/src/muigui.js +++ b/src/muigui.js @@ -28,9 +28,6 @@ export { Row, }; -let stylesInjected = false; -const styleElem = createElem('style'); - export class GUIFolder extends Folder { add(object, property, ...args) { const controller = object instanceof Controller @@ -55,11 +52,40 @@ export class GUIFolder extends Folder { } } +class MuiguiElement extends HTMLElement { + constructor() { + super(); + this.shadow = this.attachShadow({mode: 'open'}) + } +} + +customElements.define("muigui-element", MuiguiElement); + +const baseStyleSheet = new CSSStyleSheet(); +baseStyleSheet.replaceSync(css); +const userStyleSheet = new CSSStyleSheet(); +window.bss = baseStyleSheet; + +let newCss; +let newCssPromise; + +function updateStyle() { + if (newCss && !newCssPromise) { + const css = newCss; + newCss = undefined; + newCssPromise = userStyleSheet.replace(css).then(() => { + newCssPromise = undefined; + updateStyle(); + }); + } +} + export class GUI extends GUIFolder { static converters = converters; static mapRange = mapRange; static makeRangeConverters = makeRangeConverters; static makeRangeOptions = makeRangeOptions; + #localStyleSheet = new CSSStyleSheet(); constructor(options = {}) { super('Controls', 'muigui-root'); @@ -70,16 +96,11 @@ export class GUI extends GUIFolder { autoPlace = true, width, title = 'Controls', - injectStyles = true, } = options; let { parent, } = options; - if (injectStyles && !stylesInjected) { - stylesInjected = true; - (document.head || document.documentElement).appendChild(styleElem); - styleElem.textContent = css; - } + if (width) { this.domElement.style.width = /^\d+$/.test(width) ? `${width}px` : width; } @@ -88,13 +109,26 @@ export class GUI extends GUIFolder { this.domElement.classList.add('muigui-auto-place'); } if (parent) { - parent.appendChild(this.domElement); + const muiguiElement = createElem('muigui-element'); + muiguiElement.shadowRoot.adoptedStyleSheets = [baseStyleSheet, userStyleSheet, this.#localStyleSheet]; + muiguiElement.shadow.appendChild(this.domElement); + parent.appendChild(muiguiElement); } if (title) { this.title(title); } this.domElement.classList.add('muigui', 'muigui-colors'); } + setStyle(css) { + this.#localStyleSheet.replace(css); + } + static setStyles(css) { + newCss = css; + updateStyle(); + } + static getStyleSheet() { + return baseStyleSheet; + } } export default GUI;