@dooboostore/simple-web-component 1.0.21 → 1.0.23

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 (174) hide show
  1. package/README.md +1113 -95
  2. package/dist/cjs/decorators/addEventListener.js +4 -0
  3. package/dist/cjs/decorators/addEventListener.js.map +2 -2
  4. package/dist/cjs/decorators/applyNode.js +174 -0
  5. package/dist/cjs/decorators/applyNode.js.map +7 -0
  6. package/dist/cjs/decorators/attribute.js +30 -10
  7. package/dist/cjs/decorators/attribute.js.map +3 -3
  8. package/dist/cjs/decorators/{changedAttribute.js → changedAttributeHost.js} +6 -6
  9. package/dist/cjs/decorators/changedAttributeHost.js.map +7 -0
  10. package/dist/cjs/decorators/classList.js +45 -15
  11. package/dist/cjs/decorators/classList.js.map +2 -2
  12. package/dist/cjs/decorators/elementDefine.js +107 -57
  13. package/dist/cjs/decorators/elementDefine.js.map +2 -2
  14. package/dist/cjs/decorators/emitCustomEvent.js +4 -3
  15. package/dist/cjs/decorators/emitCustomEvent.js.map +2 -2
  16. package/dist/cjs/decorators/index.js +2 -4
  17. package/dist/cjs/decorators/index.js.map +2 -2
  18. package/dist/cjs/decorators/lifecycles.js +29 -0
  19. package/dist/cjs/decorators/lifecycles.js.map +2 -2
  20. package/dist/cjs/decorators/query.js +5 -1
  21. package/dist/cjs/decorators/query.js.map +2 -2
  22. package/dist/cjs/decorators/queryAll.js +5 -1
  23. package/dist/cjs/decorators/queryAll.js.map +2 -2
  24. package/dist/cjs/decorators/setAttribute.js +5 -1
  25. package/dist/cjs/decorators/setAttribute.js.map +2 -2
  26. package/dist/cjs/decorators/style.js +39 -13
  27. package/dist/cjs/decorators/style.js.map +2 -2
  28. package/dist/cjs/elements/SwcAppEngine.js.map +2 -2
  29. package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
  30. package/dist/cjs/elements/SwcAsync.js +2 -2
  31. package/dist/cjs/elements/SwcAsync.js.map +2 -2
  32. package/dist/cjs/elements/SwcChoose.js +2 -2
  33. package/dist/cjs/elements/SwcChoose.js.map +2 -2
  34. package/dist/cjs/elements/SwcIf.js +2 -2
  35. package/dist/cjs/elements/SwcIf.js.map +2 -2
  36. package/dist/cjs/elements/SwcLoop.js +2 -2
  37. package/dist/cjs/elements/SwcLoop.js.map +2 -2
  38. package/dist/cjs/elements/register.js +6 -5
  39. package/dist/cjs/elements/register.js.map +2 -2
  40. package/dist/cjs/index.js +6 -18
  41. package/dist/cjs/index.js.map +2 -2
  42. package/dist/cjs/types.js.map +2 -2
  43. package/dist/cjs/utils/TemplateUtils.js +6 -0
  44. package/dist/cjs/utils/TemplateUtils.js.map +2 -2
  45. package/dist/esm/decorators/addEventListener.js +4 -0
  46. package/dist/esm/decorators/addEventListener.js.map +2 -2
  47. package/dist/esm/decorators/applyNode.js +155 -0
  48. package/dist/esm/decorators/applyNode.js.map +7 -0
  49. package/dist/esm/decorators/attribute.js +30 -10
  50. package/dist/esm/decorators/attribute.js.map +3 -3
  51. package/dist/esm/decorators/{changedAttribute.js → changedAttributeHost.js} +3 -3
  52. package/dist/esm/decorators/changedAttributeHost.js.map +7 -0
  53. package/dist/esm/decorators/classList.js +45 -15
  54. package/dist/esm/decorators/classList.js.map +2 -2
  55. package/dist/esm/decorators/elementDefine.js +106 -56
  56. package/dist/esm/decorators/elementDefine.js.map +2 -2
  57. package/dist/esm/decorators/emitCustomEvent.js +4 -3
  58. package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
  59. package/dist/esm/decorators/index.js +2 -4
  60. package/dist/esm/decorators/index.js.map +2 -2
  61. package/dist/esm/decorators/lifecycles.js +29 -0
  62. package/dist/esm/decorators/lifecycles.js.map +2 -2
  63. package/dist/esm/decorators/query.js +5 -1
  64. package/dist/esm/decorators/query.js.map +2 -2
  65. package/dist/esm/decorators/queryAll.js +5 -1
  66. package/dist/esm/decorators/queryAll.js.map +2 -2
  67. package/dist/esm/decorators/setAttribute.js +5 -1
  68. package/dist/esm/decorators/setAttribute.js.map +2 -2
  69. package/dist/esm/decorators/style.js +39 -13
  70. package/dist/esm/decorators/style.js.map +2 -2
  71. package/dist/esm/elements/SwcAppEngine.js.map +2 -2
  72. package/dist/esm/elements/SwcAppMixin.js.map +2 -2
  73. package/dist/esm/elements/SwcAsync.js +2 -2
  74. package/dist/esm/elements/SwcAsync.js.map +2 -2
  75. package/dist/esm/elements/SwcChoose.js +2 -2
  76. package/dist/esm/elements/SwcChoose.js.map +2 -2
  77. package/dist/esm/elements/SwcIf.js +2 -2
  78. package/dist/esm/elements/SwcIf.js.map +2 -2
  79. package/dist/esm/elements/SwcLoop.js +2 -2
  80. package/dist/esm/elements/SwcLoop.js.map +2 -2
  81. package/dist/esm/elements/register.js +6 -5
  82. package/dist/esm/elements/register.js.map +2 -2
  83. package/dist/esm/index.js +6 -18
  84. package/dist/esm/index.js.map +2 -2
  85. package/dist/esm/types.js.map +2 -2
  86. package/dist/esm/utils/TemplateUtils.js +6 -0
  87. package/dist/esm/utils/TemplateUtils.js.map +2 -2
  88. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +385 -206
  89. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
  90. package/dist/types/decorators/addEventListener.d.ts +6 -0
  91. package/dist/types/decorators/addEventListener.d.ts.map +1 -1
  92. package/dist/types/decorators/applyNode.d.ts +121 -0
  93. package/dist/types/decorators/applyNode.d.ts.map +1 -0
  94. package/dist/types/decorators/attribute.d.ts +6 -0
  95. package/dist/types/decorators/attribute.d.ts.map +1 -1
  96. package/dist/types/decorators/{changedAttribute.d.ts → changedAttributeHost.d.ts} +6 -2
  97. package/dist/types/decorators/changedAttributeHost.d.ts.map +1 -0
  98. package/dist/types/decorators/classList.d.ts +32 -5
  99. package/dist/types/decorators/classList.d.ts.map +1 -1
  100. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  101. package/dist/types/decorators/emitCustomEvent.d.ts +14 -2
  102. package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
  103. package/dist/types/decorators/index.d.ts +2 -4
  104. package/dist/types/decorators/index.d.ts.map +1 -1
  105. package/dist/types/decorators/lifecycles.d.ts +16 -0
  106. package/dist/types/decorators/lifecycles.d.ts.map +1 -1
  107. package/dist/types/decorators/query.d.ts +6 -3
  108. package/dist/types/decorators/query.d.ts.map +1 -1
  109. package/dist/types/decorators/queryAll.d.ts +6 -0
  110. package/dist/types/decorators/queryAll.d.ts.map +1 -1
  111. package/dist/types/decorators/setAttribute.d.ts +5 -0
  112. package/dist/types/decorators/setAttribute.d.ts.map +1 -1
  113. package/dist/types/decorators/style.d.ts +28 -3
  114. package/dist/types/decorators/style.d.ts.map +1 -1
  115. package/dist/types/elements/SwcAppEngine.d.ts.map +1 -1
  116. package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
  117. package/dist/types/elements/register.d.ts +1 -1
  118. package/dist/types/elements/register.d.ts.map +1 -1
  119. package/dist/types/index.d.ts +3 -15
  120. package/dist/types/index.d.ts.map +1 -1
  121. package/dist/types/types.d.ts +2 -1
  122. package/dist/types/types.d.ts.map +1 -1
  123. package/dist/types/utils/TemplateUtils.d.ts +5 -0
  124. package/dist/types/utils/TemplateUtils.d.ts.map +1 -1
  125. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +385 -206
  126. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
  127. package/package.json +3 -3
  128. package/src/decorators/addEventListener.ts +9 -0
  129. package/src/decorators/applyNode.ts +290 -0
  130. package/src/decorators/attribute.ts +46 -12
  131. package/src/decorators/{changedAttribute.ts → changedAttributeHost.ts} +5 -1
  132. package/src/decorators/classList.ts +71 -16
  133. package/src/decorators/elementDefine.ts +130 -63
  134. package/src/decorators/emitCustomEvent.ts +13 -5
  135. package/src/decorators/index.ts +2 -4
  136. package/src/decorators/lifecycles.ts +43 -1
  137. package/src/decorators/query.ts +9 -2
  138. package/src/decorators/queryAll.ts +9 -0
  139. package/src/decorators/setAttribute.ts +8 -0
  140. package/src/decorators/style.ts +64 -13
  141. package/src/elements/SwcAppEngine.ts +1 -0
  142. package/src/elements/SwcAppMixin.ts +2 -1
  143. package/src/elements/SwcAsync.ts +2 -2
  144. package/src/elements/SwcChoose.ts +2 -2
  145. package/src/elements/SwcIf.ts +2 -2
  146. package/src/elements/SwcLoop.ts +2 -2
  147. package/src/elements/register.ts +7 -5
  148. package/src/index.ts +8 -17
  149. package/src/types.ts +2 -1
  150. package/src/utils/TemplateUtils.ts +9 -0
  151. package/dist/cjs/decorators/appendChild.js +0 -92
  152. package/dist/cjs/decorators/appendChild.js.map +0 -7
  153. package/dist/cjs/decorators/changedAttribute.js.map +0 -7
  154. package/dist/cjs/decorators/onConnectedInnerHtml.js +0 -48
  155. package/dist/cjs/decorators/onConnectedInnerHtml.js.map +0 -7
  156. package/dist/cjs/decorators/replaceChildren.js +0 -79
  157. package/dist/cjs/decorators/replaceChildren.js.map +0 -7
  158. package/dist/esm/decorators/appendChild.js +0 -73
  159. package/dist/esm/decorators/appendChild.js.map +0 -7
  160. package/dist/esm/decorators/changedAttribute.js.map +0 -7
  161. package/dist/esm/decorators/onConnectedInnerHtml.js +0 -29
  162. package/dist/esm/decorators/onConnectedInnerHtml.js.map +0 -7
  163. package/dist/esm/decorators/replaceChildren.js +0 -60
  164. package/dist/esm/decorators/replaceChildren.js.map +0 -7
  165. package/dist/types/decorators/appendChild.d.ts +0 -17
  166. package/dist/types/decorators/appendChild.d.ts.map +0 -1
  167. package/dist/types/decorators/changedAttribute.d.ts.map +0 -1
  168. package/dist/types/decorators/onConnectedInnerHtml.d.ts +0 -15
  169. package/dist/types/decorators/onConnectedInnerHtml.d.ts.map +0 -1
  170. package/dist/types/decorators/replaceChildren.d.ts +0 -9
  171. package/dist/types/decorators/replaceChildren.d.ts.map +0 -1
  172. package/src/decorators/appendChild.ts +0 -86
  173. package/src/decorators/onConnectedInnerHtml.ts +0 -42
  174. package/src/decorators/replaceChildren.ts +0 -64
