fix(runtime-dom): should set <input list="..."> as attribute

fix #1526
This commit is contained in:
Evan You 2020-07-06 19:00:53 -04:00
parent 31e37b417b
commit 441c23602f

View File

@ -5,6 +5,7 @@ import { patchDOMProp } from './modules/props'
import { patchEvent } from './modules/events'
import { isOn, isString, isFunction } from '@vue/shared'
import { RendererOptions } from '@vue/runtime-core'
import { chdir } from 'process'
const nativeOnRE = /^on[a-z]/
@ -38,26 +39,7 @@ export const patchProp: DOMRendererOptions['patchProp'] = (
if (!key.startsWith('onUpdate:')) {
patchEvent(el, key, prevValue, nextValue, parentComponent)
}
} else if (
// spellcheck and draggable are numerated attrs, however their
// corresponding DOM properties are actually booleans - this leads to
// setting it with a string "false" value leading it to be coerced to
// `true`, so we need to always treat them as attributes.
// Note that `contentEditable` doesn't have this problem: its DOM
// property is also enumerated string values.
key !== 'spellcheck' &&
key !== 'draggable' &&
(isSVG
? // most keys must be set as attribute on svg elements to work
// ...except innerHTML
key === 'innerHTML' ||
// or native onclick with function values
(key in el && nativeOnRE.test(key) && isFunction(nextValue))
: // for normal html elements, set as a property if it exists
key in el &&
// except native onclick with string values
!(nativeOnRE.test(key) && isString(nextValue)))
) {
} else if (shouldSetAsProp(el, key, nextValue, isSVG)) {
patchDOMProp(
el,
key,
@ -82,3 +64,45 @@ export const patchProp: DOMRendererOptions['patchProp'] = (
break
}
}
function shouldSetAsProp(
el: Element,
key: string,
value: unknown,
isSVG: boolean
) {
if (isSVG) {
// most keys must be set as attribute on svg elements to work
// ...except innerHTML
if (key === 'innerHTML') {
return true
}
// or native onclick with function values
if (key in el && nativeOnRE.test(key) && isFunction(value)) {
return true
}
return false
}
// spellcheck and draggable are numerated attrs, however their
// corresponding DOM properties are actually booleans - this leads to
// setting it with a string "false" value leading it to be coerced to
// `true`, so we need to always treat them as attributes.
// Note that `contentEditable` doesn't have this problem: its DOM
// property is also enumerated string values.
if (key === 'spellcheck' || key === 'draggable') {
return false
}
// #1526 <input list> must be set as attribute
if (key === 'list' && el.tagName === 'INPUT') {
return false
}
// native onclick with string value, must be set as attribute
if (nativeOnRE.test(key) && isString(value)) {
return false
}
return key in el
}