Browse Source

fix: handle encoded tabs and newlines in attributes for Chrome a[href] and IE/Edge

fix #6828, fix #6916
dev
Evan You 7 years ago
parent
commit
cfd73c2386
  1. 3
      flow/compiler.js
  2. 13
      src/compiler/parser/html-parser.js
  3. 1
      src/compiler/parser/index.js
  4. 3
      src/platforms/web/entry-runtime-with-compiler.js
  5. 16
      src/platforms/web/util/compat.js

3
flow/compiler.js

@ -14,7 +14,8 @@ declare type CompilerOptions = {
preserveWhitespace?: boolean;
isFromDOM?: boolean;
shouldDecodeTags?: boolean;
shouldDecodeNewlines?: boolean;
shouldDecodeNewlines?: boolean;
shouldDecodeNewlinesForHref?: boolean;
// for ssr optimization compiler
scopeId?: string;

13
src/compiler/parser/html-parser.js

@ -39,10 +39,11 @@ const decodingMap = {
'>': '>',
'"': '"',
'&': '&',
'
': '\n'
'
': '\n',
'	': '\t'
}
const encodedAttr = /&(?:lt|gt|quot|amp);/g
const encodedAttrWithNewLines = /&(?:lt|gt|quot|amp|#10);/g
const encodedAttrWithNewLines = /&(?:lt|gt|quot|amp|#10|#9);/g
// #5992
const isIgnoreNewlineTag = makeMap('pre,textarea', true)
@ -233,12 +234,12 @@ export function parseHTML (html, options) {
if (args[5] === '') { delete args[5] }
}
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,
options.shouldDecodeNewlines
)
value: decodeAttr(value, shouldDecodeNewlines)
}
}

1
src/compiler/parser/index.js

@ -107,6 +107,7 @@ export function parse (
isUnaryTag: options.isUnaryTag,
canBeLeftOpenTag: options.canBeLeftOpenTag,
shouldDecodeNewlines: options.shouldDecodeNewlines,
shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref,
shouldKeepComment: options.comments,
start (tag, attrs, unary) {
// check namespace.

3
src/platforms/web/entry-runtime-with-compiler.js

@ -6,8 +6,8 @@ import { mark, measure } from 'core/util/perf'
import Vue from './runtime/index'
import { query } from './util/index'
import { shouldDecodeNewlines } from './util/compat'
import { compileToFunctions } from './compiler/index'
import { shouldDecodeNewlines, shouldDecodeNewlinesForHref } from './util/compat'
const idToTemplate = cached(id => {
const el = query(id)
@ -64,6 +64,7 @@ Vue.prototype.$mount = function (
const { render, staticRenderFns } = compileToFunctions(template, {
shouldDecodeNewlines,
shouldDecodeNewlinesForHref,
delimiters: options.delimiters,
comments: options.comments
}, this)

16
src/platforms/web/util/compat.js

@ -3,12 +3,14 @@
import { inBrowser } from 'core/util/index'
// check whether current browser encodes a char inside attribute values
function shouldDecode (content: string, encoded: string): boolean {
const div = document.createElement('div')
div.innerHTML = `<div a="${content}"/>`
return div.innerHTML.indexOf(encoded) > 0
let div
function getShouldDecode (href: boolean): boolean {
div = div || document.createElement('div')
div.innerHTML = href ? `<a href="\n"/>` : `<div a="\n"/>`
return div.innerHTML.indexOf('&#10;') > 0
}
// #3663
// IE encodes newlines inside attribute values while other browsers don't
export const shouldDecodeNewlines = inBrowser ? shouldDecode('\n', '&#10;') : false
// #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

Loading…
Cancel
Save