UNPKG

@downforce/webx

Version:

Awesome Web Components and Custom Elements

70 lines 2.12 kB
import { returnUndefined, tryCatch } from '@downforce/std/fn'; import { useEventListener, useMounted, WebElement } from '@downforce/web/element'; /* * EXAMPLE * * customElements.define('html-sandbox', HtmlSandbox) * * <html-sandbox> * <style> * p { color: red; } * </style> * * <p>Hello World!</p> * </html-sandbox> */ export class HtmlSandbox extends WebElement { static getImplementation() { return Implementation; } constructor() { super(); this.attachShadow({ mode: 'open' }); useMounted(this, () => { Implementation.onMounted(this); }); useEventListener(this, window, 'hashchange', Implementation.onHashChange.bind(this, this)); } connectedCallback() { Implementation.onContentChange(this); } } const Implementation = { onMounted(element) { const observer = new MutationObserver(() => Implementation.onContentChange(element)); observer.observe(element, { subtree: true, characterData: true }); function onUnmount() { observer.disconnect(); } return onUnmount; }, onContentChange(element) { if (!element.shadowRoot) { return; } const children = Array.from(element.childNodes); const html = children.map(it => it.textContent).join('\n'); element.shadowRoot.innerHTML = html; Implementation.onHashChange(element); }, onHashChange(element) { const target = tryCatch(() => { if (!element.shadowRoot) { return; } if (!window.location.hash) { return; } const id = window.location.hash; const shadowElement = element.shadowRoot.querySelector(id); return shadowElement; }, returnUndefined); if (!target) { return; } // We can't use {behavior:'smooth'} because the Safari shim/polyfill // does not work inside Web Components. target.scrollIntoView(); }, }; //# sourceMappingURL=html-sandbox.js.map