diff --git a/src/compiler/parser/html-parser.js b/src/compiler/parser/html-parser.js index b7c2f1d0e92..670ee3ddf15 100644 --- a/src/compiler/parser/html-parser.js +++ b/src/compiler/parser/html-parser.js @@ -59,6 +59,10 @@ const decodingMap = { const encodedAttr = /&(?:lt|gt|quot|amp);/g const encodedAttrWithNewLines = /&(?:lt|gt|quot|amp|#10);/g +// #5992 +const isIgnoreNewlineTag = makeMap('pre,textarea', true) +const shouldIgnoreFirstNewline = (tag, html) => tag && isIgnoreNewlineTag(tag) && html[0] === '\n' + function decodeAttr (value, shouldDecodeNewlines) { const re = shouldDecodeNewlines ? encodedAttrWithNewLines : encodedAttr return value.replace(re, match => decodingMap[match]) @@ -75,6 +79,9 @@ export function parseHTML (html, options) { last = html // Make sure we're not in a plaintext content element like script/style if (!lastTag || !isPlainTextElement(lastTag)) { + if (shouldIgnoreFirstNewline(lastTag, html)) { + advance(1) + } let textEnd = html.indexOf('<') if (textEnd === 0) { // Comment: @@ -152,16 +159,19 @@ export function parseHTML (html, options) { options.chars(text) } } else { - var stackedTag = lastTag.toLowerCase() - var reStackedTag = reCache[stackedTag] || (reCache[stackedTag] = new RegExp('([\\s\\S]*?)(' + stackedTag + '[^>]*>)', 'i')) - var endTagLength = 0 - var rest = html.replace(reStackedTag, function (all, text, endTag) { + let endTagLength = 0 + const stackedTag = lastTag.toLowerCase() + const reStackedTag = reCache[stackedTag] || (reCache[stackedTag] = new RegExp('([\\s\\S]*?)(' + stackedTag + '[^>]*>)', 'i')) + const rest = html.replace(reStackedTag, function (all, text, endTag) { endTagLength = endTag.length if (!isPlainTextElement(stackedTag) && stackedTag !== 'noscript') { text = text .replace(//g, '$1') .replace(//g, '$1') } + if (shouldIgnoreFirstNewline(stackedTag, text)) { + text = text.slice(1) + } if (options.chars) { options.chars(text) } diff --git a/test/unit/modules/compiler/parser.spec.js b/test/unit/modules/compiler/parser.spec.js index 171faf6672f..71e032f15b9 100644 --- a/test/unit/modules/compiler/parser.spec.js +++ b/test/unit/modules/compiler/parser.spec.js @@ -495,6 +495,21 @@ describe('parser', () => { expect(span.children[0].text).toBe(' ') }) + // #5992 + it('ignore the first newline in
tag', function () {
+ const options = extend({}, baseOptions)
+ const ast = parse('\nabc
\ndef\n\nabc
', options)
+ const pre = ast.children[0]
+ expect(pre.children[0].type).toBe(3)
+ expect(pre.children[0].text).toBe('abc')
+ const text = ast.children[1]
+ expect(text.type).toBe(3)
+ expect(text.text).toBe('\ndef')
+ const pre2 = ast.children[2]
+ expect(pre2.children[0].type).toBe(3)
+ expect(pre2.children[0].text).toBe('\nabc')
+ })
+
it('forgivingly handle < in plain text', () => {
const options = extend({}, baseOptions)
const ast = parse('1 < 2 < 3
', options)
@@ -530,8 +545,7 @@ describe('parser', () => {
expect(whitespace.children.length).toBe(1)
expect(whitespace.children[0].type).toBe(3)
// textarea is whitespace sensitive
- expect(whitespace.children[0].text).toBe(`
- Test 1
+ expect(whitespace.children[0].text).toBe(` Test 1
test2
`)