@fluxion-ui/runtime-dom 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/runtime-dom.cjs +2 -0
- package/dist/runtime-dom.cjs.map +1 -0
- package/dist/runtime-dom.d.ts +311 -0
- package/dist/runtime-dom.d.ts.map +1 -0
- package/dist/runtime-dom.js +2 -0
- package/dist/runtime-dom.js.map +1 -0
- package/package.json +38 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026-present, Fluxion Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("@fluxion-ui/runtime-core"),t=require("@fluxion-ui/shared"),n=require("@fluxion-ui/reactivity");function r(e){return e?document.createElement(e):(t.warn("createElement: 标签名不能为空"),document.createElement("div"))}function o(e){return document.createTextNode(e??"")}function i(e){return document.createComment(e??"")}function a(e,n,r){e?n?n.insertBefore(e,r??null):t.warn("insert: 父节点不能为空"):t.warn("insert: 子节点不能为空")}function s(e){if(!e)return void t.warn("remove: 节点不能为空");const n=e.parentNode;n&&n.removeChild(e)}function c(e,n){e?e.textContent=n??"":t.warn("setElementText: 元素不能为空")}function l(e,n){e?e.nodeValue=n??"":t.warn("setText: 文本节点不能为空")}function u(e){return e?e.parentNode:(t.warn("parentNode: 节点不能为空"),null)}function p(e){return e?e.nextSibling:(t.warn("nextSibling: 节点不能为空"),null)}const f={createElement:r,createText:o,createComment:i,insert:a,remove:s,setElementText:c,setText:l,parentNode:u,nextSibling:p},d="__vei";function m(e){return e.startsWith("on")&&e.length>2&&/[A-Z]/.test(e[2])}function x(e){return e.slice(2).toLowerCase()}function g(e,n,r,o){if(!e)return void t.warn("patchEvent: 元素不能为空");const i=x(n),a=e[d]??(e[d]={}),s=a[i];if(null==r)s&&(e.removeEventListener(i,s),delete a[i]);else if(s)s.value=r;else{const n=function(e){const n=e=>{if(t.isArray(n.value))for(let r=0;r<n.value.length;r++){const o=n.value[r];t.isFunction(o)&&o(e)}else t.isFunction(n.value)&&n.value(e)};return n.value=e,n.attached=0,n}(r);n.attached=Date.now(),a[i]=n,e.addEventListener(i,n)}}const b=new Set(["value","checked","selected","muted","innerHTML","textContent","className","indeterminate","defaultChecked","defaultValue","disabled","readOnly","required","multiple","autofocus","autoplay","controls","loop","playsinline","default","open","contentEditable","spellcheck"]);function h(e){return b.has(e)}function w(e,n,r,o){if(e)switch(n){case"value":{const t=e.tagName?.toLowerCase();if("input"===t||"textarea"===t||"select"===t){const t=r??"";e.value!==t&&(e.value=t)}else e.value=r??"";break}case"innerHTML":e.innerHTML=null==r?"":r;break;case"textContent":e.textContent=null==r?"":r;break;case"className":null==r?e.className="":t.isString(r)?e.className=r:t.warn("patchDOMProp: className 应该是字符串");break;case"checked":case"selected":case"muted":case"disabled":case"readOnly":case"required":case"multiple":case"autofocus":case"autoplay":case"controls":case"loop":case"playsinline":case"default":case"open":case"indeterminate":e[n]=null!=r&&!1!==r;break;case"contentEditable":case"spellcheck":e[n]=null==r?null:r;break;default:n in e?e[n]=r:t.warn(`patchDOMProp: 未知的 DOM 属性 ${n}`)}else t.warn("patchDOMProp: 元素不能为空")}function y(e){return null==e?"":t.isString(e)?e.trim():t.isArray(e)?function(e){const t=[];for(let n=0;n<e.length;n++){const r=y(e[n]);r&&t.push(r)}return t.join(" ")}(e):t.isObject(e)?function(e){const t=[];for(const n in e)e[n]&&t.push(n);return t.join(" ")}(e):(t.warn("normalizeClass: 无效的 class 值类型"),"")}function v(e,n,r){if(!e)return void t.warn("patchClass: 元素不能为空");const o=y(n);e.className=o||""}function S(e){return e.replace(/-(\w)/g,(e,t)=>t?t.toUpperCase():"")}function N(e){return e.replace(/\B([A-Z])/g,"-$1").toLowerCase()}function O(e,n){if(t.isString(n))return n;const r=new Set(["animationIterationCount","aspectRatio","borderImageOutset","borderImageSlice","borderImageWidth","boxFlex","boxFlexGroup","boxOrdinalGroup","columnCount","columns","flex","flexGrow","flexPositive","flexShrink","flexNegative","flexOrder","gridArea","gridColumn","gridColumnEnd","gridColumnStart","gridRow","gridRowEnd","gridRowStart","lineClamp","lineHeight","opacity","order","orphans","tabSize","widows","zIndex","zoom","fillOpacity","floodOpacity","stopOpacity","strokeDasharray","strokeDashoffset","strokeMiterlimit","strokeOpacity","strokeWidth"]),o=S(e);return"number"!=typeof n||r.has(o)?String(n):`${n}px`}function C(e,t,n){if(null==n||""===n)e.removeProperty(t);else{const r=O(t,n);e.setProperty(t,r)}}function P(e,n,r){if(!e)return void t.warn("patchStyle: 元素不能为空");const o=e.style;if(!o){if(null!=n&&t.isString(n))e.setAttribute("style",n);else if(null!=n&&t.isObject(n)){const t=function(e){const t=[];for(const n in e){const r=e[n];null!=r&&""!==r&&t.push(`${N(n)}: ${O(n,r)}`)}return t.join("; ")}(n);e.setAttribute("style",t)}return}if(null==n){if(t.isString(r))o.cssText="";else if(t.isObject(r))for(const e in r)o.removeProperty(N(e));return}if(t.isString(n))return void(o.cssText=n);const i=n,a=t.isObject(r)?r:{};for(const e in a)t.hasOwn(i,e)||o.removeProperty(N(e));for(const e in i){const t=i[e];t!==a[e]&&C(o,N(e),t)}}const E=new Set(["allowfullscreen","async","autofocus","autoplay","checked","controls","default","defer","disabled","formnovalidate","hidden","inert","ismap","itemscope","loop","multiple","muted","nomodule","novalidate","open","playsinline","readonly","required","reversed","selected"]);function A(e){return E.has(e.toLowerCase())}const k=new Set(["value","checked","selected","muted","innerHTML","textContent","className","style"]);function j(e){return k.has(e)}function V(e,n,r,o){if(!e)return void t.warn("patchAttr: 元素不能为空");if(!n)return void t.warn("patchAttr: 属性名不能为空");if(j(n))return void t.warn(`patchAttr: ${n} 应该由对应的 patch 函数处理`);const i=n.toLowerCase();null==r||!1===r?e.removeAttribute(n):A(i)?e.setAttribute(n,""):e.setAttribute(n,r)}function T(e,n,r,o){e?n?m(n)?g(e,n,r):h(n)?w(e,n,r):"class"!==n?"style"!==n?V(e,n,r):P(e,r,o):v(e,r):t.warn("patchProp: 属性名不能为空"):t.warn("patchProp: 元素不能为空")}const M="http://www.w3.org/2000/svg",L="http://www.w3.org/1999/xlink",G="http://www.w3.org/XML/1998/namespace",D=new Set(["svg","animate","animateMotion","animateTransform","circle","clipPath","defs","desc","ellipse","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","filter","foreignObject","g","image","line","linearGradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialGradient","rect","set","stop","switch","symbol","text","textPath","tspan","use","view"]);function R(e){return D.has(e)}function F(e){return e||(t.warn("createSVGElement: 标签名不能为空"),e="svg"),document.createElementNS(M,e)}const I=new Set(["xlink:href","xlink:title","xlink:role","xlink:arcrole","xlink:show","xlink:actuate","xlink:type","xlink:label"]);function q(e){return I.has(e)}const z=new Set(["xml:space","xml:lang","xml:base"]);function B(e){return z.has(e)}const $={...f,patchProp:T,createElement:e=>R(e)?F(e):f.createElement(e)},H=e.createRenderer($),{render:X,createApp:_}=H;e.setAppRenderer({createApp:_}),e.setRenderRenderer({render:X}),Object.defineProperty(exports,"cloneVNode",{enumerable:!0,get:function(){return e.cloneVNode}}),Object.defineProperty(exports,"createCommentVNode",{enumerable:!0,get:function(){return e.createCommentVNode}}),Object.defineProperty(exports,"createEmptyVNode",{enumerable:!0,get:function(){return e.createEmptyVNode}}),Object.defineProperty(exports,"createTextVNode",{enumerable:!0,get:function(){return e.createTextVNode}}),Object.defineProperty(exports,"createVNode",{enumerable:!0,get:function(){return e.createVNode}}),Object.defineProperty(exports,"h",{enumerable:!0,get:function(){return e.h}}),Object.defineProperty(exports,"isComponentVNode",{enumerable:!0,get:function(){return e.isComponentVNode}}),Object.defineProperty(exports,"isElementVNode",{enumerable:!0,get:function(){return e.isElementVNode}}),Object.defineProperty(exports,"isVNode",{enumerable:!0,get:function(){return e.isVNode}}),Object.defineProperty(exports,"nextTick",{enumerable:!0,get:function(){return e.nextTick}}),Object.defineProperty(exports,"queueJob",{enumerable:!0,get:function(){return e.queueJob}}),Object.defineProperty(exports,"asyncSignal",{enumerable:!0,get:function(){return n.asyncSignal}}),Object.defineProperty(exports,"computed",{enumerable:!0,get:function(){return n.computed}}),Object.defineProperty(exports,"effect",{enumerable:!0,get:function(){return n.effect}}),Object.defineProperty(exports,"reactive",{enumerable:!0,get:function(){return n.reactive}}),Object.defineProperty(exports,"signal",{enumerable:!0,get:function(){return n.signal}}),Object.defineProperty(exports,"watch",{enumerable:!0,get:function(){return n.watch}}),Object.defineProperty(exports,"watchEffect",{enumerable:!0,get:function(){return n.watchEffect}}),exports.SVG_NAMESPACE=M,exports.XLINK_NAMESPACE=L,exports.XML_NAMESPACE=G,exports.camelize=S,exports.createApp=_,exports.createComment=i,exports.createElement=r,exports.createSVGElement=F,exports.createText=o,exports.getSVGNamespace=function(e){return e.namespaceURI},exports.getTagName=function(e){return e?.tagName?.toLowerCase()??""},exports.hyphenate=N,exports.insert=a,exports.isBooleanAttr=A,exports.isDOMProp=h,exports.isEventKey=m,exports.isInSVG=function(e){let t=e;for(;t;){if("svg"===t.tagName.toLowerCase())return!0;t=t.parentElement}return!1},exports.isSVGTag=R,exports.isSpecialAttr=j,exports.isXMLAttr=B,exports.isXlinkAttr=q,exports.nextSibling=p,exports.nodeOps=f,exports.normalizeClass=y,exports.normalizeEventName=x,exports.normalizeStyle=function(e){return null==e?{}:t.isString(e)?function(e){const t={},n=e.split(";");for(let e=0;e<n.length;e++){const r=n[e].trim();if(r){const e=r.indexOf(":");if(e>0){const n=r.slice(0,e).trim(),o=r.slice(e+1).trim();n&&o&&(t[S(n)]=o)}}}return t}(e):t.isObject(e)?e:{}},exports.parentNode=u,exports.patchAttr=V,exports.patchClass=v,exports.patchDOMProp=w,exports.patchEvent=g,exports.patchProp=T,exports.patchStyle=P,exports.remove=s,exports.render=X,exports.setElementText=c,exports.setSVGAttr=function(e,n,r){if(e)if(null!=r&&!1!==r){if(q(n)){const t=n.slice(6);return void e.setAttributeNS(L,t,r)}if(B(n)){const t=n.slice(4);return void e.setAttributeNS(G,t,r)}e.setAttribute(n,r)}else e.removeAttribute(n);else t.warn("setSVGAttr: 元素不能为空")},exports.setText=l;
|
|
2
|
+
//# sourceMappingURL=runtime-dom.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-dom.cjs","sources":["../src/nodeOps.ts","../src/patchProp/patchEvent.ts","../src/patchProp/patchDOMProp.ts","../src/patchProp/patchClass.ts","../src/patchProp/patchStyle.ts","../src/patchProp/patchAttr.ts","../src/patchProp/index.ts","../src/modules/svg.ts","../src/renderer.ts"],"sourcesContent":["/**\n * DOM 节点操作\n * 提供 RendererOptions 所需的基础 DOM 操作方法\n */\n\nimport { warn } from '@fluxion-ui/shared'\n\n/**\n * 创建 HTML 元素\n * @param tag 标签名\n */\nexport function createElement(tag: string): Element {\n if (!tag) {\n warn('createElement: 标签名不能为空')\n return document.createElement('div')\n }\n return document.createElement(tag)\n}\n\n/**\n * 创建文本节点\n * @param text 文本内容\n */\nexport function createText(text: string): Text {\n return document.createTextNode(text ?? '')\n}\n\n/**\n * 创建注释节点\n * @param text 注释内容\n */\nexport function createComment(text: string): Comment {\n return document.createComment(text ?? '')\n}\n\n/**\n * 插入节点到父节点\n * @param child 要插入的子节点\n * @param parent 父节点\n * @param anchor 参考节点(插入到该节点之前)\n */\nexport function insert(\n child: Node,\n parent: Node,\n anchor?: Node | null\n): void {\n if (!child) {\n warn('insert: 子节点不能为空')\n return\n }\n if (!parent) {\n warn('insert: 父节点不能为空')\n return\n }\n // 使用 insertBefore 实现,anchor 为 null 时插入到末尾\n parent.insertBefore(child, anchor ?? null)\n}\n\n/**\n * 移除节点\n * @param child 要移除的节点\n */\nexport function remove(child: Node): void {\n if (!child) {\n warn('remove: 节点不能为空')\n return\n }\n const parent = child.parentNode\n if (parent) {\n parent.removeChild(child)\n }\n}\n\n/**\n * 设置元素的文本内容\n * @param el 元素\n * @param text 文本内容\n */\nexport function setElementText(el: Element, text: string): void {\n if (!el) {\n warn('setElementText: 元素不能为空')\n return\n }\n el.textContent = text ?? ''\n}\n\n/**\n * 设置文本节点的内容\n * @param node 文本节点\n * @param text 文本内容\n */\nexport function setText(node: Text, text: string): void {\n if (!node) {\n warn('setText: 文本节点不能为空')\n return\n }\n node.nodeValue = text ?? ''\n}\n\n/**\n * 获取父节点\n * @param node 节点\n */\nexport function parentNode(node: Node): Node | null {\n if (!node) {\n warn('parentNode: 节点不能为空')\n return null\n }\n return node.parentNode\n}\n\n/**\n * 获取下一个兄弟节点\n * @param node 节点\n */\nexport function nextSibling(node: Node): Node | null {\n if (!node) {\n warn('nextSibling: 节点不能为空')\n return null\n }\n return node.nextSibling\n}\n\n/**\n * 获取元素的标签名\n * @param el 元素\n */\nexport function getTagName(el: Element): string {\n return el?.tagName?.toLowerCase() ?? ''\n}\n\n/**\n * 导出所有 nodeOps 方法\n */\nexport const nodeOps = {\n createElement,\n createText,\n createComment,\n insert,\n remove,\n setElementText,\n setText,\n parentNode,\n nextSibling\n}","/**\n * 事件属性处理\n * 使用 invoker 模式避免频繁 addEventListener/removeEventListener\n */\n\nimport { warn, isFunction, isArray } from '@fluxion-ui/shared'\n\n/**\n * Invoker 缓存键\n * 用于在元素上存储事件 invoker\n */\nconst VEI_KEY = '__vei'\n\n/**\n * 事件处理器类型\n */\ntype EventHandler = (event: Event) => void\n\n/**\n * 事件处理器数组类型\n */\ntype EventHandlerArray = EventHandler[]\n\n/**\n * Invoker 对象\n * 包装事件处理器,支持动态更换内部处理函数\n */\ninterface Invoker extends EventHandler {\n value: EventHandler | EventHandlerArray\n attached: number // 绑定时间戳,用于去重\n}\n\n/**\n * Invoker 处理函数\n */\ntype InvokerHandlers = Record<string, Invoker>\n\n/**\n * 判断是否为事件属性\n * 事件属性格式:onXxx(第三个字符必须是大写字母)\n * @param key 属性名\n */\nexport function isEventKey(key: string): boolean {\n return key.startsWith('on') && key.length > 2 && /[A-Z]/.test(key[2])\n}\n\n/**\n * 规范化事件名\n * onClick -> click\n * onMyEvent -> myevent\n * @param key 属性名\n */\nexport function normalizeEventName(key: string): string {\n // 移除 'on' 前缀并转为小写\n return key.slice(2).toLowerCase()\n}\n\n/**\n * 创建事件包装函数\n * @param value 事件处理器\n */\nfunction createInvokerWrapper(value: EventHandler | EventHandlerArray): Invoker {\n const invoker: Invoker = (event: Event) => {\n if (isArray(invoker.value)) {\n // 处理函数数组\n for (let i = 0; i < invoker.value.length; i++) {\n const handler = invoker.value[i]\n if (isFunction(handler)) {\n handler(event)\n }\n }\n } else if (isFunction(invoker.value)) {\n // 单个处理函数\n invoker.value(event)\n }\n }\n invoker.value = value\n invoker.attached = 0\n return invoker\n}\n\n/**\n * 处理事件属性\n * @param el 元素\n * @param key 属性名(如 onClick)\n * @param value 新的事件处理器\n * @param prevValue 旧的事件处理器\n */\nexport function patchEvent(\n el: Element & { [VEI_KEY]?: InvokerHandlers },\n key: string,\n value: EventHandler | EventHandlerArray | null,\n prevValue: EventHandler | EventHandlerArray | null\n): void {\n if (!el) {\n warn('patchEvent: 元素不能为空')\n return\n }\n\n // 获取事件名\n const eventName = normalizeEventName(key)\n\n // 获取或创建 invokers 缓存\n const invokers = (el[VEI_KEY] ??= {}) as InvokerHandlers\n\n // 获取现有的 invoker\n const existingInvoker = invokers[eventName]\n\n if (value == null) {\n // 移除事件\n if (existingInvoker) {\n // 使用 invoker 本身作为移除的函数(invoker 是 wrapper)\n el.removeEventListener(eventName, existingInvoker)\n delete invokers[eventName]\n }\n } else {\n if (existingInvoker) {\n // 更新现有 invoker 的值\n // 不需要重新 addEventListener,直接替换 value\n existingInvoker.value = value\n } else {\n // 创建新的 invoker(invoker 本身就是 wrapper 函数)\n const invoker = createInvokerWrapper(value)\n invoker.attached = Date.now()\n invokers[eventName] = invoker\n el.addEventListener(eventName, invoker)\n }\n }\n}","/**\n * DOM 属性处理\n * 处理需要直接设置到 DOM 对象的属性(不能使用 setAttribute)\n */\n\nimport { warn, isString } from '@fluxion-ui/shared'\n\n/**\n * 需要直接设置的 DOM 属性列表\n * 这些属性不能通过 setAttribute 设置,必须直接赋值\n */\nconst DOM_PROP_KEYS = new Set([\n 'value',\n 'checked',\n 'selected',\n 'muted',\n 'innerHTML',\n 'textContent',\n 'className',\n // 表单相关\n 'indeterminate',\n 'defaultChecked',\n 'defaultValue',\n // 其他布尔属性\n 'disabled',\n 'readOnly',\n 'required',\n 'multiple',\n 'autofocus',\n 'autoplay',\n 'controls',\n 'loop',\n 'playsinline',\n 'default',\n 'open',\n 'contentEditable',\n 'spellcheck'\n])\n\n/**\n * 判断是否为 DOM 属性\n * @param key 属性名\n */\nexport function isDOMProp(key: string): boolean {\n return DOM_PROP_KEYS.has(key)\n}\n\n/**\n * 处理 DOM 属性\n * @param el 元素\n * @param key 属性名\n * @param value 新值\n * @param prevValue 旧值\n */\nexport function patchDOMProp(\n el: Element & Record<string, any>,\n key: string,\n value: any,\n prevValue: any\n): void {\n if (!el) {\n warn('patchDOMProp: 元素不能为空')\n return\n }\n\n switch (key) {\n case 'value': {\n // value 特殊处理\n const tagName = el.tagName?.toLowerCase()\n if (tagName === 'input' || tagName === 'textarea' || tagName === 'select') {\n // 表单元素:设置 value\n const newValue = value ?? ''\n if (el.value !== newValue) {\n el.value = newValue\n }\n } else {\n // 其他元素:直接设置\n el.value = value ?? ''\n }\n break\n }\n\n case 'innerHTML': {\n // innerHTML 特殊处理\n if (value == null) {\n el.innerHTML = ''\n } else {\n el.innerHTML = value\n }\n break\n }\n\n case 'textContent': {\n // textContent 特殊处理\n if (value == null) {\n el.textContent = ''\n } else {\n el.textContent = value\n }\n break\n }\n\n case 'className': {\n // className 特殊处理(兼容 SVG)\n if (value == null) {\n el.className = ''\n } else if (isString(value)) {\n el.className = value\n } else {\n warn('patchDOMProp: className 应该是字符串')\n }\n break\n }\n\n case 'checked':\n case 'selected':\n case 'muted':\n case 'disabled':\n case 'readOnly':\n case 'required':\n case 'multiple':\n case 'autofocus':\n case 'autoplay':\n case 'controls':\n case 'loop':\n case 'playsinline':\n case 'default':\n case 'open':\n case 'indeterminate': {\n // 布尔属性\n if (value == null || value === false) {\n el[key] = false\n } else {\n el[key] = true\n }\n break\n }\n\n case 'contentEditable':\n case 'spellcheck': {\n // 字符串/布尔混合属性\n if (value == null) {\n el[key] = null\n } else {\n el[key] = value\n }\n break\n }\n\n default: {\n // 其他 DOM 属性直接设置\n if (key in el) {\n el[key] = value\n } else {\n warn(`patchDOMProp: 未知的 DOM 属性 ${key}`)\n }\n }\n }\n}","/**\n * class 属性处理\n * 支持字符串、数组、对象三种形式\n */\n\nimport { warn, isString, isArray, isObject } from '@fluxion-ui/shared'\n\n/**\n * class 值类型\n */\ntype ClassValue = string | ClassArray | ClassObject | null | undefined\n\ntype ClassArray = ClassValue[]\n\ntype ClassObject = Record<string, boolean | undefined | null>\n\n/**\n * 将 class 值规范化为字符串\n * @param value class 值\n */\nexport function normalizeClass(value: ClassValue): string {\n if (value == null) {\n return ''\n }\n\n if (isString(value)) {\n return value.trim()\n }\n\n if (isArray(value)) {\n return normalizeArrayClass(value)\n }\n\n if (isObject(value)) {\n return normalizeObjectClass(value as ClassObject)\n }\n\n warn('normalizeClass: 无效的 class 值类型')\n return ''\n}\n\n/**\n * 规范化数组形式的 class\n * @param values class 数组\n */\nfunction normalizeArrayClass(values: ClassArray): string {\n const classes: string[] = []\n\n for (let i = 0; i < values.length; i++) {\n const value = normalizeClass(values[i])\n if (value) {\n classes.push(value)\n }\n }\n\n return classes.join(' ')\n}\n\n/**\n * 规范化对象形式的 class\n * @param obj class 对象\n */\nfunction normalizeObjectClass(obj: ClassObject): string {\n const classes: string[] = []\n\n for (const key in obj) {\n if (obj[key]) {\n classes.push(key)\n }\n }\n\n return classes.join(' ')\n}\n\n/**\n * 处理 class 属性\n * @param el 元素\n * @param value 新的 class 值\n * @param prevValue 旧的 class 值(暂未使用,预留用于增量更新)\n */\nexport function patchClass(\n el: Element,\n value: ClassValue,\n prevValue: ClassValue\n): void {\n if (!el) {\n warn('patchClass: 元素不能为空')\n return\n }\n\n // 规范化 class 值\n const normalizedClass = normalizeClass(value)\n\n // 设置 class\n if (normalizedClass) {\n el.className = normalizedClass\n } else {\n // 空值时清空 class\n el.className = ''\n }\n}","/**\n * style 属性处理\n * 支持字符串和对象两种形式\n */\n\nimport { warn, isString, isObject, hasOwn } from '@fluxion-ui/shared'\n\n/**\n * CSS 属性名映射(用于处理简写属性)\n */\nconst cssTextCache = new WeakMap<object, string>()\n\n/**\n * style 值类型\n */\ntype StyleValue = string | StyleObject | null | undefined\n\ntype StyleObject = Record<string, string | number | null | undefined>\n\n/**\n * 重要样式属性,需要添加 !important 后缀\n */\nconst importantStyles = new Set([\n 'display'\n])\n\n/**\n * CSS 属性名转换\n * camelCase -> kebab-case\n * @param name 属性名\n */\nexport function camelize(name: string): string {\n return name.replace(/-(\\w)/g, (_, c) => (c ? c.toUpperCase() : ''))\n}\n\n/**\n * CSS 属性名转换\n * camelCase -> kebab-case\n * @param name 属性名\n */\nexport function hyphenate(name: string): string {\n return name.replace(/\\B([A-Z])/g, '-$1').toLowerCase()\n}\n\n/**\n * 规范化样式值\n * 添加必要的单位(如 px)\n * @param name 属性名\n * @param value 属性值\n */\nfunction normalizeStyleValue(\n name: string,\n value: string | number\n): string {\n // 如果已经是字符串,直接返回\n if (isString(value)) {\n return value\n }\n\n // 数值类型需要添加单位\n // 无单位的 CSS 属性列表\n const unitlessProperties = new Set([\n 'animationIterationCount',\n 'aspectRatio',\n 'borderImageOutset',\n 'borderImageSlice',\n 'borderImageWidth',\n 'boxFlex',\n 'boxFlexGroup',\n 'boxOrdinalGroup',\n 'columnCount',\n 'columns',\n 'flex',\n 'flexGrow',\n 'flexPositive',\n 'flexShrink',\n 'flexNegative',\n 'flexOrder',\n 'gridArea',\n 'gridColumn',\n 'gridColumnEnd',\n 'gridColumnStart',\n 'gridRow',\n 'gridRowEnd',\n 'gridRowStart',\n 'lineClamp',\n 'lineHeight',\n 'opacity',\n 'order',\n 'orphans',\n 'tabSize',\n 'widows',\n 'zIndex',\n 'zoom',\n 'fillOpacity',\n 'floodOpacity',\n 'stopOpacity',\n 'strokeDasharray',\n 'strokeDashoffset',\n 'strokeMiterlimit',\n 'strokeOpacity',\n 'strokeWidth'\n ])\n\n // 检查是否需要单位\n const key = camelize(name)\n if (typeof value === 'number' && !unitlessProperties.has(key)) {\n return `${value}px`\n }\n\n return String(value)\n}\n\n/**\n * 设置单个样式属性\n * @param style style 对象\n * @param name 属性名\n * @param value 属性值\n */\nfunction setStyleProperty(\n style: CSSStyleDeclaration,\n name: string,\n value: string | number | null | undefined\n): void {\n if (value == null || value === '') {\n // 移除样式\n style.removeProperty(name)\n } else {\n // 设置样式\n const normalized = normalizeStyleValue(name, value)\n style.setProperty(name, normalized)\n }\n}\n\n/**\n * 规范化 style 值为对象形式\n * @param value style 值\n */\nexport function normalizeStyle(value: StyleValue): StyleObject {\n if (value == null) {\n return {}\n }\n\n if (isString(value)) {\n return parseStyleString(value)\n }\n\n if (isObject(value)) {\n return value as StyleObject\n }\n\n return {}\n}\n\n/**\n * 解析 style 字符串为对象\n * @param styleString style 字符串\n */\nfunction parseStyleString(styleString: string): StyleObject {\n const result: StyleObject = {}\n const styles = styleString.split(';')\n\n for (let i = 0; i < styles.length; i++) {\n const style = styles[i].trim()\n if (style) {\n const colonIndex = style.indexOf(':')\n if (colonIndex > 0) {\n const name = style.slice(0, colonIndex).trim()\n const value = style.slice(colonIndex + 1).trim()\n if (name && value) {\n result[camelize(name)] = value\n }\n }\n }\n }\n\n return result\n}\n\n/**\n * 处理 style 属性\n * @param el 元素\n * @param value 新的 style 值\n * @param prevValue 旧的 style 值\n */\nexport function patchStyle(\n el: Element,\n value: StyleValue,\n prevValue: StyleValue\n): void {\n if (!el) {\n warn('patchStyle: 元素不能为空')\n return\n }\n\n const style = (el as HTMLElement).style\n\n if (!style) {\n // 非 HTMLElement,尝试设置 style 属性\n if (value != null && isString(value)) {\n el.setAttribute('style', value)\n } else if (value != null && isObject(value)) {\n const styleStr = objectToStyleString(value as StyleObject)\n el.setAttribute('style', styleStr)\n }\n return\n }\n\n // 处理新值\n if (value == null) {\n // 清空所有样式\n if (isString(prevValue)) {\n style.cssText = ''\n } else if (isObject(prevValue)) {\n // 移除旧的样式属性\n for (const key in prevValue as StyleObject) {\n style.removeProperty(hyphenate(key))\n }\n }\n return\n }\n\n if (isString(value)) {\n // 字符串形式:直接设置 cssText\n style.cssText = value\n return\n }\n\n // 对象形式:增量更新\n const newStyle = value as StyleObject\n const oldStyle = isObject(prevValue) ? (prevValue as StyleObject) : {}\n\n // 移除旧的样式\n for (const key in oldStyle) {\n if (!hasOwn(newStyle, key)) {\n style.removeProperty(hyphenate(key))\n }\n }\n\n // 设置新的样式\n for (const key in newStyle) {\n const newValue = newStyle[key]\n const oldValue = oldStyle[key]\n if (newValue !== oldValue) {\n setStyleProperty(style, hyphenate(key), newValue)\n }\n }\n}\n\n/**\n * 将样式对象转换为字符串\n * @param style 样式对象\n */\nfunction objectToStyleString(style: StyleObject): string {\n const parts: string[] = []\n for (const key in style) {\n const value = style[key]\n if (value != null && value !== '') {\n parts.push(`${hyphenate(key)}: ${normalizeStyleValue(key, value)}`)\n }\n }\n return parts.join('; ')\n}","/**\n * HTML 属性处理\n * 使用 setAttribute/removeAttribute 处理 HTML 属性\n */\n\nimport { warn, isString, isBoolean } from '@fluxion-ui/shared'\n\n/**\n * 布尔属性列表\n * 这些属性只要存在即为 true,值会被忽略\n */\nconst BOOLEAN_ATTRIBUTES = new Set([\n 'allowfullscreen',\n 'async',\n 'autofocus',\n 'autoplay',\n 'checked',\n 'controls',\n 'default',\n 'defer',\n 'disabled',\n 'formnovalidate',\n 'hidden',\n 'inert',\n 'ismap',\n 'itemscope',\n 'loop',\n 'multiple',\n 'muted',\n 'nomodule',\n 'novalidate',\n 'open',\n 'playsinline',\n 'readonly',\n 'required',\n 'reversed',\n 'selected'\n])\n\n/**\n * 判断是否为布尔属性\n * @param name 属性名\n */\nexport function isBooleanAttr(name: string): boolean {\n return BOOLEAN_ATTRIBUTES.has(name.toLowerCase())\n}\n\n/**\n * 需要特殊处理的属性\n * 这些属性使用 setAttribute 会有问题\n */\nconst SPECIAL_ATTRIBUTES = new Set([\n 'value',\n 'checked',\n 'selected',\n 'muted',\n 'innerHTML',\n 'textContent',\n 'className',\n 'style'\n])\n\n/**\n * 判断是否需要特殊处理\n * @param name 属性名\n */\nexport function isSpecialAttr(name: string): boolean {\n return SPECIAL_ATTRIBUTES.has(name)\n}\n\n/**\n * 处理 HTML 属性\n * @param el 元素\n * @param key 属性名\n * @param value 新值\n * @param prevValue 旧值(暂未使用)\n */\nexport function patchAttr(\n el: Element,\n key: string,\n value: any,\n prevValue: any\n): void {\n if (!el) {\n warn('patchAttr: 元素不能为空')\n return\n }\n\n if (!key) {\n warn('patchAttr: 属性名不能为空')\n return\n }\n\n // 检查是否为特殊属性\n if (isSpecialAttr(key)) {\n warn(`patchAttr: ${key} 应该由对应的 patch 函数处理`)\n return\n }\n\n // 转为小写进行比较\n const lowerKey = key.toLowerCase()\n\n if (value == null || value === false) {\n // 移除属性\n el.removeAttribute(key)\n } else if (isBooleanAttr(lowerKey)) {\n // 布尔属性:值存在即为 true\n el.setAttribute(key, '')\n } else {\n // 普通属性\n el.setAttribute(key, value)\n }\n}\n\n/**\n * 批量设置属性\n * @param el 元素\n * @param attrs 属性对象\n */\nexport function setAttrs(el: Element, attrs: Record<string, any>): void {\n if (!el || !attrs) return\n\n for (const key in attrs) {\n const value = attrs[key]\n patchAttr(el, key, value, null)\n }\n}\n\n/**\n * 移除所有属性\n * @param el 元素\n * @param attrs 要移除的属性名数组\n */\nexport function removeAttrs(el: Element, attrs: string[]): void {\n if (!el || !attrs) return\n\n for (let i = 0; i < attrs.length; i++) {\n el.removeAttribute(attrs[i])\n }\n}","/**\n * patchProp 分发入口\n * 根据属性类型分发到对应的处理函数\n */\n\nimport { patchEvent, isEventKey } from './patchEvent'\nimport { patchDOMProp, isDOMProp } from './patchDOMProp'\nimport { patchClass } from './patchClass'\nimport { patchStyle } from './patchStyle'\nimport { patchAttr } from './patchAttr'\nimport { warn } from '@fluxion-ui/shared'\n\n/**\n * 处理元素属性\n * 按优先级分发到对应的处理函数:\n * 1. 事件 (onClick 等) → patchEvent\n * 2. DOM 属性 (value, checked 等) → patchDOMProp\n * 3. class → patchClass\n * 4. style → patchStyle\n * 5. HTML 属性 → patchAttr\n *\n * @param el 元素\n * @param key 属性名\n * @param value 新值\n * @param prevValue 旧值\n */\nexport function patchProp(\n el: Element,\n key: string,\n value: any,\n prevValue: any\n): void {\n if (!el) {\n warn('patchProp: 元素不能为空')\n return\n }\n\n if (!key) {\n warn('patchProp: 属性名不能为空')\n return\n }\n\n // 1. 事件处理\n if (isEventKey(key)) {\n patchEvent(el as any, key, value, prevValue)\n return\n }\n\n // 2. DOM 属性处理\n if (isDOMProp(key)) {\n patchDOMProp(el as any, key, value, prevValue)\n return\n }\n\n // 3. class 处理\n if (key === 'class') {\n patchClass(el, value, prevValue)\n return\n }\n\n // 4. style 处理\n if (key === 'style') {\n patchStyle(el, value, prevValue)\n return\n }\n\n // 5. HTML 属性处理\n patchAttr(el, key, value, prevValue)\n}\n\n// 导出各个子模块\nexport { patchEvent, isEventKey, normalizeEventName } from './patchEvent'\nexport { patchDOMProp, isDOMProp } from './patchDOMProp'\nexport { patchClass, normalizeClass } from './patchClass'\nexport { patchStyle, normalizeStyle, hyphenate, camelize } from './patchStyle'\nexport { patchAttr, isBooleanAttr, isSpecialAttr } from './patchAttr'","/**\n * SVG 支持\n * 提供 SVG 元素的创建和属性处理\n */\n\nimport { warn } from '@fluxion-ui/shared'\n\n/**\n * SVG 命名空间\n */\nexport const SVG_NAMESPACE = 'http://www.w3.org/2000/svg'\n\n/**\n * XLINK 命名空间\n */\nexport const XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink'\n\n/**\n * XML 命名空间\n */\nexport const XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace'\n\n/**\n * SVG 标签列表\n */\nconst SVG_TAGS = new Set([\n 'svg',\n 'animate',\n 'animateMotion',\n 'animateTransform',\n 'circle',\n 'clipPath',\n 'defs',\n 'desc',\n 'ellipse',\n 'feBlend',\n 'feColorMatrix',\n 'feComponentTransfer',\n 'feComposite',\n 'feConvolveMatrix',\n 'feDiffuseLighting',\n 'feDisplacementMap',\n 'feDistantLight',\n 'feDropShadow',\n 'feFlood',\n 'feFuncA',\n 'feFuncB',\n 'feFuncG',\n 'feFuncR',\n 'feGaussianBlur',\n 'feImage',\n 'feMerge',\n 'feMergeNode',\n 'feMorphology',\n 'feOffset',\n 'fePointLight',\n 'feSpecularLighting',\n 'feSpotLight',\n 'feTile',\n 'feTurbulence',\n 'filter',\n 'foreignObject',\n 'g',\n 'image',\n 'line',\n 'linearGradient',\n 'marker',\n 'mask',\n 'metadata',\n 'mpath',\n 'path',\n 'pattern',\n 'polygon',\n 'polyline',\n 'radialGradient',\n 'rect',\n 'set',\n 'stop',\n 'switch',\n 'symbol',\n 'text',\n 'textPath',\n 'tspan',\n 'use',\n 'view'\n])\n\n/**\n * 判断是否为 SVG 标签\n * @param tag 标签名\n */\nexport function isSVGTag(tag: string): boolean {\n return SVG_TAGS.has(tag)\n}\n\n/**\n * 创建 SVG 元素\n * @param tag 标签名\n */\nexport function createSVGElement(tag: string): SVGElement {\n if (!tag) {\n warn('createSVGElement: 标签名不能为空')\n tag = 'svg'\n }\n return document.createElementNS(SVG_NAMESPACE, tag) as SVGElement\n}\n\n/**\n * 需要使用 XLINK 命名空间的属性\n */\nconst XLINK_ATTRIBUTES = new Set([\n 'xlink:href',\n 'xlink:title',\n 'xlink:role',\n 'xlink:arcrole',\n 'xlink:show',\n 'xlink:actuate',\n 'xlink:type',\n 'xlink:label'\n])\n\n/**\n * 判断是否为 XLINK 属性\n * @param attr 属性名\n */\nexport function isXlinkAttr(attr: string): boolean {\n return XLINK_ATTRIBUTES.has(attr)\n}\n\n/**\n * 需要使用 XML 命名空间的属性\n */\nconst XML_ATTRIBUTES = new Set([\n 'xml:space',\n 'xml:lang',\n 'xml:base'\n])\n\n/**\n * 判断是否为 XML 属性\n * @param attr 属性名\n */\nexport function isXMLAttr(attr: string): boolean {\n return XML_ATTRIBUTES.has(attr)\n}\n\n/**\n * 设置 SVG 属性\n * @param el SVG 元素\n * @param key 属性名\n * @param value 属性值\n */\nexport function setSVGAttr(\n el: SVGElement,\n key: string,\n value: any\n): void {\n if (!el) {\n warn('setSVGAttr: 元素不能为空')\n return\n }\n\n if (value == null || value === false) {\n // 移除属性\n el.removeAttribute(key)\n return\n }\n\n // XLINK 属性\n if (isXlinkAttr(key)) {\n // 提取本地名称:xlink:href -> href\n const localName = key.slice(6) // 'xlink:'.length = 6\n el.setAttributeNS(XLINK_NAMESPACE, localName, value)\n return\n }\n\n // XML 属性\n if (isXMLAttr(key)) {\n // 提取本地名称:xml:space -> space\n const localName = key.slice(4) // 'xml:'.length = 4\n el.setAttributeNS(XML_NAMESPACE, localName, value)\n return\n }\n\n // 普通属性(但在 SVG 命名空间中)\n el.setAttribute(key, value)\n}\n\n/**\n * 获取 SVG 元素的命名空间\n * @param el 元素\n */\nexport function getSVGNamespace(el: Element): string | null {\n return el.namespaceURI\n}\n\n/**\n * 判断元素是否在 SVG 上下文中\n * @param el 元素\n */\nexport function isInSVG(el: Element): boolean {\n let current: Element | null = el\n while (current) {\n if (current.tagName.toLowerCase() === 'svg') {\n return true\n }\n current = current.parentElement\n }\n return false\n}","/**\n * DOM 渲染器\n * 组合 nodeOps 和 patchProp,创建平台渲染器\n */\n\nimport {\n createRenderer,\n setAppRenderer,\n setRenderRenderer\n} from '@fluxion-ui/runtime-core'\nimport { nodeOps } from './nodeOps'\nimport { patchProp } from './patchProp'\nimport { isSVGTag, createSVGElement } from './modules/svg'\nimport type { RendererOptions } from '@fluxion-ui/runtime-core'\n\n/**\n * 扩展的渲染器选项\n * 支持 SVG 元素创建\n */\nconst rendererOptions: RendererOptions = {\n ...nodeOps,\n patchProp,\n\n /**\n * 重写 createElement 以支持 SVG\n * @param tag 标签名\n */\n createElement(tag: string): Element {\n // 检查是否为 SVG 标签\n if (isSVGTag(tag)) {\n return createSVGElement(tag)\n }\n return nodeOps.createElement(tag)\n }\n}\n\n// 创建渲染器\nconst renderer = createRenderer(rendererOptions)\n\n// 获取 render 和 createApp\nconst { render, createApp } = renderer\n\n// 注入渲染器到 runtime-core\nsetAppRenderer({ createApp })\nsetRenderRenderer({ render })\n\n// 导出渲染器 API\nexport { render, createApp }"],"names":["createElement","tag","document","warn","createText","text","createTextNode","createComment","insert","child","parent","anchor","insertBefore","remove","parentNode","removeChild","setElementText","el","textContent","setText","node","nodeValue","nextSibling","nodeOps","VEI_KEY","isEventKey","key","startsWith","length","test","normalizeEventName","slice","toLowerCase","patchEvent","value","prevValue","eventName","invokers","existingInvoker","removeEventListener","invoker","event","isArray","i","handler","isFunction","attached","createInvokerWrapper","Date","now","addEventListener","DOM_PROP_KEYS","Set","isDOMProp","has","patchDOMProp","tagName","newValue","innerHTML","className","isString","normalizeClass","trim","values","classes","push","join","normalizeArrayClass","isObject","obj","normalizeObjectClass","patchClass","normalizedClass","camelize","name","replace","_","c","toUpperCase","hyphenate","normalizeStyleValue","unitlessProperties","String","setStyleProperty","style","removeProperty","normalized","setProperty","patchStyle","setAttribute","styleStr","parts","objectToStyleString","cssText","newStyle","oldStyle","hasOwn","BOOLEAN_ATTRIBUTES","isBooleanAttr","SPECIAL_ATTRIBUTES","isSpecialAttr","patchAttr","lowerKey","removeAttribute","patchProp","SVG_NAMESPACE","XLINK_NAMESPACE","XML_NAMESPACE","SVG_TAGS","isSVGTag","createSVGElement","createElementNS","XLINK_ATTRIBUTES","isXlinkAttr","attr","XML_ATTRIBUTES","isXMLAttr","rendererOptions","renderer","createRenderer","render","createApp","setAppRenderer","setRenderRenderer","namespaceURI","current","parentElement","styleString","result","styles","split","colonIndex","indexOf","parseStyleString","localName","setAttributeNS"],"mappings":"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"}
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import * as _fluxion_ui_runtime_core from '@fluxion-ui/runtime-core';
|
|
2
|
+
export { Component, ComponentInstance, ComponentProps, VNode, VNodeChildren, VNodeProps, VNodeType, cloneVNode, createCommentVNode, createEmptyVNode, createTextVNode, createVNode, h, isComponentVNode, isElementVNode, isVNode, nextTick, queueJob } from '@fluxion-ui/runtime-core';
|
|
3
|
+
export { Computed, Effect, Signal, asyncSignal, computed, effect, reactive, signal, watch, watchEffect } from '@fluxion-ui/reactivity';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* DOM 渲染器
|
|
7
|
+
* 组合 nodeOps 和 patchProp,创建平台渲染器
|
|
8
|
+
*/
|
|
9
|
+
declare const render: (vnode: _fluxion_ui_runtime_core.VNode | null, container: Element) => void;
|
|
10
|
+
declare const createApp: (rootComponent: _fluxion_ui_runtime_core.Component) => _fluxion_ui_runtime_core.App;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* DOM 节点操作
|
|
14
|
+
* 提供 RendererOptions 所需的基础 DOM 操作方法
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* 创建 HTML 元素
|
|
18
|
+
* @param tag 标签名
|
|
19
|
+
*/
|
|
20
|
+
declare function createElement(tag: string): Element;
|
|
21
|
+
/**
|
|
22
|
+
* 创建文本节点
|
|
23
|
+
* @param text 文本内容
|
|
24
|
+
*/
|
|
25
|
+
declare function createText(text: string): Text;
|
|
26
|
+
/**
|
|
27
|
+
* 创建注释节点
|
|
28
|
+
* @param text 注释内容
|
|
29
|
+
*/
|
|
30
|
+
declare function createComment(text: string): Comment;
|
|
31
|
+
/**
|
|
32
|
+
* 插入节点到父节点
|
|
33
|
+
* @param child 要插入的子节点
|
|
34
|
+
* @param parent 父节点
|
|
35
|
+
* @param anchor 参考节点(插入到该节点之前)
|
|
36
|
+
*/
|
|
37
|
+
declare function insert(child: Node, parent: Node, anchor?: Node | null): void;
|
|
38
|
+
/**
|
|
39
|
+
* 移除节点
|
|
40
|
+
* @param child 要移除的节点
|
|
41
|
+
*/
|
|
42
|
+
declare function remove(child: Node): void;
|
|
43
|
+
/**
|
|
44
|
+
* 设置元素的文本内容
|
|
45
|
+
* @param el 元素
|
|
46
|
+
* @param text 文本内容
|
|
47
|
+
*/
|
|
48
|
+
declare function setElementText(el: Element, text: string): void;
|
|
49
|
+
/**
|
|
50
|
+
* 设置文本节点的内容
|
|
51
|
+
* @param node 文本节点
|
|
52
|
+
* @param text 文本内容
|
|
53
|
+
*/
|
|
54
|
+
declare function setText(node: Text, text: string): void;
|
|
55
|
+
/**
|
|
56
|
+
* 获取父节点
|
|
57
|
+
* @param node 节点
|
|
58
|
+
*/
|
|
59
|
+
declare function parentNode(node: Node): Node | null;
|
|
60
|
+
/**
|
|
61
|
+
* 获取下一个兄弟节点
|
|
62
|
+
* @param node 节点
|
|
63
|
+
*/
|
|
64
|
+
declare function nextSibling(node: Node): Node | null;
|
|
65
|
+
/**
|
|
66
|
+
* 获取元素的标签名
|
|
67
|
+
* @param el 元素
|
|
68
|
+
*/
|
|
69
|
+
declare function getTagName(el: Element): string;
|
|
70
|
+
/**
|
|
71
|
+
* 导出所有 nodeOps 方法
|
|
72
|
+
*/
|
|
73
|
+
declare const nodeOps: {
|
|
74
|
+
createElement: typeof createElement;
|
|
75
|
+
createText: typeof createText;
|
|
76
|
+
createComment: typeof createComment;
|
|
77
|
+
insert: typeof insert;
|
|
78
|
+
remove: typeof remove;
|
|
79
|
+
setElementText: typeof setElementText;
|
|
80
|
+
setText: typeof setText;
|
|
81
|
+
parentNode: typeof parentNode;
|
|
82
|
+
nextSibling: typeof nextSibling;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* 事件属性处理
|
|
87
|
+
* 使用 invoker 模式避免频繁 addEventListener/removeEventListener
|
|
88
|
+
*/
|
|
89
|
+
/**
|
|
90
|
+
* Invoker 缓存键
|
|
91
|
+
* 用于在元素上存储事件 invoker
|
|
92
|
+
*/
|
|
93
|
+
declare const VEI_KEY = "__vei";
|
|
94
|
+
/**
|
|
95
|
+
* 事件处理器类型
|
|
96
|
+
*/
|
|
97
|
+
type EventHandler = (event: Event) => void;
|
|
98
|
+
/**
|
|
99
|
+
* 事件处理器数组类型
|
|
100
|
+
*/
|
|
101
|
+
type EventHandlerArray = EventHandler[];
|
|
102
|
+
/**
|
|
103
|
+
* Invoker 对象
|
|
104
|
+
* 包装事件处理器,支持动态更换内部处理函数
|
|
105
|
+
*/
|
|
106
|
+
interface Invoker extends EventHandler {
|
|
107
|
+
value: EventHandler | EventHandlerArray;
|
|
108
|
+
attached: number;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Invoker 处理函数
|
|
112
|
+
*/
|
|
113
|
+
type InvokerHandlers = Record<string, Invoker>;
|
|
114
|
+
/**
|
|
115
|
+
* 判断是否为事件属性
|
|
116
|
+
* 事件属性格式:onXxx(第三个字符必须是大写字母)
|
|
117
|
+
* @param key 属性名
|
|
118
|
+
*/
|
|
119
|
+
declare function isEventKey(key: string): boolean;
|
|
120
|
+
/**
|
|
121
|
+
* 规范化事件名
|
|
122
|
+
* onClick -> click
|
|
123
|
+
* onMyEvent -> myevent
|
|
124
|
+
* @param key 属性名
|
|
125
|
+
*/
|
|
126
|
+
declare function normalizeEventName(key: string): string;
|
|
127
|
+
/**
|
|
128
|
+
* 处理事件属性
|
|
129
|
+
* @param el 元素
|
|
130
|
+
* @param key 属性名(如 onClick)
|
|
131
|
+
* @param value 新的事件处理器
|
|
132
|
+
* @param prevValue 旧的事件处理器
|
|
133
|
+
*/
|
|
134
|
+
declare function patchEvent(el: Element & {
|
|
135
|
+
[VEI_KEY]?: InvokerHandlers;
|
|
136
|
+
}, key: string, value: EventHandler | EventHandlerArray | null, prevValue: EventHandler | EventHandlerArray | null): void;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* DOM 属性处理
|
|
140
|
+
* 处理需要直接设置到 DOM 对象的属性(不能使用 setAttribute)
|
|
141
|
+
*/
|
|
142
|
+
/**
|
|
143
|
+
* 判断是否为 DOM 属性
|
|
144
|
+
* @param key 属性名
|
|
145
|
+
*/
|
|
146
|
+
declare function isDOMProp(key: string): boolean;
|
|
147
|
+
/**
|
|
148
|
+
* 处理 DOM 属性
|
|
149
|
+
* @param el 元素
|
|
150
|
+
* @param key 属性名
|
|
151
|
+
* @param value 新值
|
|
152
|
+
* @param prevValue 旧值
|
|
153
|
+
*/
|
|
154
|
+
declare function patchDOMProp(el: Element & Record<string, any>, key: string, value: any, prevValue: any): void;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* class 属性处理
|
|
158
|
+
* 支持字符串、数组、对象三种形式
|
|
159
|
+
*/
|
|
160
|
+
/**
|
|
161
|
+
* class 值类型
|
|
162
|
+
*/
|
|
163
|
+
type ClassValue = string | ClassArray | ClassObject | null | undefined;
|
|
164
|
+
type ClassArray = ClassValue[];
|
|
165
|
+
type ClassObject = Record<string, boolean | undefined | null>;
|
|
166
|
+
/**
|
|
167
|
+
* 将 class 值规范化为字符串
|
|
168
|
+
* @param value class 值
|
|
169
|
+
*/
|
|
170
|
+
declare function normalizeClass(value: ClassValue): string;
|
|
171
|
+
/**
|
|
172
|
+
* 处理 class 属性
|
|
173
|
+
* @param el 元素
|
|
174
|
+
* @param value 新的 class 值
|
|
175
|
+
* @param prevValue 旧的 class 值(暂未使用,预留用于增量更新)
|
|
176
|
+
*/
|
|
177
|
+
declare function patchClass(el: Element, value: ClassValue, prevValue: ClassValue): void;
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* style 属性处理
|
|
181
|
+
* 支持字符串和对象两种形式
|
|
182
|
+
*/
|
|
183
|
+
/**
|
|
184
|
+
* style 值类型
|
|
185
|
+
*/
|
|
186
|
+
type StyleValue = string | StyleObject | null | undefined;
|
|
187
|
+
type StyleObject = Record<string, string | number | null | undefined>;
|
|
188
|
+
/**
|
|
189
|
+
* CSS 属性名转换
|
|
190
|
+
* camelCase -> kebab-case
|
|
191
|
+
* @param name 属性名
|
|
192
|
+
*/
|
|
193
|
+
declare function camelize(name: string): string;
|
|
194
|
+
/**
|
|
195
|
+
* CSS 属性名转换
|
|
196
|
+
* camelCase -> kebab-case
|
|
197
|
+
* @param name 属性名
|
|
198
|
+
*/
|
|
199
|
+
declare function hyphenate(name: string): string;
|
|
200
|
+
/**
|
|
201
|
+
* 规范化 style 值为对象形式
|
|
202
|
+
* @param value style 值
|
|
203
|
+
*/
|
|
204
|
+
declare function normalizeStyle(value: StyleValue): StyleObject;
|
|
205
|
+
/**
|
|
206
|
+
* 处理 style 属性
|
|
207
|
+
* @param el 元素
|
|
208
|
+
* @param value 新的 style 值
|
|
209
|
+
* @param prevValue 旧的 style 值
|
|
210
|
+
*/
|
|
211
|
+
declare function patchStyle(el: Element, value: StyleValue, prevValue: StyleValue): void;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* HTML 属性处理
|
|
215
|
+
* 使用 setAttribute/removeAttribute 处理 HTML 属性
|
|
216
|
+
*/
|
|
217
|
+
/**
|
|
218
|
+
* 判断是否为布尔属性
|
|
219
|
+
* @param name 属性名
|
|
220
|
+
*/
|
|
221
|
+
declare function isBooleanAttr(name: string): boolean;
|
|
222
|
+
/**
|
|
223
|
+
* 判断是否需要特殊处理
|
|
224
|
+
* @param name 属性名
|
|
225
|
+
*/
|
|
226
|
+
declare function isSpecialAttr(name: string): boolean;
|
|
227
|
+
/**
|
|
228
|
+
* 处理 HTML 属性
|
|
229
|
+
* @param el 元素
|
|
230
|
+
* @param key 属性名
|
|
231
|
+
* @param value 新值
|
|
232
|
+
* @param prevValue 旧值(暂未使用)
|
|
233
|
+
*/
|
|
234
|
+
declare function patchAttr(el: Element, key: string, value: any, prevValue: any): void;
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* patchProp 分发入口
|
|
238
|
+
* 根据属性类型分发到对应的处理函数
|
|
239
|
+
*/
|
|
240
|
+
/**
|
|
241
|
+
* 处理元素属性
|
|
242
|
+
* 按优先级分发到对应的处理函数:
|
|
243
|
+
* 1. 事件 (onClick 等) → patchEvent
|
|
244
|
+
* 2. DOM 属性 (value, checked 等) → patchDOMProp
|
|
245
|
+
* 3. class → patchClass
|
|
246
|
+
* 4. style → patchStyle
|
|
247
|
+
* 5. HTML 属性 → patchAttr
|
|
248
|
+
*
|
|
249
|
+
* @param el 元素
|
|
250
|
+
* @param key 属性名
|
|
251
|
+
* @param value 新值
|
|
252
|
+
* @param prevValue 旧值
|
|
253
|
+
*/
|
|
254
|
+
declare function patchProp(el: Element, key: string, value: any, prevValue: any): void;
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* SVG 支持
|
|
258
|
+
* 提供 SVG 元素的创建和属性处理
|
|
259
|
+
*/
|
|
260
|
+
/**
|
|
261
|
+
* SVG 命名空间
|
|
262
|
+
*/
|
|
263
|
+
declare const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
264
|
+
/**
|
|
265
|
+
* XLINK 命名空间
|
|
266
|
+
*/
|
|
267
|
+
declare const XLINK_NAMESPACE = "http://www.w3.org/1999/xlink";
|
|
268
|
+
/**
|
|
269
|
+
* XML 命名空间
|
|
270
|
+
*/
|
|
271
|
+
declare const XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace";
|
|
272
|
+
/**
|
|
273
|
+
* 判断是否为 SVG 标签
|
|
274
|
+
* @param tag 标签名
|
|
275
|
+
*/
|
|
276
|
+
declare function isSVGTag(tag: string): boolean;
|
|
277
|
+
/**
|
|
278
|
+
* 创建 SVG 元素
|
|
279
|
+
* @param tag 标签名
|
|
280
|
+
*/
|
|
281
|
+
declare function createSVGElement(tag: string): SVGElement;
|
|
282
|
+
/**
|
|
283
|
+
* 判断是否为 XLINK 属性
|
|
284
|
+
* @param attr 属性名
|
|
285
|
+
*/
|
|
286
|
+
declare function isXlinkAttr(attr: string): boolean;
|
|
287
|
+
/**
|
|
288
|
+
* 判断是否为 XML 属性
|
|
289
|
+
* @param attr 属性名
|
|
290
|
+
*/
|
|
291
|
+
declare function isXMLAttr(attr: string): boolean;
|
|
292
|
+
/**
|
|
293
|
+
* 设置 SVG 属性
|
|
294
|
+
* @param el SVG 元素
|
|
295
|
+
* @param key 属性名
|
|
296
|
+
* @param value 属性值
|
|
297
|
+
*/
|
|
298
|
+
declare function setSVGAttr(el: SVGElement, key: string, value: any): void;
|
|
299
|
+
/**
|
|
300
|
+
* 获取 SVG 元素的命名空间
|
|
301
|
+
* @param el 元素
|
|
302
|
+
*/
|
|
303
|
+
declare function getSVGNamespace(el: Element): string | null;
|
|
304
|
+
/**
|
|
305
|
+
* 判断元素是否在 SVG 上下文中
|
|
306
|
+
* @param el 元素
|
|
307
|
+
*/
|
|
308
|
+
declare function isInSVG(el: Element): boolean;
|
|
309
|
+
|
|
310
|
+
export { SVG_NAMESPACE, XLINK_NAMESPACE, XML_NAMESPACE, camelize, createApp, createComment, createElement, createSVGElement, createText, getSVGNamespace, getTagName, hyphenate, insert, isBooleanAttr, isDOMProp, isEventKey, isInSVG, isSVGTag, isSpecialAttr, isXMLAttr, isXlinkAttr, nextSibling, nodeOps, normalizeClass, normalizeEventName, normalizeStyle, parentNode, patchAttr, patchClass, patchDOMProp, patchEvent, patchProp, patchStyle, remove, render, setElementText, setSVGAttr, setText };
|
|
311
|
+
//# sourceMappingURL=runtime-dom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-dom.d.ts","sources":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","names":[]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createRenderer as e,setAppRenderer as t,setRenderRenderer as n}from"@fluxion-ui/runtime-core";export{cloneVNode,createCommentVNode,createEmptyVNode,createTextVNode,createVNode,h,isComponentVNode,isElementVNode,isVNode,nextTick,queueJob}from"@fluxion-ui/runtime-core";import{warn as r,isArray as o,isFunction as i,isString as a,isObject as l,hasOwn as c}from"@fluxion-ui/shared";export{asyncSignal,computed,effect,reactive,signal,watch,watchEffect}from"@fluxion-ui/reactivity";function s(e){return e?document.createElement(e):(r("createElement: 标签名不能为空"),document.createElement("div"))}function u(e){return document.createTextNode(e??"")}function f(e){return document.createComment(e??"")}function d(e,t,n){e?t?t.insertBefore(e,n??null):r("insert: 父节点不能为空"):r("insert: 子节点不能为空")}function p(e){if(!e)return void r("remove: 节点不能为空");const t=e.parentNode;t&&t.removeChild(e)}function m(e,t){e?e.textContent=t??"":r("setElementText: 元素不能为空")}function x(e,t){e?e.nodeValue=t??"":r("setText: 文本节点不能为空")}function v(e){return e?e.parentNode:(r("parentNode: 节点不能为空"),null)}function g(e){return e?e.nextSibling:(r("nextSibling: 节点不能为空"),null)}function w(e){return e?.tagName?.toLowerCase()??""}const b={createElement:s,createText:u,createComment:f,insert:d,remove:p,setElementText:m,setText:x,parentNode:v,nextSibling:g},y="__vei";function k(e){return e.startsWith("on")&&e.length>2&&/[A-Z]/.test(e[2])}function C(e){return e.slice(2).toLowerCase()}function N(e,t,n,a){if(!e)return void r("patchEvent: 元素不能为空");const l=C(t),c=e[y]??(e[y]={}),s=c[l];if(null==n)s&&(e.removeEventListener(l,s),delete c[l]);else if(s)s.value=n;else{const t=function(e){const t=e=>{if(o(t.value))for(let n=0;n<t.value.length;n++){const r=t.value[n];i(r)&&r(e)}else i(t.value)&&t.value(e)};return t.value=e,t.attached=0,t}(n);t.attached=Date.now(),c[l]=t,e.addEventListener(l,t)}}const S=new Set(["value","checked","selected","muted","innerHTML","textContent","className","indeterminate","defaultChecked","defaultValue","disabled","readOnly","required","multiple","autofocus","autoplay","controls","loop","playsinline","default","open","contentEditable","spellcheck"]);function E(e){return S.has(e)}function A(e,t,n,o){if(e)switch(t){case"value":{const t=e.tagName?.toLowerCase();if("input"===t||"textarea"===t||"select"===t){const t=n??"";e.value!==t&&(e.value=t)}else e.value=n??"";break}case"innerHTML":e.innerHTML=null==n?"":n;break;case"textContent":e.textContent=null==n?"":n;break;case"className":null==n?e.className="":a(n)?e.className=n:r("patchDOMProp: className 应该是字符串");break;case"checked":case"selected":case"muted":case"disabled":case"readOnly":case"required":case"multiple":case"autofocus":case"autoplay":case"controls":case"loop":case"playsinline":case"default":case"open":case"indeterminate":e[t]=null!=n&&!1!==n;break;case"contentEditable":case"spellcheck":e[t]=null==n?null:n;break;default:t in e?e[t]=n:r(`patchDOMProp: 未知的 DOM 属性 ${t}`)}else r("patchDOMProp: 元素不能为空")}function L(e){return null==e?"":a(e)?e.trim():o(e)?function(e){const t=[];for(let n=0;n<e.length;n++){const r=L(e[n]);r&&t.push(r)}return t.join(" ")}(e):l(e)?function(e){const t=[];for(const n in e)e[n]&&t.push(n);return t.join(" ")}(e):(r("normalizeClass: 无效的 class 值类型"),"")}function T(e,t,n){if(!e)return void r("patchClass: 元素不能为空");const o=L(t);e.className=o||""}function M(e){return e.replace(/-(\w)/g,(e,t)=>t?t.toUpperCase():"")}function O(e){return e.replace(/\B([A-Z])/g,"-$1").toLowerCase()}function P(e,t){if(a(t))return t;const n=new Set(["animationIterationCount","aspectRatio","borderImageOutset","borderImageSlice","borderImageWidth","boxFlex","boxFlexGroup","boxOrdinalGroup","columnCount","columns","flex","flexGrow","flexPositive","flexShrink","flexNegative","flexOrder","gridArea","gridColumn","gridColumnEnd","gridColumnStart","gridRow","gridRowEnd","gridRowStart","lineClamp","lineHeight","opacity","order","orphans","tabSize","widows","zIndex","zoom","fillOpacity","floodOpacity","stopOpacity","strokeDasharray","strokeDashoffset","strokeMiterlimit","strokeOpacity","strokeWidth"]),r=M(e);return"number"!=typeof t||n.has(r)?String(t):`${t}px`}function V(e,t,n){if(null==n||""===n)e.removeProperty(t);else{const r=P(t,n);e.setProperty(t,r)}}function D(e){return null==e?{}:a(e)?function(e){const t={},n=e.split(";");for(let e=0;e<n.length;e++){const r=n[e].trim();if(r){const e=r.indexOf(":");if(e>0){const n=r.slice(0,e).trim(),o=r.slice(e+1).trim();n&&o&&(t[M(n)]=o)}}}return t}(e):l(e)?e:{}}function G(e,t,n){if(!e)return void r("patchStyle: 元素不能为空");const o=e.style;if(!o){if(null!=t&&a(t))e.setAttribute("style",t);else if(null!=t&&l(t)){const n=function(e){const t=[];for(const n in e){const r=e[n];null!=r&&""!==r&&t.push(`${O(n)}: ${P(n,r)}`)}return t.join("; ")}(t);e.setAttribute("style",n)}return}if(null==t){if(a(n))o.cssText="";else if(l(n))for(const e in n)o.removeProperty(O(e));return}if(a(t))return void(o.cssText=t);const i=t,s=l(n)?n:{};for(const e in s)c(i,e)||o.removeProperty(O(e));for(const e in i){const t=i[e];t!==s[e]&&V(o,O(e),t)}}const F=new Set(["allowfullscreen","async","autofocus","autoplay","checked","controls","default","defer","disabled","formnovalidate","hidden","inert","ismap","itemscope","loop","multiple","muted","nomodule","novalidate","open","playsinline","readonly","required","reversed","selected"]);function I(e){return F.has(e.toLowerCase())}const R=new Set(["value","checked","selected","muted","innerHTML","textContent","className","style"]);function $(e){return R.has(e)}function B(e,t,n,o){if(!e)return void r("patchAttr: 元素不能为空");if(!t)return void r("patchAttr: 属性名不能为空");if($(t))return void r(`patchAttr: ${t} 应该由对应的 patch 函数处理`);const i=t.toLowerCase();null==n||!1===n?e.removeAttribute(t):I(i)?e.setAttribute(t,""):e.setAttribute(t,n)}function H(e,t,n,o){e?t?k(t)?N(e,t,n):E(t)?A(e,t,n):"class"!==t?"style"!==t?B(e,t,n):G(e,n,o):T(e,n):r("patchProp: 属性名不能为空"):r("patchProp: 元素不能为空")}const j="http://www.w3.org/2000/svg",q="http://www.w3.org/1999/xlink",z="http://www.w3.org/XML/1998/namespace",W=new Set(["svg","animate","animateMotion","animateTransform","circle","clipPath","defs","desc","ellipse","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","filter","foreignObject","g","image","line","linearGradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialGradient","rect","set","stop","switch","symbol","text","textPath","tspan","use","view"]);function U(e){return W.has(e)}function Z(e){return e||(r("createSVGElement: 标签名不能为空"),e="svg"),document.createElementNS(j,e)}const _=new Set(["xlink:href","xlink:title","xlink:role","xlink:arcrole","xlink:show","xlink:actuate","xlink:type","xlink:label"]);function J(e){return _.has(e)}const X=new Set(["xml:space","xml:lang","xml:base"]);function K(e){return X.has(e)}function Q(e,t,n){if(e)if(null!=n&&!1!==n){if(J(t)){const r=t.slice(6);return void e.setAttributeNS(q,r,n)}if(K(t)){const r=t.slice(4);return void e.setAttributeNS(z,r,n)}e.setAttribute(t,n)}else e.removeAttribute(t);else r("setSVGAttr: 元素不能为空")}function Y(e){return e.namespaceURI}function ee(e){let t=e;for(;t;){if("svg"===t.tagName.toLowerCase())return!0;t=t.parentElement}return!1}const te=e({...b,patchProp:H,createElement:e=>U(e)?Z(e):b.createElement(e)}),{render:ne,createApp:re}=te;t({createApp:re}),n({render:ne});export{j as SVG_NAMESPACE,q as XLINK_NAMESPACE,z as XML_NAMESPACE,M as camelize,re as createApp,f as createComment,s as createElement,Z as createSVGElement,u as createText,Y as getSVGNamespace,w as getTagName,O as hyphenate,d as insert,I as isBooleanAttr,E as isDOMProp,k as isEventKey,ee as isInSVG,U as isSVGTag,$ as isSpecialAttr,K as isXMLAttr,J as isXlinkAttr,g as nextSibling,b as nodeOps,L as normalizeClass,C as normalizeEventName,D as normalizeStyle,v as parentNode,B as patchAttr,T as patchClass,A as patchDOMProp,N as patchEvent,H as patchProp,G as patchStyle,p as remove,ne as render,m as setElementText,Q as setSVGAttr,x as setText};
|
|
2
|
+
//# sourceMappingURL=runtime-dom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-dom.js","sources":["../src/nodeOps.ts","../src/patchProp/patchEvent.ts","../src/patchProp/patchDOMProp.ts","../src/patchProp/patchClass.ts","../src/patchProp/patchStyle.ts","../src/patchProp/patchAttr.ts","../src/patchProp/index.ts","../src/modules/svg.ts","../src/renderer.ts"],"sourcesContent":["/**\n * DOM 节点操作\n * 提供 RendererOptions 所需的基础 DOM 操作方法\n */\n\nimport { warn } from '@fluxion-ui/shared'\n\n/**\n * 创建 HTML 元素\n * @param tag 标签名\n */\nexport function createElement(tag: string): Element {\n if (!tag) {\n warn('createElement: 标签名不能为空')\n return document.createElement('div')\n }\n return document.createElement(tag)\n}\n\n/**\n * 创建文本节点\n * @param text 文本内容\n */\nexport function createText(text: string): Text {\n return document.createTextNode(text ?? '')\n}\n\n/**\n * 创建注释节点\n * @param text 注释内容\n */\nexport function createComment(text: string): Comment {\n return document.createComment(text ?? '')\n}\n\n/**\n * 插入节点到父节点\n * @param child 要插入的子节点\n * @param parent 父节点\n * @param anchor 参考节点(插入到该节点之前)\n */\nexport function insert(\n child: Node,\n parent: Node,\n anchor?: Node | null\n): void {\n if (!child) {\n warn('insert: 子节点不能为空')\n return\n }\n if (!parent) {\n warn('insert: 父节点不能为空')\n return\n }\n // 使用 insertBefore 实现,anchor 为 null 时插入到末尾\n parent.insertBefore(child, anchor ?? null)\n}\n\n/**\n * 移除节点\n * @param child 要移除的节点\n */\nexport function remove(child: Node): void {\n if (!child) {\n warn('remove: 节点不能为空')\n return\n }\n const parent = child.parentNode\n if (parent) {\n parent.removeChild(child)\n }\n}\n\n/**\n * 设置元素的文本内容\n * @param el 元素\n * @param text 文本内容\n */\nexport function setElementText(el: Element, text: string): void {\n if (!el) {\n warn('setElementText: 元素不能为空')\n return\n }\n el.textContent = text ?? ''\n}\n\n/**\n * 设置文本节点的内容\n * @param node 文本节点\n * @param text 文本内容\n */\nexport function setText(node: Text, text: string): void {\n if (!node) {\n warn('setText: 文本节点不能为空')\n return\n }\n node.nodeValue = text ?? ''\n}\n\n/**\n * 获取父节点\n * @param node 节点\n */\nexport function parentNode(node: Node): Node | null {\n if (!node) {\n warn('parentNode: 节点不能为空')\n return null\n }\n return node.parentNode\n}\n\n/**\n * 获取下一个兄弟节点\n * @param node 节点\n */\nexport function nextSibling(node: Node): Node | null {\n if (!node) {\n warn('nextSibling: 节点不能为空')\n return null\n }\n return node.nextSibling\n}\n\n/**\n * 获取元素的标签名\n * @param el 元素\n */\nexport function getTagName(el: Element): string {\n return el?.tagName?.toLowerCase() ?? ''\n}\n\n/**\n * 导出所有 nodeOps 方法\n */\nexport const nodeOps = {\n createElement,\n createText,\n createComment,\n insert,\n remove,\n setElementText,\n setText,\n parentNode,\n nextSibling\n}","/**\n * 事件属性处理\n * 使用 invoker 模式避免频繁 addEventListener/removeEventListener\n */\n\nimport { warn, isFunction, isArray } from '@fluxion-ui/shared'\n\n/**\n * Invoker 缓存键\n * 用于在元素上存储事件 invoker\n */\nconst VEI_KEY = '__vei'\n\n/**\n * 事件处理器类型\n */\ntype EventHandler = (event: Event) => void\n\n/**\n * 事件处理器数组类型\n */\ntype EventHandlerArray = EventHandler[]\n\n/**\n * Invoker 对象\n * 包装事件处理器,支持动态更换内部处理函数\n */\ninterface Invoker extends EventHandler {\n value: EventHandler | EventHandlerArray\n attached: number // 绑定时间戳,用于去重\n}\n\n/**\n * Invoker 处理函数\n */\ntype InvokerHandlers = Record<string, Invoker>\n\n/**\n * 判断是否为事件属性\n * 事件属性格式:onXxx(第三个字符必须是大写字母)\n * @param key 属性名\n */\nexport function isEventKey(key: string): boolean {\n return key.startsWith('on') && key.length > 2 && /[A-Z]/.test(key[2])\n}\n\n/**\n * 规范化事件名\n * onClick -> click\n * onMyEvent -> myevent\n * @param key 属性名\n */\nexport function normalizeEventName(key: string): string {\n // 移除 'on' 前缀并转为小写\n return key.slice(2).toLowerCase()\n}\n\n/**\n * 创建事件包装函数\n * @param value 事件处理器\n */\nfunction createInvokerWrapper(value: EventHandler | EventHandlerArray): Invoker {\n const invoker: Invoker = (event: Event) => {\n if (isArray(invoker.value)) {\n // 处理函数数组\n for (let i = 0; i < invoker.value.length; i++) {\n const handler = invoker.value[i]\n if (isFunction(handler)) {\n handler(event)\n }\n }\n } else if (isFunction(invoker.value)) {\n // 单个处理函数\n invoker.value(event)\n }\n }\n invoker.value = value\n invoker.attached = 0\n return invoker\n}\n\n/**\n * 处理事件属性\n * @param el 元素\n * @param key 属性名(如 onClick)\n * @param value 新的事件处理器\n * @param prevValue 旧的事件处理器\n */\nexport function patchEvent(\n el: Element & { [VEI_KEY]?: InvokerHandlers },\n key: string,\n value: EventHandler | EventHandlerArray | null,\n prevValue: EventHandler | EventHandlerArray | null\n): void {\n if (!el) {\n warn('patchEvent: 元素不能为空')\n return\n }\n\n // 获取事件名\n const eventName = normalizeEventName(key)\n\n // 获取或创建 invokers 缓存\n const invokers = (el[VEI_KEY] ??= {}) as InvokerHandlers\n\n // 获取现有的 invoker\n const existingInvoker = invokers[eventName]\n\n if (value == null) {\n // 移除事件\n if (existingInvoker) {\n // 使用 invoker 本身作为移除的函数(invoker 是 wrapper)\n el.removeEventListener(eventName, existingInvoker)\n delete invokers[eventName]\n }\n } else {\n if (existingInvoker) {\n // 更新现有 invoker 的值\n // 不需要重新 addEventListener,直接替换 value\n existingInvoker.value = value\n } else {\n // 创建新的 invoker(invoker 本身就是 wrapper 函数)\n const invoker = createInvokerWrapper(value)\n invoker.attached = Date.now()\n invokers[eventName] = invoker\n el.addEventListener(eventName, invoker)\n }\n }\n}","/**\n * DOM 属性处理\n * 处理需要直接设置到 DOM 对象的属性(不能使用 setAttribute)\n */\n\nimport { warn, isString } from '@fluxion-ui/shared'\n\n/**\n * 需要直接设置的 DOM 属性列表\n * 这些属性不能通过 setAttribute 设置,必须直接赋值\n */\nconst DOM_PROP_KEYS = new Set([\n 'value',\n 'checked',\n 'selected',\n 'muted',\n 'innerHTML',\n 'textContent',\n 'className',\n // 表单相关\n 'indeterminate',\n 'defaultChecked',\n 'defaultValue',\n // 其他布尔属性\n 'disabled',\n 'readOnly',\n 'required',\n 'multiple',\n 'autofocus',\n 'autoplay',\n 'controls',\n 'loop',\n 'playsinline',\n 'default',\n 'open',\n 'contentEditable',\n 'spellcheck'\n])\n\n/**\n * 判断是否为 DOM 属性\n * @param key 属性名\n */\nexport function isDOMProp(key: string): boolean {\n return DOM_PROP_KEYS.has(key)\n}\n\n/**\n * 处理 DOM 属性\n * @param el 元素\n * @param key 属性名\n * @param value 新值\n * @param prevValue 旧值\n */\nexport function patchDOMProp(\n el: Element & Record<string, any>,\n key: string,\n value: any,\n prevValue: any\n): void {\n if (!el) {\n warn('patchDOMProp: 元素不能为空')\n return\n }\n\n switch (key) {\n case 'value': {\n // value 特殊处理\n const tagName = el.tagName?.toLowerCase()\n if (tagName === 'input' || tagName === 'textarea' || tagName === 'select') {\n // 表单元素:设置 value\n const newValue = value ?? ''\n if (el.value !== newValue) {\n el.value = newValue\n }\n } else {\n // 其他元素:直接设置\n el.value = value ?? ''\n }\n break\n }\n\n case 'innerHTML': {\n // innerHTML 特殊处理\n if (value == null) {\n el.innerHTML = ''\n } else {\n el.innerHTML = value\n }\n break\n }\n\n case 'textContent': {\n // textContent 特殊处理\n if (value == null) {\n el.textContent = ''\n } else {\n el.textContent = value\n }\n break\n }\n\n case 'className': {\n // className 特殊处理(兼容 SVG)\n if (value == null) {\n el.className = ''\n } else if (isString(value)) {\n el.className = value\n } else {\n warn('patchDOMProp: className 应该是字符串')\n }\n break\n }\n\n case 'checked':\n case 'selected':\n case 'muted':\n case 'disabled':\n case 'readOnly':\n case 'required':\n case 'multiple':\n case 'autofocus':\n case 'autoplay':\n case 'controls':\n case 'loop':\n case 'playsinline':\n case 'default':\n case 'open':\n case 'indeterminate': {\n // 布尔属性\n if (value == null || value === false) {\n el[key] = false\n } else {\n el[key] = true\n }\n break\n }\n\n case 'contentEditable':\n case 'spellcheck': {\n // 字符串/布尔混合属性\n if (value == null) {\n el[key] = null\n } else {\n el[key] = value\n }\n break\n }\n\n default: {\n // 其他 DOM 属性直接设置\n if (key in el) {\n el[key] = value\n } else {\n warn(`patchDOMProp: 未知的 DOM 属性 ${key}`)\n }\n }\n }\n}","/**\n * class 属性处理\n * 支持字符串、数组、对象三种形式\n */\n\nimport { warn, isString, isArray, isObject } from '@fluxion-ui/shared'\n\n/**\n * class 值类型\n */\ntype ClassValue = string | ClassArray | ClassObject | null | undefined\n\ntype ClassArray = ClassValue[]\n\ntype ClassObject = Record<string, boolean | undefined | null>\n\n/**\n * 将 class 值规范化为字符串\n * @param value class 值\n */\nexport function normalizeClass(value: ClassValue): string {\n if (value == null) {\n return ''\n }\n\n if (isString(value)) {\n return value.trim()\n }\n\n if (isArray(value)) {\n return normalizeArrayClass(value)\n }\n\n if (isObject(value)) {\n return normalizeObjectClass(value as ClassObject)\n }\n\n warn('normalizeClass: 无效的 class 值类型')\n return ''\n}\n\n/**\n * 规范化数组形式的 class\n * @param values class 数组\n */\nfunction normalizeArrayClass(values: ClassArray): string {\n const classes: string[] = []\n\n for (let i = 0; i < values.length; i++) {\n const value = normalizeClass(values[i])\n if (value) {\n classes.push(value)\n }\n }\n\n return classes.join(' ')\n}\n\n/**\n * 规范化对象形式的 class\n * @param obj class 对象\n */\nfunction normalizeObjectClass(obj: ClassObject): string {\n const classes: string[] = []\n\n for (const key in obj) {\n if (obj[key]) {\n classes.push(key)\n }\n }\n\n return classes.join(' ')\n}\n\n/**\n * 处理 class 属性\n * @param el 元素\n * @param value 新的 class 值\n * @param prevValue 旧的 class 值(暂未使用,预留用于增量更新)\n */\nexport function patchClass(\n el: Element,\n value: ClassValue,\n prevValue: ClassValue\n): void {\n if (!el) {\n warn('patchClass: 元素不能为空')\n return\n }\n\n // 规范化 class 值\n const normalizedClass = normalizeClass(value)\n\n // 设置 class\n if (normalizedClass) {\n el.className = normalizedClass\n } else {\n // 空值时清空 class\n el.className = ''\n }\n}","/**\n * style 属性处理\n * 支持字符串和对象两种形式\n */\n\nimport { warn, isString, isObject, hasOwn } from '@fluxion-ui/shared'\n\n/**\n * CSS 属性名映射(用于处理简写属性)\n */\nconst cssTextCache = new WeakMap<object, string>()\n\n/**\n * style 值类型\n */\ntype StyleValue = string | StyleObject | null | undefined\n\ntype StyleObject = Record<string, string | number | null | undefined>\n\n/**\n * 重要样式属性,需要添加 !important 后缀\n */\nconst importantStyles = new Set([\n 'display'\n])\n\n/**\n * CSS 属性名转换\n * camelCase -> kebab-case\n * @param name 属性名\n */\nexport function camelize(name: string): string {\n return name.replace(/-(\\w)/g, (_, c) => (c ? c.toUpperCase() : ''))\n}\n\n/**\n * CSS 属性名转换\n * camelCase -> kebab-case\n * @param name 属性名\n */\nexport function hyphenate(name: string): string {\n return name.replace(/\\B([A-Z])/g, '-$1').toLowerCase()\n}\n\n/**\n * 规范化样式值\n * 添加必要的单位(如 px)\n * @param name 属性名\n * @param value 属性值\n */\nfunction normalizeStyleValue(\n name: string,\n value: string | number\n): string {\n // 如果已经是字符串,直接返回\n if (isString(value)) {\n return value\n }\n\n // 数值类型需要添加单位\n // 无单位的 CSS 属性列表\n const unitlessProperties = new Set([\n 'animationIterationCount',\n 'aspectRatio',\n 'borderImageOutset',\n 'borderImageSlice',\n 'borderImageWidth',\n 'boxFlex',\n 'boxFlexGroup',\n 'boxOrdinalGroup',\n 'columnCount',\n 'columns',\n 'flex',\n 'flexGrow',\n 'flexPositive',\n 'flexShrink',\n 'flexNegative',\n 'flexOrder',\n 'gridArea',\n 'gridColumn',\n 'gridColumnEnd',\n 'gridColumnStart',\n 'gridRow',\n 'gridRowEnd',\n 'gridRowStart',\n 'lineClamp',\n 'lineHeight',\n 'opacity',\n 'order',\n 'orphans',\n 'tabSize',\n 'widows',\n 'zIndex',\n 'zoom',\n 'fillOpacity',\n 'floodOpacity',\n 'stopOpacity',\n 'strokeDasharray',\n 'strokeDashoffset',\n 'strokeMiterlimit',\n 'strokeOpacity',\n 'strokeWidth'\n ])\n\n // 检查是否需要单位\n const key = camelize(name)\n if (typeof value === 'number' && !unitlessProperties.has(key)) {\n return `${value}px`\n }\n\n return String(value)\n}\n\n/**\n * 设置单个样式属性\n * @param style style 对象\n * @param name 属性名\n * @param value 属性值\n */\nfunction setStyleProperty(\n style: CSSStyleDeclaration,\n name: string,\n value: string | number | null | undefined\n): void {\n if (value == null || value === '') {\n // 移除样式\n style.removeProperty(name)\n } else {\n // 设置样式\n const normalized = normalizeStyleValue(name, value)\n style.setProperty(name, normalized)\n }\n}\n\n/**\n * 规范化 style 值为对象形式\n * @param value style 值\n */\nexport function normalizeStyle(value: StyleValue): StyleObject {\n if (value == null) {\n return {}\n }\n\n if (isString(value)) {\n return parseStyleString(value)\n }\n\n if (isObject(value)) {\n return value as StyleObject\n }\n\n return {}\n}\n\n/**\n * 解析 style 字符串为对象\n * @param styleString style 字符串\n */\nfunction parseStyleString(styleString: string): StyleObject {\n const result: StyleObject = {}\n const styles = styleString.split(';')\n\n for (let i = 0; i < styles.length; i++) {\n const style = styles[i].trim()\n if (style) {\n const colonIndex = style.indexOf(':')\n if (colonIndex > 0) {\n const name = style.slice(0, colonIndex).trim()\n const value = style.slice(colonIndex + 1).trim()\n if (name && value) {\n result[camelize(name)] = value\n }\n }\n }\n }\n\n return result\n}\n\n/**\n * 处理 style 属性\n * @param el 元素\n * @param value 新的 style 值\n * @param prevValue 旧的 style 值\n */\nexport function patchStyle(\n el: Element,\n value: StyleValue,\n prevValue: StyleValue\n): void {\n if (!el) {\n warn('patchStyle: 元素不能为空')\n return\n }\n\n const style = (el as HTMLElement).style\n\n if (!style) {\n // 非 HTMLElement,尝试设置 style 属性\n if (value != null && isString(value)) {\n el.setAttribute('style', value)\n } else if (value != null && isObject(value)) {\n const styleStr = objectToStyleString(value as StyleObject)\n el.setAttribute('style', styleStr)\n }\n return\n }\n\n // 处理新值\n if (value == null) {\n // 清空所有样式\n if (isString(prevValue)) {\n style.cssText = ''\n } else if (isObject(prevValue)) {\n // 移除旧的样式属性\n for (const key in prevValue as StyleObject) {\n style.removeProperty(hyphenate(key))\n }\n }\n return\n }\n\n if (isString(value)) {\n // 字符串形式:直接设置 cssText\n style.cssText = value\n return\n }\n\n // 对象形式:增量更新\n const newStyle = value as StyleObject\n const oldStyle = isObject(prevValue) ? (prevValue as StyleObject) : {}\n\n // 移除旧的样式\n for (const key in oldStyle) {\n if (!hasOwn(newStyle, key)) {\n style.removeProperty(hyphenate(key))\n }\n }\n\n // 设置新的样式\n for (const key in newStyle) {\n const newValue = newStyle[key]\n const oldValue = oldStyle[key]\n if (newValue !== oldValue) {\n setStyleProperty(style, hyphenate(key), newValue)\n }\n }\n}\n\n/**\n * 将样式对象转换为字符串\n * @param style 样式对象\n */\nfunction objectToStyleString(style: StyleObject): string {\n const parts: string[] = []\n for (const key in style) {\n const value = style[key]\n if (value != null && value !== '') {\n parts.push(`${hyphenate(key)}: ${normalizeStyleValue(key, value)}`)\n }\n }\n return parts.join('; ')\n}","/**\n * HTML 属性处理\n * 使用 setAttribute/removeAttribute 处理 HTML 属性\n */\n\nimport { warn, isString, isBoolean } from '@fluxion-ui/shared'\n\n/**\n * 布尔属性列表\n * 这些属性只要存在即为 true,值会被忽略\n */\nconst BOOLEAN_ATTRIBUTES = new Set([\n 'allowfullscreen',\n 'async',\n 'autofocus',\n 'autoplay',\n 'checked',\n 'controls',\n 'default',\n 'defer',\n 'disabled',\n 'formnovalidate',\n 'hidden',\n 'inert',\n 'ismap',\n 'itemscope',\n 'loop',\n 'multiple',\n 'muted',\n 'nomodule',\n 'novalidate',\n 'open',\n 'playsinline',\n 'readonly',\n 'required',\n 'reversed',\n 'selected'\n])\n\n/**\n * 判断是否为布尔属性\n * @param name 属性名\n */\nexport function isBooleanAttr(name: string): boolean {\n return BOOLEAN_ATTRIBUTES.has(name.toLowerCase())\n}\n\n/**\n * 需要特殊处理的属性\n * 这些属性使用 setAttribute 会有问题\n */\nconst SPECIAL_ATTRIBUTES = new Set([\n 'value',\n 'checked',\n 'selected',\n 'muted',\n 'innerHTML',\n 'textContent',\n 'className',\n 'style'\n])\n\n/**\n * 判断是否需要特殊处理\n * @param name 属性名\n */\nexport function isSpecialAttr(name: string): boolean {\n return SPECIAL_ATTRIBUTES.has(name)\n}\n\n/**\n * 处理 HTML 属性\n * @param el 元素\n * @param key 属性名\n * @param value 新值\n * @param prevValue 旧值(暂未使用)\n */\nexport function patchAttr(\n el: Element,\n key: string,\n value: any,\n prevValue: any\n): void {\n if (!el) {\n warn('patchAttr: 元素不能为空')\n return\n }\n\n if (!key) {\n warn('patchAttr: 属性名不能为空')\n return\n }\n\n // 检查是否为特殊属性\n if (isSpecialAttr(key)) {\n warn(`patchAttr: ${key} 应该由对应的 patch 函数处理`)\n return\n }\n\n // 转为小写进行比较\n const lowerKey = key.toLowerCase()\n\n if (value == null || value === false) {\n // 移除属性\n el.removeAttribute(key)\n } else if (isBooleanAttr(lowerKey)) {\n // 布尔属性:值存在即为 true\n el.setAttribute(key, '')\n } else {\n // 普通属性\n el.setAttribute(key, value)\n }\n}\n\n/**\n * 批量设置属性\n * @param el 元素\n * @param attrs 属性对象\n */\nexport function setAttrs(el: Element, attrs: Record<string, any>): void {\n if (!el || !attrs) return\n\n for (const key in attrs) {\n const value = attrs[key]\n patchAttr(el, key, value, null)\n }\n}\n\n/**\n * 移除所有属性\n * @param el 元素\n * @param attrs 要移除的属性名数组\n */\nexport function removeAttrs(el: Element, attrs: string[]): void {\n if (!el || !attrs) return\n\n for (let i = 0; i < attrs.length; i++) {\n el.removeAttribute(attrs[i])\n }\n}","/**\n * patchProp 分发入口\n * 根据属性类型分发到对应的处理函数\n */\n\nimport { patchEvent, isEventKey } from './patchEvent'\nimport { patchDOMProp, isDOMProp } from './patchDOMProp'\nimport { patchClass } from './patchClass'\nimport { patchStyle } from './patchStyle'\nimport { patchAttr } from './patchAttr'\nimport { warn } from '@fluxion-ui/shared'\n\n/**\n * 处理元素属性\n * 按优先级分发到对应的处理函数:\n * 1. 事件 (onClick 等) → patchEvent\n * 2. DOM 属性 (value, checked 等) → patchDOMProp\n * 3. class → patchClass\n * 4. style → patchStyle\n * 5. HTML 属性 → patchAttr\n *\n * @param el 元素\n * @param key 属性名\n * @param value 新值\n * @param prevValue 旧值\n */\nexport function patchProp(\n el: Element,\n key: string,\n value: any,\n prevValue: any\n): void {\n if (!el) {\n warn('patchProp: 元素不能为空')\n return\n }\n\n if (!key) {\n warn('patchProp: 属性名不能为空')\n return\n }\n\n // 1. 事件处理\n if (isEventKey(key)) {\n patchEvent(el as any, key, value, prevValue)\n return\n }\n\n // 2. DOM 属性处理\n if (isDOMProp(key)) {\n patchDOMProp(el as any, key, value, prevValue)\n return\n }\n\n // 3. class 处理\n if (key === 'class') {\n patchClass(el, value, prevValue)\n return\n }\n\n // 4. style 处理\n if (key === 'style') {\n patchStyle(el, value, prevValue)\n return\n }\n\n // 5. HTML 属性处理\n patchAttr(el, key, value, prevValue)\n}\n\n// 导出各个子模块\nexport { patchEvent, isEventKey, normalizeEventName } from './patchEvent'\nexport { patchDOMProp, isDOMProp } from './patchDOMProp'\nexport { patchClass, normalizeClass } from './patchClass'\nexport { patchStyle, normalizeStyle, hyphenate, camelize } from './patchStyle'\nexport { patchAttr, isBooleanAttr, isSpecialAttr } from './patchAttr'","/**\n * SVG 支持\n * 提供 SVG 元素的创建和属性处理\n */\n\nimport { warn } from '@fluxion-ui/shared'\n\n/**\n * SVG 命名空间\n */\nexport const SVG_NAMESPACE = 'http://www.w3.org/2000/svg'\n\n/**\n * XLINK 命名空间\n */\nexport const XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink'\n\n/**\n * XML 命名空间\n */\nexport const XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace'\n\n/**\n * SVG 标签列表\n */\nconst SVG_TAGS = new Set([\n 'svg',\n 'animate',\n 'animateMotion',\n 'animateTransform',\n 'circle',\n 'clipPath',\n 'defs',\n 'desc',\n 'ellipse',\n 'feBlend',\n 'feColorMatrix',\n 'feComponentTransfer',\n 'feComposite',\n 'feConvolveMatrix',\n 'feDiffuseLighting',\n 'feDisplacementMap',\n 'feDistantLight',\n 'feDropShadow',\n 'feFlood',\n 'feFuncA',\n 'feFuncB',\n 'feFuncG',\n 'feFuncR',\n 'feGaussianBlur',\n 'feImage',\n 'feMerge',\n 'feMergeNode',\n 'feMorphology',\n 'feOffset',\n 'fePointLight',\n 'feSpecularLighting',\n 'feSpotLight',\n 'feTile',\n 'feTurbulence',\n 'filter',\n 'foreignObject',\n 'g',\n 'image',\n 'line',\n 'linearGradient',\n 'marker',\n 'mask',\n 'metadata',\n 'mpath',\n 'path',\n 'pattern',\n 'polygon',\n 'polyline',\n 'radialGradient',\n 'rect',\n 'set',\n 'stop',\n 'switch',\n 'symbol',\n 'text',\n 'textPath',\n 'tspan',\n 'use',\n 'view'\n])\n\n/**\n * 判断是否为 SVG 标签\n * @param tag 标签名\n */\nexport function isSVGTag(tag: string): boolean {\n return SVG_TAGS.has(tag)\n}\n\n/**\n * 创建 SVG 元素\n * @param tag 标签名\n */\nexport function createSVGElement(tag: string): SVGElement {\n if (!tag) {\n warn('createSVGElement: 标签名不能为空')\n tag = 'svg'\n }\n return document.createElementNS(SVG_NAMESPACE, tag) as SVGElement\n}\n\n/**\n * 需要使用 XLINK 命名空间的属性\n */\nconst XLINK_ATTRIBUTES = new Set([\n 'xlink:href',\n 'xlink:title',\n 'xlink:role',\n 'xlink:arcrole',\n 'xlink:show',\n 'xlink:actuate',\n 'xlink:type',\n 'xlink:label'\n])\n\n/**\n * 判断是否为 XLINK 属性\n * @param attr 属性名\n */\nexport function isXlinkAttr(attr: string): boolean {\n return XLINK_ATTRIBUTES.has(attr)\n}\n\n/**\n * 需要使用 XML 命名空间的属性\n */\nconst XML_ATTRIBUTES = new Set([\n 'xml:space',\n 'xml:lang',\n 'xml:base'\n])\n\n/**\n * 判断是否为 XML 属性\n * @param attr 属性名\n */\nexport function isXMLAttr(attr: string): boolean {\n return XML_ATTRIBUTES.has(attr)\n}\n\n/**\n * 设置 SVG 属性\n * @param el SVG 元素\n * @param key 属性名\n * @param value 属性值\n */\nexport function setSVGAttr(\n el: SVGElement,\n key: string,\n value: any\n): void {\n if (!el) {\n warn('setSVGAttr: 元素不能为空')\n return\n }\n\n if (value == null || value === false) {\n // 移除属性\n el.removeAttribute(key)\n return\n }\n\n // XLINK 属性\n if (isXlinkAttr(key)) {\n // 提取本地名称:xlink:href -> href\n const localName = key.slice(6) // 'xlink:'.length = 6\n el.setAttributeNS(XLINK_NAMESPACE, localName, value)\n return\n }\n\n // XML 属性\n if (isXMLAttr(key)) {\n // 提取本地名称:xml:space -> space\n const localName = key.slice(4) // 'xml:'.length = 4\n el.setAttributeNS(XML_NAMESPACE, localName, value)\n return\n }\n\n // 普通属性(但在 SVG 命名空间中)\n el.setAttribute(key, value)\n}\n\n/**\n * 获取 SVG 元素的命名空间\n * @param el 元素\n */\nexport function getSVGNamespace(el: Element): string | null {\n return el.namespaceURI\n}\n\n/**\n * 判断元素是否在 SVG 上下文中\n * @param el 元素\n */\nexport function isInSVG(el: Element): boolean {\n let current: Element | null = el\n while (current) {\n if (current.tagName.toLowerCase() === 'svg') {\n return true\n }\n current = current.parentElement\n }\n return false\n}","/**\n * DOM 渲染器\n * 组合 nodeOps 和 patchProp,创建平台渲染器\n */\n\nimport {\n createRenderer,\n setAppRenderer,\n setRenderRenderer\n} from '@fluxion-ui/runtime-core'\nimport { nodeOps } from './nodeOps'\nimport { patchProp } from './patchProp'\nimport { isSVGTag, createSVGElement } from './modules/svg'\nimport type { RendererOptions } from '@fluxion-ui/runtime-core'\n\n/**\n * 扩展的渲染器选项\n * 支持 SVG 元素创建\n */\nconst rendererOptions: RendererOptions = {\n ...nodeOps,\n patchProp,\n\n /**\n * 重写 createElement 以支持 SVG\n * @param tag 标签名\n */\n createElement(tag: string): Element {\n // 检查是否为 SVG 标签\n if (isSVGTag(tag)) {\n return createSVGElement(tag)\n }\n return nodeOps.createElement(tag)\n }\n}\n\n// 创建渲染器\nconst renderer = createRenderer(rendererOptions)\n\n// 获取 render 和 createApp\nconst { render, createApp } = renderer\n\n// 注入渲染器到 runtime-core\nsetAppRenderer({ createApp })\nsetRenderRenderer({ render })\n\n// 导出渲染器 API\nexport { render, createApp }"],"names":["createElement","tag","document","warn","createText","text","createTextNode","createComment","insert","child","parent","anchor","insertBefore","remove","parentNode","removeChild","setElementText","el","textContent","setText","node","nodeValue","nextSibling","getTagName","tagName","toLowerCase","nodeOps","VEI_KEY","isEventKey","key","startsWith","length","test","normalizeEventName","slice","patchEvent","value","prevValue","eventName","invokers","existingInvoker","removeEventListener","invoker","event","isArray","i","handler","isFunction","attached","createInvokerWrapper","Date","now","addEventListener","DOM_PROP_KEYS","Set","isDOMProp","has","patchDOMProp","newValue","innerHTML","className","isString","normalizeClass","trim","values","classes","push","join","normalizeArrayClass","isObject","obj","normalizeObjectClass","patchClass","normalizedClass","camelize","name","replace","_","c","toUpperCase","hyphenate","normalizeStyleValue","unitlessProperties","String","setStyleProperty","style","removeProperty","normalized","setProperty","normalizeStyle","styleString","result","styles","split","colonIndex","indexOf","parseStyleString","patchStyle","setAttribute","styleStr","parts","objectToStyleString","cssText","newStyle","oldStyle","hasOwn","BOOLEAN_ATTRIBUTES","isBooleanAttr","SPECIAL_ATTRIBUTES","isSpecialAttr","patchAttr","lowerKey","removeAttribute","patchProp","SVG_NAMESPACE","XLINK_NAMESPACE","XML_NAMESPACE","SVG_TAGS","isSVGTag","createSVGElement","createElementNS","XLINK_ATTRIBUTES","isXlinkAttr","attr","XML_ATTRIBUTES","isXMLAttr","setSVGAttr","localName","setAttributeNS","getSVGNamespace","namespaceURI","isInSVG","current","parentElement","renderer","createRenderer","render","createApp","setAppRenderer","setRenderRenderer"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fluxion-ui/runtime-dom",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "Fluxion DOM runtime renderer",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/runtime-dom.cjs",
|
|
7
|
+
"module": "./dist/runtime-dom.js",
|
|
8
|
+
"types": "./dist/runtime-dom.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/runtime-dom.js",
|
|
12
|
+
"require": "./dist/runtime-dom.cjs",
|
|
13
|
+
"types": "./dist/runtime-dom.d.ts"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/AiFu-o/fluxion"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"fluxion",
|
|
25
|
+
"runtime",
|
|
26
|
+
"dom",
|
|
27
|
+
"renderer"
|
|
28
|
+
],
|
|
29
|
+
"author": "Fluxion Team",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@fluxion-ui/runtime-core": "0.0.3",
|
|
33
|
+
"@fluxion-ui/shared": "0.0.3"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@fluxion-ui/reactivity": "0.0.3"
|
|
37
|
+
}
|
|
38
|
+
}
|