Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: some dom property setting error #5545 #5552

Merged
merged 3 commits into from Apr 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 18 additions & 1 deletion packages/runtime-dom/__tests__/patchProps.spec.ts
Expand Up @@ -234,12 +234,29 @@ describe('runtime-dom: props patching', () => {
expect(el.getAttribute('x')).toBe('2')
})

test('input with size', () => {
test('input with size (number property)', () => {
const el = document.createElement('input')
patchProp(el, 'size', null, 100)
expect(el.size).toBe(100)
patchProp(el, 'size', 100, 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', () => {
Expand Down
62 changes: 30 additions & 32 deletions packages/runtime-dom/src/modules/props.ts
Expand Up @@ -51,51 +51,48 @@ export function patchDOMProp(
return
}

let needRemove = false
if (value === '' || value == null) {
const type = typeof el[key]
if (type === 'boolean') {
// e.g. <select multiple> compiles to { multiple: '' }
el[key] = includeBooleanAttr(value)
return
value = includeBooleanAttr(value)
} else if (value == null && type === 'string') {
// e.g. <div :id="null">
el[key] = ''
el.removeAttribute(key)
return
value = ''
needRemove = true
} else if (type === 'number') {
// e.g. <img :width="null">
// the value of some IDL attr must be greater than 0, e.g. input.size = 0 -> error
try {
el[key] = 0
} catch {}
el.removeAttribute(key)
return
value = 0
needRemove = true
}
}

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
)
el[key] = type === 'number' ? 0 : ''
el.removeAttribute(key)
return
} else {
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
}
}
}

// some properties perform value validation and throw
// some properties perform value validation and throw,
// some properties has getter, no setter, will error in 'use strict'
// eg. <select :type="null"></select> <select :willValidate="null"></select>
try {
el[key] = value
} catch (e: any) {
Expand All @@ -107,4 +104,5 @@ export function patchDOMProp(
)
}
}
needRemove && el.removeAttribute(key)
}