fix(runtime-dom): consistently remove boolean attributes for falsy values (#4348)
This commit is contained in:
@@ -23,6 +23,18 @@ describe('runtime-dom: attrs patching', () => {
|
||||
expect(el.getAttribute('readonly')).toBe('')
|
||||
patchProp(el, 'readonly', true, false)
|
||||
expect(el.getAttribute('readonly')).toBe(null)
|
||||
patchProp(el, 'readonly', false, '')
|
||||
expect(el.getAttribute('readonly')).toBe('')
|
||||
patchProp(el, 'readonly', '', 0)
|
||||
expect(el.getAttribute('readonly')).toBe(null)
|
||||
patchProp(el, 'readonly', 0, '0')
|
||||
expect(el.getAttribute('readonly')).toBe('')
|
||||
patchProp(el, 'readonly', '0', false)
|
||||
expect(el.getAttribute('readonly')).toBe(null)
|
||||
patchProp(el, 'readonly', false, 1)
|
||||
expect(el.getAttribute('readonly')).toBe('')
|
||||
patchProp(el, 'readonly', 1, undefined)
|
||||
expect(el.getAttribute('readonly')).toBe(null)
|
||||
})
|
||||
|
||||
test('attributes', () => {
|
||||
|
||||
@@ -43,6 +43,18 @@ describe('runtime-dom: props patching', () => {
|
||||
expect(el.multiple).toBe(true)
|
||||
patchProp(el, 'multiple', null, null)
|
||||
expect(el.multiple).toBe(false)
|
||||
patchProp(el, 'multiple', null, true)
|
||||
expect(el.multiple).toBe(true)
|
||||
patchProp(el, 'multiple', null, 0)
|
||||
expect(el.multiple).toBe(false)
|
||||
patchProp(el, 'multiple', null, '0')
|
||||
expect(el.multiple).toBe(true)
|
||||
patchProp(el, 'multiple', null, false)
|
||||
expect(el.multiple).toBe(false)
|
||||
patchProp(el, 'multiple', null, 1)
|
||||
expect(el.multiple).toBe(true)
|
||||
patchProp(el, 'multiple', null, undefined)
|
||||
expect(el.multiple).toBe(false)
|
||||
})
|
||||
|
||||
test('innerHTML unmount prev children', () => {
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import { isSpecialBooleanAttr, makeMap, NOOP } from '@vue/shared'
|
||||
import {
|
||||
includeBooleanAttr,
|
||||
isSpecialBooleanAttr,
|
||||
makeMap,
|
||||
NOOP
|
||||
} from '@vue/shared'
|
||||
import {
|
||||
compatUtils,
|
||||
ComponentInternalInstance,
|
||||
@@ -28,7 +33,7 @@ export function patchAttr(
|
||||
// note we are only checking boolean attributes that don't have a
|
||||
// corresponding dom prop of the same name here.
|
||||
const isBoolean = isSpecialBooleanAttr(key)
|
||||
if (value == null || (isBoolean && value === false)) {
|
||||
if (value == null || (isBoolean && !includeBooleanAttr(value))) {
|
||||
el.removeAttribute(key)
|
||||
} else {
|
||||
el.setAttribute(key, isBoolean ? '' : value)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// This can come from explicit usage of v-html or innerHTML as a prop in render
|
||||
|
||||
import { warn, DeprecationTypes, compatUtils } from '@vue/runtime-core'
|
||||
import { includeBooleanAttr } from '@vue/shared'
|
||||
|
||||
// functions. The user is responsible for using them with only trusted content.
|
||||
export function patchDOMProp(
|
||||
@@ -41,9 +42,9 @@ export function patchDOMProp(
|
||||
|
||||
if (value === '' || value == null) {
|
||||
const type = typeof el[key]
|
||||
if (value === '' && type === 'boolean') {
|
||||
if (type === 'boolean') {
|
||||
// e.g. <select multiple> compiles to { multiple: '' }
|
||||
el[key] = true
|
||||
el[key] = includeBooleanAttr(value)
|
||||
return
|
||||
} else if (value == null && type === 'string') {
|
||||
// e.g. <div :id="null">
|
||||
|
||||
Reference in New Issue
Block a user