From 1701bf3968f001dd3a2bc9f41e3e7e0f1b13e922 Mon Sep 17 00:00:00 2001 From: Stefan Mayer Date: Thu, 25 Nov 2021 11:30:32 +0100 Subject: [PATCH] fix(runtime-dom): patchDOMProps should not set _value if element is custom element (#4839) Co-authored-by: Stefan Mayer --- .../runtime-dom/__tests__/patchProps.spec.ts | 34 +++++++++++++++++++ packages/runtime-dom/src/modules/props.ts | 7 +++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/packages/runtime-dom/__tests__/patchProps.spec.ts b/packages/runtime-dom/__tests__/patchProps.spec.ts index e2590e2e0ee..1b97c6ea14a 100644 --- a/packages/runtime-dom/__tests__/patchProps.spec.ts +++ b/packages/runtime-dom/__tests__/patchProps.spec.ts @@ -25,6 +25,40 @@ describe('runtime-dom: props patching', () => { expect((el as any)._value).toBe(obj) }) + test('value for custom elements', () => { + class TestElement extends HTMLElement { + constructor() { + super() + } + + // intentionally uses _value because this is used in "normal" HTMLElement for storing the object of the set property value + private _value: any + get value() { + return this._value + } + + set value(val) { + this._value = val + this.setterCalled++ + } + + public setterCalled: number = 0 + } + window.customElements.define('test-element', TestElement) + const el = document.createElement('test-element') as TestElement + patchProp(el, 'value', null, 'foo') + expect(el.value).toBe('foo') + expect(el.setterCalled).toBe(1) + patchProp(el, 'value', null, null) + expect(el.value).toBe('') + expect(el.setterCalled).toBe(2) + expect(el.getAttribute('value')).toBe(null) + const obj = {} + patchProp(el, 'value', null, obj) + expect(el.value).toBe(obj) + expect(el.setterCalled).toBe(3) + }) + // For , setting el.value won't create a `value` attribute // so we need to add tests for other elements test('value for non-text input', () => { diff --git a/packages/runtime-dom/src/modules/props.ts b/packages/runtime-dom/src/modules/props.ts index 63513f34756..5092911e44a 100644 --- a/packages/runtime-dom/src/modules/props.ts +++ b/packages/runtime-dom/src/modules/props.ts @@ -26,7 +26,12 @@ export function patchDOMProp( return } - if (key === 'value' && el.tagName !== 'PROGRESS') { + if ( + key === 'value' && + el.tagName !== 'PROGRESS' && + // custom elements may use _value internally + !el.tagName.includes('-') + ) { // store value as _value as well since // non-string values will be stringified. el._value = value