import { ChildOne, IProps } from "./interface"; import { subscribeElement } from "./state"; import { loadable } from "./loadable"; import { bindFn } from "./bindFn"; import { isElement, isString, uiCaches } from "./helper"; import { parseChildren, // parseForChildren, // parseIfChildren, // parseReplaceChildren, } from "./parseChildren"; const ignoreKeys: any = { class: 1, className: 1, classAdd: 1, classPick: 1, classExtends: 1, onsubmit: 1, for: 1, fixFor: 1, replace: 1, ref: 1, child: 1, children: 1, length: 1, // __propsKeys: 1, __proxy: 1, __proxyEle: 1, }; const classKeys = ["className", "classReplace", "classPick", "classAdd"]; const cssCache = {} as any; export const dom = (tag: ChildOne, attrs?: ChildOne, ...child: ChildOne[]): HTMLElement => { let props = {} as IProps; // 兼容第二个参数,attrs是child if (attrs && (typeof attrs === "function" || Array.isArray(attrs) || isString(attrs) || isElement(attrs))) { child = [attrs, ...child]; } else if (attrs) { props = attrs as any; } props.children = [...child]; if (props.class) { props.className = props.class; } if (typeof tag === "function") { return (tag as any)(props, ...child) as any; } if (Array.isArray(tag)) { return (dom as any)(...tag); } let ele: any; // 若 tag 是一个函数组件,attrs 就作为 props 使用,并且实力化这个组件 if (typeof tag === "string") { if (uiCaches[tag]) { ele = loadable(uiCaches[tag], [props, ...child]); return ele; } else if (tag === "style") { // style 元素只往 head 中添加一次 if (child && typeof child[0] === "string") { const cssTxt = child[0]; if (!cssCache[cssTxt]) { cssCache[cssTxt] = true; const sty = document.createElement("style"); sty.textContent = cssTxt; document.head.append(sty); } } return document.createTextNode("") as any; } else { ele = document.createElement(tag as any); } } else if (isElement(tag)) { ele = tag as any; } if (props.onsubmit) { ele.onsubmit = (e: any) => { e.preventDefault(); props.onsubmit && props.onsubmit(e as any); }; } classKeys.forEach((key) => { if (props[key]) { const fn = bindFn(ele, key, props[key]); if (fn) { subscribeElement(ele, key, fn); } } }); Object.keys(props).forEach((key) => { if (ignoreKeys[key]) { return; } const fn = bindFn(ele, key, props[key]); if (fn) { subscribeElement(ele, key, fn); } }); parseChildren(child, ele); // if (props.if !== void 0) { // parseIfChildren(child[0] as any, props.if, ele); // } else if (props.for !== void 0) { // if (typeof props.for === "number") { // props.for = Array(props.for) // .fill(0) // .map((v, i) => i); // } // parseForChildren(child[0] as any, props.for, props.fixFor!, ele); // } else if (props.replace) { // parseReplaceChildren(child[0] as any, ele); // } else { // parseChildren(child, ele); // } if (typeof props.ref === "function") { props.ref(ele); } return ele as any; }; export const domFrag = (...attrs: any[]) => { console.error("Dont Use Frag JSX"); }; (window as any).domJSX = dom;