From 3f38d599f5aacdd3eeaa9475251a24f74e7ae3b4 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sat, 9 Oct 2021 19:31:52 -0400 Subject: [PATCH] fix(runtime-dom): fix behavior regression for v-show + style display binding fix #4768 --- .../runtime-dom/__tests__/patchStyle.spec.ts | 8 +++++ packages/runtime-dom/src/modules/style.ts | 31 ++++++++++--------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/packages/runtime-dom/__tests__/patchStyle.spec.ts b/packages/runtime-dom/__tests__/patchStyle.spec.ts index b8dfc49d..92b30aa5 100644 --- a/packages/runtime-dom/__tests__/patchStyle.spec.ts +++ b/packages/runtime-dom/__tests__/patchStyle.spec.ts @@ -68,6 +68,14 @@ describe(`runtime-dom: style patching`, () => { expect(el.style.width).toBe('0px') }) + it('should remove style attribute on falsy value', () => { + const el = document.createElement('div') + el.style.cssText = 'color: red;' + patchProp(el as any, 'style', {}, null) + expect(el.hasAttribute('style')).toBe(false) + expect(el.style.cssText).toBe('') + }) + // JSDOM doesn't support custom properties on style object so we have to // mock it here. function mockElementWithStyle() { diff --git a/packages/runtime-dom/src/modules/style.ts b/packages/runtime-dom/src/modules/style.ts index 69a60879..a9cc67ba 100644 --- a/packages/runtime-dom/src/modules/style.ts +++ b/packages/runtime-dom/src/modules/style.ts @@ -5,14 +5,8 @@ type Style = string | Record | null export function patchStyle(el: Element, prev: Style, next: Style) { const style = (el as HTMLElement).style - const currentDisplay = style.display - if (!next) { - el.removeAttribute('style') - } else if (isString(next)) { - if (prev !== next) { - style.cssText = next - } - } else { + const isCssString = isString(next) + if (next && !isCssString) { for (const key in next) { setStyle(style, key, next[key]) } @@ -23,12 +17,21 @@ export function patchStyle(el: Element, prev: Style, next: Style) { } } } - } - // indicates that the `display` of the element is controlled by `v-show`, - // so we always keep the current `display` value regardless of the `style` value, - // thus handing over control to `v-show`. - if ('_vod' in el) { - style.display = currentDisplay + } else { + const currentDisplay = style.display + if (isCssString) { + if (prev !== next) { + style.cssText = next as string + } + } else if (prev) { + el.removeAttribute('style') + } + // indicates that the `display` of the element is controlled by `v-show`, + // so we always keep the current `display` value regardless of the `style` + // value, thus handing over control to `v-show`. + if ('_vod' in el) { + style.display = currentDisplay + } } }