@@ -1,15 +1,10 @@
1
1
  import { ReflectUtils } from '@dooboostore/core';
2
2
  import { FunctionUtils } from '@dooboostore/core';
3
- import { getOnConnectedInnerHtmlMetadata } from './onConnectedInnerHtml';
4
3
  import { getAddEventListenerMetadata } from './addEventListener';
5
- import { ON_BEFORE_CONNECTED_METADATA_KEY, ON_AFTER_CONNECTED_METADATA_KEY, ON_BEFORE_DISCONNECTED_METADATA_KEY, ON_AFTER_DISCONNECTED_METADATA_KEY, ON_BEFORE_ADOPTED_METADATA_KEY, ON_AFTER_ADOPTED_METADATA_KEY, findAllLifecycleMetadata } from './lifecycles';
4
+ import { ON_CONSTRUCTOR_METADATA_KEY, ON_BEFORE_CONNECTED_METADATA_KEY, ON_AFTER_CONNECTED_METADATA_KEY, ON_BEFORE_DISCONNECTED_METADATA_KEY, ON_AFTER_DISCONNECTED_METADATA_KEY, ON_BEFORE_ADOPTED_METADATA_KEY, ON_AFTER_ADOPTED_METADATA_KEY, findAllLifecycleMetadata, getOnConnectedInnerHtmlMetadata } from './lifecycles';
6
5
  import { getEmitCustomEventMetadataList } from './emitCustomEvent';
