( el: any, key: string, value: any, parentComponent: any, attrName?: string, )
| 4 | |
| 5 | // functions. The user is responsible for using them with only trusted content. |
| 6 | export function patchDOMProp( |
| 7 | el: any, |
| 8 | key: string, |
| 9 | value: any, |
| 10 | parentComponent: any, |
| 11 | attrName?: string, |
| 12 | ): void { |
| 13 | // __UNSAFE__ |
| 14 | // Reason: potentially setting innerHTML. |
| 15 | // This can come from explicit usage of v-html or innerHTML as a prop in render |
| 16 | if (key === 'innerHTML' || key === 'textContent') { |
| 17 | // null value case is handled in renderer patchElement before patching |
| 18 | // children |
| 19 | if (value != null) { |
| 20 | el[key] = key === 'innerHTML' ? unsafeToTrustedHTML(value) : value |
| 21 | } |
| 22 | return |
| 23 | } |
| 24 | |
| 25 | const tag = el.tagName |
| 26 | |
| 27 | if ( |
| 28 | key === 'value' && |
| 29 | tag !== 'PROGRESS' && |
| 30 | // custom elements may use _value internally |
| 31 | !tag.includes('-') |
| 32 | ) { |
| 33 | // #4956: <option> value will fallback to its text content so we need to |
| 34 | // compare against its attribute value instead. |
| 35 | const oldValue = |
| 36 | tag === 'OPTION' ? el.getAttribute('value') || '' : el.value |
| 37 | const newValue = |
| 38 | value == null |
| 39 | ? // #11647: value should be set as empty string for null and undefined, |
| 40 | // but <input type="checkbox"> should be set as 'on'. |
| 41 | el.type === 'checkbox' |
| 42 | ? 'on' |
| 43 | : '' |
| 44 | : String(value) |
| 45 | if (oldValue !== newValue || !('_value' in el)) { |
| 46 | el.value = newValue |
| 47 | } |
| 48 | if (value == null) { |
| 49 | el.removeAttribute(key) |
| 50 | } |
| 51 | // store value as _value as well since |
| 52 | // non-string values will be stringified. |
| 53 | el._value = value |
| 54 | return |
| 55 | } |
| 56 | |
| 57 | let needRemove = false |
| 58 | if (value === '' || value == null) { |
| 59 | const type = typeof el[key] |
| 60 | if (type === 'boolean') { |
| 61 | // e.g. <select multiple> compiles to { multiple: '' } |
| 62 | value = includeBooleanAttr(value) |
| 63 | } else if (value == null && type === 'string') { |
no test coverage detected