]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(parser): fix interpolation parsing in v-pre
authorEvan You <yyx990803@gmail.com>
Mon, 4 Dec 2023 15:06:56 +0000 (23:06 +0800)
committerEvan You <yyx990803@gmail.com>
Mon, 4 Dec 2023 15:06:56 +0000 (23:06 +0800)
ref: https://github.com/vuejs/docs/issues/2586

packages/compiler-core/__tests__/parse.spec.ts
packages/compiler-core/src/parser.ts
packages/compiler-core/src/tokenizer.ts

index 9d84e80c2a6e031a9866419e19259bfd5a23b82c..7c6b9f463d8a5afaa68ee29a770fef188b9f4e45 100644 (file)
@@ -1733,6 +1733,35 @@ describe('compiler: parse', () => {
       })
     })
 
+    // https://github.com/vuejs/docs/issues/2586
+    test('v-pre with half-open interpolation', () => {
+      const ast = baseParse(
+        `<div v-pre>
+          <span>{{ number </span>
+          <span>}}</span>
+        </div>
+        `
+      )
+      expect((ast.children[0] as ElementNode).children).toMatchObject([
+        {
+          type: NodeTypes.ELEMENT,
+          children: [{ type: NodeTypes.TEXT, content: `{{ number ` }]
+        },
+        {
+          type: NodeTypes.ELEMENT,
+          children: [{ type: NodeTypes.TEXT, content: `}}` }]
+        }
+      ])
+
+      const ast2 = baseParse(`<div v-pre><span>{{ number </span></div>`)
+      expect((ast2.children[0] as ElementNode).children).toMatchObject([
+        {
+          type: NodeTypes.ELEMENT,
+          children: [{ type: NodeTypes.TEXT, content: `{{ number ` }]
+        }
+      ])
+    })
+
     test('self-closing v-pre', () => {
       const ast = baseParse(
         `<div v-pre/>\n<div :id="foo"><Comp/>{{ bar }}</div>`
index f1d712b3643c8715673baad2216b153fde9d4ca8..2250719f5707d23e94ad2551b4469174863dae35 100644 (file)
@@ -236,7 +236,7 @@ const tokenizer = new Tokenizer(stack, {
         loc: getLoc(start)
       }
       if (name === 'pre') {
-        inVPre = true
+        inVPre = tokenizer.inVPre = true
         currentVPreBoundary = currentOpenTag
         // convert dirs before this one to attributes
         const props = currentOpenTag!.props
@@ -652,7 +652,7 @@ function onCloseTag(el: ElementNode, end: number, isImplied = false) {
     inPre--
   }
   if (currentVPreBoundary === el) {
-    inVPre = false
+    inVPre = tokenizer.inVPre = false
     currentVPreBoundary = null
   }
   if (
index ca122f3098204f98741297d562e086d1c8a2da1e..8adb1b47b4d01078cc9c4a4f3ffa0a4c49a6643e 100644 (file)
@@ -242,6 +242,8 @@ export default class Tokenizer {
   public inRCDATA = false
   /** For disabling RCDATA tags handling */
   public inXML = false
+  /** For disabling interpolation parsing in v-pre */
+  public inVPre = false
   /** Record newline positions for fast line / column calculation */
   private newlines: number[] = []
 
@@ -314,7 +316,7 @@ export default class Tokenizer {
       this.sectionStart = this.index
     } else if (!__BROWSER__ && c === CharCodes.Amp) {
       this.startEntity()
-    } else if (c === this.delimiterOpen[0]) {
+    } else if (!this.inVPre && c === this.delimiterOpen[0]) {
       this.state = State.InterpolationOpen
       this.delimiterIndex = 0
       this.stateInterpolationOpen(c)