From 43a38070e3205f6a68d10f15348e6a206bf4abdc Mon Sep 17 00:00:00 2001
From: yurj26 <1816387074@qq.com>
Date: Thu, 4 May 2023 10:57:34 +0800
Subject: [PATCH] feat(uts): transformText
---
.../transforms/transformText.spec.ts | 30 +++++
.../src/plugins/uvue/compiler/index.ts | 2 +
.../uvue/compiler/transforms/transformText.ts | 107 ++++++++++++++++++
3 files changed, 139 insertions(+)
create mode 100644 packages/uni-app-uts/__tests__/transforms/transformText.spec.ts
create mode 100644 packages/uni-app-uts/src/plugins/uvue/compiler/transforms/transformText.ts
diff --git a/packages/uni-app-uts/__tests__/transforms/transformText.spec.ts b/packages/uni-app-uts/__tests__/transforms/transformText.spec.ts
new file mode 100644
index 0000000000..35318b4cb5
--- /dev/null
+++ b/packages/uni-app-uts/__tests__/transforms/transformText.spec.ts
@@ -0,0 +1,30 @@
+import { assert } from '../testUtils'
+
+describe('compiler: transform text', () => {
+ test('transform text', () => {
+ assert(
+ `hello`,
+ `createElementVNode("view", null, [
+ createElementVNode("text", null, "hello")
+])`
+ )
+ assert(
+ `hello`,
+ `createElementVNode("view", null, [
+ createElementVNode("text", null, "hello")
+])`
+ )
+ assert(
+ `hello{{a}}aaa{{a}}{{b}}`,
+ `createElementVNode("view", null, [
+ createElementVNode("text", null, "hello"),
+ createElementVNode("text", null, toDisplayString(_ctx.a), 1 /* TEXT */),
+ createElementVNode("view", null, [
+ createElementVNode("text", null, "aaa"),
+ createElementVNode("text", null, toDisplayString(_ctx.a), 1 /* TEXT */)
+ ]),
+ createElementVNode("text", null, toDisplayString(_ctx.b), 1 /* TEXT */)
+])`
+ )
+ })
+})
diff --git a/packages/uni-app-uts/src/plugins/uvue/compiler/index.ts b/packages/uni-app-uts/src/plugins/uvue/compiler/index.ts
index 39d281336d..d987d9bc40 100644
--- a/packages/uni-app-uts/src/plugins/uvue/compiler/index.ts
+++ b/packages/uni-app-uts/src/plugins/uvue/compiler/index.ts
@@ -18,6 +18,7 @@ import { transformIf } from './transforms/vIf'
import { transformFor } from './transforms/vFor'
import { transformModel } from './transforms/vModel'
import { transformShow } from './transforms/vShow'
+import { transformText } from './transforms/transformText'
export type TransformPreset = [
NodeTransform[],
@@ -36,6 +37,7 @@ export function getBaseTransformPreset(
transformExpression,
transformElement,
trackSlotScopes,
+ transformText,
] as any,
{
on: transformOn,
diff --git a/packages/uni-app-uts/src/plugins/uvue/compiler/transforms/transformText.ts b/packages/uni-app-uts/src/plugins/uvue/compiler/transforms/transformText.ts
new file mode 100644
index 0000000000..c89f8990ad
--- /dev/null
+++ b/packages/uni-app-uts/src/plugins/uvue/compiler/transforms/transformText.ts
@@ -0,0 +1,107 @@
+import { isElementNode } from '@dcloudio/uni-cli-shared'
+import {
+ CompoundExpressionNode,
+ ElementNode,
+ ElementTypes,
+ InterpolationNode,
+ NodeTransform,
+ NodeTypes,
+ TemplateChildNode,
+ TextCallNode,
+ TextNode,
+} from '@vue/compiler-core'
+
+function isTextNode({ tag }: ElementNode) {
+ return tag === 'text' || tag === 'u-text' || tag === 'button'
+}
+
+function isTextElement(node: TemplateChildNode) {
+ return node.type === NodeTypes.ELEMENT && node.tag === 'text'
+}
+
+function isText(
+ node: TemplateChildNode
+): node is
+ | TextNode
+ | TextCallNode
+ | InterpolationNode
+ | CompoundExpressionNode {
+ const { type } = node
+ return (
+ type === NodeTypes.TEXT ||
+ type === NodeTypes.TEXT_CALL ||
+ type === NodeTypes.INTERPOLATION ||
+ type === NodeTypes.COMPOUND_EXPRESSION
+ )
+}
+
+export const transformText: NodeTransform = (node, _) => {
+ if (!isElementNode(node)) {
+ return
+ }
+ if (isTextNode(node)) {
+ return
+ }
+ const { children } = node
+ if (!children.length) {
+ return
+ }
+ children.forEach((child, index) => {
+ if (isTextElement(child)) {
+ parseText(child as ElementNode)
+ }
+
+ if (isText(child)) {
+ children.splice(index, 1, createText(node, child))
+ }
+ })
+}
+
+/*
+ 1. 转换 \\n 为 \n
+ 2. u-text 下只能有一个文本节点(不支持 children),需要移除子组件并合并文本
+*/
+function parseText(node: ElementNode) {
+ if (node.children.length) {
+ let firstTextChild
+ for (let i = 0; i < node.children.length; i++) {
+ const child = node.children[i]
+ if (isText(child) && typeof (child as TextNode).content === 'string') {
+ if (!firstTextChild) {
+ firstTextChild = child
+ ;(firstTextChild as TextNode).content = (
+ firstTextChild as TextNode
+ ).content.replace(/\\n/g, '\n')
+ } else {
+ ;(firstTextChild as TextNode).content += (
+ child as TextNode
+ ).content.replace(/\\n/g, '\n')
+ node.children.splice(i, 1)
+ i--
+ }
+ } else if (child.type === 1 || child.type === 3) {
+ node.children.splice(i, 1)
+ i--
+ } else {
+ firstTextChild = null
+ }
+ }
+ }
+}
+
+function createText(
+ parent: ElementNode,
+ node: TextNode | TextCallNode | InterpolationNode | CompoundExpressionNode
+): ElementNode {
+ return {
+ tag: 'text',
+ type: NodeTypes.ELEMENT,
+ tagType: ElementTypes.ELEMENT,
+ props: [],
+ isSelfClosing: false,
+ children: [node],
+ codegenNode: undefined,
+ ns: parent.ns,
+ loc: node.loc,
+ }
+}
--
GitLab