Skip to content

Commit 0833d7f

Browse files
yyx990803hefeng
authored and
hefeng
committed
fix: handle encoded tabs and newlines in attributes for Chrome a[href] and IE/Edge
fix vuejs#6828, fix vuejs#6916
1 parent 58f8d1d commit 0833d7f

File tree

5 files changed

+21
-15
lines changed

5 files changed

+21
-15
lines changed

flow/compiler.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ declare type CompilerOptions = {
1414
preserveWhitespace?: boolean;
1515
isFromDOM?: boolean;
1616
shouldDecodeTags?: boolean;
17-
shouldDecodeNewlines?: boolean;
17+
shouldDecodeNewlines?: boolean;
18+
shouldDecodeNewlinesForHref?: boolean;
1819

1920
// for ssr optimization compiler
2021
scopeId?: string;

src/compiler/parser/html-parser.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,11 @@ const decodingMap = {
3939
'>': '>',
4040
'"': '"',
4141
'&': '&',
42-
'
': '\n'
42+
'
': '\n',
43+
'	': '\t'
4344
}
4445
const encodedAttr = /&(?:lt|gt|quot|amp);/g
45-
const encodedAttrWithNewLines = /&(?:lt|gt|quot|amp|#10);/g
46+
const encodedAttrWithNewLines = /&(?:lt|gt|quot|amp|#10|#9);/g
4647

4748
// #5992
4849
const isIgnoreNewlineTag = makeMap('pre,textarea', true)
@@ -233,12 +234,12 @@ export function parseHTML (html, options) {
233234
if (args[5] === '') { delete args[5] }
234235
}
235236
const value = args[3] || args[4] || args[5] || ''
237+
const shouldDecodeNewlines = tagName === 'a' && args[1] === 'href'
238+
? options.shouldDecodeNewlinesForHref
239+
: options.shouldDecodeNewlines
236240
attrs[i] = {
237241
name: args[1],
238-
value: decodeAttr(
239-
value,
240-
options.shouldDecodeNewlines
241-
)
242+
value: decodeAttr(value, shouldDecodeNewlines)
242243
}
243244
}
244245

src/compiler/parser/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ export function parse (
107107
isUnaryTag: options.isUnaryTag,
108108
canBeLeftOpenTag: options.canBeLeftOpenTag,
109109
shouldDecodeNewlines: options.shouldDecodeNewlines,
110+
shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref,
110111
shouldKeepComment: options.comments,
111112
start (tag, attrs, unary) {
112113
// check namespace.

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import { mark, measure } from 'core/util/perf'
66

77
import Vue from './runtime/index'
88
import { query } from './util/index'
9-
import { shouldDecodeNewlines } from './util/compat'
109
import { compileToFunctions } from './compiler/index'
10+
import { shouldDecodeNewlines, shouldDecodeNewlinesForHref } from './util/compat'
1111

1212
const idToTemplate = cached(id => {
1313
const el = query(id)
@@ -64,6 +64,7 @@ Vue.prototype.$mount = function (
6464

6565
const { render, staticRenderFns } = compileToFunctions(template, {
6666
shouldDecodeNewlines,
67+
shouldDecodeNewlinesForHref,
6768
delimiters: options.delimiters,
6869
comments: options.comments
6970
}, this)

src/platforms/web/util/compat.js

+9-7
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
import { inBrowser } from 'core/util/index'
44

55
// check whether current browser encodes a char inside attribute values
6-
function shouldDecode (content: string, encoded: string): boolean {
7-
const div = document.createElement('div')
8-
div.innerHTML = `<div a="${content}"/>`
9-
return div.innerHTML.indexOf(encoded) > 0
6+
let div
7+
function getShouldDecode (href: boolean): boolean {
8+
div = div || document.createElement('div')
9+
div.innerHTML = href ? `<a href="\n"/>` : `<div a="\n"/>`
10+
return div.innerHTML.indexOf('&#10;') > 0
1011
}
1112

12-
// #3663
13-
// IE encodes newlines inside attribute values while other browsers don't
14-
export const shouldDecodeNewlines = inBrowser ? shouldDecode('\n', '&#10;') : false
13+
// #3663: IE encodes newlines inside attribute values while other browsers don't
14+
export const shouldDecodeNewlines = inBrowser ? getShouldDecode(false) : false
15+
// #6828: chrome encodes content in a[href]
16+
export const shouldDecodeNewlinesForHref = inBrowser ? getShouldDecode(true) : false

0 commit comments

Comments
 (0)