UNPKG

@ou-imdt/utils

Version:

Utility library for interactive media development

57 lines (46 loc) 1.68 kB
import { id, defaultState } from '../Base.js'; // TODO look into stylesheet module - a stylesheet can be adopted by multiple shadowRoots with changes reflected where adopted // defines a prop to store a CSSStyleSheet instance adopted by document export const styleSheet = Symbol('styleSheet'); // defines a prop to export const preferShadow = Symbol('preferShadowStyles'); /** * manages a light DOM stylesheet to expose internal styling */ export default (superClass) => class StyleSheetMixin extends superClass { static get [defaultState]() { return { ...super[defaultState], [preferShadow]: true, [styleSheet]: null }; }; constructor() { super(); this[styleSheet] = new CSSStyleSheet(); }; get #root() { return (this[preferShadow] && this.shadowRoot) ? this.shadowRoot : document; } connectedCallback() { super.connectedCallback(); this.#root.adoptedStyleSheets.push(this[styleSheet]); } disconnectedCallback() { super.disconnectedCallback(); const index = this.#root.adoptedStyleSheets.indexOf(this[styleSheet]); this.#root.adoptedStyleSheets.splice(index, 1); } updateStyleSheet(styles) { // console.log('update style sheet', { styles, sheet: this[styleSheet], root: this.#root, current: this[styleSheet].cssRules }); this[styleSheet].replaceSync(styles); if (this.#root === document) { // scope styles [...this[styleSheet].cssRules].forEach((rule, index) => { if (!(rule instanceof CSSStyleRule)) return; this[styleSheet].deleteRule(index); this[styleSheet].insertRule(`#${this[id]} ${rule.cssText}`, index); }); } } }