@dooboostore/simple-web-component 1.0.16 → 1.0.18

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.
Files changed (130) hide show
  1. package/README.md +109 -48
  2. package/dist/cjs/decorators/addEventListener.js.map +2 -2
  3. package/dist/cjs/decorators/appendChild.js +48 -0
  4. package/dist/cjs/decorators/appendChild.js.map +7 -0
  5. package/dist/cjs/decorators/elementDefine.js +216 -67
  6. package/dist/cjs/decorators/elementDefine.js.map +3 -3
  7. package/dist/cjs/decorators/index.js +2 -1
  8. package/dist/cjs/decorators/index.js.map +2 -2
  9. package/dist/cjs/decorators/{innerHtml.js → onConnectedInnerHtml.js} +8 -8
  10. package/dist/cjs/decorators/onConnectedInnerHtml.js.map +7 -0
  11. package/dist/cjs/decorators/query.js +38 -0
  12. package/dist/cjs/decorators/query.js.map +2 -2
  13. package/dist/cjs/decorators/queryAll.js +32 -0
  14. package/dist/cjs/decorators/queryAll.js.map +2 -2
  15. package/dist/cjs/decorators/replaceChildren.js +53 -0
  16. package/dist/cjs/decorators/replaceChildren.js.map +7 -0
  17. package/dist/cjs/elements/SwcAppEngine.js +2 -1
  18. package/dist/cjs/elements/SwcAppEngine.js.map +2 -2
  19. package/dist/cjs/elements/SwcAsync.js +188 -0
  20. package/dist/cjs/elements/SwcAsync.js.map +7 -0
  21. package/dist/cjs/elements/SwcChoose.js +155 -0
  22. package/dist/cjs/elements/SwcChoose.js.map +7 -0
  23. package/dist/cjs/elements/SwcIf.js +167 -0
  24. package/dist/cjs/elements/SwcIf.js.map +7 -0
  25. package/dist/cjs/elements/SwcLoop.js +246 -0
  26. package/dist/cjs/elements/SwcLoop.js.map +7 -0
  27. package/dist/cjs/elements/SwcSubTemplates.js +65 -0
  28. package/dist/cjs/elements/SwcSubTemplates.js.map +7 -0
  29. package/dist/cjs/elements/index.js +7 -0
  30. package/dist/cjs/elements/index.js.map +2 -2
  31. package/dist/cjs/index.js +12 -2
  32. package/dist/cjs/index.js.map +2 -2
  33. package/dist/cjs/types.js.map +1 -1
  34. package/dist/cjs/utils/Utils.js +74 -37
  35. package/dist/cjs/utils/Utils.js.map +3 -3
  36. package/dist/esm/decorators/addEventListener.js.map +2 -2
  37. package/dist/esm/decorators/appendChild.js +29 -0
  38. package/dist/esm/decorators/appendChild.js.map +7 -0
  39. package/dist/esm/decorators/elementDefine.js +216 -67
  40. package/dist/esm/decorators/elementDefine.js.map +3 -3
  41. package/dist/esm/decorators/index.js +2 -1
  42. package/dist/esm/decorators/index.js.map +2 -2
  43. package/dist/esm/decorators/{innerHtml.js → onConnectedInnerHtml.js} +5 -5
  44. package/dist/esm/decorators/onConnectedInnerHtml.js.map +7 -0
  45. package/dist/esm/decorators/query.js +38 -0
  46. package/dist/esm/decorators/query.js.map +2 -2
  47. package/dist/esm/decorators/queryAll.js +32 -0
  48. package/dist/esm/decorators/queryAll.js.map +2 -2
  49. package/dist/esm/decorators/replaceChildren.js +34 -0
  50. package/dist/esm/decorators/replaceChildren.js.map +7 -0
  51. package/dist/esm/elements/SwcAppEngine.js +2 -1
  52. package/dist/esm/elements/SwcAppEngine.js.map +2 -2
  53. package/dist/esm/elements/SwcAsync.js +169 -0
  54. package/dist/esm/elements/SwcAsync.js.map +7 -0
  55. package/dist/esm/elements/SwcChoose.js +136 -0
  56. package/dist/esm/elements/SwcChoose.js.map +7 -0
  57. package/dist/esm/elements/SwcIf.js +148 -0
  58. package/dist/esm/elements/SwcIf.js.map +7 -0
  59. package/dist/esm/elements/SwcLoop.js +227 -0
  60. package/dist/esm/elements/SwcLoop.js.map +7 -0
  61. package/dist/esm/elements/SwcSubTemplates.js +46 -0
  62. package/dist/esm/elements/SwcSubTemplates.js.map +7 -0
  63. package/dist/esm/elements/index.js +7 -0
  64. package/dist/esm/elements/index.js.map +2 -2
  65. package/dist/esm/index.js +8 -2
  66. package/dist/esm/index.js.map +2 -2
  67. package/dist/esm/types.js.map +1 -1
  68. package/dist/esm/utils/Utils.js +74 -37
  69. package/dist/esm/utils/Utils.js.map +3 -3
  70. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +1226 -149
  71. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
  72. package/dist/types/decorators/addEventListener.d.ts +1 -0
  73. package/dist/types/decorators/addEventListener.d.ts.map +1 -1
  74. package/dist/types/decorators/appendChild.d.ts +17 -0
  75. package/dist/types/decorators/appendChild.d.ts.map +1 -0
  76. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  77. package/dist/types/decorators/index.d.ts +2 -1
  78. package/dist/types/decorators/index.d.ts.map +1 -1
  79. package/dist/types/decorators/onConnectedInnerHtml.d.ts +15 -0
  80. package/dist/types/decorators/onConnectedInnerHtml.d.ts.map +1 -0
  81. package/dist/types/decorators/query.d.ts +0 -2
  82. package/dist/types/decorators/query.d.ts.map +1 -1
  83. package/dist/types/decorators/queryAll.d.ts +0 -2
  84. package/dist/types/decorators/queryAll.d.ts.map +1 -1
  85. package/dist/types/decorators/replaceChildren.d.ts +9 -0
  86. package/dist/types/decorators/replaceChildren.d.ts.map +1 -0
  87. package/dist/types/elements/SwcAppEngine.d.ts.map +1 -1
  88. package/dist/types/elements/SwcAsync.d.ts +16 -0
  89. package/dist/types/elements/SwcAsync.d.ts.map +1 -0
  90. package/dist/types/elements/SwcChoose.d.ts +13 -0
  91. package/dist/types/elements/SwcChoose.d.ts.map +1 -0
  92. package/dist/types/elements/SwcIf.d.ts +15 -0
  93. package/dist/types/elements/SwcIf.d.ts.map +1 -0
  94. package/dist/types/elements/SwcLoop.d.ts +20 -0
  95. package/dist/types/elements/SwcLoop.d.ts.map +1 -0
  96. package/dist/types/elements/SwcSubTemplates.d.ts +13 -0
  97. package/dist/types/elements/SwcSubTemplates.d.ts.map +1 -0
  98. package/dist/types/elements/index.d.ts +7 -0
  99. package/dist/types/elements/index.d.ts.map +1 -1
  100. package/dist/types/index.d.ts +5 -2
  101. package/dist/types/index.d.ts.map +1 -1
  102. package/dist/types/types.d.ts +8 -0
  103. package/dist/types/types.d.ts.map +1 -1
  104. package/dist/types/utils/Utils.d.ts +16 -10
  105. package/dist/types/utils/Utils.d.ts.map +1 -1
  106. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +1226 -149
  107. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
  108. package/package.json +10 -3
  109. package/src/decorators/addEventListener.ts +1 -0
  110. package/src/decorators/appendChild.ts +42 -0
  111. package/src/decorators/elementDefine.ts +225 -71
  112. package/src/decorators/index.ts +2 -1
  113. package/src/decorators/{innerHtml.ts → onConnectedInnerHtml.ts} +7 -6
  114. package/src/decorators/query.ts +32 -2
  115. package/src/decorators/queryAll.ts +32 -2
  116. package/src/decorators/replaceChildren.ts +35 -0
  117. package/src/elements/SwcAppEngine.ts +2 -1
  118. package/src/elements/SwcAsync.ts +163 -0
  119. package/src/elements/SwcChoose.ts +127 -0
  120. package/src/elements/SwcIf.ts +134 -0
  121. package/src/elements/SwcLoop.ts +215 -0
  122. package/src/elements/SwcSubTemplates.ts +19 -0
  123. package/src/elements/index.ts +8 -3
  124. package/src/index.ts +5 -2
  125. package/src/types.ts +9 -1
  126. package/src/utils/Utils.ts +86 -36
  127. package/dist/cjs/decorators/innerHtml.js.map +0 -7
  128. package/dist/esm/decorators/innerHtml.js.map +0 -7
  129. package/dist/types/decorators/innerHtml.d.ts +0 -12
  130. package/dist/types/decorators/innerHtml.d.ts.map +0 -1
