Skip to content

Commit 00fc037

Browse files
authored
Merge pull request #200 from github/catalyst-delegate
Move controller responsibility into delegate
2 parents a0f3855 + 6ad8c13 commit 00fc037

File tree

2 files changed

+68
-43
lines changed

2 files changed

+68
-43
lines changed

src/controller.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {initializeInstance, initializeClass, initializeAttributeChanged} from './core.js'
1+
import {CatalystDelegate} from './core.js'
22
import type {CustomElement} from './custom-element.js'
33
/**
44
* Controller is a decorator to be used over a class that extends HTMLElement.
@@ -7,18 +7,5 @@ import type {CustomElement} from './custom-element.js'
77
* wrapping the classes `connectedCallback` method if needed.
88
*/
99
export function controller(classObject: CustomElement): void {
10-
const connect = classObject.prototype.connectedCallback
11-
classObject.prototype.connectedCallback = function (this: HTMLElement) {
12-
initializeInstance(this, connect)
13-
}
14-
const attributeChanged = classObject.prototype.attributeChangedCallback
15-
classObject.prototype.attributeChangedCallback = function (
16-
this: HTMLElement,
17-
name: string,
18-
oldValue: unknown,
19-
newValue: unknown
20-
) {
21-
initializeAttributeChanged(this, name, oldValue, newValue, attributeChanged)
22-
}
23-
initializeClass(classObject)
10+
new CatalystDelegate(classObject)
2411
}

src/core.ts

Lines changed: 66 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,78 @@ import {autoShadowRoot} from './auto-shadow-root.js'
44
import {defineObservedAttributes, initializeAttrs} from './attr.js'
55
import type {CustomElement} from './custom-element.js'
66

7-
const instances = new WeakSet<Element>()
87
const symbol = Symbol.for('catalyst')
98

10-
export function initializeInstance(instance: HTMLElement, connect?: (this: HTMLElement) => void): void {
11-
instance.toggleAttribute('data-catalyst', true)
12-
customElements.upgrade(instance)
13-
instances.add(instance)
14-
autoShadowRoot(instance)
15-
initializeAttrs(instance)
16-
bind(instance)
17-
if (connect) connect.call(instance)
18-
if (instance.shadowRoot) bindShadow(instance.shadowRoot)
19-
}
9+
export class CatalystDelegate {
10+
constructor(classObject: CustomElement) {
11+
// eslint-disable-next-line @typescript-eslint/no-this-alias
12+
const delegate = this
13+
14+
const connectedCallback = classObject.prototype.connectedCallback
15+
classObject.prototype.connectedCallback = function (this: HTMLElement) {
16+
delegate.connectedCallback(this, connectedCallback)
17+
}
18+
19+
const disconnectedCallback = classObject.prototype.disconnectedCallback
20+
classObject.prototype.disconnectedCallback = function (this: HTMLElement) {
21+
delegate.disconnectedCallback(this, disconnectedCallback)
22+
}
23+
24+
const attributeChangedCallback = classObject.prototype.attributeChangedCallback
25+
classObject.prototype.attributeChangedCallback = function (
26+
this: HTMLElement,
27+
name: string,
28+
oldValue: string | null,
29+
newValue: string | null
30+
) {
31+
delegate.attributeChangedCallback(this, name, oldValue, newValue, attributeChangedCallback)
32+
}
33+
34+
let observedAttributes = classObject.observedAttributes || []
35+
Object.defineProperty(classObject, 'observedAttributes', {
36+
configurable: true,
37+
get() {
38+
return delegate.observedAttributes(this, observedAttributes)
39+
},
40+
set(attributes: string[]) {
41+
observedAttributes = attributes
42+
}
43+
})
2044

21-
export function initializeAttributeChanged(
22-
instance: HTMLElement,
23-
name: string,
24-
oldValue: unknown,
25-
newValue: unknown,
26-
attributeChangedCallback?: (this: HTMLElement, name: string, oldValue: unknown, newValue: unknown) => void
27-
): void {
28-
initializeAttrs(instance)
29-
if (name !== 'data-catalyst' && attributeChangedCallback) {
30-
attributeChangedCallback.call(instance, name, oldValue, newValue)
45+
defineObservedAttributes(classObject)
46+
register(classObject)
3147
}
32-
}
3348

34-
export function initializeClass(classObject: CustomElement): void {
35-
defineObservedAttributes(classObject)
36-
register(classObject)
37-
}
49+
observedAttributes(instance: HTMLElement, observedAttributes: string[]) {
50+
return observedAttributes
51+
}
52+
53+
connectedCallback(instance: HTMLElement, connectedCallback: () => void) {
54+
instance.toggleAttribute('data-catalyst', true)
55+
customElements.upgrade(instance)
56+
autoShadowRoot(instance)
57+
initializeAttrs(instance)
58+
bind(instance)
59+
connectedCallback?.call(instance)
60+
if (instance.shadowRoot) bindShadow(instance.shadowRoot)
61+
}
3862

39-
export function initialized(el: Element): boolean {
40-
return instances.has(el)
63+
disconnectedCallback(element: HTMLElement, disconnectedCallback: () => void) {
64+
disconnectedCallback?.call(element)
65+
}
66+
67+
attributeChangedCallback(
68+
instance: HTMLElement,
69+
name: string,
70+
oldValue: string | null,
71+
newValue: string | null,
72+
attributeChangedCallback: (...args: unknown[]) => void
73+
) {
74+
initializeAttrs(instance)
75+
if (name !== 'data-catalyst' && attributeChangedCallback) {
76+
attributeChangedCallback.call(instance, name, oldValue, newValue)
77+
}
78+
}
4179
}
4280

4381
export function meta(proto: Record<PropertyKey, unknown>, name: string): Set<string> {

0 commit comments

Comments
 (0)