fix(runtime-dom): catch more cases of DOM property setting error (#5552)
close #5545
This commit is contained in:
parent
74d239caf7
commit
fa1d14c2c8
@ -234,12 +234,29 @@ describe('runtime-dom: props patching', () => {
|
|||||||
expect(el.getAttribute('x')).toBe('2')
|
expect(el.getAttribute('x')).toBe('2')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('input with size', () => {
|
test('input with size (number property)', () => {
|
||||||
const el = document.createElement('input')
|
const el = document.createElement('input')
|
||||||
patchProp(el, 'size', null, 100)
|
patchProp(el, 'size', null, 100)
|
||||||
expect(el.size).toBe(100)
|
expect(el.size).toBe(100)
|
||||||
patchProp(el, 'size', 100, null)
|
patchProp(el, 'size', 100, null)
|
||||||
expect(el.getAttribute('size')).toBe(null)
|
expect(el.getAttribute('size')).toBe(null)
|
||||||
|
expect('Failed setting prop "size" on <input>').toHaveBeenWarnedLast()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('select with type (string property)', () => {
|
||||||
|
const el = document.createElement('select')
|
||||||
|
patchProp(el, 'type', null, 'test')
|
||||||
|
expect(el.type).toBe('select-one')
|
||||||
|
expect('Failed setting prop "type" on <select>').toHaveBeenWarnedLast()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('select with willValidate (boolean property)', () => {
|
||||||
|
const el = document.createElement('select')
|
||||||
|
patchProp(el, 'willValidate', true, null)
|
||||||
|
expect(el.willValidate).toBe(true)
|
||||||
|
expect(
|
||||||
|
'Failed setting prop "willValidate" on <select>'
|
||||||
|
).toHaveBeenWarnedLast()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('patch value for select', () => {
|
test('patch value for select', () => {
|
||||||
|
@ -51,51 +51,48 @@ export function patchDOMProp(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let needRemove = false
|
||||||
if (value === '' || value == null) {
|
if (value === '' || value == null) {
|
||||||
const type = typeof el[key]
|
const type = typeof el[key]
|
||||||
if (type === 'boolean') {
|
if (type === 'boolean') {
|
||||||
// e.g. <select multiple> compiles to { multiple: '' }
|
// e.g. <select multiple> compiles to { multiple: '' }
|
||||||
el[key] = includeBooleanAttr(value)
|
value = includeBooleanAttr(value)
|
||||||
return
|
|
||||||
} else if (value == null && type === 'string') {
|
} else if (value == null && type === 'string') {
|
||||||
// e.g. <div :id="null">
|
// e.g. <div :id="null">
|
||||||
el[key] = ''
|
value = ''
|
||||||
el.removeAttribute(key)
|
needRemove = true
|
||||||
return
|
|
||||||
} else if (type === 'number') {
|
} else if (type === 'number') {
|
||||||
// e.g. <img :width="null">
|
// e.g. <img :width="null">
|
||||||
// the value of some IDL attr must be greater than 0, e.g. input.size = 0 -> error
|
// the value of some IDL attr must be greater than 0, e.g. input.size = 0 -> error
|
||||||
try {
|
value = 0
|
||||||
el[key] = 0
|
needRemove = true
|
||||||
} catch {}
|
}
|
||||||
el.removeAttribute(key)
|
} else {
|
||||||
return
|
if (
|
||||||
|
__COMPAT__ &&
|
||||||
|
value === false &&
|
||||||
|
compatUtils.isCompatEnabled(
|
||||||
|
DeprecationTypes.ATTR_FALSE_VALUE,
|
||||||
|
parentComponent
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
const type = typeof el[key]
|
||||||
|
if (type === 'string' || type === 'number') {
|
||||||
|
__DEV__ &&
|
||||||
|
compatUtils.warnDeprecation(
|
||||||
|
DeprecationTypes.ATTR_FALSE_VALUE,
|
||||||
|
parentComponent,
|
||||||
|
key
|
||||||
|
)
|
||||||
|
value = type === 'number' ? 0 : ''
|
||||||
|
needRemove = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
// some properties perform value validation and throw,
|
||||||
__COMPAT__ &&
|
// some properties has getter, no setter, will error in 'use strict'
|
||||||
value === false &&
|
// eg. <select :type="null"></select> <select :willValidate="null"></select>
|
||||||
compatUtils.isCompatEnabled(
|
|
||||||
DeprecationTypes.ATTR_FALSE_VALUE,
|
|
||||||
parentComponent
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
const type = typeof el[key]
|
|
||||||
if (type === 'string' || type === 'number') {
|
|
||||||
__DEV__ &&
|
|
||||||
compatUtils.warnDeprecation(
|
|
||||||
DeprecationTypes.ATTR_FALSE_VALUE,
|
|
||||||
parentComponent,
|
|
||||||
key
|
|
||||||
)
|
|
||||||
el[key] = type === 'number' ? 0 : ''
|
|
||||||
el.removeAttribute(key)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// some properties perform value validation and throw
|
|
||||||
try {
|
try {
|
||||||
el[key] = value
|
el[key] = value
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
@ -107,4 +104,5 @@ export function patchDOMProp(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
needRemove && el.removeAttribute(key)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user