import { create, text, createCursor, createEventNameProxy, } from "@hesxenon/prelude/Dom.js"; import { ignore } from "@hesxenon/prelude/Function.js"; import { attribute, customElement } from "simple-custom-elements"; declare global { // eslint-disable-next-line no-var var hljs: { highlight: ( content: string, opts: { language?: string }, ) => { value: string }; }; } const Events = createEventNameProxy(); if (globalThis.hljs == null) { console.info( "uwc-playground: could not find 'hljs' in global scope, highlighting won't be available :/", ); } @customElement({ tagname: "uwc-playground" }) export class UwcPlaygroundElement extends HTMLElement { /** * set the default .innerHTML of the iframe. * * @default the current pages head innerHTML */ static head = document.head.innerHTML; /** * the content to display */ @attribute() src?: string; /** * the language the content is in, e.g. html */ @attribute() language?: string; connectedCallback(): void { const preview = create("div", { part: "preview" }); const editor = create( "code", { contentEditable: "true", oninput: () => { this.src = editor.innerText.replaceAll(String.fromCharCode(160), " "); highlight(); }, }, [text(decodeURIComponent(this.src ?? ""))], ); const cursor = createCursor(editor); const highlight = globalThis.hljs == null ? ignore : () => { const current = cursor.getPosition(); editor.innerHTML = hljs .highlight(editor.innerText, { language: this.language, }) .value.replaceAll("\n", "
"); if (current != null) { cursor.setPosition(current); } }; const update = () => { preview.innerHTML = decodeURIComponent(this.src ?? ""); highlight(); }; this.insertAdjacentElement("beforeend", preview); this.insertAdjacentElement("afterbegin", create("pre", {}, [editor])); this.addEventListener(Events.srcChanged, update); update(); } } declare global { const UwcPlaygroundElement: typeof import("./uwc-playground").UwcPlaygroundElement; type UwcPlaygroundElement = InstanceType; } Object.assign(globalThis, { UwcPlaygroundElement });