@weapp-vite/web 1.3.16 → 1.3.18
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/README.md +2 -2
- package/dist/compiler/wxml/attributes.mjs +6 -6
- package/dist/compiler/wxml/attributes.mjs.map +1 -1
- package/dist/compiler/wxml/renderer.mjs +6 -6
- package/dist/compiler/wxml/renderer.mjs.map +1 -1
- package/dist/compiler/wxml/specialNodes.mjs +6 -5
- package/dist/compiler/wxml/specialNodes.mjs.map +1 -1
- package/dist/plugin/files.mjs +1 -1
- package/dist/plugin/files.mjs.map +1 -1
- package/dist/runtime/component/constants.mjs +7 -2
- package/dist/runtime/component/constants.mjs.map +1 -1
- package/dist/runtime/component/dom.mjs +9 -3
- package/dist/runtime/component/dom.mjs.map +1 -1
- package/dist/runtime/component/events.mjs +5 -4
- package/dist/runtime/component/events.mjs.map +1 -1
- package/dist/runtime/legacyTemplate/dom.mjs +10 -65
- package/dist/runtime/legacyTemplate/dom.mjs.map +1 -1
- package/dist/runtime/legacyTemplate/index.mjs +7 -6
- package/dist/runtime/legacyTemplate/index.mjs.map +1 -1
- package/dist/runtime/polyfill/async.mjs +3 -3
- package/dist/runtime/polyfill/async.mjs.map +1 -1
- package/dist/runtime/polyfill/authApi.mjs +16 -16
- package/dist/runtime/polyfill/authApi.mjs.map +1 -1
- package/dist/runtime/polyfill/background.mjs +4 -4
- package/dist/runtime/polyfill/background.mjs.map +1 -1
- package/dist/runtime/polyfill/capability.mjs +6 -3
- package/dist/runtime/polyfill/capability.mjs.map +1 -1
- package/dist/runtime/polyfill/cloud.mjs +3 -3
- package/dist/runtime/polyfill/cloud.mjs.map +1 -1
- package/dist/runtime/polyfill/deviceApi.mjs +5 -5
- package/dist/runtime/polyfill/deviceApi.mjs.map +1 -1
- package/dist/runtime/polyfill/deviceAuthSystemApi.d.mts +2 -2
- package/dist/runtime/polyfill/deviceAuthSystemApi.mjs.map +1 -1
- package/dist/runtime/polyfill/fileSystemManager.mjs +7 -7
- package/dist/runtime/polyfill/fileSystemManager.mjs.map +1 -1
- package/dist/runtime/polyfill/index.mjs +21 -10
- package/dist/runtime/polyfill/index.mjs.map +1 -1
- package/dist/runtime/polyfill/interactionApi.mjs +8 -8
- package/dist/runtime/polyfill/interactionApi.mjs.map +1 -1
- package/dist/runtime/polyfill/locationApi.mjs +21 -21
- package/dist/runtime/polyfill/locationApi.mjs.map +1 -1
- package/dist/runtime/polyfill/mediaApi/file.mjs +12 -12
- package/dist/runtime/polyfill/mediaApi/file.mjs.map +1 -1
- package/dist/runtime/polyfill/mediaApi/info.mjs +7 -7
- package/dist/runtime/polyfill/mediaApi/info.mjs.map +1 -1
- package/dist/runtime/polyfill/mediaApi/picker.mjs +11 -11
- package/dist/runtime/polyfill/mediaApi/picker.mjs.map +1 -1
- package/dist/runtime/polyfill/mediaApi/preview.mjs +7 -7
- package/dist/runtime/polyfill/mediaApi/preview.mjs.map +1 -1
- package/dist/runtime/polyfill/mediaApi/process.mjs +6 -6
- package/dist/runtime/polyfill/mediaApi/process.mjs.map +1 -1
- package/dist/runtime/polyfill/menuApi.mjs +13 -13
- package/dist/runtime/polyfill/menuApi.mjs.map +1 -1
- package/dist/runtime/polyfill/navigationBarRuntime.mjs +5 -4
- package/dist/runtime/polyfill/navigationBarRuntime.mjs.map +1 -1
- package/dist/runtime/polyfill/network/requestBridge.mjs +7 -7
- package/dist/runtime/polyfill/network/requestBridge.mjs.map +1 -1
- package/dist/runtime/polyfill/platformApi.mjs +2 -2
- package/dist/runtime/polyfill/platformApi.mjs.map +1 -1
- package/dist/runtime/polyfill/runtimeCapabilityApi.mjs +2 -2
- package/dist/runtime/polyfill/runtimeCapabilityApi.mjs.map +1 -1
- package/dist/runtime/polyfill/runtimeDataApi.d.mts +7 -7
- package/dist/runtime/polyfill/runtimeDataApi.mjs +5 -5
- package/dist/runtime/polyfill/runtimeDataApi.mjs.map +1 -1
- package/dist/runtime/polyfill/runtimeOps.mjs +10 -10
- package/dist/runtime/polyfill/runtimeOps.mjs.map +1 -1
- package/dist/runtime/polyfill/storageAsync.mjs +12 -12
- package/dist/runtime/polyfill/storageAsync.mjs.map +1 -1
- package/dist/runtime/polyfill/systemApi.mjs +3 -3
- package/dist/runtime/polyfill/systemApi.mjs.map +1 -1
- package/dist/runtime/polyfill/types/base.d.mts +5 -5
- package/dist/runtime/polyfill/types/common.d.mts +22 -22
- package/dist/runtime/polyfill/types/locationRuntime.d.mts +27 -27
- package/dist/runtime/polyfill/types/mediaAuth.d.mts +30 -30
- package/dist/runtime/polyfill/types/platformRuntime.d.mts +13 -13
- package/dist/runtime/polyfill/types/systemAuth.d.mts +11 -11
- package/dist/runtime/polyfill/uiFeedback.mjs +4 -4
- package/dist/runtime/polyfill/uiFeedback.mjs.map +1 -1
- package/dist/runtime/polyfill/uiMediaApi.d.mts +2 -2
- package/dist/runtime/polyfill/uiMediaApi.mjs.map +1 -1
- package/dist/shared/wxml.mjs +29 -10
- package/dist/shared/wxml.mjs.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
实验性的 H5 运行时与工具集,为 `weapp-vite` 工程提供最小化的浏览器适配能力:
|
|
4
4
|
|
|
5
5
|
- 将 `wxml` 模板编译为渲染函数,并在 Web Components 中渲染
|
|
6
|
-
- 支持 `wx
|
|
6
|
+
- 支持 `wx` / `a` / `tt` / `s` 前缀的条件与循环指令,以及插值语法等常见模板语法糖
|
|
7
7
|
- 将小程序 `Page` / `Component` 映射为自定义元素,Shadow DOM 隔离样式与事件
|
|
8
8
|
- 事件桥接(如 `bindtap` → `click`),保留 `this.setData`、`this.triggerEvent` 等调用体验
|
|
9
|
-
- `wx.navigateTo` / `
|
|
9
|
+
- 提供宿主中立的小程序桥,并兼容 `wx.navigateTo` / `my.navigateTo` / `tt.navigateTo` 等路由调用,以及 `getCurrentPages`、`onLoad`、`onShow`、`onHide`、`onUnload` 生命周期
|
|
10
10
|
- `App` 级别的 `onLaunch` / `onShow` 回调、`getApp` 全局实例访问
|
|
11
11
|
- `wxss` → `css` 的基础转换,默认按 `1rpx = 0.5px`
|
|
12
12
|
- 提供 Vite 插件,自动把 `.wxml` / `.wxss` 转换为 Web 侧模块
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { CONTROL_ATTRS, EVENT_KIND_ALIAS, EVENT_PREFIX_RE, normalizeAttributeName } from "../../shared/wxml.mjs";
|
|
1
|
+
import { CONTROL_ATTRS, EVENT_KIND_ALIAS, EVENT_PREFIX_RE, hasControlAttribute, normalizeAttributeName, resolveControlAttributeValue } from "../../shared/wxml.mjs";
|
|
2
2
|
import { buildExpression, parseInterpolations } from "./interpolation.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/compiler/wxml/attributes.ts
|
|
5
5
|
function extractFor(attribs) {
|
|
6
|
-
const expr = attribs
|
|
7
|
-
const itemName = attribs
|
|
8
|
-
let indexName = attribs
|
|
9
|
-
const key = attribs
|
|
6
|
+
const expr = resolveControlAttributeValue(attribs, "for");
|
|
7
|
+
const itemName = resolveControlAttributeValue(attribs, "for-item")?.trim() || "item";
|
|
8
|
+
let indexName = resolveControlAttributeValue(attribs, "for-index")?.trim() || "index";
|
|
9
|
+
const key = resolveControlAttributeValue(attribs, "key");
|
|
10
10
|
const restAttribs = {};
|
|
11
11
|
for (const [name, value] of Object.entries(attribs)) {
|
|
12
12
|
if (CONTROL_ATTRS.has(name)) continue;
|
|
@@ -24,7 +24,7 @@ function extractFor(attribs) {
|
|
|
24
24
|
function isConditionalElement(node) {
|
|
25
25
|
if (node.type !== "element") return false;
|
|
26
26
|
const attribs = node.attribs ?? {};
|
|
27
|
-
return "
|
|
27
|
+
return hasControlAttribute(attribs, "if") || hasControlAttribute(attribs, "elif") || hasControlAttribute(attribs, "else");
|
|
28
28
|
}
|
|
29
29
|
function stripControlAttributes(attribs) {
|
|
30
30
|
const result = {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attributes.mjs","names":[],"sources":["../../../src/compiler/wxml/attributes.ts"],"sourcesContent":["import type { RenderElementNode, RenderNode } from './types'\nimport {
|
|
1
|
+
{"version":3,"file":"attributes.mjs","names":[],"sources":["../../../src/compiler/wxml/attributes.ts"],"sourcesContent":["import type { RenderElementNode, RenderNode } from './types'\nimport {\n CONTROL_ATTRS,\n EVENT_KIND_ALIAS,\n EVENT_PREFIX_RE,\n hasControlAttribute,\n normalizeAttributeName,\n resolveControlAttributeValue,\n} from '../../shared/wxml'\nimport { buildExpression, parseInterpolations } from './interpolation'\n\nexport function extractFor(attribs: Record<string, string>) {\n const expr = resolveControlAttributeValue(attribs, 'for')\n const itemName = resolveControlAttributeValue(attribs, 'for-item')?.trim() || 'item'\n let indexName = resolveControlAttributeValue(attribs, 'for-index')?.trim() || 'index'\n const key = resolveControlAttributeValue(attribs, 'key')\n const restAttribs: Record<string, string> = {}\n for (const [name, value] of Object.entries(attribs)) {\n if (CONTROL_ATTRS.has(name)) {\n continue\n }\n restAttribs[name] = value\n }\n if (itemName === indexName) {\n indexName = `${indexName}Index`\n }\n return { expr, itemName, indexName, key, restAttribs }\n}\n\nexport function isConditionalElement(node: RenderNode): node is RenderElementNode {\n if (node.type !== 'element') {\n return false\n }\n const attribs = node.attribs ?? {}\n return hasControlAttribute(attribs, 'if')\n || hasControlAttribute(attribs, 'elif')\n || hasControlAttribute(attribs, 'else')\n}\n\nexport function stripControlAttributes(attribs: Record<string, string>) {\n const result: Record<string, string> = {}\n for (const [name, value] of Object.entries(attribs)) {\n if (!CONTROL_ATTRS.has(name)) {\n result[name] = value\n }\n }\n return result\n}\n\nfunction parseEventAttribute(name: string) {\n if (name.includes(':')) {\n const [prefix, rawEvent] = name.split(':', 2)\n return { prefix, rawEvent }\n }\n const match = EVENT_PREFIX_RE.exec(name)\n if (!match) {\n return undefined\n }\n return { prefix: name.slice(0, name.length - match[1].length), rawEvent: match[1] }\n}\n\nexport function resolveComponentTagName(name: string, componentTags?: Record<string, string>) {\n if (!componentTags) {\n return undefined\n }\n return componentTags[name] ?? componentTags[name.toLowerCase()]\n}\n\nconst PROPERTY_BIND_EXCLUSIONS = new Set(['class', 'style', 'id', 'slot'])\n\nfunction shouldBindAsProperty(name: string) {\n if (PROPERTY_BIND_EXCLUSIONS.has(name)) {\n return false\n }\n if (name.startsWith('data-') || name.startsWith('aria-')) {\n return false\n }\n return true\n}\n\nfunction normalizePropertyName(name: string) {\n return name.replace(/-([a-z])/g, (_, char: string) => char.toUpperCase())\n}\n\nexport function renderAttributes(\n attribs: Record<string, string>,\n scopeVar: string,\n wxsVar: string,\n options?: { skipControl?: boolean, preferProperty?: boolean },\n) {\n let buffer = ''\n for (const [rawName, rawValue] of Object.entries(attribs)) {\n if (options?.skipControl && CONTROL_ATTRS.has(rawName)) {\n continue\n }\n const eventInfo = parseEventAttribute(rawName)\n if (eventInfo) {\n const event = eventInfo.rawEvent.toLowerCase()\n const handlerExpr = buildExpression(parseInterpolations(rawValue ?? ''), scopeVar, wxsVar)\n const domEvent = EVENT_KIND_ALIAS[event] ?? event\n const flags = {\n catch: eventInfo.prefix.includes('catch'),\n capture: eventInfo.prefix.includes('capture'),\n }\n buffer += ` @${domEvent}=\\${ctx.event(${JSON.stringify(event)}, ${handlerExpr}, ${scopeVar}, ${wxsVar}, ${JSON.stringify(flags)})}`\n continue\n }\n const useProperty = options?.preferProperty && shouldBindAsProperty(rawName)\n const name = useProperty ? normalizePropertyName(rawName) : normalizeAttributeName(rawName)\n const expr = buildExpression(parseInterpolations(rawValue ?? ''), scopeVar, wxsVar)\n buffer += ` ${useProperty ? '.' : ''}${name}=\\${${expr}}`\n }\n return buffer\n}\n"],"mappings":";;;;AAWA,SAAgB,WAAW,SAAiC;CAC1D,MAAM,OAAO,6BAA6B,SAAS,MAAM;CACzD,MAAM,WAAW,6BAA6B,SAAS,WAAW,EAAE,MAAM,IAAI;CAC9E,IAAI,YAAY,6BAA6B,SAAS,YAAY,EAAE,MAAM,IAAI;CAC9E,MAAM,MAAM,6BAA6B,SAAS,MAAM;CACxD,MAAM,cAAsC,EAAE;AAC9C,MAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,QAAQ,EAAE;AACnD,MAAI,cAAc,IAAI,KAAK,CACzB;AAEF,cAAY,QAAQ;;AAEtB,KAAI,aAAa,UACf,aAAY,GAAG,UAAU;AAE3B,QAAO;EAAE;EAAM;EAAU;EAAW;EAAK;EAAa;;AAGxD,SAAgB,qBAAqB,MAA6C;AAChF,KAAI,KAAK,SAAS,UAChB,QAAO;CAET,MAAM,UAAU,KAAK,WAAW,EAAE;AAClC,QAAO,oBAAoB,SAAS,KAAK,IACpC,oBAAoB,SAAS,OAAO,IACpC,oBAAoB,SAAS,OAAO;;AAG3C,SAAgB,uBAAuB,SAAiC;CACtE,MAAM,SAAiC,EAAE;AACzC,MAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,QAAQ,CACjD,KAAI,CAAC,cAAc,IAAI,KAAK,CAC1B,QAAO,QAAQ;AAGnB,QAAO;;AAGT,SAAS,oBAAoB,MAAc;AACzC,KAAI,KAAK,SAAS,IAAI,EAAE;EACtB,MAAM,CAAC,QAAQ,YAAY,KAAK,MAAM,KAAK,EAAE;AAC7C,SAAO;GAAE;GAAQ;GAAU;;CAE7B,MAAM,QAAQ,gBAAgB,KAAK,KAAK;AACxC,KAAI,CAAC,MACH;AAEF,QAAO;EAAE,QAAQ,KAAK,MAAM,GAAG,KAAK,SAAS,MAAM,GAAG,OAAO;EAAE,UAAU,MAAM;EAAI;;AAGrF,SAAgB,wBAAwB,MAAc,eAAwC;AAC5F,KAAI,CAAC,cACH;AAEF,QAAO,cAAc,SAAS,cAAc,KAAK,aAAa;;AAGhE,MAAM,2BAA2B,IAAI,IAAI;CAAC;CAAS;CAAS;CAAM;CAAO,CAAC;AAE1E,SAAS,qBAAqB,MAAc;AAC1C,KAAI,yBAAyB,IAAI,KAAK,CACpC,QAAO;AAET,KAAI,KAAK,WAAW,QAAQ,IAAI,KAAK,WAAW,QAAQ,CACtD,QAAO;AAET,QAAO;;AAGT,SAAS,sBAAsB,MAAc;AAC3C,QAAO,KAAK,QAAQ,cAAc,GAAG,SAAiB,KAAK,aAAa,CAAC;;AAG3E,SAAgB,iBACd,SACA,UACA,QACA,SACA;CACA,IAAI,SAAS;AACb,MAAK,MAAM,CAAC,SAAS,aAAa,OAAO,QAAQ,QAAQ,EAAE;AACzD,MAAI,SAAS,eAAe,cAAc,IAAI,QAAQ,CACpD;EAEF,MAAM,YAAY,oBAAoB,QAAQ;AAC9C,MAAI,WAAW;GACb,MAAM,QAAQ,UAAU,SAAS,aAAa;GAC9C,MAAM,cAAc,gBAAgB,oBAAoB,YAAY,GAAG,EAAE,UAAU,OAAO;GAC1F,MAAM,WAAW,iBAAiB,UAAU;GAC5C,MAAM,QAAQ;IACZ,OAAO,UAAU,OAAO,SAAS,QAAQ;IACzC,SAAS,UAAU,OAAO,SAAS,UAAU;IAC9C;AACD,aAAU,KAAK,SAAS,gBAAgB,KAAK,UAAU,MAAM,CAAC,IAAI,YAAY,IAAI,SAAS,IAAI,OAAO,IAAI,KAAK,UAAU,MAAM,CAAC;AAChI;;EAEF,MAAM,cAAc,SAAS,kBAAkB,qBAAqB,QAAQ;EAC5E,MAAM,OAAO,cAAc,sBAAsB,QAAQ,GAAG,uBAAuB,QAAQ;EAC3F,MAAM,OAAO,gBAAgB,oBAAoB,YAAY,GAAG,EAAE,UAAU,OAAO;AACnF,YAAU,IAAI,cAAc,MAAM,KAAK,KAAK,MAAM,KAAK;;AAEzD,QAAO"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SELF_CLOSING_TAGS, normalizeTagName } from "../../shared/wxml.mjs";
|
|
1
|
+
import { SELF_CLOSING_TAGS, hasControlAttribute, normalizeTagName, resolveControlAttributeValue } from "../../shared/wxml.mjs";
|
|
2
2
|
import { buildExpression, buildTemplateDataExpression, parseInterpolations } from "./interpolation.mjs";
|
|
3
3
|
import { extractFor, isConditionalElement, renderAttributes, resolveComponentTagName, stripControlAttributes } from "./attributes.mjs";
|
|
4
4
|
|
|
@@ -27,14 +27,14 @@ var Renderer = class {
|
|
|
27
27
|
const candidate = nodes[cursor];
|
|
28
28
|
if (!isConditionalElement(candidate)) break;
|
|
29
29
|
const attribs = candidate.attribs ?? {};
|
|
30
|
-
if (branches.length === 0 && !("
|
|
31
|
-
if (branches.length > 0 && !("
|
|
30
|
+
if (branches.length === 0 && !hasControlAttribute(attribs, "if")) break;
|
|
31
|
+
if (branches.length > 0 && !hasControlAttribute(attribs, "elif") && !hasControlAttribute(attribs, "else")) break;
|
|
32
32
|
branches.push({
|
|
33
33
|
node: candidate,
|
|
34
34
|
attribs
|
|
35
35
|
});
|
|
36
36
|
cursor += 1;
|
|
37
|
-
if ("
|
|
37
|
+
if (hasControlAttribute(attribs, "else")) break;
|
|
38
38
|
}
|
|
39
39
|
if (!branches.length) {
|
|
40
40
|
const node = nodes[startIndex];
|
|
@@ -51,11 +51,11 @@ var Renderer = class {
|
|
|
51
51
|
for (let index = branches.length - 1; index >= 0; index -= 1) {
|
|
52
52
|
const { node, attribs } = branches[index];
|
|
53
53
|
const cleanedAttribs = stripControlAttributes(attribs);
|
|
54
|
-
if ("
|
|
54
|
+
if (hasControlAttribute(attribs, "else")) {
|
|
55
55
|
expr = this.renderElement(node, scopeVar, wxsVar, componentTags, { overrideAttribs: cleanedAttribs });
|
|
56
56
|
continue;
|
|
57
57
|
}
|
|
58
|
-
const conditionExpr = attribs
|
|
58
|
+
const conditionExpr = resolveControlAttributeValue(attribs, "if") ?? resolveControlAttributeValue(attribs, "elif") ?? "";
|
|
59
59
|
const rendered = this.renderElement(node, scopeVar, wxsVar, componentTags, { overrideAttribs: cleanedAttribs });
|
|
60
60
|
expr = `(${buildExpression(parseInterpolations(conditionExpr), scopeVar, wxsVar)} ? ${rendered} : ${expr})`;
|
|
61
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.mjs","names":[],"sources":["../../../src/compiler/wxml/renderer.ts"],"sourcesContent":["import type { RenderElementNode, RenderNode } from './types'\nimport { normalizeTagName, SELF_CLOSING_TAGS } from '../../shared/wxml'\nimport {\n extractFor,\n isConditionalElement,\n renderAttributes,\n resolveComponentTagName,\n stripControlAttributes,\n} from './attributes'\nimport { buildExpression, buildTemplateDataExpression, parseInterpolations } from './interpolation'\n\ninterface RenderElementOptions {\n skipFor?: boolean\n overrideAttribs?: Record<string, string>\n}\n\nexport class Renderer {\n renderNodes(\n nodes: RenderNode[],\n scopeVar: string,\n wxsVar: string,\n componentTags?: Record<string, string>,\n ): string {\n const parts: string[] = []\n for (let index = 0; index < nodes.length; index += 1) {\n const node = nodes[index]\n if (isConditionalElement(node)) {\n const { rendered, endIndex } = this.renderConditionalSequence(\n nodes,\n index,\n scopeVar,\n wxsVar,\n componentTags,\n )\n parts.push(rendered)\n index = endIndex\n continue\n }\n parts.push(this.renderNode(node, scopeVar, wxsVar, componentTags))\n }\n if (parts.length === 0) {\n return '\"\"'\n }\n if (parts.length === 1) {\n return parts[0]!\n }\n return `[${parts.join(', ')}]`\n }\n\n private renderConditionalSequence(\n nodes: RenderNode[],\n startIndex: number,\n scopeVar: string,\n wxsVar: string,\n componentTags?: Record<string, string>,\n ): { rendered: string, endIndex: number } {\n const branches: Array<{ node: RenderElementNode, attribs: Record<string, string> }> = []\n let cursor = startIndex\n while (cursor < nodes.length) {\n const candidate = nodes[cursor]\n if (!isConditionalElement(candidate)) {\n break\n }\n const attribs = candidate.attribs ?? {}\n if (branches.length === 0 && !('wx:if' in attribs)) {\n break\n }\n if (branches.length > 0 && !('wx:elif' in attribs) && !('wx:else' in attribs)) {\n break\n }\n branches.push({ node: candidate, attribs })\n cursor += 1\n if ('wx:else' in attribs) {\n break\n }\n }\n if (!branches.length) {\n const node = nodes[startIndex]\n if (!node) {\n return { rendered: '\"\"', endIndex: startIndex }\n }\n return { rendered: this.renderNode(node, scopeVar, wxsVar, componentTags), endIndex: startIndex }\n }\n let expr = '\"\"'\n for (let index = branches.length - 1; index >= 0; index -= 1) {\n const { node, attribs } = branches[index]!\n const cleanedAttribs = stripControlAttributes(attribs)\n if ('wx:else' in attribs) {\n expr = this.renderElement(node, scopeVar, wxsVar, componentTags, { overrideAttribs: cleanedAttribs })\n continue\n }\n const conditionExpr = attribs['wx:if'] ?? attribs['wx:elif'] ?? ''\n const rendered = this.renderElement(node, scopeVar, wxsVar, componentTags, { overrideAttribs: cleanedAttribs })\n const condition = buildExpression(parseInterpolations(conditionExpr), scopeVar, wxsVar)\n expr = `(${condition} ? ${rendered} : ${expr})`\n }\n return { rendered: expr, endIndex: startIndex + branches.length - 1 }\n }\n\n private renderNode(\n node: RenderNode,\n scopeVar: string,\n wxsVar: string,\n componentTags?: Record<string, string>,\n ): string {\n if (node.type === 'text') {\n const parts = parseInterpolations(node.data ?? '')\n return buildExpression(parts, scopeVar, wxsVar)\n }\n if (node.type === 'element') {\n if (node.name === 'template' && node.attribs?.is) {\n return this.renderTemplateInvoke(node, scopeVar, wxsVar)\n }\n return this.renderElement(node, scopeVar, wxsVar, componentTags)\n }\n return '\"\"'\n }\n\n private renderTemplateInvoke(\n node: RenderElementNode,\n scopeVar: string,\n wxsVar: string,\n ): string {\n const attribs = node.attribs ?? {}\n const isExpr = buildExpression(parseInterpolations(attribs.is ?? ''), scopeVar, wxsVar)\n const dataExpr = attribs.data\n ? buildTemplateDataExpression(attribs.data, scopeVar, wxsVar)\n : undefined\n const scopeExpr = dataExpr\n ? `ctx.mergeScope(${scopeVar}, ${dataExpr})`\n : scopeVar\n return `ctx.renderTemplate(__templates, ${isExpr}, ${scopeExpr}, ctx)`\n }\n\n private renderElement(\n node: RenderElementNode,\n scopeVar: string,\n wxsVar: string,\n componentTags?: Record<string, string>,\n options: RenderElementOptions = {},\n ): string {\n const attribs = options.overrideAttribs ?? node.attribs ?? {}\n if (!options.skipFor) {\n const forInfo = extractFor(node.attribs ?? {})\n if (forInfo.expr) {\n const listExpression = buildExpression(parseInterpolations(forInfo.expr), scopeVar, wxsVar)\n const listExpr = `ctx.normalizeList(${listExpression})`\n const itemVar = forInfo.itemName\n const indexVar = forInfo.indexName\n const scopeExpr = `ctx.createScope(${scopeVar}, { ${itemVar}: ${itemVar}, ${indexVar}: ${indexVar} })`\n const itemRender = this.renderElement(\n node,\n '__scope',\n wxsVar,\n componentTags,\n { skipFor: true, overrideAttribs: forInfo.restAttribs },\n )\n const keyExpr = `ctx.key(${JSON.stringify(forInfo.key ?? '')}, ${itemVar}, ${indexVar}, ${scopeExpr}, ${wxsVar})`\n return `repeat(${listExpr}, (${itemVar}, ${indexVar}) => ${keyExpr}, (${itemVar}, ${indexVar}) => { const __scope = ${scopeExpr}; return ${itemRender}; })`\n }\n }\n\n const customTag = resolveComponentTagName(node.name ?? '', componentTags)\n const tagName = customTag ?? normalizeTagName(node.name ?? '')\n if (tagName === '#fragment') {\n return this.renderNodes(node.children ?? [], scopeVar, wxsVar, componentTags)\n }\n\n const attrs = renderAttributes(attribs, scopeVar, wxsVar, {\n skipControl: true,\n preferProperty: Boolean(customTag),\n })\n const childNodes = node.children ?? []\n const children = childNodes\n .map(child => `\\${${this.renderNode(child, scopeVar, wxsVar, componentTags)}}`)\n .join('')\n if (SELF_CLOSING_TAGS.has(tagName) && childNodes.length === 0) {\n return `html\\`<${tagName}${attrs} />\\``\n }\n return `html\\`<${tagName}${attrs}>${children}</${tagName}>\\``\n }\n}\n\nexport const renderer = new Renderer()\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"renderer.mjs","names":[],"sources":["../../../src/compiler/wxml/renderer.ts"],"sourcesContent":["import type { RenderElementNode, RenderNode } from './types'\nimport {\n hasControlAttribute,\n normalizeTagName,\n resolveControlAttributeValue,\n SELF_CLOSING_TAGS,\n} from '../../shared/wxml'\nimport {\n extractFor,\n isConditionalElement,\n renderAttributes,\n resolveComponentTagName,\n stripControlAttributes,\n} from './attributes'\nimport { buildExpression, buildTemplateDataExpression, parseInterpolations } from './interpolation'\n\ninterface RenderElementOptions {\n skipFor?: boolean\n overrideAttribs?: Record<string, string>\n}\n\nexport class Renderer {\n renderNodes(\n nodes: RenderNode[],\n scopeVar: string,\n wxsVar: string,\n componentTags?: Record<string, string>,\n ): string {\n const parts: string[] = []\n for (let index = 0; index < nodes.length; index += 1) {\n const node = nodes[index]\n if (isConditionalElement(node)) {\n const { rendered, endIndex } = this.renderConditionalSequence(\n nodes,\n index,\n scopeVar,\n wxsVar,\n componentTags,\n )\n parts.push(rendered)\n index = endIndex\n continue\n }\n parts.push(this.renderNode(node, scopeVar, wxsVar, componentTags))\n }\n if (parts.length === 0) {\n return '\"\"'\n }\n if (parts.length === 1) {\n return parts[0]!\n }\n return `[${parts.join(', ')}]`\n }\n\n private renderConditionalSequence(\n nodes: RenderNode[],\n startIndex: number,\n scopeVar: string,\n wxsVar: string,\n componentTags?: Record<string, string>,\n ): { rendered: string, endIndex: number } {\n const branches: Array<{ node: RenderElementNode, attribs: Record<string, string> }> = []\n let cursor = startIndex\n while (cursor < nodes.length) {\n const candidate = nodes[cursor]\n if (!isConditionalElement(candidate)) {\n break\n }\n const attribs = candidate.attribs ?? {}\n if (branches.length === 0 && !hasControlAttribute(attribs, 'if')) {\n break\n }\n if (branches.length > 0 && !hasControlAttribute(attribs, 'elif') && !hasControlAttribute(attribs, 'else')) {\n break\n }\n branches.push({ node: candidate, attribs })\n cursor += 1\n if (hasControlAttribute(attribs, 'else')) {\n break\n }\n }\n if (!branches.length) {\n const node = nodes[startIndex]\n if (!node) {\n return { rendered: '\"\"', endIndex: startIndex }\n }\n return { rendered: this.renderNode(node, scopeVar, wxsVar, componentTags), endIndex: startIndex }\n }\n let expr = '\"\"'\n for (let index = branches.length - 1; index >= 0; index -= 1) {\n const { node, attribs } = branches[index]!\n const cleanedAttribs = stripControlAttributes(attribs)\n if (hasControlAttribute(attribs, 'else')) {\n expr = this.renderElement(node, scopeVar, wxsVar, componentTags, { overrideAttribs: cleanedAttribs })\n continue\n }\n const conditionExpr = resolveControlAttributeValue(attribs, 'if')\n ?? resolveControlAttributeValue(attribs, 'elif')\n ?? ''\n const rendered = this.renderElement(node, scopeVar, wxsVar, componentTags, { overrideAttribs: cleanedAttribs })\n const condition = buildExpression(parseInterpolations(conditionExpr), scopeVar, wxsVar)\n expr = `(${condition} ? ${rendered} : ${expr})`\n }\n return { rendered: expr, endIndex: startIndex + branches.length - 1 }\n }\n\n private renderNode(\n node: RenderNode,\n scopeVar: string,\n wxsVar: string,\n componentTags?: Record<string, string>,\n ): string {\n if (node.type === 'text') {\n const parts = parseInterpolations(node.data ?? '')\n return buildExpression(parts, scopeVar, wxsVar)\n }\n if (node.type === 'element') {\n if (node.name === 'template' && node.attribs?.is) {\n return this.renderTemplateInvoke(node, scopeVar, wxsVar)\n }\n return this.renderElement(node, scopeVar, wxsVar, componentTags)\n }\n return '\"\"'\n }\n\n private renderTemplateInvoke(\n node: RenderElementNode,\n scopeVar: string,\n wxsVar: string,\n ): string {\n const attribs = node.attribs ?? {}\n const isExpr = buildExpression(parseInterpolations(attribs.is ?? ''), scopeVar, wxsVar)\n const dataExpr = attribs.data\n ? buildTemplateDataExpression(attribs.data, scopeVar, wxsVar)\n : undefined\n const scopeExpr = dataExpr\n ? `ctx.mergeScope(${scopeVar}, ${dataExpr})`\n : scopeVar\n return `ctx.renderTemplate(__templates, ${isExpr}, ${scopeExpr}, ctx)`\n }\n\n private renderElement(\n node: RenderElementNode,\n scopeVar: string,\n wxsVar: string,\n componentTags?: Record<string, string>,\n options: RenderElementOptions = {},\n ): string {\n const attribs = options.overrideAttribs ?? node.attribs ?? {}\n if (!options.skipFor) {\n const forInfo = extractFor(node.attribs ?? {})\n if (forInfo.expr) {\n const listExpression = buildExpression(parseInterpolations(forInfo.expr), scopeVar, wxsVar)\n const listExpr = `ctx.normalizeList(${listExpression})`\n const itemVar = forInfo.itemName\n const indexVar = forInfo.indexName\n const scopeExpr = `ctx.createScope(${scopeVar}, { ${itemVar}: ${itemVar}, ${indexVar}: ${indexVar} })`\n const itemRender = this.renderElement(\n node,\n '__scope',\n wxsVar,\n componentTags,\n { skipFor: true, overrideAttribs: forInfo.restAttribs },\n )\n const keyExpr = `ctx.key(${JSON.stringify(forInfo.key ?? '')}, ${itemVar}, ${indexVar}, ${scopeExpr}, ${wxsVar})`\n return `repeat(${listExpr}, (${itemVar}, ${indexVar}) => ${keyExpr}, (${itemVar}, ${indexVar}) => { const __scope = ${scopeExpr}; return ${itemRender}; })`\n }\n }\n\n const customTag = resolveComponentTagName(node.name ?? '', componentTags)\n const tagName = customTag ?? normalizeTagName(node.name ?? '')\n if (tagName === '#fragment') {\n return this.renderNodes(node.children ?? [], scopeVar, wxsVar, componentTags)\n }\n\n const attrs = renderAttributes(attribs, scopeVar, wxsVar, {\n skipControl: true,\n preferProperty: Boolean(customTag),\n })\n const childNodes = node.children ?? []\n const children = childNodes\n .map(child => `\\${${this.renderNode(child, scopeVar, wxsVar, componentTags)}}`)\n .join('')\n if (SELF_CLOSING_TAGS.has(tagName) && childNodes.length === 0) {\n return `html\\`<${tagName}${attrs} />\\``\n }\n return `html\\`<${tagName}${attrs}>${children}</${tagName}>\\``\n }\n}\n\nexport const renderer = new Renderer()\n"],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TEMPLATE_IMPORT_TAG_NAMES, TEMPLATE_INCLUDE_TAG_NAMES } from "../../shared/wxml.mjs";
|
|
1
2
|
import { dirname, relative } from "pathe";
|
|
2
3
|
|
|
3
4
|
//#region src/compiler/wxml/specialNodes.ts
|
|
@@ -18,7 +19,7 @@ function collectSpecialNodes(nodes, context) {
|
|
|
18
19
|
});
|
|
19
20
|
continue;
|
|
20
21
|
}
|
|
21
|
-
if ((name
|
|
22
|
+
if (TEMPLATE_IMPORT_TAG_NAMES.includes(name) && node.attribs?.src) {
|
|
22
23
|
const resolved = context.resolveTemplate(node.attribs.src);
|
|
23
24
|
if (resolved) context.imports.push({
|
|
24
25
|
id: resolved,
|
|
@@ -27,7 +28,7 @@ function collectSpecialNodes(nodes, context) {
|
|
|
27
28
|
else context.warnings.push(`[web] 无法解析模板依赖: ${node.attribs.src} (from ${context.sourceId})`);
|
|
28
29
|
continue;
|
|
29
30
|
}
|
|
30
|
-
if ((name
|
|
31
|
+
if (TEMPLATE_INCLUDE_TAG_NAMES.includes(name) && node.attribs?.src) {
|
|
31
32
|
const resolved = context.resolveTemplate(node.attribs.src);
|
|
32
33
|
if (resolved) context.includes.push({
|
|
33
34
|
id: resolved,
|
|
@@ -67,6 +68,9 @@ function collectSpecialNodes(nodes, context) {
|
|
|
67
68
|
}
|
|
68
69
|
return renderable;
|
|
69
70
|
}
|
|
71
|
+
function normalizeTemplatePath(pathname) {
|
|
72
|
+
return pathname.split("\\").join("/");
|
|
73
|
+
}
|
|
70
74
|
function toRelativeImport(from, target) {
|
|
71
75
|
const rel = relative(dirname(from), target);
|
|
72
76
|
if (!rel || rel.startsWith(".")) {
|
|
@@ -75,9 +79,6 @@ function toRelativeImport(from, target) {
|
|
|
75
79
|
}
|
|
76
80
|
return `./${rel}`;
|
|
77
81
|
}
|
|
78
|
-
function normalizeTemplatePath(pathname) {
|
|
79
|
-
return pathname.split("\\").join("/");
|
|
80
|
-
}
|
|
81
82
|
|
|
82
83
|
//#endregion
|
|
83
84
|
export { collectSpecialNodes, normalizeTemplatePath, shouldMarkWxsImport, toRelativeImport };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"specialNodes.mjs","names":[],"sources":["../../../src/compiler/wxml/specialNodes.ts"],"sourcesContent":["import type {\n ImportEntry,\n IncludeEntry,\n RenderNode,\n TemplateDefinition,\n WxsEntry,\n} from './types'\n\nimport { dirname, relative } from 'pathe'\n\nexport function shouldMarkWxsImport(pathname: string) {\n const lower = pathname.toLowerCase()\n if (lower.endsWith('.wxs') || lower.endsWith('.wxs.ts') || lower.endsWith('.wxs.js')) {\n return false\n }\n return lower.endsWith('.ts') || lower.endsWith('.js')\n}\n\ninterface CollectSpecialNodesContext {\n templates: TemplateDefinition[]\n includes: IncludeEntry[]\n imports: ImportEntry[]\n wxs: WxsEntry[]\n wxsModules: Map<string, string>\n warnings: string[]\n sourceId: string\n resolveTemplate: (raw: string) => string | undefined\n resolveWxs: (raw: string) => string | undefined\n}\n\nexport function collectSpecialNodes(nodes: RenderNode[], context: CollectSpecialNodesContext) {\n const renderable: RenderNode[] = []\n for (const node of nodes) {\n if (node.type === 'element') {\n const name = node.name ?? ''\n if (name === 'template' && node.attribs?.name) {\n context.templates.push({\n name: node.attribs.name,\n nodes: collectSpecialNodes(node.children ?? [], context),\n })\n continue\n }\n if ((name
|
|
1
|
+
{"version":3,"file":"specialNodes.mjs","names":[],"sources":["../../../src/compiler/wxml/specialNodes.ts"],"sourcesContent":["import type {\n ImportEntry,\n IncludeEntry,\n RenderNode,\n TemplateDefinition,\n WxsEntry,\n} from './types'\n\nimport { dirname, relative } from 'pathe'\nimport { TEMPLATE_IMPORT_TAG_NAMES, TEMPLATE_INCLUDE_TAG_NAMES } from '../../shared/wxml'\n\nexport function shouldMarkWxsImport(pathname: string) {\n const lower = pathname.toLowerCase()\n if (lower.endsWith('.wxs') || lower.endsWith('.wxs.ts') || lower.endsWith('.wxs.js')) {\n return false\n }\n return lower.endsWith('.ts') || lower.endsWith('.js')\n}\n\ninterface CollectSpecialNodesContext {\n templates: TemplateDefinition[]\n includes: IncludeEntry[]\n imports: ImportEntry[]\n wxs: WxsEntry[]\n wxsModules: Map<string, string>\n warnings: string[]\n sourceId: string\n resolveTemplate: (raw: string) => string | undefined\n resolveWxs: (raw: string) => string | undefined\n}\n\nexport function collectSpecialNodes(nodes: RenderNode[], context: CollectSpecialNodesContext) {\n const renderable: RenderNode[] = []\n for (const node of nodes) {\n if (node.type === 'element') {\n const name = node.name ?? ''\n if (name === 'template' && node.attribs?.name) {\n context.templates.push({\n name: node.attribs.name,\n nodes: collectSpecialNodes(node.children ?? [], context),\n })\n continue\n }\n if (TEMPLATE_IMPORT_TAG_NAMES.includes(name) && node.attribs?.src) {\n const resolved = context.resolveTemplate(node.attribs.src)\n if (resolved) {\n context.imports.push({\n id: resolved,\n importName: `__wxml_import_${context.imports.length}`,\n })\n }\n else {\n context.warnings.push(`[web] 无法解析模板依赖: ${node.attribs.src} (from ${context.sourceId})`)\n }\n continue\n }\n if (TEMPLATE_INCLUDE_TAG_NAMES.includes(name) && node.attribs?.src) {\n const resolved = context.resolveTemplate(node.attribs.src)\n if (resolved) {\n context.includes.push({\n id: resolved,\n importName: `__wxml_include_${context.includes.length}`,\n })\n }\n else {\n context.warnings.push(`[web] 无法解析模板依赖: ${node.attribs.src} (from ${context.sourceId})`)\n }\n continue\n }\n if (name === 'wxs') {\n const moduleName = node.attribs?.module?.trim()\n if (moduleName) {\n const previousSource = context.wxsModules.get(moduleName)\n if (previousSource) {\n context.warnings.push(`[web] WXS 模块名重复: ${moduleName} (from ${context.sourceId})`)\n }\n context.wxsModules.set(moduleName, context.sourceId)\n if (node.attribs?.src) {\n const resolved = context.resolveWxs(node.attribs.src)\n if (resolved) {\n context.wxs.push({\n module: moduleName,\n kind: 'src',\n importName: `__wxs_${context.wxs.length}`,\n value: resolved,\n })\n }\n }\n else {\n const inlineCode = (node.children ?? [])\n .filter(child => child.type === 'text')\n .map(child => child.data ?? '')\n .join('')\n context.wxs.push({\n module: moduleName,\n kind: 'inline',\n importName: `__wxs_${context.wxs.length}`,\n value: inlineCode,\n })\n }\n }\n continue\n }\n if (node.children?.length) {\n node.children = collectSpecialNodes(node.children, context)\n }\n }\n renderable.push(node)\n }\n return renderable\n}\n\nexport function normalizeTemplatePath(pathname: string) {\n return pathname.split('\\\\').join('/')\n}\n\nexport function toRelativeImport(from: string, target: string) {\n const fromDir = dirname(from)\n const rel = relative(fromDir, target)\n if (!rel || rel.startsWith('.')) {\n const fallback = normalizeTemplatePath(target).split('/').pop() ?? ''\n return rel || `./${fallback}`\n }\n return `./${rel}`\n}\n"],"mappings":";;;;AAWA,SAAgB,oBAAoB,UAAkB;CACpD,MAAM,QAAQ,SAAS,aAAa;AACpC,KAAI,MAAM,SAAS,OAAO,IAAI,MAAM,SAAS,UAAU,IAAI,MAAM,SAAS,UAAU,CAClF,QAAO;AAET,QAAO,MAAM,SAAS,MAAM,IAAI,MAAM,SAAS,MAAM;;AAevD,SAAgB,oBAAoB,OAAqB,SAAqC;CAC5F,MAAM,aAA2B,EAAE;AACnC,MAAK,MAAM,QAAQ,OAAO;AACxB,MAAI,KAAK,SAAS,WAAW;GAC3B,MAAM,OAAO,KAAK,QAAQ;AAC1B,OAAI,SAAS,cAAc,KAAK,SAAS,MAAM;AAC7C,YAAQ,UAAU,KAAK;KACrB,MAAM,KAAK,QAAQ;KACnB,OAAO,oBAAoB,KAAK,YAAY,EAAE,EAAE,QAAQ;KACzD,CAAC;AACF;;AAEF,OAAI,0BAA0B,SAAS,KAAK,IAAI,KAAK,SAAS,KAAK;IACjE,MAAM,WAAW,QAAQ,gBAAgB,KAAK,QAAQ,IAAI;AAC1D,QAAI,SACF,SAAQ,QAAQ,KAAK;KACnB,IAAI;KACJ,YAAY,iBAAiB,QAAQ,QAAQ;KAC9C,CAAC;QAGF,SAAQ,SAAS,KAAK,mBAAmB,KAAK,QAAQ,IAAI,SAAS,QAAQ,SAAS,GAAG;AAEzF;;AAEF,OAAI,2BAA2B,SAAS,KAAK,IAAI,KAAK,SAAS,KAAK;IAClE,MAAM,WAAW,QAAQ,gBAAgB,KAAK,QAAQ,IAAI;AAC1D,QAAI,SACF,SAAQ,SAAS,KAAK;KACpB,IAAI;KACJ,YAAY,kBAAkB,QAAQ,SAAS;KAChD,CAAC;QAGF,SAAQ,SAAS,KAAK,mBAAmB,KAAK,QAAQ,IAAI,SAAS,QAAQ,SAAS,GAAG;AAEzF;;AAEF,OAAI,SAAS,OAAO;IAClB,MAAM,aAAa,KAAK,SAAS,QAAQ,MAAM;AAC/C,QAAI,YAAY;AAEd,SADuB,QAAQ,WAAW,IAAI,WAAW,CAEvD,SAAQ,SAAS,KAAK,oBAAoB,WAAW,SAAS,QAAQ,SAAS,GAAG;AAEpF,aAAQ,WAAW,IAAI,YAAY,QAAQ,SAAS;AACpD,SAAI,KAAK,SAAS,KAAK;MACrB,MAAM,WAAW,QAAQ,WAAW,KAAK,QAAQ,IAAI;AACrD,UAAI,SACF,SAAQ,IAAI,KAAK;OACf,QAAQ;OACR,MAAM;OACN,YAAY,SAAS,QAAQ,IAAI;OACjC,OAAO;OACR,CAAC;YAGD;MACH,MAAM,cAAc,KAAK,YAAY,EAAE,EACpC,QAAO,UAAS,MAAM,SAAS,OAAO,CACtC,KAAI,UAAS,MAAM,QAAQ,GAAG,CAC9B,KAAK,GAAG;AACX,cAAQ,IAAI,KAAK;OACf,QAAQ;OACR,MAAM;OACN,YAAY,SAAS,QAAQ,IAAI;OACjC,OAAO;OACR,CAAC;;;AAGN;;AAEF,OAAI,KAAK,UAAU,OACjB,MAAK,WAAW,oBAAoB,KAAK,UAAU,QAAQ;;AAG/D,aAAW,KAAK,KAAK;;AAEvB,QAAO;;AAGT,SAAgB,sBAAsB,UAAkB;AACtD,QAAO,SAAS,MAAM,KAAK,CAAC,KAAK,IAAI;;AAGvC,SAAgB,iBAAiB,MAAc,QAAgB;CAE7D,MAAM,MAAM,SADI,QAAQ,KAAK,EACC,OAAO;AACrC,KAAI,CAAC,OAAO,IAAI,WAAW,IAAI,EAAE;EAC/B,MAAM,WAAW,sBAAsB,OAAO,CAAC,MAAM,IAAI,CAAC,KAAK,IAAI;AACnE,SAAO,OAAO,KAAK;;AAErB,QAAO,KAAK"}
|
package/dist/plugin/files.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SCRIPT_EXTS, STYLE_EXTS, TEMPLATE_EXTS } from "./constants.mjs";
|
|
2
2
|
import { extname } from "pathe";
|
|
3
|
-
import { fs } from "@weapp-core/shared";
|
|
3
|
+
import { fs } from "@weapp-core/shared/fs";
|
|
4
4
|
import { bundleRequire } from "rolldown-require";
|
|
5
5
|
|
|
6
6
|
//#region src/plugin/files.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files.mjs","names":[],"sources":["../../src/plugin/files.ts"],"sourcesContent":["import { fs } from '@weapp-core/shared'\nimport { extname } from 'pathe'\nimport { bundleRequire } from 'rolldown-require'\n\nimport { SCRIPT_EXTS, STYLE_EXTS, TEMPLATE_EXTS } from './constants'\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nexport async function readJsonFile(pathname: string) {\n const candidates = [pathname]\n if (pathname.endsWith('.json')) {\n candidates.push(`${pathname}.ts`, `${pathname}.js`)\n }\n\n for (const candidate of candidates) {\n if (!(await fs.pathExists(candidate))) {\n continue\n }\n if (candidate.endsWith('.json')) {\n const json = await fs.readJson(candidate).catch(() => undefined)\n if (!isRecord(json)) {\n return undefined\n }\n return json\n }\n const { mod } = await bundleRequire({\n filepath: candidate,\n preserveTemporaryFile: true,\n })\n const resolved = typeof mod.default === 'function'\n ? await mod.default()\n : mod.default\n if (!isRecord(resolved)) {\n return undefined\n }\n return resolved\n }\n\n return undefined\n}\n\nexport async function resolveJsonPath(basePath: string) {\n const candidates = [basePath]\n if (basePath.endsWith('.json')) {\n candidates.push(`${basePath}.ts`, `${basePath}.js`)\n }\n for (const candidate of candidates) {\n if (await fs.pathExists(candidate)) {\n return candidate\n }\n }\n return undefined\n}\n\nexport async function resolveScriptFile(basePath: string) {\n const ext = extname(basePath)\n if (ext && (await fs.pathExists(basePath))) {\n return basePath\n }\n for (const candidateExt of SCRIPT_EXTS) {\n const candidate = `${basePath}${candidateExt}`\n if (await fs.pathExists(candidate)) {\n return candidate\n }\n }\n return undefined\n}\n\nexport async function resolveStyleFile(scriptPath: string) {\n const base = scriptPath.replace(new RegExp(`${extname(scriptPath)}$`), '')\n for (const ext of STYLE_EXTS) {\n const candidate = `${base}${ext}`\n if (await fs.pathExists(candidate)) {\n return candidate\n }\n }\n return undefined\n}\n\nexport async function resolveTemplateFile(scriptPath: string) {\n const base = scriptPath.replace(new RegExp(`${extname(scriptPath)}$`), '')\n for (const ext of TEMPLATE_EXTS) {\n const candidate = `${base}${ext}`\n if (await fs.pathExists(candidate)) {\n return candidate\n }\n }\n return undefined\n}\n"],"mappings":";;;;;;AAMA,SAAgB,SAAS,OAAkD;AACzE,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;;AAG7E,eAAsB,aAAa,UAAkB;CACnD,MAAM,aAAa,CAAC,SAAS;AAC7B,KAAI,SAAS,SAAS,QAAQ,CAC5B,YAAW,KAAK,GAAG,SAAS,MAAM,GAAG,SAAS,KAAK;AAGrD,MAAK,MAAM,aAAa,YAAY;AAClC,MAAI,CAAE,MAAM,GAAG,WAAW,UAAU,CAClC;AAEF,MAAI,UAAU,SAAS,QAAQ,EAAE;GAC/B,MAAM,OAAO,MAAM,GAAG,SAAS,UAAU,CAAC,YAAY,OAAU;AAChE,OAAI,CAAC,SAAS,KAAK,CACjB;AAEF,UAAO;;EAET,MAAM,EAAE,QAAQ,MAAM,cAAc;GAClC,UAAU;GACV,uBAAuB;GACxB,CAAC;EACF,MAAM,WAAW,OAAO,IAAI,YAAY,aACpC,MAAM,IAAI,SAAS,GACnB,IAAI;AACR,MAAI,CAAC,SAAS,SAAS,CACrB;AAEF,SAAO;;;AAMX,eAAsB,gBAAgB,UAAkB;CACtD,MAAM,aAAa,CAAC,SAAS;AAC7B,KAAI,SAAS,SAAS,QAAQ,CAC5B,YAAW,KAAK,GAAG,SAAS,MAAM,GAAG,SAAS,KAAK;AAErD,MAAK,MAAM,aAAa,WACtB,KAAI,MAAM,GAAG,WAAW,UAAU,CAChC,QAAO;;AAMb,eAAsB,kBAAkB,UAAkB;AAExD,KADY,QAAQ,SAAS,IACjB,MAAM,GAAG,WAAW,SAAS,CACvC,QAAO;AAET,MAAK,MAAM,gBAAgB,aAAa;EACtC,MAAM,YAAY,GAAG,WAAW;AAChC,MAAI,MAAM,GAAG,WAAW,UAAU,CAChC,QAAO;;;AAMb,eAAsB,iBAAiB,YAAoB;CACzD,MAAM,OAAO,WAAW,QAAQ,IAAI,OAAO,GAAG,QAAQ,WAAW,CAAC,GAAG,EAAE,GAAG;AAC1E,MAAK,MAAM,OAAO,YAAY;EAC5B,MAAM,YAAY,GAAG,OAAO;AAC5B,MAAI,MAAM,GAAG,WAAW,UAAU,CAChC,QAAO;;;AAMb,eAAsB,oBAAoB,YAAoB;CAC5D,MAAM,OAAO,WAAW,QAAQ,IAAI,OAAO,GAAG,QAAQ,WAAW,CAAC,GAAG,EAAE,GAAG;AAC1E,MAAK,MAAM,OAAO,eAAe;EAC/B,MAAM,YAAY,GAAG,OAAO;AAC5B,MAAI,MAAM,GAAG,WAAW,UAAU,CAChC,QAAO"}
|
|
1
|
+
{"version":3,"file":"files.mjs","names":[],"sources":["../../src/plugin/files.ts"],"sourcesContent":["import { fs } from '@weapp-core/shared/fs'\nimport { extname } from 'pathe'\nimport { bundleRequire } from 'rolldown-require'\n\nimport { SCRIPT_EXTS, STYLE_EXTS, TEMPLATE_EXTS } from './constants'\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nexport async function readJsonFile(pathname: string) {\n const candidates = [pathname]\n if (pathname.endsWith('.json')) {\n candidates.push(`${pathname}.ts`, `${pathname}.js`)\n }\n\n for (const candidate of candidates) {\n if (!(await fs.pathExists(candidate))) {\n continue\n }\n if (candidate.endsWith('.json')) {\n const json = await fs.readJson(candidate).catch(() => undefined)\n if (!isRecord(json)) {\n return undefined\n }\n return json\n }\n const { mod } = await bundleRequire({\n filepath: candidate,\n preserveTemporaryFile: true,\n })\n const resolved = typeof mod.default === 'function'\n ? await mod.default()\n : mod.default\n if (!isRecord(resolved)) {\n return undefined\n }\n return resolved\n }\n\n return undefined\n}\n\nexport async function resolveJsonPath(basePath: string) {\n const candidates = [basePath]\n if (basePath.endsWith('.json')) {\n candidates.push(`${basePath}.ts`, `${basePath}.js`)\n }\n for (const candidate of candidates) {\n if (await fs.pathExists(candidate)) {\n return candidate\n }\n }\n return undefined\n}\n\nexport async function resolveScriptFile(basePath: string) {\n const ext = extname(basePath)\n if (ext && (await fs.pathExists(basePath))) {\n return basePath\n }\n for (const candidateExt of SCRIPT_EXTS) {\n const candidate = `${basePath}${candidateExt}`\n if (await fs.pathExists(candidate)) {\n return candidate\n }\n }\n return undefined\n}\n\nexport async function resolveStyleFile(scriptPath: string) {\n const base = scriptPath.replace(new RegExp(`${extname(scriptPath)}$`), '')\n for (const ext of STYLE_EXTS) {\n const candidate = `${base}${ext}`\n if (await fs.pathExists(candidate)) {\n return candidate\n }\n }\n return undefined\n}\n\nexport async function resolveTemplateFile(scriptPath: string) {\n const base = scriptPath.replace(new RegExp(`${extname(scriptPath)}$`), '')\n for (const ext of TEMPLATE_EXTS) {\n const candidate = `${base}${ext}`\n if (await fs.pathExists(candidate)) {\n return candidate\n }\n }\n return undefined\n}\n"],"mappings":";;;;;;AAMA,SAAgB,SAAS,OAAkD;AACzE,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;;AAG7E,eAAsB,aAAa,UAAkB;CACnD,MAAM,aAAa,CAAC,SAAS;AAC7B,KAAI,SAAS,SAAS,QAAQ,CAC5B,YAAW,KAAK,GAAG,SAAS,MAAM,GAAG,SAAS,KAAK;AAGrD,MAAK,MAAM,aAAa,YAAY;AAClC,MAAI,CAAE,MAAM,GAAG,WAAW,UAAU,CAClC;AAEF,MAAI,UAAU,SAAS,QAAQ,EAAE;GAC/B,MAAM,OAAO,MAAM,GAAG,SAAS,UAAU,CAAC,YAAY,OAAU;AAChE,OAAI,CAAC,SAAS,KAAK,CACjB;AAEF,UAAO;;EAET,MAAM,EAAE,QAAQ,MAAM,cAAc;GAClC,UAAU;GACV,uBAAuB;GACxB,CAAC;EACF,MAAM,WAAW,OAAO,IAAI,YAAY,aACpC,MAAM,IAAI,SAAS,GACnB,IAAI;AACR,MAAI,CAAC,SAAS,SAAS,CACrB;AAEF,SAAO;;;AAMX,eAAsB,gBAAgB,UAAkB;CACtD,MAAM,aAAa,CAAC,SAAS;AAC7B,KAAI,SAAS,SAAS,QAAQ,CAC5B,YAAW,KAAK,GAAG,SAAS,MAAM,GAAG,SAAS,KAAK;AAErD,MAAK,MAAM,aAAa,WACtB,KAAI,MAAM,GAAG,WAAW,UAAU,CAChC,QAAO;;AAMb,eAAsB,kBAAkB,UAAkB;AAExD,KADY,QAAQ,SAAS,IACjB,MAAM,GAAG,WAAW,SAAS,CACvC,QAAO;AAET,MAAK,MAAM,gBAAgB,aAAa;EACtC,MAAM,YAAY,GAAG,WAAW;AAChC,MAAI,MAAM,GAAG,WAAW,UAAU,CAChC,QAAO;;;AAMb,eAAsB,iBAAiB,YAAoB;CACzD,MAAM,OAAO,WAAW,QAAQ,IAAI,OAAO,GAAG,QAAQ,WAAW,CAAC,GAAG,EAAE,GAAG;AAC1E,MAAK,MAAM,OAAO,YAAY;EAC5B,MAAM,YAAY,GAAG,OAAO;AAC5B,MAAI,MAAM,GAAG,WAAW,UAAU,CAChC,QAAO;;;AAMb,eAAsB,oBAAoB,YAAoB;CAC5D,MAAM,OAAO,WAAW,QAAQ,IAAI,OAAO,GAAG,QAAQ,WAAW,CAAC,GAAG,EAAE,GAAG;AAC1E,MAAK,MAAM,OAAO,eAAe;EAC/B,MAAM,YAAY,GAAG,OAAO;AAC5B,MAAI,MAAM,GAAG,WAAW,UAAU,CAChC,QAAO"}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
//#region src/runtime/component/constants.ts
|
|
2
2
|
const supportsLit = typeof document !== "undefined" && typeof document.createComment === "function" && typeof document.createTreeWalker === "function";
|
|
3
3
|
const FallbackElement = class {};
|
|
4
|
-
const
|
|
4
|
+
const MINI_PROGRAM_EVENT_ATTRIBUTE_PREFIX = "data-mp-on-";
|
|
5
|
+
const MINI_PROGRAM_EVENT_FLAG_ATTRIBUTE_PREFIX = "data-mp-on-flags-";
|
|
6
|
+
const WECHAT_LEGACY_EVENT_ATTRIBUTE_PREFIX = "data-wx-on-";
|
|
7
|
+
const WECHAT_LEGACY_EVENT_FLAG_ATTRIBUTE_PREFIX = "data-wx-on-flags-";
|
|
8
|
+
const EVENT_ATTRIBUTE_PREFIXES = [MINI_PROGRAM_EVENT_ATTRIBUTE_PREFIX, WECHAT_LEGACY_EVENT_ATTRIBUTE_PREFIX];
|
|
9
|
+
const EVENT_FLAG_ATTRIBUTE_PREFIXES = [MINI_PROGRAM_EVENT_FLAG_ATTRIBUTE_PREFIX, WECHAT_LEGACY_EVENT_FLAG_ATTRIBUTE_PREFIX];
|
|
5
10
|
|
|
6
11
|
//#endregion
|
|
7
|
-
export {
|
|
12
|
+
export { EVENT_ATTRIBUTE_PREFIXES, EVENT_FLAG_ATTRIBUTE_PREFIXES, FallbackElement, MINI_PROGRAM_EVENT_ATTRIBUTE_PREFIX, MINI_PROGRAM_EVENT_FLAG_ATTRIBUTE_PREFIX, supportsLit };
|
|
8
13
|
//# sourceMappingURL=constants.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.mjs","names":[],"sources":["../../../src/runtime/component/constants.ts"],"sourcesContent":["export const supportsLit = typeof document !== 'undefined'\n && typeof document.createComment === 'function'\n && typeof document.createTreeWalker === 'function'\n\nexport const FallbackElement = class {}\n\nexport const
|
|
1
|
+
{"version":3,"file":"constants.mjs","names":[],"sources":["../../../src/runtime/component/constants.ts"],"sourcesContent":["export const supportsLit = typeof document !== 'undefined'\n && typeof document.createComment === 'function'\n && typeof document.createTreeWalker === 'function'\n\nexport const FallbackElement = class {}\n\nexport const MINI_PROGRAM_EVENT_ATTRIBUTE_PREFIX = 'data-mp-on-'\nexport const MINI_PROGRAM_EVENT_FLAG_ATTRIBUTE_PREFIX = 'data-mp-on-flags-'\n\nexport const WECHAT_LEGACY_EVENT_ATTRIBUTE_PREFIX = 'data-wx-on-'\nexport const WECHAT_LEGACY_EVENT_FLAG_ATTRIBUTE_PREFIX = 'data-wx-on-flags-'\n\nexport const LEGACY_EVENT_ATTRIBUTE_PREFIX = WECHAT_LEGACY_EVENT_ATTRIBUTE_PREFIX\nexport const LEGACY_EVENT_FLAG_ATTRIBUTE_PREFIX = WECHAT_LEGACY_EVENT_FLAG_ATTRIBUTE_PREFIX\n\nexport const EVENT_ATTRIBUTE_PREFIXES = [\n MINI_PROGRAM_EVENT_ATTRIBUTE_PREFIX,\n WECHAT_LEGACY_EVENT_ATTRIBUTE_PREFIX,\n] as const\n\nexport const EVENT_FLAG_ATTRIBUTE_PREFIXES = [\n MINI_PROGRAM_EVENT_FLAG_ATTRIBUTE_PREFIX,\n WECHAT_LEGACY_EVENT_FLAG_ATTRIBUTE_PREFIX,\n] as const\n"],"mappings":";AAAA,MAAa,cAAc,OAAO,aAAa,eAC1C,OAAO,SAAS,kBAAkB,cAClC,OAAO,SAAS,qBAAqB;AAE1C,MAAa,kBAAkB,MAAM;AAErC,MAAa,sCAAsC;AACnD,MAAa,2CAA2C;AAExD,MAAa,uCAAuC;AACpD,MAAa,4CAA4C;AAKzD,MAAa,2BAA2B,CACtC,qCACA,qCACD;AAED,MAAa,gCAAgC,CAC3C,0CACA,0CACD"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { getMiniProgramRuntimeGlobalKeys } from "@weapp-core/shared";
|
|
2
|
+
|
|
1
3
|
//#region src/runtime/component/dom.ts
|
|
4
|
+
const MINI_PROGRAM_RUNTIME_GLOBAL_KEYS = getMiniProgramRuntimeGlobalKeys();
|
|
2
5
|
function resolveQueryRoot(instance) {
|
|
3
6
|
return instance.renderRoot ?? instance.shadowRoot ?? instance;
|
|
4
7
|
}
|
|
@@ -6,9 +9,12 @@ function resolveRenderRoot(instance) {
|
|
|
6
9
|
return instance.renderRoot ?? instance.shadowRoot ?? instance;
|
|
7
10
|
}
|
|
8
11
|
function createScopedSelectorQuery(instance) {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
const runtime = globalThis;
|
|
13
|
+
for (const globalKey of MINI_PROGRAM_RUNTIME_GLOBAL_KEYS) {
|
|
14
|
+
const query = runtime[globalKey]?.createSelectorQuery?.();
|
|
15
|
+
if (query && typeof query.in === "function") return query.in(instance);
|
|
16
|
+
if (query) return query;
|
|
17
|
+
}
|
|
12
18
|
}
|
|
13
19
|
function selectRuntimeComponent(instance, selector) {
|
|
14
20
|
const root = resolveQueryRoot(instance);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom.mjs","names":[],"sources":["../../../src/runtime/component/dom.ts"],"sourcesContent":["import type { ComponentPublicInstance } from './types'\n\ntype QueryRoot = ParentNode & {\n querySelector?: ParentNode['querySelector']\n querySelectorAll?: ParentNode['querySelectorAll']\n}\n\nexport function resolveQueryRoot(instance: ComponentPublicInstance & { renderRoot?: ParentNode }): QueryRoot {\n return (instance.renderRoot ?? instance.shadowRoot ?? instance) as QueryRoot\n}\n\nexport function resolveRenderRoot(instance: ComponentPublicInstance & { renderRoot?: HTMLElement | ShadowRoot }) {\n return (instance.renderRoot ?? instance.shadowRoot ?? instance) as HTMLElement | ShadowRoot\n}\n\nexport function createScopedSelectorQuery(instance: ComponentPublicInstance) {\n const runtime = globalThis as {\n
|
|
1
|
+
{"version":3,"file":"dom.mjs","names":[],"sources":["../../../src/runtime/component/dom.ts"],"sourcesContent":["import type { ComponentPublicInstance } from './types'\nimport { getMiniProgramRuntimeGlobalKeys } from '@weapp-core/shared'\n\ntype QueryRoot = ParentNode & {\n querySelector?: ParentNode['querySelector']\n querySelectorAll?: ParentNode['querySelectorAll']\n}\n\nconst MINI_PROGRAM_RUNTIME_GLOBAL_KEYS = getMiniProgramRuntimeGlobalKeys()\n\nexport function resolveQueryRoot(instance: ComponentPublicInstance & { renderRoot?: ParentNode }): QueryRoot {\n return (instance.renderRoot ?? instance.shadowRoot ?? instance) as QueryRoot\n}\n\nexport function resolveRenderRoot(instance: ComponentPublicInstance & { renderRoot?: HTMLElement | ShadowRoot }) {\n return (instance.renderRoot ?? instance.shadowRoot ?? instance) as HTMLElement | ShadowRoot\n}\n\nexport function createScopedSelectorQuery(instance: ComponentPublicInstance) {\n const runtime = globalThis as Record<string, {\n createSelectorQuery?: () => {\n in?: (context: unknown) => unknown\n }\n } | undefined>\n for (const globalKey of MINI_PROGRAM_RUNTIME_GLOBAL_KEYS) {\n const query = runtime[globalKey]?.createSelectorQuery?.()\n if (query && typeof query.in === 'function') {\n return query.in(instance)\n }\n if (query) {\n return query\n }\n }\n return undefined\n}\n\nexport function selectRuntimeComponent(instance: ComponentPublicInstance & { renderRoot?: ParentNode }, selector: string) {\n const root = resolveQueryRoot(instance)\n if (!selector || typeof root.querySelector !== 'function') {\n return null\n }\n return root.querySelector(selector) as ComponentPublicInstance | null\n}\n\nexport function selectRuntimeComponents(instance: ComponentPublicInstance & { renderRoot?: ParentNode }, selector: string) {\n const root = resolveQueryRoot(instance)\n if (!selector || typeof root.querySelectorAll !== 'function') {\n return []\n }\n return Array.from(root.querySelectorAll(selector)) as ComponentPublicInstance[]\n}\n"],"mappings":";;;AAQA,MAAM,mCAAmC,iCAAiC;AAE1E,SAAgB,iBAAiB,UAA4E;AAC3G,QAAQ,SAAS,cAAc,SAAS,cAAc;;AAGxD,SAAgB,kBAAkB,UAA+E;AAC/G,QAAQ,SAAS,cAAc,SAAS,cAAc;;AAGxD,SAAgB,0BAA0B,UAAmC;CAC3E,MAAM,UAAU;AAKhB,MAAK,MAAM,aAAa,kCAAkC;EACxD,MAAM,QAAQ,QAAQ,YAAY,uBAAuB;AACzD,MAAI,SAAS,OAAO,MAAM,OAAO,WAC/B,QAAO,MAAM,GAAG,SAAS;AAE3B,MAAI,MACF,QAAO;;;AAMb,SAAgB,uBAAuB,UAAiE,UAAkB;CACxH,MAAM,OAAO,iBAAiB,SAAS;AACvC,KAAI,CAAC,YAAY,OAAO,KAAK,kBAAkB,WAC7C,QAAO;AAET,QAAO,KAAK,cAAc,SAAS;;AAGrC,SAAgB,wBAAwB,UAAiE,UAAkB;CACzH,MAAM,OAAO,iBAAiB,SAAS;AACvC,KAAI,CAAC,YAAY,OAAO,KAAK,qBAAqB,WAChD,QAAO,EAAE;AAEX,QAAO,MAAM,KAAK,KAAK,iBAAiB,SAAS,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EVENT_ATTRIBUTE_PREFIXES, EVENT_FLAG_ATTRIBUTE_PREFIXES } from "./constants.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/runtime/component/events.ts
|
|
4
4
|
function parseEventFlags(value) {
|
|
@@ -19,13 +19,14 @@ function bindRuntimeEvents(root, methods, instance) {
|
|
|
19
19
|
while (walker.nextNode()) {
|
|
20
20
|
const element = walker.currentNode;
|
|
21
21
|
for (const attribute of element.getAttributeNames()) {
|
|
22
|
-
|
|
22
|
+
const matchedPrefix = EVENT_ATTRIBUTE_PREFIXES.find((prefix) => attribute.startsWith(prefix));
|
|
23
|
+
if (!matchedPrefix || EVENT_FLAG_ATTRIBUTE_PREFIXES.some((prefix) => attribute.startsWith(prefix))) continue;
|
|
23
24
|
const handlerName = element.getAttribute(attribute);
|
|
24
25
|
if (!handlerName) continue;
|
|
25
26
|
const handler = methods[handlerName];
|
|
26
27
|
if (!handler) continue;
|
|
27
|
-
const eventName = attribute.slice(
|
|
28
|
-
const flags = parseEventFlags(element.getAttribute(`${
|
|
28
|
+
const eventName = attribute.slice(matchedPrefix.length);
|
|
29
|
+
const flags = parseEventFlags(EVENT_FLAG_ATTRIBUTE_PREFIXES.map((prefix) => element.getAttribute(`${prefix}${eventName}`)).find((value) => value !== null) ?? null);
|
|
29
30
|
element.addEventListener(eventName, (nativeEvent) => {
|
|
30
31
|
if (flags.catch) nativeEvent.stopPropagation();
|
|
31
32
|
const dataset = { ...element.dataset };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.mjs","names":[],"sources":["../../../src/runtime/component/events.ts"],"sourcesContent":["import type { ComponentPublicInstance } from './types'\nimport {
|
|
1
|
+
{"version":3,"file":"events.mjs","names":[],"sources":["../../../src/runtime/component/events.ts"],"sourcesContent":["import type { ComponentPublicInstance } from './types'\nimport {\n EVENT_ATTRIBUTE_PREFIXES,\n EVENT_FLAG_ATTRIBUTE_PREFIXES,\n} from './constants'\n\nfunction parseEventFlags(value: string | null) {\n if (!value) {\n return { catch: false, capture: false }\n }\n const tokens = value.split(',').map(token => token.trim()).filter(Boolean)\n const tokenSet = new Set(tokens)\n return {\n catch: tokenSet.has('catch'),\n capture: tokenSet.has('capture'),\n }\n}\n\nexport function bindRuntimeEvents(\n root: HTMLElement | ShadowRoot,\n methods: Record<string, (event: any) => any>,\n instance: ComponentPublicInstance,\n) {\n if (typeof document === 'undefined') {\n return\n }\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT)\n while (walker.nextNode()) {\n const element = walker.currentNode as HTMLElement\n for (const attribute of element.getAttributeNames()) {\n const matchedPrefix = EVENT_ATTRIBUTE_PREFIXES.find(prefix => attribute.startsWith(prefix))\n if (!matchedPrefix || EVENT_FLAG_ATTRIBUTE_PREFIXES.some(prefix => attribute.startsWith(prefix))) {\n continue\n }\n const handlerName = element.getAttribute(attribute)\n if (!handlerName) {\n continue\n }\n const handler = methods[handlerName]\n if (!handler) {\n continue\n }\n const eventName = attribute.slice(matchedPrefix.length)\n const flagAttributeValue = EVENT_FLAG_ATTRIBUTE_PREFIXES\n .map(prefix => element.getAttribute(`${prefix}${eventName}`))\n .find(value => value !== null) ?? null\n const flags = parseEventFlags(flagAttributeValue)\n element.addEventListener(eventName, (nativeEvent) => {\n if (flags.catch) {\n nativeEvent.stopPropagation()\n }\n const dataset = { ...element.dataset }\n const syntheticEvent = {\n type: eventName,\n timeStamp: nativeEvent.timeStamp,\n detail: (nativeEvent as CustomEvent).detail ?? (nativeEvent as InputEvent).data ?? undefined,\n target: {\n dataset,\n },\n currentTarget: {\n dataset,\n },\n originalEvent: nativeEvent,\n }\n handler.call(instance, syntheticEvent)\n }, flags.capture)\n }\n }\n}\n"],"mappings":";;;AAMA,SAAS,gBAAgB,OAAsB;AAC7C,KAAI,CAAC,MACH,QAAO;EAAE,OAAO;EAAO,SAAS;EAAO;CAEzC,MAAM,SAAS,MAAM,MAAM,IAAI,CAAC,KAAI,UAAS,MAAM,MAAM,CAAC,CAAC,OAAO,QAAQ;CAC1E,MAAM,WAAW,IAAI,IAAI,OAAO;AAChC,QAAO;EACL,OAAO,SAAS,IAAI,QAAQ;EAC5B,SAAS,SAAS,IAAI,UAAU;EACjC;;AAGH,SAAgB,kBACd,MACA,SACA,UACA;AACA,KAAI,OAAO,aAAa,YACtB;CAEF,MAAM,SAAS,SAAS,iBAAiB,MAAM,WAAW,aAAa;AACvE,QAAO,OAAO,UAAU,EAAE;EACxB,MAAM,UAAU,OAAO;AACvB,OAAK,MAAM,aAAa,QAAQ,mBAAmB,EAAE;GACnD,MAAM,gBAAgB,yBAAyB,MAAK,WAAU,UAAU,WAAW,OAAO,CAAC;AAC3F,OAAI,CAAC,iBAAiB,8BAA8B,MAAK,WAAU,UAAU,WAAW,OAAO,CAAC,CAC9F;GAEF,MAAM,cAAc,QAAQ,aAAa,UAAU;AACnD,OAAI,CAAC,YACH;GAEF,MAAM,UAAU,QAAQ;AACxB,OAAI,CAAC,QACH;GAEF,MAAM,YAAY,UAAU,MAAM,cAAc,OAAO;GAIvD,MAAM,QAAQ,gBAHa,8BACxB,KAAI,WAAU,QAAQ,aAAa,GAAG,SAAS,YAAY,CAAC,CAC5D,MAAK,UAAS,UAAU,KAAK,IAAI,KACa;AACjD,WAAQ,iBAAiB,YAAY,gBAAgB;AACnD,QAAI,MAAM,MACR,aAAY,iBAAiB;IAE/B,MAAM,UAAU,EAAE,GAAG,QAAQ,SAAS;IACtC,MAAM,iBAAiB;KACrB,MAAM;KACN,WAAW,YAAY;KACvB,QAAS,YAA4B,UAAW,YAA2B,QAAQ;KACnF,QAAQ,EACN,SACD;KACD,eAAe,EACb,SACD;KACD,eAAe;KAChB;AACD,YAAQ,KAAK,UAAU,eAAe;MACrC,MAAM,QAAQ"}
|
|
@@ -1,15 +1,8 @@
|
|
|
1
|
+
import { CONTROL_ATTRS, hasControlAttribute, normalizeAttributeName, resolveControlAttributeValue } from "../../shared/wxml.mjs";
|
|
2
|
+
import { MINI_PROGRAM_EVENT_ATTRIBUTE_PREFIX, MINI_PROGRAM_EVENT_FLAG_ATTRIBUTE_PREFIX } from "../component/constants.mjs";
|
|
1
3
|
import { escapeAttribute, resolveAttributeValue } from "./expression.mjs";
|
|
2
4
|
|
|
3
5
|
//#region src/runtime/legacyTemplate/dom.ts
|
|
4
|
-
const CONTROL_ATTRS = new Set([
|
|
5
|
-
"wx:if",
|
|
6
|
-
"wx:elif",
|
|
7
|
-
"wx:else",
|
|
8
|
-
"wx:for",
|
|
9
|
-
"wx:for-item",
|
|
10
|
-
"wx:for-index",
|
|
11
|
-
"wx:key"
|
|
12
|
-
]);
|
|
13
6
|
const EVENT_PREFIX_RE = /^(bind|catch|mut-bind|capture-bind|capture-catch)([\w-]+)$/;
|
|
14
7
|
const EVENT_KIND_ALIAS = {
|
|
15
8
|
tap: "click",
|
|
@@ -26,61 +19,13 @@ const EVENT_PREFIX_FLAGS = {
|
|
|
26
19
|
catch: true
|
|
27
20
|
}
|
|
28
21
|
};
|
|
29
|
-
const SELF_CLOSING_TAGS = new Set([
|
|
30
|
-
"area",
|
|
31
|
-
"base",
|
|
32
|
-
"br",
|
|
33
|
-
"col",
|
|
34
|
-
"embed",
|
|
35
|
-
"hr",
|
|
36
|
-
"img",
|
|
37
|
-
"image",
|
|
38
|
-
"input",
|
|
39
|
-
"link",
|
|
40
|
-
"meta",
|
|
41
|
-
"param",
|
|
42
|
-
"source",
|
|
43
|
-
"track",
|
|
44
|
-
"wbr"
|
|
45
|
-
]);
|
|
46
|
-
function normalizeTagName(name) {
|
|
47
|
-
switch (name) {
|
|
48
|
-
case "view":
|
|
49
|
-
case "cover-view":
|
|
50
|
-
case "navigator":
|
|
51
|
-
case "scroll-view":
|
|
52
|
-
case "swiper":
|
|
53
|
-
case "swiper-item":
|
|
54
|
-
case "movable-area":
|
|
55
|
-
case "movable-view":
|
|
56
|
-
case "cover-image": return "div";
|
|
57
|
-
case "text":
|
|
58
|
-
case "icon": return "span";
|
|
59
|
-
case "image": return "img";
|
|
60
|
-
case "button": return "weapp-button";
|
|
61
|
-
case "input": return "input";
|
|
62
|
-
case "textarea": return "textarea";
|
|
63
|
-
case "form": return "form";
|
|
64
|
-
case "label": return "label";
|
|
65
|
-
case "picker":
|
|
66
|
-
case "picker-view": return "select";
|
|
67
|
-
case "block": return "#fragment";
|
|
68
|
-
case "slot": return "slot";
|
|
69
|
-
default: return name || "div";
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
function normalizeAttributeName(name) {
|
|
73
|
-
if (name === "class" || name === "style" || name.startsWith("data-")) return name;
|
|
74
|
-
if (name === "hover-class") return "data-hover-class";
|
|
75
|
-
return name.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
76
|
-
}
|
|
77
22
|
function extractFor(attribs) {
|
|
78
|
-
const expr = attribs
|
|
23
|
+
const expr = resolveControlAttributeValue(attribs, "for");
|
|
79
24
|
const restAttribs = {};
|
|
80
|
-
const itemName = attribs
|
|
81
|
-
let indexName = attribs
|
|
25
|
+
const itemName = resolveControlAttributeValue(attribs, "for-item")?.trim() || "item";
|
|
26
|
+
let indexName = resolveControlAttributeValue(attribs, "for-index")?.trim() || "index";
|
|
82
27
|
for (const [key, val] of Object.entries(attribs)) {
|
|
83
|
-
if (key
|
|
28
|
+
if (CONTROL_ATTRS.has(key)) continue;
|
|
84
29
|
restAttribs[key] = val;
|
|
85
30
|
}
|
|
86
31
|
if (itemName === indexName) indexName = `${indexName}Index`;
|
|
@@ -103,9 +48,9 @@ function buildAttributeString(attribs, scope) {
|
|
|
103
48
|
if (!handlerName) continue;
|
|
104
49
|
const runtimeEvent = EVENT_KIND_ALIAS[event] ?? event;
|
|
105
50
|
const flags = EVENT_PREFIX_FLAGS[prefix] ?? {};
|
|
106
|
-
result += `
|
|
51
|
+
result += ` ${MINI_PROGRAM_EVENT_ATTRIBUTE_PREFIX}${runtimeEvent}="${escapeAttribute(handlerName)}"`;
|
|
107
52
|
const flagTokens = [flags.capture ? "capture" : "", flags.catch ? "catch" : ""].filter(Boolean);
|
|
108
|
-
if (flagTokens.length) result += `
|
|
53
|
+
if (flagTokens.length) result += ` ${MINI_PROGRAM_EVENT_FLAG_ATTRIBUTE_PREFIX}${runtimeEvent}="${flagTokens.join(",")}"`;
|
|
109
54
|
continue;
|
|
110
55
|
}
|
|
111
56
|
const value = resolveAttributeValue(rawValue, scope);
|
|
@@ -123,9 +68,9 @@ function stripControlAttributes(attribs) {
|
|
|
123
68
|
function isConditionalElement(node) {
|
|
124
69
|
if (node.type !== "tag") return false;
|
|
125
70
|
const attribs = node.attribs ?? {};
|
|
126
|
-
return "
|
|
71
|
+
return hasControlAttribute(attribs, "if") || hasControlAttribute(attribs, "elif") || hasControlAttribute(attribs, "else");
|
|
127
72
|
}
|
|
128
73
|
|
|
129
74
|
//#endregion
|
|
130
|
-
export {
|
|
75
|
+
export { buildAttributeString, extractFor, isConditionalElement, stripControlAttributes };
|
|
131
76
|
//# sourceMappingURL=dom.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom.mjs","names":[],"sources":["../../../src/runtime/legacyTemplate/dom.ts"],"sourcesContent":["import type { Element, Node } from 'domhandler'\nimport type { ExtractForResult, LegacyTemplateScope } from './types'\nimport {
|
|
1
|
+
{"version":3,"file":"dom.mjs","names":[],"sources":["../../../src/runtime/legacyTemplate/dom.ts"],"sourcesContent":["import type { Element, Node } from 'domhandler'\nimport type { ExtractForResult, LegacyTemplateScope } from './types'\nimport {\n CONTROL_ATTRS,\n hasControlAttribute,\n normalizeAttributeName,\n resolveControlAttributeValue,\n} from '../../shared/wxml'\nimport {\n MINI_PROGRAM_EVENT_ATTRIBUTE_PREFIX,\n MINI_PROGRAM_EVENT_FLAG_ATTRIBUTE_PREFIX,\n} from '../component/constants'\nimport { escapeAttribute, resolveAttributeValue } from './expression'\n\nconst EVENT_PREFIX_RE = /^(bind|catch|mut-bind|capture-bind|capture-catch)([\\w-]+)$/\nconst EVENT_KIND_ALIAS: Record<string, string> = {\n tap: 'click',\n longtap: 'contextmenu',\n longpress: 'contextmenu',\n}\n\nconst EVENT_PREFIX_FLAGS: Record<string, { catch?: boolean, capture?: boolean }> = {\n 'bind': {},\n 'catch': { catch: true },\n 'mut-bind': {},\n 'capture-bind': { capture: true },\n 'capture-catch': { capture: true, catch: true },\n}\n\nexport function extractFor(attribs: Record<string, string>): ExtractForResult {\n const expr = resolveControlAttributeValue(attribs, 'for')\n const restAttribs: Record<string, string> = {}\n const itemName = resolveControlAttributeValue(attribs, 'for-item')?.trim() || 'item'\n let indexName = resolveControlAttributeValue(attribs, 'for-index')?.trim() || 'index'\n\n for (const [key, val] of Object.entries(attribs)) {\n if (CONTROL_ATTRS.has(key)) {\n continue\n }\n restAttribs[key] = val\n }\n\n if (itemName === indexName) {\n indexName = `${indexName}Index`\n }\n\n return {\n expr,\n itemName,\n indexName,\n restAttribs,\n }\n}\n\nexport function buildAttributeString(\n attribs: Record<string, string>,\n scope: LegacyTemplateScope,\n) {\n let result = ''\n for (const [name, rawValue] of Object.entries(attribs)) {\n if (CONTROL_ATTRS.has(name)) {\n continue\n }\n\n const eventMatch = EVENT_PREFIX_RE.exec(name)\n if (eventMatch) {\n const [, prefix, rawEvent] = eventMatch\n const event = rawEvent.toLowerCase()\n const handlerName = resolveAttributeValue(rawValue, scope).trim()\n if (!handlerName) {\n continue\n }\n const runtimeEvent = EVENT_KIND_ALIAS[event] ?? event\n const flags = EVENT_PREFIX_FLAGS[prefix] ?? {}\n result += ` ${MINI_PROGRAM_EVENT_ATTRIBUTE_PREFIX}${runtimeEvent}=\"${escapeAttribute(handlerName)}\"`\n const flagTokens = [\n flags.capture ? 'capture' : '',\n flags.catch ? 'catch' : '',\n ].filter(Boolean)\n if (flagTokens.length) {\n result += ` ${MINI_PROGRAM_EVENT_FLAG_ATTRIBUTE_PREFIX}${runtimeEvent}=\"${flagTokens.join(',')}\"`\n }\n continue\n }\n\n const value = resolveAttributeValue(rawValue, scope)\n if (value === '') {\n continue\n }\n const normalizedName = normalizeAttributeName(name)\n result += ` ${normalizedName}=\"${escapeAttribute(value)}\"`\n }\n return result\n}\n\nexport function stripControlAttributes(attribs: Record<string, string>) {\n const result: Record<string, string> = {}\n for (const [name, value] of Object.entries(attribs)) {\n if (!CONTROL_ATTRS.has(name)) {\n result[name] = value\n }\n }\n return result\n}\n\nexport function isConditionalElement(node: Node): node is Element {\n if (node.type !== 'tag') {\n return false\n }\n const attribs = (node as Element).attribs ?? {}\n return hasControlAttribute(attribs, 'if')\n || hasControlAttribute(attribs, 'elif')\n || hasControlAttribute(attribs, 'else')\n}\n"],"mappings":";;;;;AAcA,MAAM,kBAAkB;AACxB,MAAM,mBAA2C;CAC/C,KAAK;CACL,SAAS;CACT,WAAW;CACZ;AAED,MAAM,qBAA6E;CACjF,QAAQ,EAAE;CACV,SAAS,EAAE,OAAO,MAAM;CACxB,YAAY,EAAE;CACd,gBAAgB,EAAE,SAAS,MAAM;CACjC,iBAAiB;EAAE,SAAS;EAAM,OAAO;EAAM;CAChD;AAED,SAAgB,WAAW,SAAmD;CAC5E,MAAM,OAAO,6BAA6B,SAAS,MAAM;CACzD,MAAM,cAAsC,EAAE;CAC9C,MAAM,WAAW,6BAA6B,SAAS,WAAW,EAAE,MAAM,IAAI;CAC9E,IAAI,YAAY,6BAA6B,SAAS,YAAY,EAAE,MAAM,IAAI;AAE9E,MAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,QAAQ,EAAE;AAChD,MAAI,cAAc,IAAI,IAAI,CACxB;AAEF,cAAY,OAAO;;AAGrB,KAAI,aAAa,UACf,aAAY,GAAG,UAAU;AAG3B,QAAO;EACL;EACA;EACA;EACA;EACD;;AAGH,SAAgB,qBACd,SACA,OACA;CACA,IAAI,SAAS;AACb,MAAK,MAAM,CAAC,MAAM,aAAa,OAAO,QAAQ,QAAQ,EAAE;AACtD,MAAI,cAAc,IAAI,KAAK,CACzB;EAGF,MAAM,aAAa,gBAAgB,KAAK,KAAK;AAC7C,MAAI,YAAY;GACd,MAAM,GAAG,QAAQ,YAAY;GAC7B,MAAM,QAAQ,SAAS,aAAa;GACpC,MAAM,cAAc,sBAAsB,UAAU,MAAM,CAAC,MAAM;AACjE,OAAI,CAAC,YACH;GAEF,MAAM,eAAe,iBAAiB,UAAU;GAChD,MAAM,QAAQ,mBAAmB,WAAW,EAAE;AAC9C,aAAU,IAAI,sCAAsC,aAAa,IAAI,gBAAgB,YAAY,CAAC;GAClG,MAAM,aAAa,CACjB,MAAM,UAAU,YAAY,IAC5B,MAAM,QAAQ,UAAU,GACzB,CAAC,OAAO,QAAQ;AACjB,OAAI,WAAW,OACb,WAAU,IAAI,2CAA2C,aAAa,IAAI,WAAW,KAAK,IAAI,CAAC;AAEjG;;EAGF,MAAM,QAAQ,sBAAsB,UAAU,MAAM;AACpD,MAAI,UAAU,GACZ;EAEF,MAAM,iBAAiB,uBAAuB,KAAK;AACnD,YAAU,IAAI,eAAe,IAAI,gBAAgB,MAAM,CAAC;;AAE1D,QAAO;;AAGT,SAAgB,uBAAuB,SAAiC;CACtE,MAAM,SAAiC,EAAE;AACzC,MAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,QAAQ,CACjD,KAAI,CAAC,cAAc,IAAI,KAAK,CAC1B,QAAO,QAAQ;AAGnB,QAAO;;AAGT,SAAgB,qBAAqB,MAA6B;AAChE,KAAI,KAAK,SAAS,MAChB,QAAO;CAET,MAAM,UAAW,KAAiB,WAAW,EAAE;AAC/C,QAAO,oBAAoB,SAAS,KAAK,IACpC,oBAAoB,SAAS,OAAO,IACpC,oBAAoB,SAAS,OAAO"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { SELF_CLOSING_TAGS, hasControlAttribute, normalizeTagName, resolveControlAttributeValue } from "../../shared/wxml.mjs";
|
|
1
2
|
import { createChildScope, createScope, evaluateExpression, interpolateText, normalizeList } from "./expression.mjs";
|
|
2
|
-
import {
|
|
3
|
+
import { buildAttributeString, extractFor, isConditionalElement, stripControlAttributes } from "./dom.mjs";
|
|
3
4
|
import { parseDocument } from "htmlparser2";
|
|
4
5
|
|
|
5
6
|
//#region src/runtime/legacyTemplate/index.ts
|
|
@@ -29,14 +30,14 @@ function renderConditionalSequence(nodes, startIndex, scope, renderChildren) {
|
|
|
29
30
|
if (!isConditionalElement(candidate)) break;
|
|
30
31
|
const element = candidate;
|
|
31
32
|
const attribs = element.attribs ?? {};
|
|
32
|
-
if (branches.length === 0 && !("
|
|
33
|
-
if (branches.length > 0 && !("
|
|
33
|
+
if (branches.length === 0 && !hasControlAttribute(attribs, "if")) break;
|
|
34
|
+
if (branches.length > 0 && !hasControlAttribute(attribs, "elif") && !hasControlAttribute(attribs, "else")) break;
|
|
34
35
|
branches.push({
|
|
35
36
|
node: element,
|
|
36
37
|
attribs
|
|
37
38
|
});
|
|
38
39
|
cursor += 1;
|
|
39
|
-
if ("
|
|
40
|
+
if (hasControlAttribute(attribs, "else")) break;
|
|
40
41
|
}
|
|
41
42
|
if (!branches.length) {
|
|
42
43
|
const node = nodes[startIndex];
|
|
@@ -46,11 +47,11 @@ function renderConditionalSequence(nodes, startIndex, scope, renderChildren) {
|
|
|
46
47
|
};
|
|
47
48
|
}
|
|
48
49
|
for (const { node, attribs } of branches) {
|
|
49
|
-
if ("
|
|
50
|
+
if (hasControlAttribute(attribs, "else")) return {
|
|
50
51
|
rendered: renderElement(node, scope, renderChildren, { overrideAttribs: stripControlAttributes(attribs) }),
|
|
51
52
|
endIndex: startIndex + branches.length - 1
|
|
52
53
|
};
|
|
53
|
-
const conditionExpr = attribs
|
|
54
|
+
const conditionExpr = resolveControlAttributeValue(attribs, "if") ?? resolveControlAttributeValue(attribs, "elif");
|
|
54
55
|
if (!conditionExpr) continue;
|
|
55
56
|
if (evaluateExpression(conditionExpr, scope)) return {
|
|
56
57
|
rendered: renderElement(node, scope, renderChildren, { overrideAttribs: stripControlAttributes(attribs) }),
|