7
- import { findAllAttributeChangedMetadata } from './changedAttribute';
6
+ import { findAllAttributeChangedMetadata } from './changedAttributeHost';
8
7
  import { findAllSetAttributeMetadata } from './setAttribute';
9
- import { findAllReplaceChildrenMetadata } from './replaceChildren';
10
- import { findAllAppendChildMetadata } from './appendChild';
11
- import { findAllClassListMetadata } from './classList';
12
- import { findAllStyleMetadata } from './style';
13
8
  import { findAllAttributeMetadata } from './attribute';
14
9
  import { SwcUtils } from '../utils/Utils';
15
10
  import { HTML_TAG_ENTRIES, DOM_EVENT_NAMES } from '../config/config';
@@ -47,6 +42,12 @@ export const ensureInit = (inst: any) => {
47
42
  // Call constructor script if present
48
43
  const hostSet = SwcUtils.getHostSet(inst);
49
44
  inst._executeSwcScript?.('swc-on-constructor', hostSet);
45
+
46
+ // Call @onConstructor lifecycle methods
47
+ const cMethods = findAllLifecycleMetadata(inst, ON_CONSTRUCTOR_METADATA_KEY);
48
+ if (cMethods) {
49
+ for (const m of cMethods) (inst)._invokeLifecycleMethod(m, hostSet);
50
+ }
50
51
  }
51
52
  };
52
53
 
