@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.
- 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/setProperty.js +50 -39
- package/dist/cjs/decorators/setProperty.js.map +2 -2
- package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js.map +1 -1
- package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +1 -1
- package/dist/cjs/elements/SwcAppEngine.js +7 -7
- package/dist/cjs/elements/SwcAppEngine.js.map +3 -3
- package/dist/cjs/elements/SwcAppMixin.js +60 -42
- 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/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/setProperty.js +50 -39
- package/dist/esm/decorators/setProperty.js.map +2 -2
- package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js.map +1 -1
- package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +1 -1
- package/dist/esm/elements/SwcAppEngine.js +6 -6
- package/dist/esm/elements/SwcAppEngine.js.map +2 -2
- package/dist/esm/elements/SwcAppMixin.js +60 -42
- 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/utils/Utils.js +7 -3
- package/dist/esm/utils/Utils.js.map +2 -2
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +425 -335
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +3 -3
- 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 -1
- 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/setProperty.d.ts +5 -1
- package/dist/types/decorators/setProperty.d.ts.map +1 -1
- package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts +2 -2
- package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts.map +1 -1
- package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +2 -2
- package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +1 -1
- 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 +5 -3
- package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
- package/dist/types/elements/register.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 +425 -335
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +3 -3
- package/package.json +3 -3
- 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 -20
- package/src/decorators/emitCustomEvent.ts +65 -49
- package/src/decorators/setProperty.ts +58 -44
- package/src/decorators/subscribeSwcAppMessageWhileConnected.ts +2 -2
- package/src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts +2 -2
- package/src/elements/SwcAppEngine.ts +11 -12
- package/src/elements/SwcAppMixin.ts +76 -44
- package/src/elements/SwcChoose.ts +28 -7
- package/src/elements/register.ts +28 -7
- 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
|
-
|
|
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,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
|
|
130
|
-
const win: Window = configWindow
|
|
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
|
-
|
|
321
|
-
|
|
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
|
-
|
|
344
|
-
|
|
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:
|
|
590
|
+
script: script,
|
|
577
591
|
context: this,
|
|
578
|
-
args:
|
|
592
|
+
args: helperAndHostSet
|
|
579
593
|
});
|
|
580
|
-
|
|
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}
|
|
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
|
|
601
|
-
if (
|
|
602
|
-
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
|
+
}
|
|
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 =
|
|
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
|
}
|
|
@@ -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 =
|
|
42
|
+
descriptor.value = function (...args: any[]) {
|
|
42
43
|
ensureInit(this);
|
|
43
|
-
const res =
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
|
|
74
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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 {
|