From 7dc38dea27ba7b99d8cb56e1cbb9be0659e217f7 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 22 Oct 2016 16:27:35 +0800 Subject: [PATCH] fix SFC parsing pug templates that contains "<" (fix #3973) --- src/compiler/parser/html-parser.js | 20 ++++++++++++++++++-- src/sfc/parser.js | 3 ++- test/unit/modules/sfc/sfc-parser.spec.js | 10 ++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/compiler/parser/html-parser.js b/src/compiler/parser/html-parser.js index dcedab9f6c..930817173f 100644 --- a/src/compiler/parser/html-parser.js +++ b/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: diff --git a/src/sfc/parser.js b/src/sfc/parser.js index 3cb962b551..6b8530a828 100644 --- a/src/sfc/parser.js +++ b/src/sfc/parser.js @@ -92,7 +92,8 @@ export function parseComponent ( parseHTML(content, { start, - end + end, + sfc: true }) return sfc diff --git a/test/unit/modules/sfc/sfc-parser.spec.js b/test/unit/modules/sfc/sfc-parser.spec.js index 79b891fa8d..e98230dfa1 100644 --- a/test/unit/modules/sfc/sfc-parser.spec.js +++ b/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(` + + `) + expect(res.template.content.trim()).toBe(`div\n h1(v-if='1 < 2') hello`) + }) })