From 82ac5fa9d02d6fb9df84ac3999a0d24cd13d6c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=BA=9A=E7=90=AA?= Date: Thu, 14 Nov 2024 16:24:57 +0800 Subject: [PATCH] =?UTF-8?q?feat(mp):=20=E8=B0=83=E6=95=B4uni-app-x?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E9=9D=99=E6=80=81=E5=AE=9E=E4=BD=93=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E8=BD=AC=E4=B9=89=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/uni-cli-shared/src/utils.ts | 31 +++++++++++++++++++ .../uni-mp-compiler/src/template/codegen.ts | 27 +++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/packages/uni-cli-shared/src/utils.ts b/packages/uni-cli-shared/src/utils.ts index 675caa3f954..3568fe7c583 100644 --- a/packages/uni-cli-shared/src/utils.ts +++ b/packages/uni-cli-shared/src/utils.ts @@ -278,3 +278,34 @@ export function isNormalCompileTarget() { // 目前有特殊编译目标 uni_modules 和 ext-api return !process.env.UNI_COMPILE_TARGET } + +/** + * copy from entities 用于转义实体字符 + * @param regex + * @param map + * @returns + */ +export function getEscaper( + regex: RegExp, + map: Map +): (data: string) => string { + return function escape(data: string): string { + let match + let lastIndex = 0 + let result = '' + + while ((match = regex.exec(data))) { + if (lastIndex !== match.index) { + result += data.substring(lastIndex, match.index) + } + + // We know that this character will be in the map. + result += map.get(match[0].charCodeAt(0))! + + // Every match will be of length 1 + lastIndex = match.index + 1 + } + + return result + data.substring(lastIndex) + } +} diff --git a/packages/uni-mp-compiler/src/template/codegen.ts b/packages/uni-mp-compiler/src/template/codegen.ts index 2c7cc84ab1f..fd65e77dd1e 100644 --- a/packages/uni-mp-compiler/src/template/codegen.ts +++ b/packages/uni-mp-compiler/src/template/codegen.ts @@ -3,6 +3,7 @@ import { SLOT_DEFAULT_NAME, dynamicSlotName } from '@dcloudio/uni-shared' import { type MiniProgramCompilerOptions, formatMiniProgramEvent, + getEscaper, isAttributeNode, isElementNode, isUserComponent, @@ -51,6 +52,26 @@ export interface TemplateCodegenContext { checkPropName: TemplateCodegenOptions['checkPropName'] } +/** + * 注意此处的 escapeText 并未解决用户代码内的实体字符与产物内的不一致的Bug。 + * vue编译器在tokenize阶段会将实体字符转义为对应的字符,因此在codegen阶段无法做到完美还原用户代码。 + * 但是在uni-app-x依然要做反转义,主要考虑以下几点: + * - 用户源码>原产物为>,导致wxml解析错误 + * - 用户源码内不会出现>字符。虽然emsp等字符可以出现在用户的源码里面,但是一般不会有人这么做。因此无论用户写的是 还是\u2003,都被转义为 对用户而言影响不大 + */ +const mpEscapeText = getEscaper( + /[&<>\u2009\u00A0\u2002\u2003]/g, + new Map([ + [38, '&'], + [60, '<'], + [62, '>'], + [0x2009, ' '], + [0xa0, ' '], + [0x2002, ' '], + [0x2003, ' '], + ]) +) + export function generate( { children }: RootNode, { @@ -127,7 +148,11 @@ export function genNode( } function genText(node: TextNode, { push }: TemplateCodegenContext) { - push(node.content) + if (process.env.UNI_APP_X === 'true') { + push(mpEscapeText(node.content)) + } else { + push(node.content) + } } function genExpression(node: ExpressionNode, { push }: TemplateCodegenContext) {