@@ -160,7 +161,9 @@ const setupPrototype = (proto: any) => {
160
161
  if (oldHandler) el.removeEventListener(eventName, oldHandler);
161
162
 
162
163
  const handler = async (event: any) => {
163
- const hostSet = SwcUtils.getHostSet(el);
164
+ console.log('execute handler', event);
165
+ const parent = SwcUtils.findNearestSwcHost(el);
166
+ const hostSet = SwcUtils.getHostSet(parent || el);
164
167
  const conf = getElementConfig(this);
165
168
  const currentWin = (this as any)._resolveWindow(conf);
166
169
  const helpers = SwcUtils.getHelperSet(currentWin);
@@ -181,13 +184,19 @@ const setupPrototype = (proto: any) => {
181
184
 
182
185
  proto.__swc_executeAttributeEvent = async function (el: HTMLElement, attrName: string, script: string, event: Event) {
183
186
  ensureInit(this);
184
- const hostSet = SwcUtils.getHostSet(el);
187
+
188
+ console.log('execute handler2', event);
189
+ const parent = SwcUtils.findNearestSwcHost(el);
190
+ const hostSet = SwcUtils.getHostSet(parent || el);
185
191
  const conf = getElementConfig(this);
186
192
  const currentWin = (this as any)._resolveWindow(conf);
187
193
  const currentHelpers = SwcUtils.getHelperSet(currentWin);
194
+ const detail = (event as CustomEvent).detail;
188
195
  const args = {
189
196
  event,
190
- $data: (event as CustomEvent).detail,
197
+ $event: event,
198
+ $data: detail,
199
+ $detail: detail,
191
200
  ...hostSet,
192
201
  ...currentHelpers,
193
202
  $el: el,
@@ -220,7 +229,9 @@ export const elementDefine =
220
229
  }
221
230
 
222
231
  const emitCustomEventList = getEmitCustomEventMetadataList(constructor) || [];
232
+ const emitHostCustomEventList = emitCustomEventList.filter(meta => meta.selector === ':host' || meta.selector === '');
223
233
  const addEventListenerList = getAddEventListenerMetadata(constructor) || [];
234
+ const addHostEventListenerList = addEventListenerList.filter(meta => meta.selector === ':host' || meta.selector === '');
224
235
  const attrChangeMap = findAllAttributeChangedMetadata(constructor);
225
236
  const attributeList = findAllAttributeMetadata(constructor);
226
237
 
@@ -228,7 +239,7 @@ export const elementDefine =
228
239
  const swcOnEvents = DOM_EVENT_NAMES.map(e => `swc-on-${e}`);
229
240
 
230
241
  // Collect all observed attributes from all decorators
231
- const mergedObservedAttributes = [...new Set([...(metadata.observedAttributes ?? []), ...attrChangeMap.keys(), ...Array.from(findAllSetAttributeMetadata(constructor).values()).map(it => it.name), ...attributeList.map(it => it.options.name || String(it.propertyKey)), ...emitCustomEventList.map(it => it.options.attributeName!), ...swcLifecycleAttributes, ...swcOnEvents])];
242
+ const mergedObservedAttributes = [...new Set([...(metadata.observedAttributes ?? []), ...attrChangeMap.keys(), ...Array.from(findAllSetAttributeMetadata(constructor).values()).map(it => it.name), ...attributeList.map(it => it.options.name || String(it.propertyKey)), ...emitHostCustomEventList.map(it => (it.options as any).attributeName).filter(Boolean), ...swcLifecycleAttributes, ...swcOnEvents])];
232
243
 
233
244
  const connectedInnerHtmlList = getOnConnectedInnerHtmlMetadata(constructor) || [];
234
245
 
@@ -256,29 +267,19 @@ export const elementDefine =
256
267
  // Initialize @attribute fields (DOM <-> JS Sync)
257
268
  attributeList.forEach(meta => {
258
269
  const attrName = meta.options.name || String(meta.propertyKey);
259
- if (meta.options.connectedInitialize) {
260
- // JS -> DOM (FORCE OVERWRITE)
261
- const memoryVal = (this as any)[meta.privateKey];
262
- if (memoryVal !== undefined) {
263
- (this as any).__swc_syncing_init = true;
264
- try {
270
+ if (meta.options.connectedInitialize === true) {
271
+ // JS -> DOM (FORCE OVERWRITE with JS value)
272
+ (this as any).__swc_syncing_init = true;
273
+ try {
274
+ const memoryVal = (this as any)[meta.privateKey];
275
+ if (memoryVal !== undefined) {
265
276
  (this as any)[meta.propertyKey] = memoryVal; // Trigger setter to update DOM
266
- } finally {
267
- (this as any).__swc_syncing_init = false;
268
- }
269
- }
270
- } else if (meta.selector === ':host' || !meta.selector) {
271
- // DOM -> JS (Pull from HTML)
272
- const domVal = this.getAttribute(attrName);
273
- if (domVal !== null) {
274
- (this as any).__swc_syncing_init = true;
275
- try {
276
- (this as any)[meta.propertyKey] = domVal; // Update memory with DOM value
277
- } finally {
278
- (this as any).__swc_syncing_init = false;
279
277
  }
278
+ } finally {
279
+ (this as any).__swc_syncing_init = false;
280
280
  }
281
281
  }
282
+ // else: Do NOT sync - Keep the default value from class initialization
282
283
  });
283
284
 
284
285
  if (connectedInnerHtmlList.length > 0) {
@@ -303,7 +304,76 @@ export const elementDefine =
303
304
  globalDelegatedRoots.add(root);
304
305
  }
305
306
 
307
+ // Separate delegate and non-delegate listeners
308
+ const delegateListeners: typeof addEventListenerList = [];
309
+ const nonDelegateListeners: typeof addEventListenerList = [];
310
+
306
311
  addEventListenerList.forEach(meta => {
312
+ if (meta.options.delegate && meta.selector !== ':window' && meta.selector !== ':document' && meta.selector !== ':parentHost' && meta.selector !== ':appHost' && meta.selector !== ':firstHost' && meta.selector !== ':lastHost' && meta.selector !== ':firstAppHost' && meta.selector !== ':lastAppHost' && meta.selector !== ':hosts' && meta.selector !== ':appHosts' && meta.selector !== ':host' && meta.selector !== '') {
313
+ delegateListeners.push(meta);
314
+ } else {
315
+ nonDelegateListeners.push(meta);
316
+ }
317
+ });
318
+
319
+ // Group delegate listeners by (type, root) combination
320
+ const delegatesByTypeAndRoot = new Map<string, any[]>();
321
+ delegateListeners.forEach(meta => {
322
+ const r = meta.options.root || 'auto';
323
+ const rootKey = `${meta.type}:${r}`;
324
+ if (!delegatesByTypeAndRoot.has(rootKey)) {
325
+ delegatesByTypeAndRoot.set(rootKey, []);
326
+ }
327
+ delegatesByTypeAndRoot.get(rootKey)!.push(meta);
328
+ });
329
+
330
+ // Register unified handlers for delegate listeners
331
+ delegatesByTypeAndRoot.forEach((metaList, typeRootKey) => {
332
+ const [type, rStr] = typeRootKey.split(':');
333
+ const r = rStr === 'auto' ? 'auto' : rStr;
334
+ const opts = { capture: metaList[0].options.capture, once: metaList[0].options.once, passive: metaList[0].options.passive };
335
+
336
+ const bindRoots: (HTMLElement | ShadowRoot)[] = [];
337
+ if (r === 'auto') bindRoots.push(this.shadowRoot || (this as any));
338
+ else if (r === 'light') bindRoots.push(this as any);
339
+ else if (r === 'shadow' && this.shadowRoot) bindRoots.push(this.shadowRoot);
340
+ else if (r === 'all') {
341
+ bindRoots.push(this as any);
342
+ if (this.shadowRoot) bindRoots.push(this.shadowRoot);
343
+ }
344
+
345
+ bindRoots.forEach(br => {
346
+ // Sort: stopPropagation handlers first (more specific/terminal actions)
347
+ const sortedMetaList = [...metaList].sort((a, b) => {
348
+ const aStop = a.options.stopPropagation ? 1 : 0;
349
+ const bStop = b.options.stopPropagation ? 1 : 0;
350
+ return bStop - aStop; // stopPropagation: true comes first
351
+ });
352
+
353
+ const unifiedHandler = async (event: Event) => {
354
+ for (const meta of sortedMetaList) {
355
+ const { selector, options } = meta;
356
+ const matchedEl = (event.target as HTMLElement).closest(selector);
357
+ if (matchedEl && (br as any).contains(matchedEl)) {
358
+ if (options.stopPropagation) event.stopPropagation();
359
+ if (options.stopImmediatePropagation) event.stopImmediatePropagation();
360
+ if (options.preventDefault) event.preventDefault();
361
+ const currentHostSet = SwcUtils.getHostSet(this as any);
362
+ const args = { event, ...currentHostSet, $el: matchedEl, $root: br };
363
+ await (this as any)[meta.propertyKey](event, currentHostSet, matchedEl, args);
364
+
365
+ // Stop processing if event propagation was stopped
366
+ if ((event as any).cancelBubble) break;
367
+ }
368
+ }
369
+ };
370
+ br.addEventListener(type, unifiedHandler, opts);
371
+ (this as any)._boundListeners.push({ target: br, type, handler: unifiedHandler, options: opts });
372
+ });
373
+ });
374
+
375
+ // Process non-delegate listeners
376
+ nonDelegateListeners.forEach(meta => {
307
377
  const { selector, type, options } = meta;
308
378
  const opts = { capture: options.capture, once: options.once, passive: options.passive };
309
379
  const bindTargets: EventTarget[] = [];
@@ -329,34 +399,7 @@ export const elementDefine =
329
399
  else if (selector === ':hosts') hostSet.$hosts.forEach(applyRootOption);
330
400
  else if (selector === ':appHosts') hostSet.$appHosts.forEach(applyRootOption);
331
401
  else if (selector === ':host' || !selector) applyRootOption(this);
332
- else if (options.delegate) {
333
- const bindRoots: (HTMLElement | ShadowRoot)[] = [];
334
- if (r === 'auto') bindRoots.push(this.shadowRoot || (this as any));
335
- else if (r === 'light') bindRoots.push(this as any);
336
- else if (r === 'shadow' && this.shadowRoot) bindRoots.push(this.shadowRoot);
337
- else if (r === 'all') {
338
- bindRoots.push(this as any);
339
- if (this.shadowRoot) bindRoots.push(this.shadowRoot);
340
- }
341
-
342
- bindRoots.forEach(br => {
343
- const handler = async (event: Event) => {
344
- const matchedEl = (event.target as HTMLElement).closest(selector);
345
- if (matchedEl && (br as any).contains(matchedEl)) {
346
- if (options.stopPropagation) event.stopPropagation();
347
- if (options.stopImmediatePropagation) event.stopImmediatePropagation();
348
- if (options.preventDefault) event.preventDefault();
349
- const currentHostSet = SwcUtils.getHostSet(this as any);
350
- const args = { event, ...currentHostSet, $el: matchedEl, $root: br };
351
- await (this as any)._invokeLifecycleMethod(meta.propertyKey, currentHostSet, [event, currentHostSet, matchedEl, args]);
352
- }
353
- };
354
- br.addEventListener(type, handler, opts);
355
- if (options.removeOnDisconnected === true || (br !== this && br !== this.shadowRoot)) {
356
- (this as any)._boundListeners.push({ target: br, type, handler, options: opts });
357
- }
358
- });
359
- } else {
402
+ else {
360
403
  const searchRoots: (HTMLElement | ShadowRoot)[] = [];
361
404
  if (r === 'auto') searchRoots.push(this.shadowRoot || (this as any));
362
405
  else if (r === 'light') searchRoots.push(this as any);
@@ -378,7 +421,7 @@ export const elementDefine =
378
421
  if (options.preventDefault) event.preventDefault();
379
422
  const currentHostSet = SwcUtils.getHostSet(this as any);
380
423
  const args = { event, ...currentHostSet, $el: t, $root: t };
381
- await (this as any)._invokeLifecycleMethod(meta.propertyKey, currentHostSet, [event, currentHostSet, args]);
424
+ await (this as any)[meta.propertyKey](event, currentHostSet, args);
382
425
  };
383
426
  t.addEventListener(type, handler, opts);
384
427
  if (options.removeOnDisconnected === true || t === currentWin || t === currentWin.document) {
@@ -387,6 +430,24 @@ export const elementDefine =
387
430
  });
388
431
  });
389
432
 
433
+ addHostEventListenerList.forEach(meta => {
434
+ const { type, options } = meta;
435
+ const opts = { capture: options.capture, once: options.once, passive: options.passive };
436
+
437
+ const handler = async (event: Event) => {
438
+ if (options.stopPropagation) event.stopPropagation();
439
+ if (options.stopImmediatePropagation) event.stopImmediatePropagation();
440
+ if (options.preventDefault) event.preventDefault();
441
+ const currentHostSet = SwcUtils.getHostSet(this as any);
442
+ const args = { event, ...currentHostSet, $el: this, $root: this.getRootNode() };
443
+ await (this as any)[meta.propertyKey](event, currentHostSet, args);
444
+ };
445
+ this.addEventListener(type, handler, opts);
446
+ if (options.removeOnDisconnected === true) {
447
+ (this as any)._boundListeners.push({ target: this, type, handler, options: opts });
448
+ }
449
+ });
450
+
390
451
  if (originalConnected) originalConnected.apply(this);
391
452
 
392
453
  const aMethods = findAllLifecycleMetadata(this, ON_AFTER_CONNECTED_METADATA_KEY);
@@ -446,20 +507,26 @@ export const elementDefine =
446
507
  proto.attributeChangedCallback = function (name: string, old: string | null, newVal: string | null) {
447
508
  if (originalAttributeChanged) originalAttributeChanged.apply(this, [name, old, newVal]);
448
509
 
510
+ const hSet = SwcUtils.getHostSet(this as any);
511
+
449
512
  // Handle swc-on-* events
450
513
  if (name.startsWith('swc-on-') && !swcLifecycleAttributes.includes(name)) {
451
514
  if (newVal !== null) {
452
- const customEventMeta = emitCustomEventList.find(it => it.options.attributeName === name);
453
- const eventName = customEventMeta ? customEventMeta.type : name.substring(7);
515
+ const eventName = name.substring(7);
454
516
  (this as any)._bindAttributeEvent(this as any, name, newVal, eventName);
455
517
  }
456
518
  }
457
519
 
520
+ // Handle @emitHostCustomEvent attribute changes
521
+ const hostCustomEventMeta = emitHostCustomEventList.find(it => (it.options as any).attributeName === name);
522
+ if (hostCustomEventMeta && newVal !== null) {
523
+ (this as any)._bindAttributeEvent(this as any, name, newVal, hostCustomEventMeta.type);
524
+ }
525
+
458
526
  // Handle @changedAttribute callbacks
459
527
  const mKeys = attrChangeMap.get(name);
460
528
  if (mKeys && Array.isArray(mKeys)) {
461
- const hSet = SwcUtils.getHostSet(this as any);
462
- for (const key of mKeys) (this as any)._invokeLifecycleMethod(key, hSet, [newVal, old, name]);
529
+ for (const key of mKeys) (this as any)[key](newVal, old, name, hSet);
463
530
  }
464
531
  };
465
532
 
@@ -4,7 +4,6 @@ import { ensureInit, getElementConfig } from './elementDefine';
4
4
  import { SwcUtils } from '../utils/Utils';
5
5
 
6
6
  export interface EmitCustomEventBaseOptions {
7
- attributeName?: string;
8
7
  bubbles?: boolean;
9
8
  composed?: boolean;
10
9
  cancelable?: boolean;
@@ -14,7 +13,7 @@ export interface EmitCustomEventMetadata {
14
13
  propertyKey: string | symbol;
15
14
  selector: string;
16
15
  type: string;
17
- options: EmitCustomEventBaseOptions & SwcQueryOptions;
16
+ options: (EmitCustomEventBaseOptions & SwcQueryOptions) | (EmitCustomEventBaseOptions & SwcQueryOptions & { attributeName?: string });
18
17
  }
19
18
 
20
19
  export const EMIT_CUSTOM_EVENT_METADATA_KEY = Symbol('simple-web-component:emit-custom-event');
@@ -29,9 +28,6 @@ export function emitCustomEvent(selectorOrTarget: string, type: string, options:
29
28
 
30
29
  const fullOptions: any = { ...options, type };
31
30
 
32
- if (!fullOptions.attributeName) {
33
- fullOptions.attributeName = `swc-on-${type}`;
34
- }
35
31
  if (fullOptions.bubbles === undefined) fullOptions.bubbles = true;
36
32
  if (fullOptions.composed === undefined) fullOptions.composed = true;
37
33
 
@@ -103,3 +99,15 @@ export const getEmitCustomEventMetadataList = (target: any): EmitCustomEventMeta
103
99
  const constructor = target instanceof Function ? target : target.constructor;
104
100
  return ReflectUtils.getMetadata(EMIT_CUSTOM_EVENT_METADATA_KEY, constructor);
105
101
  };
102
+
103
+ /**
104
+ * @emitCustomEventHost decorator - simplified version of @emitCustomEvent for :host selector
105
+ * Usage: @emitCustomEventHost('navigate')
106
+ * Usage: @emitCustomEventHost('navigate', { attributeName: 'on-navigate' })
107
+ *
108
+ * The attributeName option is used to automatically observe attributes for this event.
109
+ * For example, { attributeName: 'on-navigate' } will add 'on-navigate' to observedAttributes.
110
+ */
111
+ export function emitCustomEventHost(type: string, options?: EmitCustomEventBaseOptions & SwcQueryOptions & { attributeName?: string }): MethodDecorator {
112
+ return emitCustomEvent(':host', type, options);
113
+ }
@@ -1,14 +1,12 @@
1
1
  export * from './addEventListener';
2
2
  export * from './attribute';
3
3
  export * from './elementDefine';
4
- export * from './changedAttribute';
4
+ export * from './changedAttributeHost';
5
5
  export * from './setAttribute';
6
6
  export * from './emitCustomEvent';
7
- export * from './replaceChildren';
8
- export * from './appendChild';
7
+ export * from './applyNode';
9
8
  export * from './lifecycles';
10
9
  export * from './query';
11
10
  export * from './queryAll';
12
- export * from './onConnectedInnerHtml';
13
11
  export * from './classList';
14
12
  export * from './style';
@@ -1,7 +1,8 @@
1
1
  import { ReflectUtils } from '@dooboostore/core';
2
- import { ON_ATTRIBUTE_CHANGED_METADATA_KEY } from './changedAttribute';
2
+ import { ON_ATTRIBUTE_CHANGED_METADATA_KEY } from './changedAttributeHost';
3
3
  import { SET_ATTRIBUTE_METADATA_KEY } from './setAttribute';
4
4
 
5
+ export const ON_CONSTRUCTOR_METADATA_KEY = Symbol('simple-web-component:on-constructor');
5
6
  export const ON_BEFORE_CONNECTED_METADATA_KEY = Symbol('simple-web-component:on-before-connected');
6
7
  export const ON_AFTER_CONNECTED_METADATA_KEY = Symbol('simple-web-component:on-after-connected');
7
8
  export const ON_BEFORE_DISCONNECTED_METADATA_KEY = Symbol('simple-web-component:on-before-disconnected');
@@ -9,9 +10,19 @@ export const ON_AFTER_DISCONNECTED_METADATA_KEY = Symbol('simple-web-component:o
9
10
  export const ON_BEFORE_ADOPTED_METADATA_KEY = Symbol('simple-web-component:on-before-adopted');
10
11
  export const ON_AFTER_ADOPTED_METADATA_KEY = Symbol('simple-web-component:on-after-adopted');
11
12
  export const ON_ADD_EVENT_LISTENER_METADATA_KEY = Symbol('simple-web-component:on-add-event-listener');
13
+ export const INNER_HTML_METADATA_KEY = Symbol('simple-web-component:inner-html');
12
14
 
13
15
  export const ATTRIBUTE_CHANGED_WILDCARD = '*';
14
16
 
17
+ export interface InnerHtmlOptions {
18
+ useShadow?: boolean;
19
+ }
20
+
21
+ export interface InnerHtmlMetadata {
22
+ propertyKey: string | symbol;
23
+ options: InnerHtmlOptions;
24
+ }
25
+
15
26
  function createLifecycleDecorator(metadataKey: symbol): MethodDecorator {
16
27
  return (target: Object, propertyKey: string | symbol) => {
17
28
  const constructor = target.constructor;
@@ -24,6 +35,7 @@ function createLifecycleDecorator(metadataKey: symbol): MethodDecorator {
24
35
  };
25
36
  }
26
37
 
38
+ export const onConstructor = createLifecycleDecorator(ON_CONSTRUCTOR_METADATA_KEY);
27
39
  export const onBeforeConnected = createLifecycleDecorator(ON_BEFORE_CONNECTED_METADATA_KEY);
28
40
  export const onAfterConnected = createLifecycleDecorator(ON_AFTER_CONNECTED_METADATA_KEY);
29
41
  export const onConnected = onAfterConnected;
@@ -38,6 +50,31 @@ export const onAdopted = onAfterAdopted;
38
50
 
39
51
  export const onAddEventListener = createLifecycleDecorator(ON_ADD_EVENT_LISTENER_METADATA_KEY);
40
52
 
53
+ /**
54
+ * @onConnectedInnerHtml decorator to define the initial HTML content when connected.
55
+ */
56
+ export function onConnectedInnerHtml(options: InnerHtmlOptions): MethodDecorator;
57
+ export function onConnectedInnerHtml(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
58
+ export function onConnectedInnerHtml(arg1?: InnerHtmlOptions | Object, arg2?: string | symbol, arg3?: PropertyDescriptor): MethodDecorator | void {
59
+ const decorator = (options: InnerHtmlOptions, target: Object, propertyKey: string | symbol) => {
60
+ const constructor = target.constructor;
61
+ let list = ReflectUtils.getMetadata<InnerHtmlMetadata[]>(INNER_HTML_METADATA_KEY, constructor);
62
+ if (!list) {
63
+ list = [];
64
+ ReflectUtils.defineMetadata(INNER_HTML_METADATA_KEY, list, constructor);
65
+ }
66
+ list.push({ propertyKey, options });
67
+ };
68
+
69
+ if (arg2) {
70
+ return decorator({}, arg1!, arg2);
71
+ }
72
+
73
+ return (target: Object, propertyKey: string | symbol) => {
74
+ decorator((arg1 as InnerHtmlOptions) || {}, target, propertyKey);
75
+ };
76
+ }
77
+
41
78
  /**
42
79
  * 프로토타입 체인을 순회하며 모든 라이프사이클 메서드를 수집합니다.
43
80
  */
@@ -45,3 +82,8 @@ export const findAllLifecycleMetadata = <T = (string | symbol)[]>(target: any, m
45
82
  const results = ReflectUtils.findAllMetadataFlatten(metadataKey, target);
46
83
  return results.length > 0 ? (results as unknown as T) : undefined;
47
84
  };
85
+
86
+ export const getOnConnectedInnerHtmlMetadata = (target: any): InnerHtmlMetadata[] | undefined => {
87
+ const constructor = target instanceof Function ? target : target.constructor;
88
+ return ReflectUtils.getMetadata(INNER_HTML_METADATA_KEY, constructor);
89
+ };
@@ -3,8 +3,6 @@ import { getElementConfig, ensureInit } from './elementDefine';
3
3
  import { SwcUtils } from '../utils/Utils';
4
4
  import { SpecialSelector, SwcQueryOptions } from '../types';
5
5
 
6
- export type QueryOptions = { root?: 'light' | 'shadow' | 'all' | 'auto' };
7
-
8
6
  export interface QueryMetadata {
9
7
  propertyKey: string | symbol;
10
8
  selector: string;
@@ -108,3 +106,12 @@ export const getQueryMetadata = (target: any): QueryMetadata[] | undefined => {
108
106
  const constructor = target instanceof Function ? target : target.constructor;
109
107
  return ReflectUtils.getMetadata(QUERY_METADATA_KEY, constructor);
110
108
  };
109
+
110
+ /**
111
+ * @hostQuery decorator - simplified version of @query for :host selector
112
+ * Usage: @hostQuery()
113
+ * Usage: @hostQuery({ root: 'shadow' })
114
+ */
115
+ export function queryHost(options?: SwcQueryOptions): PropertyDecorator {
116
+ return query(':host', options);
117
+ }
@@ -107,3 +107,12 @@ export const getQueryAllMetadata = (target: any): QueryAllMetadata[] | undefined
107
107
  const constructor = target instanceof Function ? target : target.constructor;
108
108
  return ReflectUtils.getMetadata(QUERY_ALL_METADATA_KEY, constructor);
109
109
  };
110
+
111
+ /**
112
+ * @hostQueryAll decorator - simplified version of @queryAll for :host selector
113
+ * Usage: @hostQueryAll()
114
+ * Usage: @hostQueryAll({ root: 'shadow' })
115
+ */
116
+ export function queryAllHost(options?: SwcQueryOptions): PropertyDecorator {
117
+ return queryAll(':host', options);
118
+ }
@@ -103,3 +103,11 @@ export const findAllSetAttributeMetadata = (target: any): Map<string | symbol, S
103
103
  });
104
104
  return result;
105
105
  };
106
+
107
+ /**
108
+ * @setAttributeHost decorator - simplified version of @setAttribute for :host selector
109
+ * Usage: @setAttributeHost('aria-disabled')
110
+ */
111
+ export function setAttributeHost(name: string, options?: SwcQueryOptions): MethodDecorator {
112
+ return setAttribute(':host', name, options);
113
+ }
@@ -1,19 +1,24 @@
1
1
  import { ReflectUtils } from '@dooboostore/core';
2
2
  import { ensureInit } from './elementDefine';
3
3
  import { SwcUtils } from '../utils/Utils';
4
+ import { SwcQueryOptions } from '../types';
4
5
 
5
6
  export type StyleAction = 'set' | 'update' | 'remove';
6
7
 
8
+ export interface StyleOptions extends SwcQueryOptions {
9
+ }
10
+
7
11
  export interface StyleMetadata {
8
12
  propertyKey: string | symbol;
9
13
  selector: string;
10
14
  action: StyleAction;
15
+ options: StyleOptions;
11
16
  }
12
17
 
13
18
  export const STYLE_METADATA_KEY = Symbol('simple-web-component:style');
14
19
 
15
20
  function createStyleDecorator(action: StyleAction) {
16
- return (selector: string): MethodDecorator => {
21
+ return (selector: string, options: StyleOptions = {}): MethodDecorator => {
17
22
  return (target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
18
23
  const constructor = target.constructor;
19
24
  let metaList = ReflectUtils.getOwnMetadata(STYLE_METADATA_KEY, constructor) as Map<string | symbol, StyleMetadata>;
@@ -21,21 +26,43 @@ function createStyleDecorator(action: StyleAction) {
21
26
  metaList = new Map<string | symbol, StyleMetadata>();
22
27
  ReflectUtils.defineMetadata(STYLE_METADATA_KEY, metaList, constructor);
23
28
  }
24
- metaList.set(propertyKey, { propertyKey, selector, action });
29
+ metaList.set(propertyKey, { propertyKey, selector, action, options });
25
30
 
26
31
  const original = descriptor.value;
27
32
  descriptor.value = async function (...args: any[]) {
28
33
  ensureInit(this);
29
34
  const res = await original.apply(this, args);
30
35
  if (res !== undefined) {
36
+ const r = options.root || 'auto';
31
37
  const hostSet = SwcUtils.getHostSet(this as any);
32
- let targetEl: HTMLElement | null = null;
33
- if (selector === ':host' || !selector) targetEl = this as any;
34
- else if (selector === ':parentHost') targetEl = hostSet.$parentHost;
35
- else if (selector === ':appHost') targetEl = hostSet.$appHost;
36
- else targetEl = (this.shadowRoot || (this as any)).querySelector(selector);
38
+ const targetEls: HTMLElement[] = [];
39
+
40
+ if (selector === ':host' || !selector) {
41
+ targetEls.push(this as any);
42
+ } else if (selector === ':parentHost') {
43
+ if (hostSet.$parentHost) targetEls.push(hostSet.$parentHost);
44
+ } else if (selector === ':appHost') {
45
+ if (hostSet.$appHost) targetEls.push(hostSet.$appHost);
46
+ } else {
47
+ if (r === 'shadow') {
48
+ const found = this.shadowRoot?.querySelectorAll(selector);
49
+ if (found) targetEls.push(...found);
50
+ } else if (r === 'light') {
51
+ const found = (this as any).querySelectorAll(selector);
52
+ if (found) targetEls.push(...found);
53
+ } else if (r === 'all') {
54
+ const sFound = this.shadowRoot?.querySelectorAll(selector);
55
+ const lFound = (this as any).querySelectorAll(selector);
56
+ if (sFound) targetEls.push(...sFound);
57
+ if (lFound) targetEls.push(...lFound);
58
+ } else {
59
+ // auto
60
+ const found = (this.shadowRoot || (this as any)).querySelectorAll(selector);
61
+ if (found) targetEls.push(...found);
62
+ }
63
+ }
37
64
 
38
- if (targetEl) {
65
+ targetEls.forEach(targetEl => {
39
66
  if (action === 'set') {
40
67
  targetEl.style.cssText = '';
41
68
  if (typeof res === 'object' && res !== null) {
@@ -49,9 +76,9 @@ function createStyleDecorator(action: StyleAction) {
49
76
  }
50
77
  } else if (action === 'remove') {
51
78
  const props = Array.isArray(res) ? res : [res];
52
- props.forEach(p => targetEl!.style.removeProperty(String(p)));
79
+ props.forEach(p => targetEl.style.removeProperty(String(p)));
53
80
  }
54
- }
81
+ });
55
82
  }
56
83
  return res;
57
84
  };
@@ -62,20 +89,44 @@ function createStyleDecorator(action: StyleAction) {
62
89
  /**
63
90
  * @setStyle decorator to surgically set styles on a target element (replaces all existing styles).
64
91
  * Usage: @setStyle('#box') getStyles() { return { color: 'red', display: 'block' }; }
92
+ * Usage: @setStyle('#box', { root: 'shadow' }) getStyles() { return { color: 'red' }; }
65
93
  */
66
- export const setStyle = createStyleDecorator('set');
94
+ export const setStyle = (selector: string, options: StyleOptions = {}) => createStyleDecorator('set')(selector, options);
95
+
96
+ /**
97
+ * @setStyleHost decorator - simplified version of @setStyle for :host selector.
98
+ * Usage: @setStyleHost getStyles() { return { color: 'red', display: 'block' }; }
99
+ * Usage: @setStyleHost({ root: 'shadow' }) getStyles() { return { color: 'red' }; }
100
+ */
101
+ export const setStyleHost = (options: StyleOptions = {}) => createStyleDecorator('set')(':host', options);
67
102
 
68
103
  /**
69
104
  * @updateStyle decorator to surgically update styles on a target element (merges with existing styles).
70
105
  * Usage: @updateStyle('#box') updateStyles() { return { color: 'blue' }; }
106
+ * Usage: @updateStyle('#box', { root: 'shadow' }) updateStyles() { return { color: 'blue' }; }
107
+ */
108
+ export const updateStyle = (selector: string, options: StyleOptions = {}) => createStyleDecorator('update')(selector, options);
109
+
110
+ /**
111
+ * @updateStyleHost decorator - simplified version of @updateStyle for :host selector.
112
+ * Usage: @updateStyleHost updateStyles() { return { color: 'blue' }; }
113
+ * Usage: @updateStyleHost({ root: 'shadow' }) updateStyles() { return { color: 'blue' }; }
71
114
  */
72
- export const updateStyle = createStyleDecorator('update');
115
+ export const updateStyleHost = (options: StyleOptions = {}) => createStyleDecorator('update')(':host', options);
73
116
 
74
117
  /**
75
118
  * @removeStyle decorator to surgically remove styles from a target element.
76
119
  * Usage: @removeStyle('#box') clearStyles() { return ['color', 'display']; }
120
+ * Usage: @removeStyle('#box', { root: 'shadow' }) clearStyles() { return ['color']; }
121
+ */
122
+ export const removeStyle = (selector: string, options: StyleOptions = {}) => createStyleDecorator('remove')(selector, options);
123
+
124
+ /**
125
+ * @removeStyleHost decorator - simplified version of @removeStyle for :host selector.
126
+ * Usage: @removeStyleHost clearStyles() { return ['color', 'display']; }
127
+ * Usage: @removeStyleHost({ root: 'shadow' }) clearStyles() { return ['color']; }
77
128
  */
78
- export const removeStyle = createStyleDecorator('remove');
129
+ export const removeStyleHost = (options: StyleOptions = {}) => createStyleDecorator('remove')(':host', options);
79
130
 
80
131
  export const findAllStyleMetadata = (target: any): Map<string | symbol, StyleMetadata> => {
81
132
  const result = new Map<string | symbol, StyleMetadata>();
@@ -88,6 +88,7 @@ export class SwcAppEngine {
88
88
  // Rendering
89
89
  const data = this.simpleApplication.sim(_config.rootRouter);
90
90
  if (data instanceof Node) {
91
+ // console.warn('[SWC-APP-ENGINE] Rendering failed: Root element is not a DocumentFragment.', data);
91
92
  if (this.host.shadowRoot) this.host.shadowRoot.replaceChildren(data);
92
93
  else this.host.replaceChildren(data);
93
94
  }
@@ -1,7 +1,8 @@
1
1
  import { SwcAppEngine, SwcAttributeConfigType } from './SwcAppEngine';
2
+ import {SwcAppInterface} from "../types";
2
3
 
3
4
  export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Base: T) {
4
- return class extends Base {
5
+ return class extends Base implements SwcAppInterface{
5
6
  __swc_engine = new SwcAppEngine(this as any);
6
7
 
7
8
  get simpleApplication() {
@@ -1,4 +1,4 @@
1
- import { changedAttribute } from '../decorators/changedAttribute';
1
+ import { changedAttributeHost } from '../decorators/changedAttributeHost';
2
2
  import { SwcUtils } from '../utils/Utils';
3
3
  import { FunctionUtils } from '@dooboostore/core';
4
4
 
@@ -28,7 +28,7 @@ export class SwcAsync extends HTMLTemplateElement {
28
28
  FunctionUtils.execute({ script, context: this, args });
29
29
  }
30
30
 
31
- @changedAttribute('on-get-value')
31
+ @changedAttributeHost('on-get-value')
32
32
  private refresh() {
33
33
  const script = this.getAttribute('on-get-value');
34
34
  if (!script) return;