@@ -0,0 +1,215 @@
1
+ import { elementDefine } from '../decorators/elementDefine';
2
+ import { changedAttribute } from '../decorators/changedAttribute';
3
+ import { SwcUtils } from '../utils/Utils';
4
+ import { FunctionUtils } from '@dooboostore/core/function/FunctionUtils';
5
+
6
+ @elementDefine({ name: 'swc-loop', extends: 'template' })
7
+ export class SwcLoop extends HTMLTemplateElement {
8
+ private _value: any[] = [];
9
+ private _nodes: (Node[] | null)[] = [];
10
+ private _defaultNodes: Node[] = [];
11
+
12
+ get value(): any[] {
13
+ return this._value;
14
+ }
15
+
16
+ set value(nv: any[]) {
17
+ this._value = Array.isArray(nv) ? [...nv] : [];
18
+ this.render();
19
+ }
20
+
21
+ getNodes(index: number): Node[] | null {
22
+ return this._nodes[index] || null;
23
+ }
24
+
25
+ private _getTarget(): Element | DocumentFragment | null {
26
+ const script = this.getAttribute('on-get-portal');
27
+ if (!script) return null;
28
+ try {
29
+ const res = FunctionUtils.executeReturn({
30
+ script,
31
+ context: this,
32
+ args: SwcUtils.getHelperAndHostSet(window, this)
33
+ });
34
+ if (typeof res === 'string') return document.querySelector(res);
35
+ if (res instanceof Node) return res as any;
36
+ } catch (e) {
37
+ console.error('[SwcLoop] Portal target error:', e);
38
+ }
39
+ return null;
40
+ }
41
+
42
+ append(...items: any[]) {
43
+ if (!items.length || !this.parentElement) return;
44
+ if (this._defaultNodes.length > 0) this._cleanupDefault();
45
+
46
+ const fragment = document.createDocumentFragment();
47
+ const startIndex = this._value.length;
48
+
49
+ items.forEach((item, i) => {
50
+ const index = startIndex + i;
51
+ const nodes = this._createItemNodes(item, index);
52
+ if (nodes) {
53
+ this._nodes.push(nodes);
54
+ nodes.forEach(n => fragment.appendChild(n));
55
+ this._value.push(item);
56
+ } else {
57
+ this._nodes.push(null);
58
+ this._value.push(null);
59
+ }
60
+ });
61
+
62
+ const target = this._getTarget();
63
+ if (target) {
64
+ target.appendChild(fragment);
65
+ } else {
66
+ const lastValidIdx = this._nodes.length - items.length - 1;
67
+ let refNode: Node = this;
68
+ for (let i = lastValidIdx; i >= 0; i--) {
69
+ const group = this._nodes[i];
70
+ if (group && group.length > 0) {
71
+ refNode = group[group.length - 1];
72
+ break;
73
+ }
74
+ }
75
+ this.parentElement.insertBefore(fragment, refNode.nextSibling);
76
+ }
77
+ }
78
+
79
+ remove(index?: number) {
80
+ const targetIdx = index !== undefined ? index : this._nodes.length - 1;
81
+ if (targetIdx < 0 || targetIdx >= this._nodes.length) return;
82
+
83
+ const nodes = this._nodes[targetIdx];
84
+ if (nodes) {
85
+ nodes.forEach(n => {
86
+ if (n.parentElement) n.parentElement.removeChild(n);
87
+ });
88
+ this._nodes[targetIdx] = null;
89
+ this._value[targetIdx] = null;
90
+ }
91
+
92
+ const activeRows = this._value.filter(v => v !== null);
93
+ if (activeRows.length === 0) {
94
+ this.render();
95
+ }
96
+ }
97
+
98
+ private _createItemNodes(item: any, index: number): Node[] {
99
+ const clone = this.content.cloneNode(true) as DocumentFragment;
100
+ Array.from(clone.querySelectorAll('template[is="swc-default"]')).forEach(t => t.remove());
101
+
102
+ const nodes = Array.from(clone.childNodes);
103
+ const elements = nodes.filter(n => n.nodeType === 1) as HTMLElement[];
104
+
105
+ const groupCtx = {
106
+ $index: index,
107
+ $item: item,
108
+ $nodes: nodes,
109
+ $elements: elements,
110
+ $firstNode: nodes[0],
111
+ $lastNode: nodes[nodes.length - 1],
112
+ $firstElement: elements[0],
113
+ $lastElement: elements[elements.length - 1],
114
+ $isFirst: index === 0,
115
+ $isLast: index === this._value.length - 1,
116
+ $isEven: index % 2 === 0,
117
+ $isOdd: index % 2 !== 0,
118
+ $count: this._value.length
119
+ };
120
+
121
+ this._executeCallback('on-clone-nodes', groupCtx);
122
+ nodes.forEach((node, nodeIndex) => {
123
+ if (node instanceof HTMLElement) (node as any).__swc_host = this;
124
+ this._executeCallback('on-clone-node', { ...groupCtx, $node: node, $nodeIndex: nodeIndex, $isElement: node.nodeType === 1 });
125
+ });
126
+
127
+ return nodes;
128
+ }
129
+
130
+ private _executeCallback(attrName: string, extraArgs: Record<string, any>) {
131
+ const script = this.getAttribute(attrName);
132
+ if (!script) return;
133
+ const helperHostSet = SwcUtils.getHelperAndHostSet(window, this);
134
+ try {
135
+ FunctionUtils.execute({ script, context: this, args: { ...helperHostSet, ...extraArgs } });
136
+ } catch (e) {
137
+ console.error(`[SwcLoop] Error in ${attrName}:`, e);
138
+ }
139
+ }
140
+
141
+ @changedAttribute('on-get-value')
142
+ private refreshValue(newValue?: string | null) {
143
+ const script = newValue !== undefined ? newValue : this.getAttribute('on-get-value');
144
+ if (!script) {
145
+ this.value = [];
146
+ return;
147
+ }
148
+ const helperHostSet = SwcUtils.getHelperAndHostSet(window, this);
149
+ try {
150
+ const res = FunctionUtils.executeReturn({ script, context: this, args: helperHostSet });
151
+ if (Array.isArray(res)) {
152
+ this.value = res;
153
+ }
154
+ } catch (e) {
155
+ console.error('[SwcLoop] Failed to get value from on-get-value script:', e);
156
+ this.value = [];
157
+ }
158
+ }
159
+
160
+ render() {
161
+ this._cleanup();
162
+ if (!this.parentElement) return;
163
+
164
+ const activeRows = this._value.filter(v => v !== null);
165
+ const target = this._getTarget();
166
+
167
+ if (activeRows.length === 0) {
168
+ const t = this.content.querySelector('template[is="swc-default"]') as HTMLTemplateElement;
169
+ if (t) {
170
+ const clone = t.content.cloneNode(true) as DocumentFragment;
171
+ this._defaultNodes = Array.from(clone.childNodes);
172
+ this._defaultNodes.forEach(n => {
173
+ if (n instanceof HTMLElement) (n as any).__swc_host = this;
174
+ });
175
+ if (target) target.appendChild(clone);
176
+ else this.parentElement.insertBefore(clone, this.nextSibling);
177
+ }
178
+ return;
179
+ }
180
+
181
+ const fragment = document.createDocumentFragment();
182
+ this._value.forEach((item, index) => {
183
+ if (item === null) {
184
+ this._nodes.push(null);
185
+ return;
186
+ }
187
+ const nodes = this._createItemNodes(item, index);
188
+ this._nodes.push(nodes);
189
+ nodes.forEach(n => fragment.appendChild(n));
190
+ });
191
+
192
+ if (target) target.appendChild(fragment);
193
+ else this.parentElement.insertBefore(fragment, this.nextSibling);
194
+ }
195
+
196
+ private _cleanup() {
197
+ this._nodes.forEach(group => {
198
+ if (group) group.forEach(node => node.parentElement?.removeChild(node));
199
+ });
200
+ this._nodes = [];
201
+ this._cleanupDefault();
202
+ }
203
+
204
+ private _cleanupDefault() {
205
+ this._defaultNodes.forEach(n => n.parentElement?.removeChild(n));
206
+ this._defaultNodes = [];
207
+ }
208
+
209
+ connectedCallback() {
210
+ this.refreshValue();
211
+ }
212
+ disconnectedCallback() {
213
+ this._cleanup();
214
+ }
215
+ }
@@ -0,0 +1,19 @@
1
+ import { elementDefine } from '../decorators/elementDefine';
2
+
3
+ @elementDefine({ name: 'swc-loading', extends: 'template' })
4
+ export class SwcLoading extends HTMLTemplateElement {}
5
+
6
+ @elementDefine({ name: 'swc-error', extends: 'template' })
7
+ export class SwcError extends HTMLTemplateElement {}
8
+
9
+ @elementDefine({ name: 'swc-success', extends: 'template' })
10
+ export class SwcSuccess extends HTMLTemplateElement {}
11
+
12
+ @elementDefine({ name: 'swc-when', extends: 'template' })
13
+ export class SwcWhen extends HTMLTemplateElement {}
14
+
15
+ @elementDefine({ name: 'swc-otherwise', extends: 'template' })
16
+ export class SwcOtherwise extends HTMLTemplateElement {}
17
+
18
+ @elementDefine({ name: 'swc-default', extends: 'template' })
19
+ export class SwcDefault extends HTMLTemplateElement {}
@@ -1,3 +1,8 @@
1
- // import {SwcHTMLElement} from "./SwcHTMLElement";
2
-
3
- export * from './is'
1
+ export * from './is';
2
+ export * from './SwcSubTemplates';
3
+ export * from './SwcLoop';
4
+ export * from './SwcIf';
5
+ export * from './SwcChoose';
6
+ export * from './SwcAsync';
7
+ export * from './SwcApp';
8
+ export * from './SwcAppEngine';
package/src/index.ts CHANGED
@@ -4,7 +4,10 @@ import 'reflect-metadata';
4
4
  export * from './decorators/elementDefine';
