@dooboostore/simple-web-component 1.0.33 → 1.0.34

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 (114) hide show
  1. package/dist/cjs/decorators/addEventListener.js.map +1 -1
  2. package/dist/cjs/decorators/applyAttribute.js +67 -57
  3. package/dist/cjs/decorators/applyAttribute.js.map +2 -2
  4. package/dist/cjs/decorators/applyClass.js +80 -70
  5. package/dist/cjs/decorators/applyClass.js.map +2 -2
  6. package/dist/cjs/decorators/applyNode.js +1 -8
  7. package/dist/cjs/decorators/applyNode.js.map +2 -2
  8. package/dist/cjs/decorators/applyStyle.js +66 -56
  9. package/dist/cjs/decorators/applyStyle.js.map +2 -2
  10. package/dist/cjs/decorators/attribute.js +35 -29
  11. package/dist/cjs/decorators/attribute.js.map +2 -2
  12. package/dist/cjs/decorators/changedAttributeHost.js +32 -12
  13. package/dist/cjs/decorators/changedAttributeHost.js.map +2 -2
  14. package/dist/cjs/decorators/elementDefine.js +29 -16
  15. package/dist/cjs/decorators/elementDefine.js.map +2 -2
  16. package/dist/cjs/decorators/emitCustomEvent.js +57 -44
  17. package/dist/cjs/decorators/emitCustomEvent.js.map +2 -2
  18. package/dist/cjs/decorators/setProperty.js +50 -39
  19. package/dist/cjs/decorators/setProperty.js.map +2 -2
  20. package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js.map +1 -1
  21. package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +1 -1
  22. package/dist/cjs/elements/SwcAppEngine.js +7 -7
  23. package/dist/cjs/elements/SwcAppEngine.js.map +3 -3
  24. package/dist/cjs/elements/SwcAppMixin.js +60 -42
  25. package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
  26. package/dist/cjs/elements/SwcChoose.js +19 -15
  27. package/dist/cjs/elements/SwcChoose.js.map +2 -2
  28. package/dist/cjs/elements/register.js +21 -16
  29. package/dist/cjs/elements/register.js.map +2 -2
  30. package/dist/cjs/utils/Utils.js +7 -3
  31. package/dist/cjs/utils/Utils.js.map +2 -2
  32. package/dist/esm/decorators/addEventListener.js.map +1 -1
  33. package/dist/esm/decorators/applyAttribute.js +67 -57
  34. package/dist/esm/decorators/applyAttribute.js.map +2 -2
  35. package/dist/esm/decorators/applyClass.js +80 -70
  36. package/dist/esm/decorators/applyClass.js.map +2 -2
  37. package/dist/esm/decorators/applyNode.js +1 -8
  38. package/dist/esm/decorators/applyNode.js.map +2 -2
  39. package/dist/esm/decorators/applyStyle.js +66 -56
  40. package/dist/esm/decorators/applyStyle.js.map +2 -2
  41. package/dist/esm/decorators/attribute.js +35 -29
  42. package/dist/esm/decorators/attribute.js.map +2 -2
  43. package/dist/esm/decorators/changedAttributeHost.js +32 -12
  44. package/dist/esm/decorators/changedAttributeHost.js.map +2 -2
  45. package/dist/esm/decorators/elementDefine.js +30 -17
  46. package/dist/esm/decorators/elementDefine.js.map +2 -2
  47. package/dist/esm/decorators/emitCustomEvent.js +57 -44
  48. package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
  49. package/dist/esm/decorators/setProperty.js +50 -39
  50. package/dist/esm/decorators/setProperty.js.map +2 -2
  51. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js.map +1 -1
  52. package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +1 -1
  53. package/dist/esm/elements/SwcAppEngine.js +6 -6
  54. package/dist/esm/elements/SwcAppEngine.js.map +2 -2
  55. package/dist/esm/elements/SwcAppMixin.js +60 -42
  56. package/dist/esm/elements/SwcAppMixin.js.map +2 -2
  57. package/dist/esm/elements/SwcChoose.js +20 -16
  58. package/dist/esm/elements/SwcChoose.js.map +2 -2
  59. package/dist/esm/elements/register.js +22 -17
  60. package/dist/esm/elements/register.js.map +2 -2
  61. package/dist/esm/utils/Utils.js +7 -3
  62. package/dist/esm/utils/Utils.js.map +2 -2
  63. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +425 -335
  64. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +3 -3
  65. package/dist/types/decorators/addEventListener.d.ts +4 -1
  66. package/dist/types/decorators/addEventListener.d.ts.map +1 -1
  67. package/dist/types/decorators/applyAttribute.d.ts +5 -1
  68. package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
  69. package/dist/types/decorators/applyClass.d.ts +4 -0
  70. package/dist/types/decorators/applyClass.d.ts.map +1 -1
  71. package/dist/types/decorators/applyNode.d.ts +4 -1
  72. package/dist/types/decorators/applyNode.d.ts.map +1 -1
  73. package/dist/types/decorators/applyStyle.d.ts +5 -1
  74. package/dist/types/decorators/applyStyle.d.ts.map +1 -1
  75. package/dist/types/decorators/attribute.d.ts +5 -0
  76. package/dist/types/decorators/attribute.d.ts.map +1 -1
  77. package/dist/types/decorators/changedAttributeHost.d.ts +13 -3
  78. package/dist/types/decorators/changedAttributeHost.d.ts.map +1 -1
  79. package/dist/types/decorators/elementDefine.d.ts +1 -1
  80. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  81. package/dist/types/decorators/emitCustomEvent.d.ts +5 -1
  82. package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
  83. package/dist/types/decorators/setProperty.d.ts +5 -1
  84. package/dist/types/decorators/setProperty.d.ts.map +1 -1
  85. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts +2 -2
  86. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts.map +1 -1
  87. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +2 -2
  88. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +1 -1
  89. package/dist/types/elements/SwcAppEngine.d.ts +6 -3
  90. package/dist/types/elements/SwcAppEngine.d.ts.map +1 -1
  91. package/dist/types/elements/SwcAppMixin.d.ts +5 -3
  92. package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
  93. package/dist/types/elements/register.d.ts.map +1 -1
  94. package/dist/types/utils/Utils.d.ts.map +1 -1
  95. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +425 -335
  96. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +3 -3
  97. package/package.json +3 -3
  98. package/src/decorators/addEventListener.ts +1 -1
  99. package/src/decorators/applyAttribute.ts +74 -61
  100. package/src/decorators/applyClass.ts +91 -77
  101. package/src/decorators/applyNode.ts +3 -12
  102. package/src/decorators/applyStyle.ts +75 -61
  103. package/src/decorators/attribute.ts +55 -43
  104. package/src/decorators/changedAttributeHost.ts +47 -14
  105. package/src/decorators/elementDefine.ts +38 -20
  106. package/src/decorators/emitCustomEvent.ts +65 -49
  107. package/src/decorators/setProperty.ts +58 -44
  108. package/src/decorators/subscribeSwcAppMessageWhileConnected.ts +2 -2
  109. package/src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts +2 -2
  110. package/src/elements/SwcAppEngine.ts +11 -12
  111. package/src/elements/SwcAppMixin.ts +76 -44
  112. package/src/elements/SwcChoose.ts +28 -7
  113. package/src/elements/register.ts +28 -7
  114. package/src/utils/Utils.ts +15 -5
