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('', 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('\nabc\ndef\n\nabc1 < 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 `)