Skip to content

Commit

Permalink
Refactor initialize method
Browse files Browse the repository at this point in the history
  • Loading branch information
edoardocavazza committed Nov 16, 2023
1 parent be5a445 commit 1224baf
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .changeset/nasty-rockets-return.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@chialab/dna': patch
---

Move element initialization to `inizitialize` method.
49 changes: 27 additions & 22 deletions src/Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ import { getRootContext, internalRender, render } from './render';
/**
* A symbol which identify components.
*/
const COMPONENT_SYMBOL: unique symbol = Symbol();
const COMPONENT_SYMBOL: unique symbol = Symbol('component');

/**
* A symbol which identify constructed elements.
*/
const CONSTRUCTED_SYMBOL: unique symbol = Symbol();
const CONSTRUCTED_SYMBOL: unique symbol = Symbol('constructed');

/**
* An augmented node with component flags.
Expand Down Expand Up @@ -174,49 +174,55 @@ export const extend = <T extends { new (...args: any[]): HTMLElement; prototype:
throw new Error('Components can be used only in browser environment');
}

const element = (args.length ? (setPrototypeOf(args[0], this), args[0]) : this) as this;
return (args.length ? (setPrototypeOf(args[0], this), args[0]) : this) as this;
}

/**
* The callback for initialized components.
* It runs once when the component is created, at the end of the constructor.
* @throws An error if the component has already been initialized.
*/
initialize() {
if (isConstructed(this)) {
throw new Error('The component has already been initialized');
}

// setup listeners
const computedListeners = getListeners(element).map((listener) => ({
const computedListeners = getListeners(this).map((listener) => ({
...listener,
callback: listener.callback.bind(element),
callback: listener.callback.bind(this),
}));
setListeners(element, computedListeners);
setListeners(this, computedListeners);

for (let i = 0, len = computedListeners.length; i < len; i++) {
const { event, target, selector, callback, options } = computedListeners[i];
if (!target) {
element.delegateEventListener(event, selector, callback, options);
this.delegateEventListener(event, selector, callback, options);
}
}

// setup properties
const computedProperties = getProperties(element);
const computedProperties = getProperties(this);
for (const propertyKey in computedProperties) {
delete element[propertyKey];
delete this[propertyKey];
const property = computedProperties[propertyKey];
if (typeof property.initializer === 'function') {
element[propertyKey] = property.initializer.call(element);
this[propertyKey] = property.initializer.call(this);
} else if (typeof property.defaultValue !== 'undefined') {
element[propertyKey] = property.defaultValue;
this[propertyKey] = property.defaultValue;
}
}

const realm = attachRealm(element);
defineProperty(element, 'realm', {
const realm = attachRealm(this);
defineProperty(this, 'realm', {
value: realm,
configurable: true,
});
realm.observe(() => element.forceUpdate());
realm.observe(() => this.forceUpdate());

return element;
(this as WithComponentProto<ComponentInstance>)[CONSTRUCTED_SYMBOL] = true;
}

/**
* The callback for initialized components.
* It runs once when the component is created, at the end of the constructor.
*/
initialize() {}

/**
* Invoked each time the Component is appended into a document-connected element.
* This will happen each time the node is moved, and may happen before the element's contents have been fully parsed.
Expand Down Expand Up @@ -579,7 +585,6 @@ export function define(name: string, constructor: ComponentConstructor, options?
constructor(...args: any[]) {
super(...args);
if (new.target === Component) {
(this as WithComponentProto<ComponentInstance>)[CONSTRUCTED_SYMBOL] = true;
this.initialize();
}
}
Expand Down

0 comments on commit 1224baf

Please sign in to comment.