5
5
  export * from './decorators/setAttribute';
6
6
  export * from './decorators/changedAttribute';
7
- export * from './decorators/innerHtml';
7
+ export * from './decorators/onConnectedInnerHtml';
8
+ export { onConnectedInnerHtml as innerHtml } from './decorators/onConnectedInnerHtml';
9
+ export * from './decorators/replaceChildren';
10
+ export * from './decorators/appendChild';
8
11
  export * from './decorators/emitCustomEvent';
9
12
  export * from './decorators/lifecycles';
10
13
  export * from './decorators/query';
@@ -15,7 +18,7 @@ export * from './decorators/addEventListener';
15
18
  export * from './types';
16
19
 
17
20
  // Apps (Customized Built-in Elements)
18
- export * from './elements/is';
21
+ export * from './elements';
19
22
 
20
23
  // Utilities
21
24
  export * from './utils/Utils';
package/src/types.ts CHANGED
@@ -13,7 +13,13 @@ export enum InjectSituationType {
13
13
  FIRST_APP_HOST = 'SIMPLE_WEB_COMPONENT://FIRSTAPPHOST',
14
14
  LAST_APP_HOST = 'SIMPLE_WEB_COMPONENT://LASTAPPHOST'
15
15
  }
16
-
16
+ export type HelperSet = {
17
+ $d: Document;
18
+ $w: Window;
19
+ $q: (selector: string, root?: Element | Document | ShadowRoot) => HTMLElement | null;
20
+ $qa: (selector: string, root?: Element | Document | ShadowRoot) => HTMLElement[];
21
+ $qi: (selector: string, root?: Element | Document | ShadowRoot) => HTMLElement | null;
22
+ }
17
23
  export type HostSet = {
18
24
  $host: HTMLElement; // Current component itself
19
25
  $parentHost: HTMLElement | null; // Nearest parent SWC component
@@ -26,6 +32,8 @@ export type HostSet = {
26
32
  $lastAppHost: SwcAppInterface | null;
27
33
  };
28
34
 
35
+ export type HelperHostSet = HelperSet & HostSet;
36
+
29
37
  export interface SwcAppInterface extends HTMLElement {
30
38
  simpleApplication?: SimpleApplication;
31
39
  router?: Router;
@@ -1,10 +1,30 @@
1
- import { SwcAppInterface, HostSet } from '../types';
1
+ import { SwcAppInterface, HostSet, HelperSet, HelperHostSet } from '../types';
2
2
  import { getElementConfig } from '../decorators/elementDefine';
3
3
 
4
4
  export const SWC_NOT_FOUND = Symbol('SWC_NOT_FOUND');
5
5
 
6
- export class SwcUtils {
7
- static getValueByPath(obj: any, path: string, rootName: string) {
6
+ export namespace SwcUtils {
7
+ export const getHelperSet = (win: Window): HelperSet => {
8
+ const doc: Document = win.document;
9
+ return {
10
+ $d: doc,
11
+ $w: win,
12
+ $q: (sel: string, root?: Element | Document | ShadowRoot) => (root ?? doc).querySelector(sel),
13
+ $qa: (sel: string, root?: Element | Document | ShadowRoot) => Array.from((root ?? doc).querySelectorAll(sel)) as HTMLElement[],
14
+ $qi: (id: string, root?: Document | ShadowRoot) => (root ?? doc).getElementById(id) as HTMLElement
15
+ } as const;
16
+ };
17
+
18
+ export const getHelperAndHostSet = (win: Window, el: HTMLElement): HelperHostSet => {
19
+ const helperSet = getHelperSet(win);
20
+ const hostSet = getHostSet(el);
21
+ return {
22
+ ...helperSet,
23
+ ...hostSet
24
+ };
25
+ };
26
+
27
+ export const getValueByPath = (obj: any, path: string, rootName: string) => {
8
28
  if (!obj || !path) return SWC_NOT_FOUND;
9
29
 
10
30
  const parts = path.split('.');
@@ -15,58 +35,87 @@ export class SwcUtils {
15
35
  current = current[part];
16
36
  }
17
37
  return current;
18
- }
38
+ };
19
39
 
20
- static findNearestSwcHost(el: HTMLElement | Node): HTMLElement | undefined {
21
- let current: any = el instanceof Node && !(el instanceof HTMLElement) ? (el as any).host : el;
22
- current = current?.parentElement || (current?.getRootNode() as any)?.host;
40
+ /**
41
+ * Finds the nearest logical SWC host for an element.
42
+ * Checks __swc_host property first, then climbs the DOM tree.
43
+ */
44
+ export const findNearestSwcHost = (el: HTMLElement | Node): HTMLElement | undefined => {
45
+ if ((el as any).__swc_host) return (el as any).__swc_host;
23
46
 
24
- while (current) {
47
+ let current: any = el.parentElement || (el.getRootNode?.() as any)?.host;
48
+ while (current && current !== document && current !== window) {
49
+ if (current.__swc_host) return current.__swc_host;
25
50
  if (getElementConfig(current)) return current as HTMLElement;
26
- current = current.parentElement || (current?.getRootNode() as any)?.host;
51
+ current = current.parentElement || (current.getRootNode?.() as any)?.host;
27
52
  }
28
53
  return undefined;
29
- }
54
+ };
30
55
 
31
56
  /**
32
57
  * Returns all SWC ancestors (excluding self) in [root, ..., parent] order.
33
58
  */
34
- static findAllSwcHosts(el: HTMLElement | Node): HTMLElement[] {
59
+ export const findAllSwcHosts = (el: HTMLElement | Node): HTMLElement[] => {
35
60
  const hosts: HTMLElement[] = [];
36
- let current = this.findNearestSwcHost(el);
61
+ let current = findNearestSwcHost(el);
37
62
  while (current) {
38
63
  hosts.push(current);
39
- current = this.findNearestSwcHost(current);
64
+ // To find the next ancestor, we must start searching from the PARENT of the found host
65
+ current = findNearestSwcHost(current);
40
66
  }
41
67
  return hosts.reverse();
42
- }
68
+ };
43
69
 
44
- static getHosts(el: HTMLElement): HTMLElement[] {
45
- return [...this.findAllSwcHosts(el), el];
46
- }
70
+ export const getHosts = (el: HTMLElement): HTMLElement[] => {
71
+ const ancestors = findAllSwcHosts(el);
72
+ if (getElementConfig(el)) return [...ancestors, el];
73
+ return ancestors;
74
+ };
47
75
 
48
- static getHost(el: HTMLElement): HTMLElement | undefined {
49
- return el;
50
- }
76
+ export const getHost = (el: HTMLElement): HTMLElement | undefined => {
77
+ if (getElementConfig(el)) return el;
78
+ return findNearestSwcHost(el);
79
+ };
51
80
 
52
- static getAppHosts(el: HTMLElement): SwcAppInterface[] {
53
- const hosts = this.getHosts(el);
81
+ export const getAppHosts = (el: HTMLElement): SwcAppInterface[] => {
82
+ const hosts = getHosts(el);
54
83
  return hosts.filter(host => host.tagName.toLowerCase() === 'swc-app' || host.getAttribute('is')?.startsWith('swc-app-')) as SwcAppInterface[];
55
- }
84
+ };
56
85
 
57
- static getAppHost(el: HTMLElement): SwcAppInterface | undefined {
58
- const appHosts = this.getAppHosts(el);
86
+ export const getAppHost = (el: HTMLElement): SwcAppInterface | undefined => {
87
+ const appHosts = getAppHosts(el);
59
88
  const appHostsWithoutSelf = appHosts.filter(h => h !== el);
60
- // Nearest app host is the last one in [root, ..., parent]
61
89
  return appHostsWithoutSelf.length > 0 ? appHostsWithoutSelf[appHostsWithoutSelf.length - 1] : undefined;
62
- }
90
+ };
63
91
 
64
- static getHostSet(el: HTMLElement): HostSet {
65
- const ancestors = this.findAllSwcHosts(el); // [root, ..., parent]
66
- const $host = el;
67
- const $hosts = [...ancestors, $host]; // [root, ..., parent, self]
68
- const $parentHost = ancestors.length > 0 ? ancestors[ancestors.length - 1] : null;
69
- const $firstHost = ancestors.length > 0 ? ancestors[0] : null;
92
+ export const getHostSet = (el: HTMLElement): HostSet => {
93
+ const isSwc = !!getElementConfig(el);
94
+ const ancestors = findAllSwcHosts(el); // [root, ..., parent]
95
+
96
+ let $host: HTMLElement;
97
+ let $parentHost: HTMLElement | null;
98
+
99
+ if (isSwc) {
100
+ $host = el;
101
+ $parentHost = ancestors.length > 0 ? ancestors[ancestors.length - 1] : null;
102
+ } else {
103
+ $host = ancestors.length > 0 ? ancestors[ancestors.length - 1] : el;
104
+ $parentHost = ancestors.length > 1 ? ancestors[ancestors.length - 2] : null;
105
+ }
106
+
107
+ const $hosts = isSwc ? [...ancestors, el] : ancestors;
108
+ const $firstHost = $hosts.length > 0 ? $hosts[0] : null;
109
+
110
+ // Collect loop contexts
111
+ const loopContext: Record<string, any> = {};
112
+ let curr: any = el;
113
+ while (curr && curr !== document.documentElement) {
114
+ if (curr.__swc_loop_context) {
115
+ Object.assign(loopContext, curr.__swc_loop_context);
116
+ }
117
+ curr = curr.parentElement || (curr.getRootNode() as any).host;
118
+ }
70
119
 
71
120
  const $appHosts = $hosts.filter(h => h.tagName.toLowerCase() === 'swc-app' || h.getAttribute('is')?.startsWith('swc-app-')) as SwcAppInterface[];
72
121
  const $appHost = $appHosts.length > 0 ? ($appHosts[$appHosts.length - 1] === el ? ($appHosts.length > 1 ? $appHosts[$appHosts.length - 2] : null) : $appHosts[$appHosts.length - 1]) : null;
@@ -81,7 +130,8 @@ export class SwcUtils {
81
130
  $appHost,
82
131
  $appHosts,
83
132
  $firstAppHost,
84
- $lastAppHost: $appHost
85
- };
86
- }
133
+ $lastAppHost: $appHost,
134
+ ...loopContext
135
+ } as any;
136
+ };
87
137
  }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/decorators/innerHtml.ts"],
4
- "sourcesContent": ["import { ReflectUtils } from '@dooboostore/core/reflect/ReflectUtils';\n\nexport interface InnerHtmlOptions {\n useShadow?: boolean;\n}\n\nexport interface InnerHtmlMetadata {\n propertyKey: string | symbol;\n options: InnerHtmlOptions;\n}\n\nexport const INNER_HTML_METADATA_KEY = Symbol('simple-web-component:inner-html');\n\nexport function innerHtml(options: InnerHtmlOptions): MethodDecorator;\nexport function innerHtml(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;\nexport function innerHtml(arg1?: InnerHtmlOptions | Object, arg2?: string | symbol, arg3?: PropertyDescriptor): MethodDecorator | void {\n const decorator = (options: InnerHtmlOptions, target: Object, propertyKey: string | symbol) => {\n const constructor = target.constructor;\n let list = ReflectUtils.getMetadata<InnerHtmlMetadata[]>(INNER_HTML_METADATA_KEY, constructor);\n if (!list) {\n list = [];\n ReflectUtils.defineMetadata(INNER_HTML_METADATA_KEY, list, constructor);\n }\n list.push({ propertyKey, options });\n };\n\n if (arg2) {\n // Used as @innerHtml\n return decorator({}, arg1!, arg2);\n }\n\n // Used as @innerHtml(options)\n return (target: Object, propertyKey: string | symbol) => {\n decorator((arg1 as InnerHtmlOptions) || {}, target, propertyKey);\n };\n}\n\nexport const getInnerHtmlMetadataList = (target: any): InnerHtmlMetadata[] | undefined => {\n const constructor = target instanceof Function ? target : target.constructor;\n return ReflectUtils.getMetadata(INNER_HTML_METADATA_KEY, constructor);\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAA6B;AAWtB,MAAM,0BAA0B,OAAO,iCAAiC;AAIxE,SAAS,UAAU,MAAkC,MAAwB,MAAmD;AACrI,QAAM,YAAY,CAAC,SAA2B,QAAgB,gBAAiC;AAC7F,UAAM,cAAc,OAAO;AAC3B,QAAI,OAAO,iCAAa,YAAiC,yBAAyB,WAAW;AAC7F,QAAI,CAAC,MAAM;AACT,aAAO,CAAC;AACR,uCAAa,eAAe,yBAAyB,MAAM,WAAW;AAAA,IACxE;AACA,SAAK,KAAK,EAAE,aAAa,QAAQ,CAAC;AAAA,EACpC;AAEA,MAAI,MAAM;AAER,WAAO,UAAU,CAAC,GAAG,MAAO,IAAI;AAAA,EAClC;AAGA,SAAO,CAAC,QAAgB,gBAAiC;AACvD,cAAW,QAA6B,CAAC,GAAG,QAAQ,WAAW;AAAA,EACjE;AACF;AAEO,MAAM,2BAA2B,CAAC,WAAiD;AACxF,QAAM,cAAc,kBAAkB,WAAW,SAAS,OAAO;AACjE,SAAO,iCAAa,YAAY,yBAAyB,WAAW;AACtE;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/decorators/innerHtml.ts"],
4
- "sourcesContent": ["import { ReflectUtils } from '@dooboostore/core/reflect/ReflectUtils';\n\nexport interface InnerHtmlOptions {\n useShadow?: boolean;\n}\n\nexport interface InnerHtmlMetadata {\n propertyKey: string | symbol;\n options: InnerHtmlOptions;\n}\n\nexport const INNER_HTML_METADATA_KEY = Symbol('simple-web-component:inner-html');\n\nexport function innerHtml(options: InnerHtmlOptions): MethodDecorator;\nexport function innerHtml(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;\nexport function innerHtml(arg1?: InnerHtmlOptions | Object, arg2?: string | symbol, arg3?: PropertyDescriptor): MethodDecorator | void {\n const decorator = (options: InnerHtmlOptions, target: Object, propertyKey: string | symbol) => {\n const constructor = target.constructor;\n let list = ReflectUtils.getMetadata<InnerHtmlMetadata[]>(INNER_HTML_METADATA_KEY, constructor);\n if (!list) {\n list = [];\n ReflectUtils.defineMetadata(INNER_HTML_METADATA_KEY, list, constructor);\n }\n list.push({ propertyKey, options });\n };\n\n if (arg2) {\n // Used as @innerHtml\n return decorator({}, arg1!, arg2);\n }\n\n // Used as @innerHtml(options)\n return (target: Object, propertyKey: string | symbol) => {\n decorator((arg1 as InnerHtmlOptions) || {}, target, propertyKey);\n };\n}\n\nexport const getInnerHtmlMetadataList = (target: any): InnerHtmlMetadata[] | undefined => {\n const constructor = target instanceof Function ? target : target.constructor;\n return ReflectUtils.getMetadata(INNER_HTML_METADATA_KEY, constructor);\n};\n"],
5
- "mappings": "AAAA,SAAS,oBAAoB;AAWtB,MAAM,0BAA0B,OAAO,iCAAiC;AAIxE,SAAS,UAAU,MAAkC,MAAwB,MAAmD;AACrI,QAAM,YAAY,CAAC,SAA2B,QAAgB,gBAAiC;AAC7F,UAAM,cAAc,OAAO;AAC3B,QAAI,OAAO,aAAa,YAAiC,yBAAyB,WAAW;AAC7F,QAAI,CAAC,MAAM;AACT,aAAO,CAAC;AACR,mBAAa,eAAe,yBAAyB,MAAM,WAAW;AAAA,IACxE;AACA,SAAK,KAAK,EAAE,aAAa,QAAQ,CAAC;AAAA,EACpC;AAEA,MAAI,MAAM;AAER,WAAO,UAAU,CAAC,GAAG,MAAO,IAAI;AAAA,EAClC;AAGA,SAAO,CAAC,QAAgB,gBAAiC;AACvD,cAAW,QAA6B,CAAC,GAAG,QAAQ,WAAW;AAAA,EACjE;AACF;AAEO,MAAM,2BAA2B,CAAC,WAAiD;AACxF,QAAM,cAAc,kBAAkB,WAAW,SAAS,OAAO;AACjE,SAAO,aAAa,YAAY,yBAAyB,WAAW;AACtE;",
6
- "names": []
7
- }
@@ -1,12 +0,0 @@
1
- export interface InnerHtmlOptions {
2
- useShadow?: boolean;
3
- }
4
- export interface InnerHtmlMetadata {
5
- propertyKey: string | symbol;
6
- options: InnerHtmlOptions;
7
- }
8
- export declare const INNER_HTML_METADATA_KEY: unique symbol;
9
- export declare function innerHtml(options: InnerHtmlOptions): MethodDecorator;
10
- export declare function innerHtml(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
11
- export declare const getInnerHtmlMetadataList: (target: any) => InnerHtmlMetadata[] | undefined;
12
- //# sourceMappingURL=innerHtml.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"innerHtml.d.ts","sourceRoot":"","sources":["../../../src/decorators/innerHtml.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,OAAO,EAAE,gBAAgB,CAAC;CAC3B;AAED,eAAO,MAAM,uBAAuB,eAA4C,CAAC;AAEjF,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,eAAe,CAAC;AACtE,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,UAAU,EAAE,kBAAkB,GAAG,IAAI,CAAC;AAuB9G,eAAO,MAAM,wBAAwB,GAAI,QAAQ,GAAG,KAAG,iBAAiB,EAAE,GAAG,SAG5E,CAAC"}