@@ -1,7 +1,7 @@
1
- import {ReflectUtils, FunctionUtils, ActionExpression} from '@dooboostore/core';
2
- import {ensureInit, getElementConfig} from './elementDefine';
3
- import {SwcUtils} from '../utils/Utils';
4
- import {SpecialSelector, SwcQueryOptions} from '../types';
1
+ import { ReflectUtils, FunctionUtils, ActionExpression } from '@dooboostore/core';
2
+ import { ensureInit, getElementConfig } from './elementDefine';
3
+ import { SwcUtils } from '../utils/Utils';
4
+ import { SpecialSelector, SwcQueryOptions } from '../types';
5
5
  import { ConvertUtils } from '@dooboostore/core-web';
6
6
  export interface AttributeFieldOptions extends SwcQueryOptions {
7
7
  name?: string;
@@ -25,6 +25,44 @@ const convertValue = (val: string | null, type: any): any => {
25
25
  return val;
26
26
  };
27
27
 
28
+ export { convertValue };
29
+
30
+ export const getAttributeValue = (inst: any, attrName: string, options?: AttributeFieldOptions & { selector?: string }): any => {
31
+ const conf = getElementConfig(inst);
32
+ const currentWin = inst._resolveWindow?.(conf) || ((typeof window !== 'undefined' ? window : undefined) as any);
33
+
34
+ // If selector is not provided, use inst itself
35
+ const targets = options?.selector ? resolveTargetEls(inst, options.selector, options, currentWin) : [inst];
36
+
37
+ const primaryTarget = targets[0];
38
+
39
+ if (primaryTarget && typeof (primaryTarget as any).hasAttribute === 'function' && (primaryTarget as any).hasAttribute(attrName)) {
40
+ let domVal = (primaryTarget as any).getAttribute(attrName);
41
+
42
+ // 표현식 체크
43
+ const ae = new ActionExpression(domVal);
44
+ const expr = ae.getFirstExpression('call-return');
45
+ if (expr) {
46
+ try {
47
+ const result = FunctionUtils.executeReturn({
48
+ script: ConvertUtils.decodeHtmlEntity(expr.script, currentWin.document),
49
+ context: inst,
50
+ args: SwcUtils.getHelperAndHostSet(currentWin, inst)
51
+ });
52
+ return convertValue(result, options?.type);
53
+ } catch (e) {
54
+ console.error(`[SWC] Failed to execute directive {{= ${expr.script} }}:`, e);
55
+ return convertValue(domVal, options?.type);
56
+ }
57
+ }
58
+
59
+ return convertValue(domVal, options?.type);
60
+ }
61
+
62
+ // If no target found, return null
63
+ return null;
64
+ };
65
+
28
66
  export const resolveTargetEls = (inst: any, selector: string, options: AttributeFieldOptions, currentWin: any): HTMLElement[] => {
29
67
  const r = options.root || 'auto';
30
68
  const results: HTMLElement[] = [];
@@ -89,7 +127,7 @@ export function attribute(selector: string, options: AttributeFieldOptions = {})
89
127
  metaList = [];
90
128
  ReflectUtils.defineMetadata(ATTRIBUTE_FIELD_METADATA_KEY, metaList, constructor);
91
129
  }
92
- metaList.push({propertyKey, selector, options, privateKey});
130
+ metaList.push({ propertyKey, selector, options, privateKey });
93
131
 
94
132
  const applySetAttribute = (inst: any, targets: HTMLElement[], attrName: string, nv: any) => {
95
133
  targets.forEach(it => {
@@ -111,45 +149,20 @@ export function attribute(selector: string, options: AttributeFieldOptions = {})
111
149
  // delete target[propertyKey];
112
150
 
113
151
  // const defineTarget = target instanceof Function ? target : (target as any).constructor;
114
-
152
+
115
153
  Object.defineProperty(target, propertyKey, {
116
154
  get(this: any) {
117
155
  const attrName = options.name || String(propertyKey);
118
- const conf = getElementConfig(this);
119
- const currentWin = this._resolveWindow?.(conf) || ((typeof window !== 'undefined' ? window : undefined) as any);
120
- const targetType = options.type || designType;
121
156
 
122
- const targets = resolveTargetEls(this, selector, options, currentWin);
123
- const primaryTarget = targets[0];
124
-
125
- if (primaryTarget && typeof (primaryTarget as any).hasAttribute === 'function') {
126
- if ((primaryTarget as any).hasAttribute(attrName)) {
127
- let domVal = (primaryTarget as any).getAttribute(attrName);
128
-
129
- // 표현식 체크
130
- const ae = new ActionExpression(domVal);
131
- const expr = ae.getFirstExpression('call-return');
132
- if (expr) {
133
- try {
134
- const result = FunctionUtils.executeReturn({
135
- script: ConvertUtils.decodeHtmlEntity(expr.script, currentWin.document),
136
- context: this,
137
- args: SwcUtils.getHelperAndHostSet(currentWin, this)
138
- });
139
- return convertValue(result, targetType);
140
- } catch (e) {
141
- console.error(`[SWC] Failed to execute directive {{= ${expr.script} }}:`, e);
142
- return convertValue(domVal, targetType);
143
- }
144
- }
145
-
146
- return convertValue(domVal, targetType);
147
- }
148
- return null;
149
- }
157
+ // Merge designType fallback into options once
158
+ const mergedOptions = {
159
+ ...options,
160
+ selector,
161
+ type: options.type || designType
162
+ };
150
163
 
151
- const data = convertValue(this[privateKey], targetType);
152
- return data;
164
+ const result = getAttributeValue(this, attrName, mergedOptions);
165
+ return result !== null ? result : this[privateKey];
153
166
  },
154
167
  set(this: any, nv: any) {
155
168
  // this[propertyKey] = nv;
@@ -158,7 +171,6 @@ export function attribute(selector: string, options: AttributeFieldOptions = {})
158
171
  const conf = getElementConfig(this);
159
172
  const currentWin = this._resolveWindow?.(conf) || ((typeof window !== 'undefined' ? window : undefined) as any);
160
173
 
161
-
162
174
  // if (!this.__swc_connected) {
163
175
  // this[privateKey] = nv;
164
176
  // return;
@@ -170,9 +182,9 @@ export function attribute(selector: string, options: AttributeFieldOptions = {})
170
182
  enumerable: true,
171
183
  configurable: true
172
184
  });
173
- } catch (err) {
174
- console.error('[SWC] defineProperty error:', err);
175
- }
185
+ } catch (err) {
186
+ console.error('[SWC] defineProperty error:', err);
187
+ }
176
188
  };
177
189
  }
178
190
 
@@ -2,34 +2,67 @@ import {ReflectUtils} from '@dooboostore/core';
2
2
 
3
3
  export const ON_ATTRIBUTE_CHANGED_METADATA_KEY = Symbol.for('simple-web-component:on-attribute-changed');
4
4
 
5
+ export interface ChangedAttributeHostOptions {
6
+ type?: typeof Number | typeof Boolean | typeof String;
7
+ }
8
+
9
+ export interface ChangedAttributeHostMetadata {
10
+ attributeName: string;
11
+ propertyKey: string | symbol;
12
+ options: ChangedAttributeHostOptions;
13
+ }
14
+
15
+ const convertValue = (val: any, type: any): any => {
16
+ if (val === null || val === undefined) return val;
17
+ if (type === Number) return Number(val);
18
+ if (type === Boolean) return val === 'false' || val === '0' ? false : true;
19
+ return val;
20
+ };
21
+
5
22
  /**
6
23
  * @changedAttributeHost decorator - fires when any attribute on :host changes
7
24
  * Usage: @changedAttributeHost('data-product-id')
25
+ * @changedAttributeHost('count', { type: Number })
8
26
  */
9
- export function changedAttributeHost(attributeName?: string): MethodDecorator {
27
+ export function changedAttributeHost(attributeName?: string, options: ChangedAttributeHostOptions = {}): MethodDecorator {
10
28
  return (target: Object, propertyKey: string | symbol) => {
11
29
  const constructor = target.constructor;
12
- let meta = ReflectUtils.getOwnMetadata(ON_ATTRIBUTE_CHANGED_METADATA_KEY, constructor) as Map<string, (string | symbol)[]>;
13
- if (!meta) {
14
- meta = new Map<string, (string | symbol)[]>();
15
- ReflectUtils.defineMetadata(ON_ATTRIBUTE_CHANGED_METADATA_KEY, meta, constructor);
30
+ let metaList = ReflectUtils.getOwnMetadata(ON_ATTRIBUTE_CHANGED_METADATA_KEY, constructor) as ChangedAttributeHostMetadata[];
31
+ if (!metaList) {
32
+ metaList = [];
33
+ ReflectUtils.defineMetadata(ON_ATTRIBUTE_CHANGED_METADATA_KEY, metaList, constructor);
16
34
  }
17
35
 
18
36
  const name = attributeName || String(propertyKey);
19
- let methods = meta.get(name);
20
- if (!methods) {
21
- methods = [];
22
- meta.set(name, methods);
23
- }
24
- if (!methods.includes(propertyKey)) methods.push(propertyKey);
37
+ metaList.push({
38
+ attributeName: name,
39
+ propertyKey,
40
+ options
41
+ });
25
42
  };
26
43
  }
27
44
 
28
- export const getChangedAttributeMetadata = (target: any): Map<string, (string | symbol)[]> | undefined => {
45
+ export const getChangedAttributeMetadata = (target: any): ChangedAttributeHostMetadata[] | undefined => {
29
46
  const constructor = target instanceof Function ? target : target.constructor;
30
47
  return ReflectUtils.getMetadata(ON_ATTRIBUTE_CHANGED_METADATA_KEY, constructor);
31
48
  };
32
49
 
33
- export const findAllAttributeChangedMetadata = (target: any): Map<string, (string | symbol)[]> => {
34
- return ReflectUtils.findAllMapMetadata<string, string | symbol>(ON_ATTRIBUTE_CHANGED_METADATA_KEY, target);
50
+ export const findAllAttributeChangedMetadata = (target: any): Map<string, ChangedAttributeHostMetadata[]> => {
51
+ const constructor = target instanceof Function ? target : target.constructor;
52
+ const metaList = ReflectUtils.findAllMetadata<ChangedAttributeHostMetadata[]>(ON_ATTRIBUTE_CHANGED_METADATA_KEY, constructor) || [];
53
+
54
+ const result = new Map<string, ChangedAttributeHostMetadata[]>();
55
+ metaList.forEach(meta => {
56
+ meta.forEach(item => {
57
+ if (!result.has(item.attributeName)) {
58
+ result.set(item.attributeName, []);
59
+ }
60
+ result.get(item.attributeName)!.push(item);
61
+ });
62
+ });
63
+ return result;
64
+ };
65
+
66
+ export const convertAttributeValue = (val: any, type?: typeof Number | typeof Boolean | typeof String): any => {
67
+ return convertValue(val, type);
35
68
  };
@@ -2,7 +2,7 @@ import { ReflectUtils, FunctionUtils, ActionExpression } from '@dooboostore/core
2
2
  import { getAddEventListenerMetadata } from './addEventListener';
3
3
  import { ON_INITIALIZE_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';
4
4
  import { getEmitCustomEventMetadataList } from './emitCustomEvent';
5
- import { findAllAttributeChangedMetadata } from './changedAttributeHost';
5
+ import { findAllAttributeChangedMetadata, convertAttributeValue } from './changedAttributeHost';
6
6
  import { findAllAttributeApplyMetadata } from './applyAttribute';
7
7
  import { findAllAttributeMetadata } from './attribute';
8
8
  import { getQueryMetadata } from './query';
@@ -22,7 +22,7 @@ export interface ElementConfig {
22
22
  observedAttributes?: string[];
23
23
  customElementRegistry?: any;
24
24
  window?: Window;
25
- useShadow?: boolean;
25
+ useShadow?: boolean | 'open' | 'closed';
26
26
  }
27
27
 
28
28
  export interface ElementMetadata extends Omit<ElementConfig, 'window'> {
@@ -126,8 +126,8 @@ const handleGlobalSwcEvent = async (event: Event) => {
126
126
  }
127
127
  };
128
128
 
129
- function buildEnv(configWindow?: Window) {
130
- const win: Window = configWindow || ((typeof window !== 'undefined' ? window : undefined) as any);
129
+ function buildEnv(configWindow: Window) {
130
+ const win: Window = configWindow;
131
131
  const doc: Document = win?.document;
132
132
  const builtInTagMap = new Map<any, string>();
133
133
  for (const [cls, tag] of HTML_TAG_ENTRIES) {
@@ -171,7 +171,7 @@ const setupPrototype = (proto: any) => {
171
171
  const aConf = getElementConfig(ancestors[i]);
172
172
  if (aConf?.window) return aConf.window;
173
173
  }
174
- return (typeof window !== 'undefined' ? window : undefined) as Window;
174
+ return getElementConfig(this).window ?? (typeof window !== 'undefined' ? window : undefined) as Window;
175
175
  };
176
176
 
177
177
  proto._invokeLifecycleMethod = function (methodName: string | symbol, hostSet?: HostSet, extraArgs: any[] = []) {
@@ -293,8 +293,15 @@ export const elementDefine =
293
293
  // const attributeListNames = attributeList.map(it => it.options.name || String(it.propertyKey));
294
294
  const hostAttributes = attributeList.filter(it => it.selector === ':host').map(it=>it.options.name || String(it.propertyKey));
295
295
 
296
+ const proto = constructor.prototype;
297
+
298
+ // Get original static observedAttributes before they're overwritten by Object.defineProperty
299
+ const originalStaticObservedAttributes = (constructor.observedAttributes ?? []) as string[];
300
+
301
+ // proto.observedAttributes??[];
296
302
  const mergedObservedAttributes = [...new Set([
297
303
  ...(metadata.observedAttributes ?? []),
304
+ ...originalStaticObservedAttributes,
298
305
  ...attrChangeMap.keys(),
299
306
  ...attributeApplyNames,
300
307
  ...hostAttributes,
@@ -305,7 +312,6 @@ export const elementDefine =
305
312
 
306
313
  const connectedInnerHtmlList = getOnConnectedInnerHtmlMetadata(constructor) || [];
307
314
 
308
- const proto = constructor.prototype;
309
315
  setupPrototype(proto);
310
316
 
311
317
  const originalConnected = proto.connectedCallback;
@@ -317,8 +323,10 @@ export const elementDefine =
317
323
  const conf = getElementConfig(this);
318
324
  const currentWin = (this as any)._resolveWindow(conf);
319
325
 
320
- if ((connectedInnerHtmlList.some(it => it.options.useShadow === true) || conf?.useShadow === true) && !this.shadowRoot) {
321
- this.attachShadow({ mode: 'open' });
326
+ const shadowMode = conf?.useShadow || connectedInnerHtmlList.find(it => it.options.useShadow)?.options.useShadow;
327
+ if (shadowMode && !this.shadowRoot) {
328
+ const mode = shadowMode === true ? 'open' : shadowMode;
329
+ this.attachShadow({ mode: mode as ShadowRootMode });
322
330
  }
323
331
 
324
332
  (this as any)._executeSwcScript('swc-on-before-connected', hostSet);
@@ -336,12 +344,16 @@ export const elementDefine =
336
344
  // console.log('------res0', res);
337
345
  // console.log('------res1', res1);
338
346
  if (res !== undefined) {
339
- if (meta.options.useShadow) sContent += res;
347
+ if (meta.options.useShadow || conf?.useShadow) sContent += res;
340
348
  else lContent += res;
341
349
  }
342
350
  }
343
- if (this.shadowRoot) this.shadowRoot.innerHTML = sContent;
344
- if (lContent) this.innerHTML = lContent;
351
+ try {
352
+ if (this.shadowRoot) this.shadowRoot.innerHTML = sContent;
353
+ if (lContent) this.innerHTML = lContent;
354
+ } catch (e) {
355
+ console.error('[ElementDefine] innerHTML setting error:', e);
356
+ }
345
357
  }
346
358
 
347
359
  const root = this.getRootNode();
@@ -468,7 +480,7 @@ export const elementDefine =
468
480
  // Apply filter if specified
469
481
  if (options.filter) {
470
482
  const helper = SwcUtils.getHelperAndHostSet(currentWin, t as HTMLElement);
471
- if (!options.filter(event, helper)) {
483
+ if (!options.filter(event, {currentThis: this,helper})) {
472
484
  return; // Skip if filter returns false
473
485
  }
474
486
  }
@@ -565,21 +577,24 @@ export const elementDefine =
565
577
  const hSet = SwcUtils.getHostSet(this as any);
566
578
 
567
579
  // Process expression directive before passing to handlers
568
- let processedVal = newVal;
580
+ let processedVal: any = newVal;
569
581
  if (newVal !== null) {
570
582
  const ae = new ActionExpression(newVal);
571
583
  const expr = ae.getFirstExpression('call-return');
572
584
  if (expr) {
573
585
  const win = (this as any)._resolveWindow?.() || ((typeof window !== 'undefined' ? window : undefined) as any);
586
+ const helperAndHostSet = SwcUtils.getHelperAndHostSet(win,this as any);
574
587
  try {
588
+ const script = ConvertUtils.decodeHtmlEntity(expr.script, win.document);
575
589
  const result = FunctionUtils.executeReturn({
576
- script: ConvertUtils.decodeHtmlEntity(expr.script, win.document),
590
+ script: script,
577
591
  context: this,
578
- args: SwcUtils.getHelperAndHostSet(win,this as any)
592
+ args: helperAndHostSet
579
593
  });
580
- processedVal = String(result);
594
+ // Pass the result object directly without serialization
595
+ processedVal = result;
581
596
  } catch (e) {
582
- console.error(`[SWC] Failed to execute directive {{= ${expr.script} }} on attribute ${name}:`, e);
597
+ console.error(`[SWC] Failed to execute directive {{= ${expr.script} }} on attribute ${name}: ${helperAndHostSet}`, e);
583
598
  processedVal = newVal;
584
599
  }
585
600
  }
@@ -597,9 +612,12 @@ export const elementDefine =
597
612
  (this as any)._bindAttributeEvent(this as any, name, newVal, hostCustomEventMeta.type);
598
613
  }
599
614
 
600
- const mKeys = attrChangeMap.get(name);
601
- if (mKeys && Array.isArray(mKeys)) {
602
- for (const key of mKeys) (this as any)[key](processedVal, old, name, hSet);
615
+ const metaList = attrChangeMap.get(name);
616
+ if (metaList && Array.isArray(metaList)) {
617
+ for (const meta of metaList) {
618
+ const convertedVal = convertAttributeValue(processedVal, meta.options.type);
619
+ (this as any)[meta.propertyKey](convertedVal, old, name, hSet);
620
+ }
603
621
  }
604
622
  };
605
623
 
@@ -1,5 +1,5 @@
1
1
  import { ReflectUtils } from '@dooboostore/core';
2
- import { SpecialSelector, SwcQueryOptions } from '../types';
2
+ import { SpecialSelector, SwcQueryOptions, HelperHostSet } from '../types';
3
3
  import { ensureInit, getElementConfig } from './elementDefine';
4
4
  import { SwcUtils } from '../utils/Utils';
5
5
 
@@ -7,6 +7,7 @@ export interface EmitCustomEventBaseOptions {
7
7
  bubbles?: boolean;
8
8
  composed?: boolean;
9
9
  cancelable?: boolean;
10
+ filter?: (target: EventTarget, detail: any, meta: {currentThis: any, helper: HelperHostSet}) => boolean;
10
11
  }
11
12
 
12
13
  export interface EmitCustomEventMetadata {
@@ -39,59 +40,74 @@ export function emitCustomEvent(selectorOrTarget: string, type: string, options:
39
40
  list.push({ propertyKey, selector: selectorOrTarget, type, options: fullOptions });
40
41
 
41
42
  const original = descriptor.value;
42
- descriptor.value = async function (...args: any[]) {
43
+ descriptor.value = function (...args: any[]) {
43
44
  ensureInit(this);
44
- const detail = await original.apply(this, args);
45
- const event = new CustomEvent(type, {
46
- detail,
47
- bubbles: fullOptions.bubbles,
48
- composed: fullOptions.composed,
49
- cancelable: fullOptions.cancelable
50
- });
51
-
52
- const hostSet = SwcUtils.getHostSet(this as any);
53
- const conf = getElementConfig(this);
54
- const currentWin = (this as any)._resolveWindow?.(conf) || ((typeof window !== 'undefined' ? window : undefined) as Window);
55
- // console.log('emitEEEEEEEEEEE', hostSet);
56
-
57
- const eventTargets: EventTarget[] = [];
58
- if (selectorOrTarget === ':window') eventTargets.push(currentWin);
59
- else if (selectorOrTarget === ':document') eventTargets.push(currentWin.document);
60
- else if (selectorOrTarget === ':parentHost') {
61
- if (hostSet.$parentHost) eventTargets.push(hostSet.$parentHost);
62
- } else if (selectorOrTarget === ':appHost') {
63
- if (hostSet.$appHost) eventTargets.push(hostSet.$appHost);
64
- } else if (selectorOrTarget === ':firstHost') {
65
- if (hostSet.$firstHost) eventTargets.push(hostSet.$firstHost);
66
- } else if (selectorOrTarget === ':lastHost') {
67
- if (hostSet.$lastHost) eventTargets.push(hostSet.$lastHost);
68
- } else if (selectorOrTarget === ':firstAppHost') {
69
- if (hostSet.$firstAppHost) eventTargets.push(hostSet.$firstAppHost);
70
- } else if (selectorOrTarget === ':lastAppHost') {
71
- if (hostSet.$lastAppHost) eventTargets.push(hostSet.$lastAppHost);
72
- } else if (selectorOrTarget === ':hosts') {
73
- hostSet.$hosts.forEach(h => eventTargets.push(h));
74
- } else if (selectorOrTarget === ':appHosts') {
75
- hostSet.$appHosts.forEach(h => eventTargets.push(h));
76
- } else if (selectorOrTarget === ':host' || !selectorOrTarget) eventTargets.push(this as any);
77
- else {
78
- const r = fullOptions.root || 'auto';
79
- const searchRoots: (HTMLElement | ShadowRoot)[] = [];
80
- if (r === 'auto') searchRoots.push(this.shadowRoot || (this as any));
81
- else if (r === 'light') searchRoots.push(this as any);
82
- else if (r === 'shadow' && this.shadowRoot) searchRoots.push(this.shadowRoot);
83
- else if (r === 'all') {
84
- searchRoots.push(this as any);
85
- if (this.shadowRoot) searchRoots.push(this.shadowRoot);
45
+ const res = original.apply(this, args);
46
+
47
+ const handleResult = (detail: any) => {
48
+ const event = new CustomEvent(type, {
49
+ detail,
50
+ bubbles: fullOptions.bubbles,
51
+ composed: fullOptions.composed,
52
+ cancelable: fullOptions.cancelable
53
+ });
54
+
55
+ const hostSet = SwcUtils.getHostSet(this as any);
56
+ const conf = getElementConfig(this);
57
+ const currentWin = (this as any)._resolveWindow?.(conf) || ((typeof window !== 'undefined' ? window : undefined) as Window);
58
+
59
+ const eventTargets: EventTarget[] = [];
60
+ if (selectorOrTarget === ':window') eventTargets.push(currentWin);
61
+ else if (selectorOrTarget === ':document') eventTargets.push(currentWin.document);
62
+ else if (selectorOrTarget === ':parentHost') {
63
+ if (hostSet.$parentHost) eventTargets.push(hostSet.$parentHost);
64
+ } else if (selectorOrTarget === ':appHost') {
65
+ if (hostSet.$appHost) eventTargets.push(hostSet.$appHost);
66
+ } else if (selectorOrTarget === ':firstHost') {
67
+ if (hostSet.$firstHost) eventTargets.push(hostSet.$firstHost);
68
+ } else if (selectorOrTarget === ':lastHost') {
69
+ if (hostSet.$lastHost) eventTargets.push(hostSet.$lastHost);
70
+ } else if (selectorOrTarget === ':firstAppHost') {
71
+ if (hostSet.$firstAppHost) eventTargets.push(hostSet.$firstAppHost);
72
+ } else if (selectorOrTarget === ':lastAppHost') {
73
+ if (hostSet.$lastAppHost) eventTargets.push(hostSet.$lastAppHost);
74
+ } else if (selectorOrTarget === ':hosts') {
75
+ hostSet.$hosts.forEach(h => eventTargets.push(h));
76
+ } else if (selectorOrTarget === ':appHosts') {
77
+ hostSet.$appHosts.forEach(h => eventTargets.push(h));
78
+ } else if (selectorOrTarget === ':host' || !selectorOrTarget) {
79
+ eventTargets.push(this as any);
80
+ } else {
81
+ const r = fullOptions.root || 'auto';
82
+ const searchRoots: (HTMLElement | ShadowRoot)[] = [];
83
+ if (r === 'auto') searchRoots.push(this.shadowRoot || (this as any));
84
+ else if (r === 'light') searchRoots.push(this as any);
85
+ else if (r === 'shadow' && this.shadowRoot) searchRoots.push(this.shadowRoot);
86
+ else if (r === 'all') {
87
+ searchRoots.push(this as any);
88
+ if (this.shadowRoot) searchRoots.push(this.shadowRoot);
89
+ }
90
+
91
+ searchRoots.forEach(sr => {
92
+ sr.querySelectorAll(selectorOrTarget).forEach(el => eventTargets.push(el));
93
+ });
86
94
  }
87
95
 
88
- searchRoots.forEach(sr => {
89
- sr.querySelectorAll(selectorOrTarget).forEach(el => eventTargets.push(el));
96
+ eventTargets.forEach(t => {
97
+ if (fullOptions.filter && !fullOptions.filter(t, detail, {currentThis: this, helper: hostSet})) {
98
+ return;
99
+ }
100
+ t.dispatchEvent(event);
90
101
  });
91
- }
92
102
 
93
- eventTargets.forEach(t => t.dispatchEvent(event));
94
- return detail;
103
+ return detail;
104
+ };
105
+
106
+ if (res instanceof Promise) {
107
+ return res.then(handleResult);
108
+ } else {
109
+ return handleResult(res);
110
+ }
95
111
  };
96
112
  };
97
113
  }
@@ -1,10 +1,11 @@
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
+ import { HelperHostSet, SwcQueryOptions } from '../types';
5
5
 
6
6
  export interface PropertySetOptions extends SwcQueryOptions {
7
7
  name?: string;
8
+ filter?: (target: HTMLElement, value: any, meta: {currentThis: any, helper: HelperHostSet}) => boolean;
8
9
  }
9
10
 
10
11
  export interface PropertySetMetadata {
@@ -38,55 +39,68 @@ export const setProperty = (selector: string, propertyNameOrOptions?: string | P
38
39
  });
39
40
 
40
41
  const original = descriptor.value;
41
- descriptor.value = async function (...args: any[]) {
42
+ descriptor.value = function (...args: any[]) {
42
43
  ensureInit(this);
43
- const res = await (original as any).apply(this, args);
44
- if (res !== undefined) {
45
- const win = (this as any).ownerDocument?.defaultView || window;
46
- const host = this as unknown as HTMLElement;
47
- const hostSet = { ...SwcUtils.getHelperAndHostSet(win, host), $this: this };
48
- const r = finalOptions.root || 'auto';
49
- const targetEls: HTMLElement[] = [];
44
+ const res = (original as any).apply(this, args);
50
45
 
51
- const applyRoot = (t: any) => {
52
- if (!t || !(t instanceof win.HTMLElement)) return;
53
- targetEls.push(t);
54
- };
46
+ const handleResult = (resolvedValue: any) => {
47
+ if (resolvedValue !== undefined) {
48
+ const win = (this as any).ownerDocument?.defaultView || window;
49
+ const host = this as unknown as HTMLElement;
50
+ const hostSet = { ...SwcUtils.getHelperAndHostSet(win, host), $this: this };
51
+ const r = finalOptions.root || 'auto';
52
+ const targetEls: HTMLElement[] = [];
55
53
 
56
- if (selector === ':parentHost') applyRoot(hostSet.$parentHost);
57
- else if (selector === ':appHost') applyRoot(hostSet.$appHost);
58
- else if (selector === ':firstHost') applyRoot(hostSet.$firstHost);
59
- else if (selector === ':lastHost') applyRoot(hostSet.$lastHost);
60
- else if (selector === ':firstAppHost') applyRoot(hostSet.$firstAppHost);
61
- else if (selector === ':lastAppHost') applyRoot(hostSet.$lastAppHost);
62
- else if (selector === ':hosts') hostSet.$hosts.forEach(applyRoot);
63
- else if (selector === ':appHosts') hostSet.$appHosts.forEach(applyRoot);
64
- else if (selector === ':host' || !selector) applyRoot(host);
65
- else {
66
- const targetRoot = r === 'auto' ? (host.shadowRoot || host) : (r === 'shadow' ? host.shadowRoot : host);
67
- if (targetRoot) {
68
- const found = targetRoot.querySelectorAll(selector);
69
- if (found) targetEls.push(...(Array.from(found) as HTMLElement[]));
54
+ const applyRoot = (t: any) => {
55
+ if (!t || !(t instanceof win.HTMLElement)) return;
56
+ targetEls.push(t);
57
+ };
58
+
59
+ if (selector === ':parentHost') applyRoot(hostSet.$parentHost);
60
+ else if (selector === ':appHost') applyRoot(hostSet.$appHost);
61
+ else if (selector === ':firstHost') applyRoot(hostSet.$firstHost);
62
+ else if (selector === ':lastHost') applyRoot(hostSet.$lastHost);
63
+ else if (selector === ':firstAppHost') applyRoot(hostSet.$firstAppHost);
64
+ else if (selector === ':lastAppHost') applyRoot(hostSet.$lastAppHost);
65
+ else if (selector === ':hosts') hostSet.$hosts.forEach(applyRoot);
66
+ else if (selector === ':appHosts') hostSet.$appHosts.forEach(applyRoot);
67
+ else if (selector === ':host' || !selector) applyRoot(host);
68
+ else {
69
+ const targetRoot = r === 'auto' ? (host.shadowRoot || host) : (r === 'shadow' ? host.shadowRoot : host);
70
+ if (targetRoot) {
71
+ const found = targetRoot.querySelectorAll(selector);
72
+ if (found) targetEls.push(...(Array.from(found) as HTMLElement[]));
73
+ }
70
74
  }
71
- }
72
75
 
73
- targetEls.forEach(targetEl => {
74
- const resolvedRes = typeof res === 'function' ? (res as any)(targetEl, hostSet) : res;
76
+ targetEls.forEach(targetEl => {
77
+ if (finalOptions.filter && !finalOptions.filter(targetEl, resolvedValue, {currentThis: this, helper: hostSet})) {
78
+ return;
79
+ }
80
+ const resolvedRes = typeof resolvedValue === 'function' ? (resolvedValue as any)(targetEl, hostSet) : resolvedValue;
75
81
 
76
- if (propertyName) {
77
- // Case: @setProperty(selector, 'propertyName')
78
- (targetEl as any)[propertyName] = resolvedRes;
79
- } else if (typeof resolvedRes === 'object' && resolvedRes !== null && !Array.isArray(resolvedRes)) {
80
- // Case: @setProperty(selector) with Object return - assign multiple properties
81
- Object.entries(resolvedRes as any).forEach(([prop, val]) => {
82
- const finalVal = typeof val === 'function' ? val(targetEl, hostSet) : val;
83
- (targetEl as any)[prop] = finalVal;
84
- });
85
- } else {
86
- // Simple value - assign to 'value' property by default
87
- (targetEl as any).value = resolvedRes;
88
- }
89
- });
82
+ if (propertyName) {
83
+ // Case: @setProperty(selector, 'propertyName')
84
+ (targetEl as any)[propertyName] = resolvedRes;
85
+ } else if (typeof resolvedRes === 'object' && resolvedRes !== null && !Array.isArray(resolvedRes)) {
86
+ // Case: @setProperty(selector) with Object return - assign multiple properties
87
+ Object.entries(resolvedRes as any).forEach(([prop, val]) => {
88
+ const finalVal = typeof val === 'function' ? val(targetEl, hostSet) : val;
89
+ (targetEl as any)[prop] = finalVal;
90
+ });
91
+ } else {
92
+ // Simple value - assign to 'value' property by default
93
+ (targetEl as any).value = resolvedRes;
94
+ }
95
+ });
96
+ }
97
+ return resolvedValue;
98
+ };
99
+
100
+ if (res instanceof Promise) {
101
+ return res.then(handleResult);
102
+ } else {
103
+ return handleResult(res);
90
104
  }
91
105
  };
92
106
  };
@@ -6,11 +6,11 @@ export const SUBSCRIBE_SWC_APP_MESSAGE_WHILE_CONNECTED_METADATA_KEY = Symbol.for
6
6
  export interface SwcAppMessageSubscriberMetadata {
7
7
  propertyKey: string | symbol;
8
8
  messageType?: string;
9
- filter?: (message: SwcAppMessage) => boolean;
9
+ filter?: (message: SwcAppMessage, currentThis: any) => boolean;
10
10
  }
11
11
 
12
12
  export interface SwcAppMessageOptions {
13
- filter?: (message: SwcAppMessage) => boolean;
13
+ filter?: (message: SwcAppMessage, currentThis: any) => boolean;
14
14
  }
15
15
 
16
16
  function createSubscribeSwcAppMessageWhileConnected(options?: SwcAppMessageOptions, messageType?: string): MethodDecorator {