Skip to content

Commit

Permalink
fix(parser): the first newline following pre and textarea tag should …
Browse files Browse the repository at this point in the history
…be ignored (#6022)

fix #6022
  • Loading branch information
defcc authored and yyx990803 committed Jul 10, 2017
1 parent a1d1145 commit 4d68079
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
18 changes: 14 additions & 4 deletions src/compiler/parser/html-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand All @@ -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:
Expand Down Expand Up @@ -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(/<!--([\s\S]*?)-->/g, '$1')
.replace(/<!\[CDATA\[([\s\S]*?)]]>/g, '$1')
}
if (shouldIgnoreFirstNewline(stackedTag, text)) {
text = text.slice(1)
}
if (options.chars) {
options.chars(text)
}
Expand Down
18 changes: 16 additions & 2 deletions test/unit/modules/compiler/parser.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,21 @@ describe('parser', () => {
expect(span.children[0].text).toBe(' ')
})

// #5992
it('ignore the first newline in <pre> tag', function () {
const options = extend({}, baseOptions)
const ast = parse('<div><pre>\nabc</pre>\ndef<pre>\n\nabc</pre></div>', 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('<p>1 < 2 < 3</p>', options)
Expand Down Expand Up @@ -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(`
<p>Test 1</p>
expect(whitespace.children[0].text).toBe(` <p>Test 1</p>
test2
`)

Expand Down

0 comments on commit 4d68079

Please sign in to comment.