@dooboostore/simple-web-component 1.0.32 → 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.
- package/README.md +280 -43
- package/dist/cjs/decorators/addEventListener.js.map +1 -1
- package/dist/cjs/decorators/applyAttribute.js +67 -57
- package/dist/cjs/decorators/applyAttribute.js.map +2 -2
- package/dist/cjs/decorators/applyClass.js +80 -70
- package/dist/cjs/decorators/applyClass.js.map +2 -2
- package/dist/cjs/decorators/applyNode.js +1 -8
- package/dist/cjs/decorators/applyNode.js.map +2 -2
- package/dist/cjs/decorators/applyStyle.js +66 -56
- package/dist/cjs/decorators/applyStyle.js.map +2 -2
- package/dist/cjs/decorators/attribute.js +35 -29
- package/dist/cjs/decorators/attribute.js.map +2 -2
- package/dist/cjs/decorators/changedAttributeHost.js +32 -12
- package/dist/cjs/decorators/changedAttributeHost.js.map +2 -2
- package/dist/cjs/decorators/elementDefine.js +29 -16
- package/dist/cjs/decorators/elementDefine.js.map +2 -2
- package/dist/cjs/decorators/emitCustomEvent.js +57 -44
- package/dist/cjs/decorators/emitCustomEvent.js.map +2 -2
- package/dist/cjs/decorators/index.js +3 -1
- package/dist/cjs/decorators/index.js.map +2 -2
- package/dist/cjs/decorators/publishSwcAppMessage.js +86 -0
- package/dist/cjs/decorators/publishSwcAppMessage.js.map +7 -0
- package/dist/cjs/decorators/setProperty.js +50 -39
- package/dist/cjs/decorators/setProperty.js.map +2 -2
- package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js +62 -0
- package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js.map +7 -0
- package/dist/cjs/decorators/{subscribeSwcAppRouteChange.js → subscribeSwcAppRouteChangeWhileConnected.js} +16 -16
- package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +7 -0
- package/dist/cjs/elements/SwcAppEngine.js +7 -7
- package/dist/cjs/elements/SwcAppEngine.js.map +3 -3
- package/dist/cjs/elements/SwcAppMixin.js +90 -43
- package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
- package/dist/cjs/elements/SwcChoose.js +19 -15
- package/dist/cjs/elements/SwcChoose.js.map +2 -2
- package/dist/cjs/elements/register.js +21 -16
- package/dist/cjs/elements/register.js.map +2 -2
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/utils/Utils.js +7 -3
- package/dist/cjs/utils/Utils.js.map +2 -2
- package/dist/esm/decorators/addEventListener.js.map +1 -1
- package/dist/esm/decorators/applyAttribute.js +67 -57
- package/dist/esm/decorators/applyAttribute.js.map +2 -2
- package/dist/esm/decorators/applyClass.js +80 -70
- package/dist/esm/decorators/applyClass.js.map +2 -2
- package/dist/esm/decorators/applyNode.js +1 -8
- package/dist/esm/decorators/applyNode.js.map +2 -2
- package/dist/esm/decorators/applyStyle.js +66 -56
- package/dist/esm/decorators/applyStyle.js.map +2 -2
- package/dist/esm/decorators/attribute.js +35 -29
- package/dist/esm/decorators/attribute.js.map +2 -2
- package/dist/esm/decorators/changedAttributeHost.js +32 -12
- package/dist/esm/decorators/changedAttributeHost.js.map +2 -2
- package/dist/esm/decorators/elementDefine.js +30 -17
- package/dist/esm/decorators/elementDefine.js.map +2 -2
- package/dist/esm/decorators/emitCustomEvent.js +57 -44
- package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
- package/dist/esm/decorators/index.js +3 -1
- package/dist/esm/decorators/index.js.map +2 -2
- package/dist/esm/decorators/publishSwcAppMessage.js +67 -0
- package/dist/esm/decorators/publishSwcAppMessage.js.map +7 -0
- package/dist/esm/decorators/setProperty.js +50 -39
- package/dist/esm/decorators/setProperty.js.map +2 -2
- package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js +43 -0
- package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js.map +7 -0
- package/dist/esm/decorators/{subscribeSwcAppRouteChange.js → subscribeSwcAppRouteChangeWhileConnected.js} +13 -13
- package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +7 -0
- package/dist/esm/elements/SwcAppEngine.js +6 -6
- package/dist/esm/elements/SwcAppEngine.js.map +2 -2
- package/dist/esm/elements/SwcAppMixin.js +90 -43
- package/dist/esm/elements/SwcAppMixin.js.map +2 -2
- package/dist/esm/elements/SwcChoose.js +20 -16
- package/dist/esm/elements/SwcChoose.js.map +2 -2
- package/dist/esm/elements/register.js +22 -17
- package/dist/esm/elements/register.js.map +2 -2
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils/Utils.js +7 -3
- package/dist/esm/utils/Utils.js.map +2 -2
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +543 -348
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
- package/dist/types/decorators/addEventListener.d.ts +4 -1
- package/dist/types/decorators/addEventListener.d.ts.map +1 -1
- package/dist/types/decorators/applyAttribute.d.ts +5 -1
- package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
- package/dist/types/decorators/applyClass.d.ts +4 -0
- package/dist/types/decorators/applyClass.d.ts.map +1 -1
- package/dist/types/decorators/applyNode.d.ts +4 -1
- package/dist/types/decorators/applyNode.d.ts.map +1 -1
- package/dist/types/decorators/applyStyle.d.ts +5 -1
- package/dist/types/decorators/applyStyle.d.ts.map +1 -1
- package/dist/types/decorators/attribute.d.ts +5 -0
- package/dist/types/decorators/attribute.d.ts.map +1 -1
- package/dist/types/decorators/changedAttributeHost.d.ts +13 -3
- package/dist/types/decorators/changedAttributeHost.d.ts.map +1 -1
- package/dist/types/decorators/elementDefine.d.ts +1 -0
- package/dist/types/decorators/elementDefine.d.ts.map +1 -1
- package/dist/types/decorators/emitCustomEvent.d.ts +5 -1
- package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
- package/dist/types/decorators/index.d.ts +3 -1
- package/dist/types/decorators/index.d.ts.map +1 -1
- package/dist/types/decorators/publishSwcAppMessage.d.ts +13 -0
- package/dist/types/decorators/publishSwcAppMessage.d.ts.map +1 -0
- package/dist/types/decorators/setProperty.d.ts +5 -1
- package/dist/types/decorators/setProperty.d.ts.map +1 -1
- package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts +16 -0
- package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts.map +1 -0
- package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +18 -0
- package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +1 -0
- package/dist/types/elements/SwcAppEngine.d.ts +6 -3
- package/dist/types/elements/SwcAppEngine.d.ts.map +1 -1
- package/dist/types/elements/SwcAppMixin.d.ts +8 -3
- package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
- package/dist/types/elements/register.d.ts.map +1 -1
- package/dist/types/types.d.ts +6 -0
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils/Utils.d.ts.map +1 -1
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +543 -348
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
- package/package.json +4 -4
- package/src/decorators/addEventListener.ts +1 -1
- package/src/decorators/applyAttribute.ts +74 -61
- package/src/decorators/applyClass.ts +91 -77
- package/src/decorators/applyNode.ts +3 -12
- package/src/decorators/applyStyle.ts +75 -61
- package/src/decorators/attribute.ts +55 -43
- package/src/decorators/changedAttributeHost.ts +47 -14
- package/src/decorators/elementDefine.ts +38 -19
- package/src/decorators/emitCustomEvent.ts +65 -49
- package/src/decorators/index.ts +3 -1
- package/src/decorators/publishSwcAppMessage.ts +100 -0
- package/src/decorators/setProperty.ts +58 -44
- package/src/decorators/subscribeSwcAppMessageWhileConnected.ts +73 -0
- package/src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts +71 -0
- package/src/elements/SwcAppEngine.ts +11 -12
- package/src/elements/SwcAppMixin.ts +115 -44
- package/src/elements/SwcChoose.ts +28 -7
- package/src/elements/register.ts +28 -7
- package/src/types.ts +8 -0
- package/src/utils/Utils.ts +15 -5
- package/dist/cjs/decorators/subscribeSwcAppRouteChange.js.map +0 -7
- package/dist/esm/decorators/subscribeSwcAppRouteChange.js.map +0 -7
- package/dist/types/decorators/subscribeSwcAppRouteChange.d.ts +0 -18
- package/dist/types/decorators/subscribeSwcAppRouteChange.d.ts.map +0 -1
- package/src/decorators/subscribeSwcAppRouteChange.ts +0 -71
|
@@ -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
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
|
152
|
-
return
|
|
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
|
-
|
|
174
|
-
|
|
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
|
|
13
|
-
if (!
|
|
14
|
-
|
|
15
|
-
ReflectUtils.defineMetadata(ON_ATTRIBUTE_CHANGED_METADATA_KEY,
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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):
|
|
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,
|
|
34
|
-
|
|
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,6 +22,7 @@ export interface ElementConfig {
|
|
|
22
22
|
observedAttributes?: string[];
|
|
23
23
|
customElementRegistry?: any;
|
|
24
24
|
window?: Window;
|
|
25
|
+
useShadow?: boolean | 'open' | 'closed';
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
export interface ElementMetadata extends Omit<ElementConfig, 'window'> {
|
|
@@ -125,8 +126,8 @@ const handleGlobalSwcEvent = async (event: Event) => {
|
|
|
125
126
|
}
|
|
126
127
|
};
|
|
127
128
|
|
|
128
|
-
function buildEnv(configWindow
|
|
129
|
-
const win: Window = configWindow
|
|
129
|
+
function buildEnv(configWindow: Window) {
|
|
130
|
+
const win: Window = configWindow;
|
|
130
131
|
const doc: Document = win?.document;
|
|
131
132
|
const builtInTagMap = new Map<any, string>();
|
|
132
133
|
for (const [cls, tag] of HTML_TAG_ENTRIES) {
|
|
@@ -170,7 +171,7 @@ const setupPrototype = (proto: any) => {
|
|
|
170
171
|
const aConf = getElementConfig(ancestors[i]);
|
|
171
172
|
if (aConf?.window) return aConf.window;
|
|
172
173
|
}
|
|
173
|
-
return (typeof window !== 'undefined' ? window : undefined) as Window;
|
|
174
|
+
return getElementConfig(this).window ?? (typeof window !== 'undefined' ? window : undefined) as Window;
|
|
174
175
|
};
|
|
175
176
|
|
|
176
177
|
proto._invokeLifecycleMethod = function (methodName: string | symbol, hostSet?: HostSet, extraArgs: any[] = []) {
|
|
@@ -292,8 +293,15 @@ export const elementDefine =
|
|
|
292
293
|
// const attributeListNames = attributeList.map(it => it.options.name || String(it.propertyKey));
|
|
293
294
|
const hostAttributes = attributeList.filter(it => it.selector === ':host').map(it=>it.options.name || String(it.propertyKey));
|
|
294
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??[];
|
|
295
302
|
const mergedObservedAttributes = [...new Set([
|
|
296
303
|
...(metadata.observedAttributes ?? []),
|
|
304
|
+
...originalStaticObservedAttributes,
|
|
297
305
|
...attrChangeMap.keys(),
|
|
298
306
|
...attributeApplyNames,
|
|
299
307
|
...hostAttributes,
|
|
@@ -304,7 +312,6 @@ export const elementDefine =
|
|
|
304
312
|
|
|
305
313
|
const connectedInnerHtmlList = getOnConnectedInnerHtmlMetadata(constructor) || [];
|
|
306
314
|
|
|
307
|
-
const proto = constructor.prototype;
|
|
308
315
|
setupPrototype(proto);
|
|
309
316
|
|
|
310
317
|
const originalConnected = proto.connectedCallback;
|
|
@@ -316,8 +323,10 @@ export const elementDefine =
|
|
|
316
323
|
const conf = getElementConfig(this);
|
|
317
324
|
const currentWin = (this as any)._resolveWindow(conf);
|
|
318
325
|
|
|
319
|
-
|
|
320
|
-
|
|
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 });
|
|
321
330
|
}
|
|
322
331
|
|
|
323
332
|
(this as any)._executeSwcScript('swc-on-before-connected', hostSet);
|
|
@@ -335,12 +344,16 @@ export const elementDefine =
|
|
|
335
344
|
// console.log('------res0', res);
|
|
336
345
|
// console.log('------res1', res1);
|
|
337
346
|
if (res !== undefined) {
|
|
338
|
-
if (meta.options.useShadow) sContent += res;
|
|
347
|
+
if (meta.options.useShadow || conf?.useShadow) sContent += res;
|
|
339
348
|
else lContent += res;
|
|
340
349
|
}
|
|
341
350
|
}
|
|
342
|
-
|
|
343
|
-
|
|
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
|
+
}
|
|
344
357
|
}
|
|
345
358
|
|
|
346
359
|
const root = this.getRootNode();
|
|
@@ -467,7 +480,7 @@ export const elementDefine =
|
|
|
467
480
|
// Apply filter if specified
|
|
468
481
|
if (options.filter) {
|
|
469
482
|
const helper = SwcUtils.getHelperAndHostSet(currentWin, t as HTMLElement);
|
|
470
|
-
if (!options.filter(event, helper)) {
|
|
483
|
+
if (!options.filter(event, {currentThis: this,helper})) {
|
|
471
484
|
return; // Skip if filter returns false
|
|
472
485
|
}
|
|
473
486
|
}
|
|
@@ -564,21 +577,24 @@ export const elementDefine =
|
|
|
564
577
|
const hSet = SwcUtils.getHostSet(this as any);
|
|
565
578
|
|
|
566
579
|
// Process expression directive before passing to handlers
|
|
567
|
-
let processedVal = newVal;
|
|
580
|
+
let processedVal: any = newVal;
|
|
568
581
|
if (newVal !== null) {
|
|
569
582
|
const ae = new ActionExpression(newVal);
|
|
570
583
|
const expr = ae.getFirstExpression('call-return');
|
|
571
584
|
if (expr) {
|
|
572
585
|
const win = (this as any)._resolveWindow?.() || ((typeof window !== 'undefined' ? window : undefined) as any);
|
|
586
|
+
const helperAndHostSet = SwcUtils.getHelperAndHostSet(win,this as any);
|
|
573
587
|
try {
|
|
588
|
+
const script = ConvertUtils.decodeHtmlEntity(expr.script, win.document);
|
|
574
589
|
const result = FunctionUtils.executeReturn({
|
|
575
|
-
script:
|
|
590
|
+
script: script,
|
|
576
591
|
context: this,
|
|
577
|
-
args:
|
|
592
|
+
args: helperAndHostSet
|
|
578
593
|
});
|
|
579
|
-
|
|
594
|
+
// Pass the result object directly without serialization
|
|
595
|
+
processedVal = result;
|
|
580
596
|
} catch (e) {
|
|
581
|
-
console.error(`[SWC] Failed to execute directive {{= ${expr.script} }} on attribute ${name}
|
|
597
|
+
console.error(`[SWC] Failed to execute directive {{= ${expr.script} }} on attribute ${name}: ${helperAndHostSet}`, e);
|
|
582
598
|
processedVal = newVal;
|
|
583
599
|
}
|
|
584
600
|
}
|
|
@@ -596,9 +612,12 @@ export const elementDefine =
|
|
|
596
612
|
(this as any)._bindAttributeEvent(this as any, name, newVal, hostCustomEventMeta.type);
|
|
597
613
|
}
|
|
598
614
|
|
|
599
|
-
const
|
|
600
|
-
if (
|
|
601
|
-
for (const
|
|
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
|
+
}
|
|
602
621
|
}
|
|
603
622
|
};
|
|
604
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 =
|
|
43
|
+
descriptor.value = function (...args: any[]) {
|
|
43
44
|
ensureInit(this);
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (
|
|
62
|
-
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
if (
|
|
66
|
-
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
searchRoots.push(this
|
|
85
|
-
if (
|
|
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
|
-
|
|
89
|
-
|
|
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
|
-
|
|
94
|
-
|
|
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
|
}
|
package/src/decorators/index.ts
CHANGED
|
@@ -11,4 +11,6 @@ export * from './applyClass';
|
|
|
11
11
|
export * from './applyStyle';
|
|
12
12
|
export * from './applyAttribute';
|
|
13
13
|
export * from './setProperty';
|
|
14
|
-
export * from './
|
|
14
|
+
export * from './subscribeSwcAppRouteChangeWhileConnected';
|
|
15
|
+
export * from './subscribeSwcAppMessageWhileConnected';
|
|
16
|
+
export * from './publishSwcAppMessage';
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { ReflectUtils } from '@dooboostore/core';
|
|
2
|
+
import { SwcAppMessage } from '../types';
|
|
3
|
+
import { SwcUtils } from '../utils/Utils';
|
|
4
|
+
|
|
5
|
+
export const PUBLISH_SWC_APP_MESSAGE_METADATA_KEY = Symbol.for('simple-web-component:publish-swc-app-message');
|
|
6
|
+
|
|
7
|
+
export interface PublishSwcAppMessageMetadata {
|
|
8
|
+
propertyKey: string | symbol;
|
|
9
|
+
messageType?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface PublishSwcAppMessageOptions {
|
|
13
|
+
messageType?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function createPublishSwcAppMessage(messageType?: string): MethodDecorator {
|
|
17
|
+
return (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => {
|
|
18
|
+
const constructor = target.constructor;
|
|
19
|
+
let list = ReflectUtils.getOwnMetadata(PUBLISH_SWC_APP_MESSAGE_METADATA_KEY, constructor) as PublishSwcAppMessageMetadata[];
|
|
20
|
+
if (!list) {
|
|
21
|
+
list = [];
|
|
22
|
+
ReflectUtils.defineMetadata(PUBLISH_SWC_APP_MESSAGE_METADATA_KEY, list, constructor);
|
|
23
|
+
}
|
|
24
|
+
list.push({ propertyKey, messageType });
|
|
25
|
+
|
|
26
|
+
if (!descriptor) {
|
|
27
|
+
return descriptor;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 메서드 래핑 - 원본 메서드의 반환값을 캡처하여 메시지 발행
|
|
31
|
+
const originalMethod = descriptor.value;
|
|
32
|
+
descriptor.value = function (...args: any[]) {
|
|
33
|
+
// 원본 메서드 실행
|
|
34
|
+
const result = originalMethod.apply(this, args);
|
|
35
|
+
|
|
36
|
+
// Promise 체크
|
|
37
|
+
if (result instanceof Promise) {
|
|
38
|
+
result.then((data) => {
|
|
39
|
+
// appHost 찾아서 메시지 발행
|
|
40
|
+
const appHost = SwcUtils.getAppHost(this as HTMLElement);
|
|
41
|
+
if (appHost) {
|
|
42
|
+
appHost.publishMessage({
|
|
43
|
+
publisher: this,
|
|
44
|
+
data,
|
|
45
|
+
type: messageType
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}).catch((err) => {
|
|
49
|
+
console.warn('publishSwcAppMessage async error:', err);
|
|
50
|
+
});
|
|
51
|
+
} else {
|
|
52
|
+
// 동기 호출 - 바로 메시지 발행
|
|
53
|
+
const appHost = SwcUtils.getAppHost(this as HTMLElement);
|
|
54
|
+
if (appHost) {
|
|
55
|
+
appHost.publishMessage({
|
|
56
|
+
publisher: this,
|
|
57
|
+
data: result,
|
|
58
|
+
type: messageType
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return result;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
return descriptor;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 오버로드 시그니처 - 직접 사용 (괄호 없음)
|
|
71
|
+
export function publishSwcAppMessage(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
|
|
72
|
+
// 오버로드 시그니처 - 함수 호출 (괄호 있음)
|
|
73
|
+
export function publishSwcAppMessage(): MethodDecorator;
|
|
74
|
+
export function publishSwcAppMessage(messageType: string): MethodDecorator;
|
|
75
|
+
|
|
76
|
+
export function publishSwcAppMessage(targetOrMessageType?: any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): any {
|
|
77
|
+
// 직접 데코레이터로 사용된 경우 (괄호 없음): @publishSwcAppMessage
|
|
78
|
+
if (targetOrMessageType && typeof targetOrMessageType === 'object' &&
|
|
79
|
+
propertyKey && (typeof propertyKey === 'string' || typeof propertyKey === 'symbol') &&
|
|
80
|
+
descriptor) {
|
|
81
|
+
const target = targetOrMessageType;
|
|
82
|
+
return createPublishSwcAppMessage()(target, propertyKey, descriptor);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 함수로 호출된 경우 (괄호 있음): @publishSwcAppMessage() / @publishSwcAppMessage('messageType')
|
|
86
|
+
let messageType: string | undefined;
|
|
87
|
+
|
|
88
|
+
if (typeof targetOrMessageType === 'string') {
|
|
89
|
+
// 메시지 타입 전달: @publishSwcAppMessage('messageType')
|
|
90
|
+
messageType = targetOrMessageType;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return createPublishSwcAppMessage(messageType);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Helper function to retrieve publish message metadata
|
|
97
|
+
export const getPublishSwcAppMessageMetadata = (target: any): PublishSwcAppMessageMetadata[] | undefined => {
|
|
98
|
+
const constructor = target instanceof Function ? target : target.constructor;
|
|
99
|
+
return ReflectUtils.getOwnMetadata(PUBLISH_SWC_APP_MESSAGE_METADATA_KEY, constructor);
|
|
100
|
+
};
|