Skip to content

Commit

Permalink
Restore node properties after upgrade.
Browse files Browse the repository at this point in the history
  • Loading branch information
edoardocavazza committed Nov 27, 2024
1 parent 3ae609b commit 41a1b35
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/hip-trees-heal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@chialab/dna': minor
---

Restore node properties after upgrade.
27 changes: 24 additions & 3 deletions src/Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,17 +108,22 @@ export const extend = <T extends HTMLElement, C extends { new (...args: any[]):
/**
* A flag to indicate if the component is collecting updates.
*/
_collectingUpdates = 0;
private _collectingUpdates = 0;

/**
* A flag to indicate if the component has a scheduled update.
*/
_updateScheduled = false;
private _updateScheduled = false;

/**
* The property that changed.
*/
_changedProperty: keyof this | null = null;
private _changedProperty: keyof this | null = null;

/**
* The initial properties of the component.
*/
private _initialProps?: Record<Extract<keyof this, string>, this[Extract<keyof this, string>]>;

/**
* A flag to indicate component instances.
Expand Down Expand Up @@ -181,6 +186,14 @@ export const extend = <T extends HTMLElement, C extends { new (...args: any[]):
configurable: true,
});

element._initialProps = Object.getOwnPropertyNames(element).reduce(
(acc, key) => {
acc[key as Extract<keyof this, string>] = element[key as Extract<keyof this, string>];
return acc;
},
{} as Record<Extract<keyof this, string>, this[Extract<keyof this, string>]>
);

return element;
}

Expand Down Expand Up @@ -215,6 +228,14 @@ export const extend = <T extends HTMLElement, C extends { new (...args: any[]):

this.realm.observe(() => this.requestUpdate());
(this as WithComponentProto<ComponentInstance>)[INITIALIZED_SYMBOL] = true;

for (const propertyKey in computedProperties) {
const property = computedProperties[propertyKey];
if (this._initialProps?.[propertyKey] !== undefined && (!property.get || property.set)) {
this[propertyKey] = this._initialProps[propertyKey];
}
}
delete this._initialProps;
}

/**
Expand Down
55 changes: 55 additions & 0 deletions test/property.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,61 @@ describe.runIf(typeof window !== 'undefined')(
expect(listener1).toHaveBeenCalledWith(42, 84, 'testProp');
expect(listener2).toHaveBeenCalledWith(42, 84, 'testProp');
});

it('should restore a property after upgrade', () => {
const tagName = getComponentName();
const element = document.createElement(tagName);

expect(element).not.toHaveProperty('testProp');
expect(element.getAttribute('test-prop')).toBeNull();
element.testProp = 84;
expect(element.getAttribute('test-prop')).toBeNull();

const MyElement = class MyElement extends DNA.Component {
constructor(...args) {
super(...args);
this.testProp = 42;
}
};
__decorate(
[
DNA.property({
attribute: 'test-prop',
}),
],
MyElement.prototype,
'testProp',
undefined
);
expect(element).not.toBeInstanceOf(MyElement);
DNA.define(tagName, MyElement);
window.customElements.upgrade(element);

expect(element).toBeInstanceOf(MyElement);
expect(element).toHaveProperty('testProp', 84);
expect(element.getAttribute('test-prop')).toBe('84');
});

it('should discard a getter property after upgrade', () => {
const tagName = getComponentName();
const element = document.createElement(tagName);

expect(element).not.toHaveProperty('testProp');
element.testProp = 84;

const MyElement = class MyElement extends DNA.Component {
get testProp() {
return 42;
}
};
__decorate([DNA.property()], MyElement.prototype, 'testProp', undefined);
expect(element).not.toBeInstanceOf(MyElement);
DNA.define(tagName, MyElement);
window.customElements.upgrade(element);

expect(element).toBeInstanceOf(MyElement);
expect(element).toHaveProperty('testProp', 42);
});
});

describe('properties getter', () => {
Expand Down

0 comments on commit 41a1b35

Please sign in to comment.