mount-observer 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,64 @@
1
+ import { EvtRt } from './EvtRt.js';
2
+ export class DefineCustomElementHandler extends EvtRt {
3
+ mount(mountedElement, mountInit, context) {
4
+ // Check if modules are specified
5
+ if (!context.modules || context.modules.length === 0) {
6
+ throw new Error('Must specify an ES Module');
7
+ }
8
+ const module = context.modules[0];
9
+ const tagName = mountedElement.localName;
10
+ // Check if already defined
11
+ if (customElements.get(tagName)) {
12
+ return;
13
+ }
14
+ // Find suitable class
15
+ const ElementClass = this.findSuitableClass(module);
16
+ // Validate that ElementClass is a constructor
17
+ if (typeof ElementClass !== 'function') {
18
+ throw new Error(`Found class is not a constructor: ${typeof ElementClass}`);
19
+ }
20
+ // Create wrapper class to allow reuse
21
+ // Use anonymous class expression which works across all browsers
22
+ const WrapperClass = class extends ElementClass {
23
+ };
24
+ // Define the custom element
25
+ customElements.define(tagName, WrapperClass);
26
+ }
27
+ findSuitableClass(module) {
28
+ // Check default export first
29
+ const defaultExport = module.default;
30
+ if (defaultExport && this.extendsHTMLElement(defaultExport)) {
31
+ return defaultExport;
32
+ }
33
+ // Find all exports that extend HTMLElement
34
+ const htmlElementClasses = Object.values(module)
35
+ .filter(exp => typeof exp === 'function' && this.extendsHTMLElement(exp));
36
+ if (htmlElementClasses.length === 0) {
37
+ throw new Error('No suitable class found in module');
38
+ }
39
+ if (htmlElementClasses.length > 1) {
40
+ throw new Error('More than one class found in module');
41
+ }
42
+ return htmlElementClasses[0];
43
+ }
44
+ extendsHTMLElement(cls) {
45
+ try {
46
+ // Must be a function
47
+ if (typeof cls !== 'function') {
48
+ return false;
49
+ }
50
+ // Handle direct HTMLElement export
51
+ if (cls === HTMLElement) {
52
+ return true;
53
+ }
54
+ // Check if it has a prototype and extends HTMLElement
55
+ if (cls.prototype && cls.prototype instanceof HTMLElement) {
56
+ return true;
57
+ }
58
+ return false;
59
+ }
60
+ catch {
61
+ return false;
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,77 @@
1
+ import { EvtRt } from './EvtRt.js';
2
+ import { MountInit, MountContext } from './types.js';
3
+
4
+ export class DefineCustomElementHandler extends EvtRt {
5
+ mount(mountedElement: Element, mountInit: MountInit, context: MountContext): void {
6
+ // Check if modules are specified
7
+ if (!context.modules || context.modules.length === 0) {
8
+ throw new Error('Must specify an ES Module');
9
+ }
10
+
11
+ const module = context.modules[0];
12
+ const tagName = mountedElement.localName;
13
+
14
+ // Check if already defined
15
+ if (customElements.get(tagName)) {
16
+ return;
17
+ }
18
+
19
+ // Find suitable class
20
+ const ElementClass = this.findSuitableClass(module);
21
+
22
+ // Validate that ElementClass is a constructor
23
+ if (typeof ElementClass !== 'function') {
24
+ throw new Error(`Found class is not a constructor: ${typeof ElementClass}`);
25
+ }
26
+
27
+ // Create wrapper class to allow reuse
28
+ // Use anonymous class expression which works across all browsers
29
+ const WrapperClass = class extends ElementClass {};
30
+
31
+ // Define the custom element
32
+ customElements.define(tagName, WrapperClass);
33
+ }
34
+
35
+ private findSuitableClass(module: any): typeof HTMLElement {
36
+ // Check default export first
37
+ const defaultExport = module.default;
38
+
39
+ if (defaultExport && this.extendsHTMLElement(defaultExport)) {
40
+ return defaultExport;
41
+ }
42
+
43
+ // Find all exports that extend HTMLElement
44
+ const htmlElementClasses = Object.values(module)
45
+ .filter(exp => typeof exp === 'function' && this.extendsHTMLElement(exp));
46
+
47
+ if (htmlElementClasses.length === 0) {
48
+ throw new Error('No suitable class found in module');
49
+ }
50
+
51
+ if (htmlElementClasses.length > 1) {
52
+ throw new Error('More than one class found in module');
53
+ }
54
+
55
+ return htmlElementClasses[0] as typeof HTMLElement;
56
+ }
57
+
58
+ private extendsHTMLElement(cls: any): boolean {
59
+ try {
60
+ // Must be a function
61
+ if (typeof cls !== 'function') {
62
+ return false;
63
+ }
64
+ // Handle direct HTMLElement export
65
+ if (cls === HTMLElement) {
66
+ return true;
67
+ }
68
+ // Check if it has a prototype and extends HTMLElement
69
+ if (cls.prototype && cls.prototype instanceof HTMLElement) {
70
+ return true;
71
+ }
72
+ return false;
73
+ } catch {
74
+ return false;
75
+ }
76
+ }
77
+ }
package/Events.js CHANGED
@@ -7,36 +7,38 @@ export const attrchangeEventName = 'attrchange';
7
7
  export const mediamatchEventName = 'mediamatch';
8
8
  export const mediaunmatchEventName = 'mediaunmatch';
9
9
  export class MountEvent extends Event {
10
- matchingElement;
10
+ mountedElement;
11
11
  modules;
12
12
  mountInit;
13
+ mountContext;
13
14
  static eventName = mountEventName;
14
- constructor(matchingElement, modules, mountInit) {
15
+ constructor(mountedElement, modules, mountInit, mountContext) {
15
16
  super(MountEvent.eventName);
16
- this.matchingElement = matchingElement;
17
+ this.mountedElement = mountedElement;
17
18
  this.modules = modules;
18
19
  this.mountInit = mountInit;
20
+ this.mountContext = mountContext;
19
21
  }
20
22
  }
21
23
  export class DismountEvent extends Event {
22
- matchingElement;
24
+ mountedElement;
23
25
  reason;
24
26
  mountInit;
25
27
  static eventName = dismountEventName;
26
- constructor(matchingElement, reason, mountInit) {
28
+ constructor(mountedElement, reason, mountInit) {
27
29
  super(DismountEvent.eventName);
28
- this.matchingElement = matchingElement;
30
+ this.mountedElement = mountedElement;
29
31
  this.reason = reason;
30
32
  this.mountInit = mountInit;
31
33
  }
32
34
  }
33
35
  export class DisconnectEvent extends Event {
34
- matchingElement;
36
+ mountedElement;
35
37
  mountInit;
36
38
  static eventName = disconnectEventName;
37
- constructor(matchingElement, mountInit) {
39
+ constructor(mountedElement, mountInit) {
38
40
  super(DisconnectEvent.eventName);
39
- this.matchingElement = matchingElement;
41
+ this.mountedElement = mountedElement;
40
42
  this.mountInit = mountInit;
41
43
  }
42
44
  }
package/Events.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // Event classes for MountObserver
2
- import type { IMountEvent, IDismountEvent, IAttrChangeEvent, AttrChange, MountInit, DismountReason } from './types.js';
2
+ import type { IMountEvent, IDismountEvent, IAttrChangeEvent, AttrChange, MountInit, DismountReason, MountContext } from './types.js';
3
3
 
4
4
  // Event name constants
5
5
  export const loadEventName = 'load';
@@ -13,7 +13,12 @@ export const mediaunmatchEventName = 'mediaunmatch';
13
13
  export class MountEvent extends Event implements IMountEvent {
14
14
  static eventName: typeof mountEventName = mountEventName;
15
15
 
16
- constructor(public matchingElement: Element, public modules: any[], public mountInit: MountInit) {
16
+ constructor(
17
+ public mountedElement: Element,
18
+ public modules: any[],
19
+ public mountInit: MountInit,
20
+ public mountContext: MountContext
21
+ ) {
17
22
  super(MountEvent.eventName);
18
23
  }
19
24
  }
@@ -21,7 +26,7 @@ export class MountEvent extends Event implements IMountEvent {
21
26
  export class DismountEvent extends Event implements IDismountEvent {
22
27
  static eventName: typeof dismountEventName = dismountEventName;
23
28
 
24
- constructor(public matchingElement: Element, public reason: DismountReason, public mountInit: MountInit) {
29
+ constructor(public mountedElement: Element, public reason: DismountReason, public mountInit: MountInit) {
25
30
  super(DismountEvent.eventName);
26
31
  }
27
32
  }
@@ -29,7 +34,7 @@ export class DismountEvent extends Event implements IDismountEvent {
29
34
  export class DisconnectEvent extends Event {
30
35
  static eventName: typeof disconnectEventName = disconnectEventName;
31
36
 
32
- constructor(public matchingElement: Element, public mountInit: MountInit) {
37
+ constructor(public mountedElement: Element, public mountInit: MountInit) {
33
38
  super(DisconnectEvent.eventName);
34
39
  }
35
40
  }
package/EvtRt.js ADDED
@@ -0,0 +1,34 @@
1
+ import { DismountEvent, MountEvent, DisconnectEvent, dismountEventName, disconnectEventName, mountEventName } from './Events.js';
2
+ export class EvtRt {
3
+ constructor(mountedElement, ctx) {
4
+ const { observer, mountInit } = ctx;
5
+ const et = observer.getNotifier(mountedElement);
6
+ et.addEventListener(mountEventName, this);
7
+ et.addEventListener(disconnectEventName, this);
8
+ et.addEventListener(dismountEventName, this);
9
+ this.mount(mountedElement, mountInit, ctx);
10
+ }
11
+ mount(mountedElement, mountInit, context) {
12
+ console.log({ mountedElement, mountInit, context });
13
+ }
14
+ disconnect(mountedElement, mountInit) {
15
+ console.log({ mountedElement, mountInit });
16
+ }
17
+ dismount(mountedElement, mountInit) {
18
+ console.log({ mountedElement, mountInit });
19
+ }
20
+ handleEvent(evt) {
21
+ if (evt instanceof MountEvent) {
22
+ const { mountedElement, mountContext, mountInit } = evt;
23
+ this.mount(mountedElement, mountInit, mountContext);
24
+ }
25
+ else if (evt instanceof DismountEvent) {
26
+ const { mountedElement, mountInit } = evt;
27
+ this.dismount(mountedElement, mountInit);
28
+ }
29
+ else if (evt instanceof DisconnectEvent) {
30
+ const { mountedElement, mountInit } = evt;
31
+ this.disconnect(mountedElement, mountInit);
32
+ }
33
+ }
34
+ }
package/EvtRt.ts ADDED
@@ -0,0 +1,42 @@
1
+ import {MountContext, MountInit} from './types.js';
2
+
3
+ import {
4
+ DismountEvent, MountEvent, DisconnectEvent,
5
+ dismountEventName, disconnectEventName, mountEventName
6
+ } from './Events.js';
7
+ export class EvtRt implements EventListenerObject{
8
+ constructor(mountedElement: Element, ctx: MountContext ){
9
+ const {observer, mountInit} = ctx;
10
+ const et = observer.getNotifier(mountedElement);
11
+ et.addEventListener(mountEventName, this);
12
+ et.addEventListener(disconnectEventName, this);
13
+ et.addEventListener(dismountEventName, this);
14
+ this.mount(mountedElement, mountInit, ctx);
15
+
16
+ }
17
+
18
+ mount(mountedElement: Element, mountInit: MountInit, context: MountContext){
19
+ console.log({mountedElement, mountInit, context});
20
+ }
21
+
22
+ disconnect(mountedElement: Element, mountInit: MountInit){
23
+ console.log({mountedElement, mountInit});
24
+ }
25
+
26
+ dismount(mountedElement: Element, mountInit: MountInit){
27
+ console.log({mountedElement, mountInit});
28
+ }
29
+
30
+ handleEvent(evt: Event): void {
31
+ if(evt instanceof MountEvent){
32
+ const {mountedElement, mountContext, mountInit} = evt;
33
+ this.mount(mountedElement, mountInit, mountContext);
34
+ }else if(evt instanceof DismountEvent){
35
+ const {mountedElement, mountInit} = evt;
36
+ this.dismount(mountedElement, mountInit);
37
+ }else if(evt instanceof DisconnectEvent){
38
+ const {mountedElement, mountInit} = evt;
39
+ this.disconnect(mountedElement, mountInit);
40
+ }
41
+ }
42
+ }