Skip to content

Commit 6e1597c

Browse files
committed
fix quote decoding for templates retrieved from innerHTML (fix vuejs#3403)
1 parent 21908b7 commit 6e1597c

File tree

5 files changed

+10
-7
lines changed

5 files changed

+10
-7
lines changed

src/compiler/codegen/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ export function generate (
2828
dataGenFns = pluckModuleFunction(options.modules, 'genData')
2929
platformDirectives = options.directives || {}
3030
const code = ast ? genElement(ast) : '_h("div")'
31-
// console.log(code)
3231
staticRenderFns = prevStaticRenderFns
3332
return {
3433
render: `with(this){return ${code}}`,

src/compiler/parser/html-parser.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,13 @@ const reCache = {}
5151
const ampRE = /&/g
5252
const ltRE = /</g
5353
const gtRE = />/g
54+
const quoteRE = /"/g
5455

5556
function decodeAttr (value, shouldDecodeTags) {
5657
if (shouldDecodeTags) {
5758
value = value.replace(ltRE, '<').replace(gtRE, '>')
5859
}
59-
return value.replace(ampRE, '&')
60+
return value.replace(ampRE, '&').replace(quoteRE, '"')
6061
}
6162

6263
export function parseHTML (html, options) {

src/platforms/web/util/index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ export const isIE = UA && /msie|trident/.test(UA)
1111
export const isIE9 = UA && UA.indexOf('msie 9.0') > 0
1212
export const isAndroid = UA && UA.indexOf('android') > 0
1313

14-
// some browsers, e.g. PhantomJS, encodes angular brackets
15-
// inside attribute values when retrieving innerHTML.
14+
// According to
15+
// https://w3c.github.io/DOM-Parsing/#dfn-serializing-an-attribute-value
16+
// when serializing innerHTML, <, >, ", & should be encoded as entities.
17+
// However, only some browsers, e.g. PhantomJS, encodes < and >.
1618
// this causes problems with the in-browser parser.
1719
export const shouldDecodeTags = inBrowser ? (function () {
1820
const div = document.createElement('div')

test/unit/features/component/component-slot.spec.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,6 @@ describe('Component slot', () => {
384384
}
385385
}
386386
}).$mount()
387-
console.log(vm.$el.innerHTML)
388387
expect(vm.$el.querySelector('.default').textContent).toBe('foo')
389388
expect(vm.$el.querySelector('.named').textContent).toBe('')
390389
})

test/unit/features/options/el.spec.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,14 @@ describe('Options el', () => {
6666
expect(vm.$el.childNodes[1].childNodes[0].childNodes[0].namespaceURI).toContain('svg')
6767
})
6868

69-
it('properly encode attribute values', function () {
69+
// https://w3c.github.io/DOM-Parsing/#dfn-serializing-an-attribute-value
70+
it('properly decode attribute values when parsing templates from DOM', function () {
7071
const el = document.createElement('div')
71-
el.innerHTML = '<a href="/a?foo=bar&baz=qux" name="<abc>"></a>'
72+
el.innerHTML = '<a href="/a?foo=bar&baz=qux" name="<abc>" single=\'"hi"\'></a>'
7273
const vm = new Vue({ el })
7374
expect(vm.$el.children[0].getAttribute('href')).toBe('/a?foo=bar&baz=qux')
7475
expect(vm.$el.children[0].getAttribute('name')).toBe('<abc>')
76+
expect(vm.$el.children[0].getAttribute('single')).toBe('"hi"')
7577
})
7678

7779
it('warn cannot find element', () => {

0 commit comments

Comments
 (0)