2021-04-30 02:45:22 +08:00
|
|
|
import { isSpecialBooleanAttr, makeMap, NOOP } from '@vue/shared'
|
|
|
|
import {
|
|
|
|
compatUtils,
|
|
|
|
ComponentInternalInstance,
|
|
|
|
DeprecationTypes
|
|
|
|
} from '@vue/runtime-core'
|
2020-01-29 11:03:53 +08:00
|
|
|
|
2020-03-17 06:46:01 +08:00
|
|
|
export const xlinkNS = 'http://www.w3.org/1999/xlink'
|
2020-01-29 07:48:27 +08:00
|
|
|
|
|
|
|
export function patchAttr(
|
|
|
|
el: Element,
|
|
|
|
key: string,
|
|
|
|
value: any,
|
2021-04-30 02:45:22 +08:00
|
|
|
isSVG: boolean,
|
|
|
|
instance?: ComponentInternalInstance | null
|
2020-01-29 07:48:27 +08:00
|
|
|
) {
|
2020-04-21 03:44:20 +08:00
|
|
|
if (isSVG && key.startsWith('xlink:')) {
|
2020-01-29 11:03:53 +08:00
|
|
|
if (value == null) {
|
2020-03-17 06:46:01 +08:00
|
|
|
el.removeAttributeNS(xlinkNS, key.slice(6, key.length))
|
2020-01-29 11:03:53 +08:00
|
|
|
} else {
|
|
|
|
el.setAttributeNS(xlinkNS, key, value)
|
|
|
|
}
|
2018-09-19 23:35:38 +08:00
|
|
|
} else {
|
2021-04-30 02:45:22 +08:00
|
|
|
if (__COMPAT__ && compatCoerceAttr(el, key, value, instance)) {
|
2021-04-08 05:36:56 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-01-29 11:03:53 +08:00
|
|
|
// note we are only checking boolean attributes that don't have a
|
2020-05-01 21:42:58 +08:00
|
|
|
// corresponding dom prop of the same name here.
|
2020-01-29 11:03:53 +08:00
|
|
|
const isBoolean = isSpecialBooleanAttr(key)
|
|
|
|
if (value == null || (isBoolean && value === false)) {
|
|
|
|
el.removeAttribute(key)
|
|
|
|
} else {
|
|
|
|
el.setAttribute(key, isBoolean ? '' : value)
|
|
|
|
}
|
2018-09-19 23:35:38 +08:00
|
|
|
}
|
|
|
|
}
|
2021-04-08 05:36:56 +08:00
|
|
|
|
|
|
|
// 2.x compat
|
|
|
|
const isEnumeratedAttr = __COMPAT__
|
|
|
|
? /*#__PURE__*/ makeMap('contenteditable,draggable,spellcheck')
|
|
|
|
: NOOP
|
|
|
|
|
|
|
|
export function compatCoerceAttr(
|
|
|
|
el: Element,
|
|
|
|
key: string,
|
2021-04-30 02:45:22 +08:00
|
|
|
value: unknown,
|
|
|
|
instance: ComponentInternalInstance | null = null
|
2021-04-08 05:36:56 +08:00
|
|
|
): boolean {
|
|
|
|
if (isEnumeratedAttr(key)) {
|
|
|
|
const v2CocercedValue =
|
|
|
|
value === null
|
|
|
|
? 'false'
|
|
|
|
: typeof value !== 'boolean' && value !== undefined
|
2021-07-20 06:24:18 +08:00
|
|
|
? 'true'
|
|
|
|
: null
|
2021-04-08 05:36:56 +08:00
|
|
|
if (
|
|
|
|
v2CocercedValue &&
|
|
|
|
compatUtils.softAssertCompatEnabled(
|
2021-05-13 05:47:00 +08:00
|
|
|
DeprecationTypes.ATTR_ENUMERATED_COERCION,
|
2021-04-30 02:45:22 +08:00
|
|
|
instance,
|
2021-04-08 05:36:56 +08:00
|
|
|
key,
|
|
|
|
value,
|
|
|
|
v2CocercedValue
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
el.setAttribute(key, v2CocercedValue)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
} else if (
|
|
|
|
value === false &&
|
|
|
|
!isSpecialBooleanAttr(key) &&
|
2021-04-10 11:21:13 +08:00
|
|
|
compatUtils.softAssertCompatEnabled(
|
|
|
|
DeprecationTypes.ATTR_FALSE_VALUE,
|
2021-04-30 02:45:22 +08:00
|
|
|
instance,
|
2021-04-10 11:21:13 +08:00
|
|
|
key
|
|
|
|
)
|
2021-04-08 05:36:56 +08:00
|
|
|
) {
|
|
|
|
el.removeAttribute(key)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|