diff --git a/examples/bugs/158-zombie/array.html b/examples/bugs/158-zombie/array.html new file mode 100644 index 0000000..5c45e1a --- /dev/null +++ b/examples/bugs/158-zombie/array.html @@ -0,0 +1,101 @@ + + + + + + + + + + + + diff --git a/examples/bugs/158-zombie/properties.html b/examples/bugs/158-zombie/properties.html new file mode 100644 index 0000000..3e5f642 --- /dev/null +++ b/examples/bugs/158-zombie/properties.html @@ -0,0 +1,110 @@ + + + + + + + + + + + + + diff --git a/package-lock.json b/package-lock.json index 90431cb..c590960 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5320,9 +5320,9 @@ } }, "node_modules/koa": { - "version": "2.16.2", - "resolved": "https://registry.npmjs.org/koa/-/koa-2.16.2.tgz", - "integrity": "sha512-+CCssgnrWKx9aI3OeZwroa/ckG4JICxvIFnSiOUyl2Uv+UTI+xIw0FfFrWS7cQFpoePpr9o8csss7KzsTzNL8Q==", + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.16.3.tgz", + "integrity": "sha512-zPPuIt+ku1iCpFBRwseMcPYQ1cJL8l60rSmKeOuGfOXyE6YnTBmf2aEFNL2HQGrD0cPcLO/t+v9RTgC+fwEh/g==", "dev": true, "license": "MIT", "dependencies": { @@ -7474,9 +7474,9 @@ } }, "node_modules/tar-fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", - "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "dev": true, "license": "MIT", "dependencies": { @@ -11903,9 +11903,9 @@ } }, "koa": { - "version": "2.16.2", - "resolved": "https://registry.npmjs.org/koa/-/koa-2.16.2.tgz", - "integrity": "sha512-+CCssgnrWKx9aI3OeZwroa/ckG4JICxvIFnSiOUyl2Uv+UTI+xIw0FfFrWS7cQFpoePpr9o8csss7KzsTzNL8Q==", + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.16.3.tgz", + "integrity": "sha512-zPPuIt+ku1iCpFBRwseMcPYQ1cJL8l60rSmKeOuGfOXyE6YnTBmf2aEFNL2HQGrD0cPcLO/t+v9RTgC+fwEh/g==", "dev": true, "requires": { "accepts": "^1.3.5", @@ -13426,9 +13426,9 @@ } }, "tar-fs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", - "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "dev": true, "requires": { "bare-fs": "^4.0.1", diff --git a/src/BaseElement.js b/src/BaseElement.js index 6ec8c46..655f0f6 100644 --- a/src/BaseElement.js +++ b/src/BaseElement.js @@ -194,9 +194,6 @@ class BaseElement extends HTMLElement { // release dom references this.$refs = {}; - // clear state - this._state = {}; - // cancel pending updates if (this._batchUpdate) { cancelAnimationFrame(this._batchUpdate); @@ -298,7 +295,7 @@ class BaseElement extends HTMLElement { // registered or connected. To avoid such timing issues we check // if a value was set for that specific property on the // prototype before assigning a default value - const value = this[prop] || this.properties()[prop]; + const value = this[prop] ?? this.properties()[prop]; this.defineProperty(prop, value); }); } @@ -312,11 +309,6 @@ class BaseElement extends HTMLElement { * @param {boolean} isAttribute */ defineProperty(property, value, isAttribute = false) { - if (this._state.hasOwnProperty(property)) { - // property has already been defined as an attribute nothing to do here - return; - } - // if property did not come from an attribute but has the option to reflect // enabled or custom fn if (!isAttribute && this._options.propertyOptions[property]?.reflect) { this.reflectProperty({ property: property, newValue: value }); diff --git a/test/unit/attributes-to-properties.test.js b/test/unit/attributes-to-properties.test.js index 29301c2..99644d1 100644 --- a/test/unit/attributes-to-properties.test.js +++ b/test/unit/attributes-to-properties.test.js @@ -2,7 +2,15 @@ import { fixture, defineCE, assert } from '@open-wc/testing'; import { BaseElement } from '../../src/BaseElement'; -const tag = defineCE(class extends BaseElement {}); +const tag = defineCE( + class extends BaseElement { + properties() { + return { + firstname: 'John', + }; + } + }, +); describe('attributes-to-properties', () => { it('reflects lowercase attributes as lowercase properties', async () => { @@ -24,4 +32,9 @@ describe('attributes-to-properties', () => { assert.isTrue(el.hasOwnProperty('dashCase')); assert.equal(el.dashCase, 'Hello'); }); + + it('prefers attribute values over the default values from the properties map for default/initial state', async () => { + const el = await fixture(`<${tag} firstname="Jane">`); + assert.equal(el.firstname, 'Jane'); + }); });