Skip to content

Commit 2fc82bf

Browse files
committed
is attribute that are not resolved should be preserved for native custom elements (fix vuejs#2642)
1 parent 9d13ca3 commit 2fc82bf

File tree

3 files changed

+28
-23
lines changed

3 files changed

+28
-23
lines changed

src/util/component.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { warn } from './debug'
22
import { resolveAsset } from './options'
3-
import { getAttr, getBindAttr } from './dom'
3+
import { getBindAttr } from './dom'
44

55
export const commonTagRE = /^(div|p|span|img|a|b|i|br|ul|ol|li|h1|h2|h3|h4|h5|h6|code|pre|table|th|td|tr|form|label|input|select|option|nav|article|section|header|footer)$/i
66
export const reservedTagRE = /^(slot|partial|component)$/i
@@ -41,7 +41,7 @@ export function checkComponentAttr (el, options) {
4141
if (resolveAsset(options, 'components', tag)) {
4242
return { id: tag }
4343
} else {
44-
var is = hasAttrs && getIsBinding(el)
44+
var is = hasAttrs && getIsBinding(el, options)
4545
if (is) {
4646
return is
4747
} else if (process.env.NODE_ENV !== 'production') {
@@ -64,22 +64,26 @@ export function checkComponentAttr (el, options) {
6464
}
6565
}
6666
} else if (hasAttrs) {
67-
return getIsBinding(el)
67+
return getIsBinding(el, options)
6868
}
6969
}
7070

7171
/**
7272
* Get "is" binding from an element.
7373
*
7474
* @param {Element} el
75+
* @param {Object} options
7576
* @return {Object|undefined}
7677
*/
7778

78-
function getIsBinding (el) {
79+
function getIsBinding (el, options) {
7980
// dynamic syntax
80-
var exp = getAttr(el, 'is')
81+
var exp = el.getAttribute('is')
8182
if (exp != null) {
82-
return { id: exp }
83+
if (resolveAsset(options, 'components', exp)) {
84+
el.removeAttribute('is')
85+
return { id: exp }
86+
}
8387
} else {
8488
exp = getBindAttr(el, 'is')
8589
if (exp != null) {

test/unit/specs/directives/internal/component_spec.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -534,9 +534,11 @@ describe('Component', function () {
534534
})
535535

536536
it('already mounted warn', function () {
537-
el.setAttribute('is', 'test')
538537
new Vue({
539-
el: el
538+
el: document.createElement('test'),
539+
components: {
540+
test: {}
541+
}
540542
})
541543
expect('cannot mount component "test" on already mounted element').toHaveBeenWarned()
542544
})

test/unit/specs/util/component_spec.js

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,41 @@ var _ = require('src/util')
33
describe('Util - component', function () {
44
it('checkComponentAttr', function () {
55
var el = document.createElement('component')
6+
var mockOptions = { components: {
7+
foo: {}
8+
}}
69

710
// <component> with no is attr
8-
var res = _.checkComponentAttr(el)
11+
var res = _.checkComponentAttr(el, mockOptions)
912
expect(res).toBeUndefined()
1013

1114
// static <component is="...">
1215
el.setAttribute('is', 'foo')
13-
res = _.checkComponentAttr(el)
16+
res = _.checkComponentAttr(el, mockOptions)
1417
expect(res.id).toBe('foo')
1518
expect(res.dynamic).toBeFalsy()
1619

1720
// <component :is="...">
1821
el.setAttribute(':is', 'foo')
19-
res = _.checkComponentAttr(el)
22+
res = _.checkComponentAttr(el, mockOptions)
2023
expect(res.id).toBe('foo')
2124
expect(res.dynamic).toBe(true)
2225

2326
// custom element, not defined
2427
el = document.createElement('test')
25-
res = _.checkComponentAttr(el, {
26-
components: {}
27-
})
28+
res = _.checkComponentAttr(el, mockOptions)
2829
expect(res).toBeUndefined()
2930

3031
// custom element, defined
31-
res = _.checkComponentAttr(el, {
32-
components: { test: true }
33-
})
34-
expect(res.id).toBe('test')
32+
el = document.createElement('foo')
33+
res = _.checkComponentAttr(el, mockOptions)
34+
expect(res.id).toBe('foo')
3535

3636
// is on undefined custom element
37+
// should be preserved in case it is a native custom element usage
3738
el = document.createElement('test2')
38-
el.setAttribute('is', 'foo')
39-
res = _.checkComponentAttr(el, {
40-
components: {}
41-
})
42-
expect(res.id).toBe('foo')
39+
el.setAttribute('is', 'bar')
40+
res = _.checkComponentAttr(el, mockOptions)
41+
expect(res).toBeUndefined()
4342
})
4443
})

0 commit comments

Comments
 (0)