Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | 3x 3x 344x 344x 344x 344x 344x 344x 344x 9x 7x 7x 9x 9x 335x 335x 335x 213x 213x 344x 209x 209x 209x 209x 44x 2x 42x 165x 209x 80x 80x 209x 44x 44x 209x 209x 209x 126x 344x 15x 15x 5x 15x 5x 5x 5x 1x 1x 1x 332x 111x 111x 111x 4x 4x 4x 4x 111x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 111x 126x 126x 332x 5x 4x 4x 4x 4x 4x 4x 5x 332x 344x | import { DeprecationTypes, compatUtils, warn } from '@vue/runtime-core'
import { includeBooleanAttr } from '@vue/shared'
import { unsafeToTrustedHTML } from '../nodeOps'
// functions. The user is responsible for using them with only trusted content.
export function patchDOMProp(
el: any,
key: string,
value: any,
parentComponent: any,
attrName?: string,
): void {
// __UNSAFE__
// Reason: potentially setting innerHTML.
// This can come from explicit usage of v-html or innerHTML as a prop in render
if (key === 'innerHTML' || key === 'textContent') {
// null value case is handled in renderer patchElement before patching
// children
if (value != null) {
el[key] = key === 'innerHTML' ? unsafeToTrustedHTML(value) : value
}
return
}
const tag = el.tagName
if (
key === 'value' &&
tag !== 'PROGRESS' &&
// custom elements may use _value internally
!tag.includes('-')
) {
// #4956: <option> value will fallback to its text content so we need to
// compare against its attribute value instead.
const oldValue =
tag === 'OPTION' ? el.getAttribute('value') || '' : el.value
const newValue =
value == null
? // #11647: value should be set as empty string for null and undefined,
// but <input type="checkbox"> should be set as 'on'.
el.type === 'checkbox'
? 'on'
: ''
: String(value)
if (oldValue !== newValue || !('_value' in el)) {
el.value = newValue
}
if (value == null) {
el.removeAttribute(key)
}
// store value as _value as well since
// non-string values will be stringified.
el._value = value
return
}
let needRemove = false
if (value === '' || value == null) {
const type = typeof el[key]
if (type === 'boolean') {
// e.g. <select multiple> compiles to { multiple: '' }
value = includeBooleanAttr(value)
} else if (value == null && type === 'string') {
// e.g. <div :id="null">
value = ''
needRemove = true
} else if (type === 'number') {
// e.g. <img :width="null">
value = 0
needRemove = true
}
} 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 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) {
// do not warn if value is auto-coerced from nullish values
if (__DEV__ && !needRemove) {
warn(
`Failed setting prop "${key}" on <${tag.toLowerCase()}>: ` +
`value ${value} is invalid.`,
e,
)
}
}
needRemove && el.removeAttribute(attrName || key)
}
|