UNPKG

lazy-js-utils

Version:

A collection of lazy-loaded JavaScript utilities for efficient development

164 lines (160 loc) 4.53 kB
import { createElement, useMutationObserver } from "../chunk-7P2KG5TJ.mjs"; import { isArray } from "../chunk-4N54TZJJ.mjs"; // src/webComponent/render.ts function render(arr, node) { arr = isArray(arr) ? arr : [arr]; arr.forEach((item) => { const el = document.createElement(item.tag); if (item.class) el.className = item.class; if (item.name) el.setAttribute("name", item.name); if (typeof item.children === "string") { const text = document.createTextNode(item.children); el.appendChild(text); } else if (item.children) { render(item.children, el); } node.appendChild(el); }); } var Render = class extends HTMLElement { props = {}; /** * 创建影子节点 * https://developer.mozilla.org/zh-CN/docs/Web/API/Element/attachShadow */ shadowRoot = this.attachShadow({ mode: "open" }); constructor() { super(); this.initial(); this.setupShadow(); } initial() { useMutationObserver(this, () => this.setProps(), { attributes: true }); } /** * 初始化影子节点 */ setupShadow() { render(this.html(), this.shadowRoot); this.renderCss(); } renderCss() { const stylesheet = new CSSStyleSheet(); stylesheet.replaceSync(this.css()); this.shadowRoot.adoptedStyleSheets = [stylesheet]; } setProps() { this.props = Array.from(this.attributes).reduce((result, item) => { const { name, value } = item; result[name] = value; return result; }, {}); this.renderCss(); } css() { throw new Error("\u5FC5\u987B\u91CD\u5199\u7236\u7C7B css \u65B9\u6CD5"); } html() { throw new Error("\u5FC5\u987B\u91CD\u5199\u7236\u7C7B html \u65B9\u6CD5"); } }; // src/webComponent/crossImageElement.ts var nameReg = /\w+-\w+/; function crossImageElement(name = "img-cors") { if (!nameReg.test(name)) { return console.error( "crossImageElement: The naming must follow this format \u201Cxxx-xxx\u201D " ); } window.customElements.define(name, ImageElement); } var ImageElement = class extends HTMLElement { shadow; width; height; constructor() { super(); this.shadow = this.attachShadow({ mode: "open" }); const iframe = createElement("iframe", { src: "about:blank", frameborder: "0" }); iframe.onload = () => this.onIfrLoad(iframe); this.shadow.appendChild(iframe); } onIfrLoad(ifr) { const doc = ifr.contentWindow.document; doc.body.setAttribute("style", "margin:0;"); const attributes = ["width", "height", "style", "class", "alt", "src"]; const attrs = attributes.reduce((result, attribute) => { const attr = this.getAttribute(attribute); if (!attr) return result; return result += `${attribute}="${attr}" `; }, ""); doc.body.innerHTML = `<img ${attrs}>`; doc.body.querySelector("img").onload = () => { this.width = ifr.width = this.width; this.height = ifr.height = this.height; }; } }; // src/webComponent/crossVideoElement.ts var nameReg2 = /\w+-\w+/; function crossVideoElement(name = "video-cors") { if (!nameReg2.test(name)) { return console.error( "crossImageElement: The naming must follow this format \u201Cxxx-xxx\u201D " ); } window.customElements.define(name, VideoElement); } var VideoElement = class extends HTMLElement { shadow; width; height; constructor() { super(); this.shadow = this.attachShadow({ mode: "open" }); const iframe = createElement("iframe", { src: "about:blank", frameborder: "0" }); iframe.onload = () => this.onIfrLoad(iframe, this.shadow.host.innerHTML); this.shadow.appendChild(iframe); } onIfrLoad(ifr, children) { const doc = ifr.contentWindow.document; doc.body.setAttribute("style", "margin:0;"); const attributes = ["width", "height", "style", "class", "src", "controls"]; const single = ["controls"]; const attrs = attributes.reduce((result, attribute) => { const attr = this.getAttribute(attribute); if (single.includes(attribute)) return result += `${attribute} `; if (!attr) return result; return result += `${attribute}="${attr}"`; }, ""); doc.body.innerHTML = `<video ${attrs}>${children}</video>`; doc.body.querySelector("video").onload = () => { this.width = ifr.width = this.width; this.height = ifr.height = this.height; }; } }; export { Render, crossImageElement, crossVideoElement, render };