Quellcode durchsuchen

fix SFC parsing pug templates that contains "<" (fix #3973)

Evan You vor 9 Jahren
Ursprung
Commit
7dc38dea27
3 geänderte Dateien mit 30 neuen und 3 gelöschten Zeilen
  1. 18 2
      src/compiler/parser/html-parser.js
  2. 2 1
      src/sfc/parser.js
  3. 10 0
      test/unit/modules/sfc/sfc-parser.spec.js

+ 18 - 2
src/compiler/parser/html-parser.js

@@ -44,7 +44,23 @@ let IS_REGEX_CAPTURING_BROKEN = false
 })
 
 // Special Elements (can contain anything)
-const isSpecialTag = makeMap('script,style', true)
+const isScriptOrStyle = makeMap('script,style', true)
+const hasLang = attr => attr.name === 'lang' && attr.value !== 'html'
+const isSpecialTag = (tag, isSFC, stack) => {
+  if (isScriptOrStyle(tag)) {
+    return true
+  }
+  // top-level template that has a pre-processor
+  if (
+    isSFC &&
+    tag === 'template' &&
+    stack.length === 1 &&
+    stack[0].attrs.some(hasLang)
+  ) {
+    return true
+  }
+  return false
+}
 
 const reCache = {}
 
@@ -74,7 +90,7 @@ export function parseHTML (html, options) {
   while (html) {
     last = html
     // Make sure we're not in a script or style element
-    if (!lastTag || !isSpecialTag(lastTag)) {
+    if (!lastTag || !isSpecialTag(lastTag, options.sfc, stack)) {
       const textEnd = html.indexOf('<')
       if (textEnd === 0) {
         // Comment:

+ 2 - 1
src/sfc/parser.js

@@ -92,7 +92,8 @@ export function parseComponent (
 
   parseHTML(content, {
     start,
-    end
+    end,
+    sfc: true
   })
 
   return sfc

+ 10 - 0
test/unit/modules/sfc/sfc-parser.spec.js

@@ -63,4 +63,14 @@ describe('Single File Component parser', () => {
     expect(res.script.content).toBe(Array(3 + 1).join('//\n') + '\nexport default {}\n')
     expect(res.styles[0].content).toBe(Array(6 + 1).join('\n') + '\nh1 { color: red }\n')
   })
+
+  it('should handle template blocks with lang as special text', () => {
+    const res = parseComponent(`
+      <template lang="pug">
+        div
+          h1(v-if='1 < 2') hello
+      </template>
+    `)
+    expect(res.template.content.trim()).toBe(`div\n  h1(v-if='1 < 2') hello`)
+  })
 })