]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-dom): patchDOMProps should not set _value if element is custom element...
authorStefan Mayer <stevijo.mayer@googlemail.com>
Thu, 25 Nov 2021 10:30:32 +0000 (11:30 +0100)
committerGitHub <noreply@github.com>
Thu, 25 Nov 2021 10:30:32 +0000 (05:30 -0500)
Co-authored-by: Stefan Mayer <stefan.m.mayer@daimler.com>
packages/runtime-dom/__tests__/patchProps.spec.ts
packages/runtime-dom/src/modules/props.ts

index e2590e2e0eef82946626dee2c95bb41a857a6071..1b97c6ea14aaab94ca71e83ed8d78421df7f4d78 100644 (file)
@@ -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 <input type="text">, setting el.value won't create a `value` attribute
   // so we need to add tests for other elements
   test('value for non-text input', () => {
index 63513f3475684e805baec1325a14654d1474db59..5092911e44a6dbed718b762b7d1e8c1f94da6859 100644 (file)
@@ -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