diff --git a/src/compiler/parser/html-parser.js b/src/compiler/parser/html-parser.js index dbc59146331..22f1b9d2423 100644 --- a/src/compiler/parser/html-parser.js +++ b/src/compiler/parser/html-parser.js @@ -30,25 +30,19 @@ const conditionalComment = /^', - '"': '"', - '&': '&', - ' ': '\n', - ' ': '\t', - ''': "'" -} -const encodedAttr = /&(?:lt|gt|quot|amp|#39);/g -const encodedAttrWithNewLines = /&(?:lt|gt|quot|amp|#39|#10|#9);/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]) +let textareaEl +function decodeHTMLEnitities(value) { + textareaEl = textareaEl || document.createElement('textarea') + textareaEl.innerHTML = value + return textareaEl.value +} + +function decodeAttr (value) { + return decodeHTMLEnitities(value) } export function parseHTML (html, options) { @@ -229,12 +223,9 @@ export function parseHTML (html, options) { for (let i = 0; i < l; i++) { const args = match.attrs[i] const value = args[3] || args[4] || args[5] || '' - const shouldDecodeNewlines = tagName === 'a' && args[1] === 'href' - ? options.shouldDecodeNewlinesForHref - : options.shouldDecodeNewlines attrs[i] = { name: args[1], - value: decodeAttr(value, shouldDecodeNewlines) + value: decodeAttr(value) } if (process.env.NODE_ENV !== 'production' && options.outputSourceRange) { attrs[i].start = args.start + args[0].match(/^\s*/).length diff --git a/src/compiler/parser/index.js b/src/compiler/parser/index.js index 342d04ff864..d84723c915d 100644 --- a/src/compiler/parser/index.js +++ b/src/compiler/parser/index.js @@ -206,8 +206,6 @@ export function parse ( expectHTML: options.expectHTML, isUnaryTag: options.isUnaryTag, canBeLeftOpenTag: options.canBeLeftOpenTag, - shouldDecodeNewlines: options.shouldDecodeNewlines, - shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref, shouldKeepComment: options.comments, outputSourceRange: options.outputSourceRange, start (tag, attrs, unary, start, end) { diff --git a/src/platforms/web/entry-runtime-with-compiler.js b/src/platforms/web/entry-runtime-with-compiler.js index 2bb46362bf9..186d0d3dd25 100644 --- a/src/platforms/web/entry-runtime-with-compiler.js +++ b/src/platforms/web/entry-runtime-with-compiler.js @@ -7,7 +7,6 @@ import { mark, measure } from 'core/util/perf' import Vue from './runtime/index' import { query } from './util/index' import { compileToFunctions } from './compiler/index' -import { shouldDecodeNewlines, shouldDecodeNewlinesForHref } from './util/compat' const idToTemplate = cached(id => { const el = query(id) @@ -64,8 +63,6 @@ Vue.prototype.$mount = function ( const { render, staticRenderFns } = compileToFunctions(template, { outputSourceRange: process.env.NODE_ENV !== 'production', - shouldDecodeNewlines, - shouldDecodeNewlinesForHref, delimiters: options.delimiters, comments: options.comments }, this) diff --git a/src/platforms/web/util/compat.js b/src/platforms/web/util/compat.js deleted file mode 100644 index d95759cce31..00000000000 --- a/src/platforms/web/util/compat.js +++ /dev/null @@ -1,16 +0,0 @@ -/* @flow */ - -import { inBrowser } from 'core/util/index' - -// check whether current browser encodes a char inside attribute values -let div -function getShouldDecode (href: boolean): boolean { - div = div || document.createElement('div') - div.innerHTML = href ? `` : `
` - return div.innerHTML.indexOf(' ') > 0 -} - -// #3663: IE encodes newlines inside attribute values while other browsers don't -export const shouldDecodeNewlines = inBrowser ? getShouldDecode(false) : false -// #6828: chrome encodes content in a[href] -export const shouldDecodeNewlinesForHref = inBrowser ? getShouldDecode(true) : false diff --git a/test/unit/modules/compiler/parser.spec.js b/test/unit/modules/compiler/parser.spec.js index d6521bbf625..399aa865857 100644 --- a/test/unit/modules/compiler/parser.spec.js +++ b/test/unit/modules/compiler/parser.spec.js @@ -2,6 +2,7 @@ import { parse } from 'compiler/parser/index' import { extend } from 'shared/util' import { baseOptions } from 'web/compiler/options' import { isIE, isEdge } from 'core/util/env' +import Vue from 'vue' describe('parser', () => { it('simple element', () => { @@ -881,4 +882,38 @@ describe('parser', () => { expect(ast.children[2].type).toBe(3) expect(ast.children[2].text).toBe('\ndef') }) + + it(`HTML entities in the value of attribute should be decoded`, () => { + const options = extend({}, baseOptions) + const ast = parse('', options) + expect(ast.attrsList[0].value).toBe('white space,single-' + "'" + '-quote,double-' + '"' + '-quote,an-&-ampersand,less-<-than,great->-than,line-\n-break,tab-\t-space') + }) + + it(`HTML entities in template should be decoded`, () => { + const vm = new Vue({ + template: '