]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(sfc): treat custom block content as raw text
authorEvan You <yyx990803@gmail.com>
Mon, 23 Dec 2019 02:09:39 +0000 (21:09 -0500)
committerEvan You <yyx990803@gmail.com>
Mon, 23 Dec 2019 02:09:39 +0000 (21:09 -0500)
packages/compiler-core/src/options.ts
packages/compiler-core/src/parse.ts
packages/compiler-sfc/__tests__/parse.spec.ts
packages/compiler-sfc/src/parse.ts

index 2e08cdaed9eff7e622998c85320b7ae8e00ad5c3..8dca9210e560f2eb31dac2e1760bf26ee1292a81 100644 (file)
@@ -10,7 +10,11 @@ export interface ParserOptions {
   isCustomElement?: (tag: string) => boolean
   isBuiltInComponent?: (tag: string) => symbol | void
   getNamespace?: (tag: string, parent: ElementNode | undefined) => Namespace
-  getTextMode?: (tag: string, ns: Namespace) => TextModes
+  getTextMode?: (
+    tag: string,
+    ns: Namespace,
+    parent: ElementNode | undefined
+  ) => TextModes
   delimiters?: [string, string] // ['{{', '}}']
 
   // Map to HTML entities. E.g., `{ "amp;": "&" }`
index b9b37953b5e1ce9319b295f0c8df8b8e3777519e..9c3299a365b5c25fda8b95f5887a1351a7da1a27 100644 (file)
@@ -365,7 +365,7 @@ function parseElement(
 
   // Children.
   ancestors.push(element)
-  const mode = context.options.getTextMode(element.tag, element.ns)
+  const mode = context.options.getTextMode(element.tag, element.ns, parent)
   const children = parseChildren(context, mode, ancestors)
   ancestors.pop()
 
index 6a4534c11c21f75ef234dbc189efcd74b5257fd2..affe1f5a368418f0018bb88ffa13bc90e5fb3226 100644 (file)
@@ -78,8 +78,8 @@ h1 { color: red }
     <template v-if="ok">ok</template>
     <div><div></div></div>
     `
-    const sfc = parse(`<template>${content}</template>`).descriptor
-    expect(sfc.template!.content).toBe(content)
+    const { descriptor } = parse(`<template>${content}</template>`)
+    expect(descriptor.template!.content).toBe(content)
   })
 
   test('error tolerance', () => {
@@ -102,6 +102,12 @@ h1 { color: red }
     expect(errors.length).toBe(1)
   })
 
+  test('treat custom blocks as raw text', () => {
+    const { errors, descriptor } = parse(`<foo> <-& </foo>`)
+    expect(errors.length).toBe(0)
+    expect(descriptor.customBlocks[0].content).toBe(` <-& `)
+  })
+
   describe('warnings', () => {
     test('should only allow single template element', () => {
       parse(`<template><div/></template><template><div/></template>`)
index 38c611dfb88bac386397974989791ceadc746348..1953027c903c7cbd4cb4c680935c0efd13753b6f 100644 (file)
@@ -2,7 +2,8 @@ import {
   NodeTypes,
   ElementNode,
   SourceLocation,
-  CompilerError
+  CompilerError,
+  TextModes
 } from '@vue/compiler-core'
 import { RawSourceMap, SourceMapGenerator } from 'source-map'
 import LRUCache from 'lru-cache'
@@ -89,6 +90,15 @@ export function parse(
     isNativeTag: () => true,
     // preserve all whitespaces
     isPreTag: () => true,
+    getTextMode: (tag, _ns, parent) => {
+      // all top level elements except <template> are parsed as raw text
+      // containers
+      if (!parent && tag !== 'template') {
+        return TextModes.RAWTEXT
+      } else {
+        return TextModes.DATA
+      }
+    },
     onError: e => {
       errors.push(e)
     }