lazy-js-utils
Version:
A collection of lazy-loaded JavaScript utilities for efficient development
154 lines (150 loc) • 4.32 kB
JavaScript
import { isArray$1 as isArray } from "../isBool-Bi9uSocl.js";
import { createElement$1 as createElement, useMutationObserver$1 as useMutationObserver } from "../createElement-D3MQi5A0.js";
//#region 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("必须重写父类 css 方法");
}
html() {
throw new Error("必须重写父类 html 方法");
}
};
//#endregion
//#region src/webComponent/crossImageElement.ts
const nameReg$1 = /\w+-\w+/;
function crossImageElement(name = "img-cors") {
if (!nameReg$1.test(name)) return console.error("crossImageElement: The naming must follow this format “xxx-xxx” ");
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;
};
}
};
//#endregion
//#region src/webComponent/crossVideoElement.ts
const nameReg = /\w+-\w+/;
function crossVideoElement(name = "video-cors") {
if (!nameReg.test(name)) return console.error("crossImageElement: The naming must follow this format “xxx-xxx” ");
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;
};
}
};
//#endregion
export { Render, crossImageElement, crossVideoElement, render };