mirror of https://github.com/vuejs/vue.git
fix(parser): the first newline following pre and textarea tag should be ignored (#6022)
fix #6022
This commit is contained in:
parent
a1d1145c91
commit
4d680794a5
|
|
@ -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(/<!--([\s\S]*?)-->/g, '$1')
|
||||
.replace(/<!\[CDATA\[([\s\S]*?)]]>/g, '$1')
|
||||
}
|
||||
if (shouldIgnoreFirstNewline(stackedTag, text)) {
|
||||
text = text.slice(1)
|
||||
}
|
||||
if (options.chars) {
|
||||
options.chars(text)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
`)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue