@dooboostore/simple-web-component 1.0.43 → 1.0.45
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 +312 -63
- package/dist/cjs/SwcAppEngine.js +3 -1
- package/dist/cjs/SwcAppEngine.js.map +2 -2
- package/dist/cjs/decorators/addEventListener.js.map +2 -2
- package/dist/cjs/decorators/applyAttribute.js +66 -43
- package/dist/cjs/decorators/applyAttribute.js.map +2 -2
- package/dist/cjs/decorators/applyClass.js +110 -43
- package/dist/cjs/decorators/applyClass.js.map +3 -3
- package/dist/cjs/decorators/applyNode.js +200 -112
- package/dist/cjs/decorators/applyNode.js.map +2 -2
- package/dist/cjs/decorators/applyProperty.js +49 -45
- package/dist/cjs/decorators/applyProperty.js.map +2 -2
- package/dist/cjs/decorators/applyStyle.js +92 -37
- package/dist/cjs/decorators/applyStyle.js.map +3 -3
- package/dist/cjs/decorators/{changedAttributeThis.js → changedAttribute.js} +6 -6
- package/dist/cjs/decorators/changedAttribute.js.map +7 -0
- package/dist/cjs/decorators/elementDefine.js +81 -31
- package/dist/cjs/decorators/elementDefine.js.map +3 -3
- package/dist/cjs/decorators/emitCustomEvent.js +80 -52
- package/dist/cjs/decorators/emitCustomEvent.js.map +2 -2
- package/dist/cjs/decorators/index.js +1 -1
- package/dist/cjs/decorators/index.js.map +2 -2
- package/dist/cjs/decorators/publishSwcAppMessage.js +5 -5
- package/dist/cjs/decorators/publishSwcAppMessage.js.map +3 -3
- package/dist/cjs/decorators/query.js +133 -147
- package/dist/cjs/decorators/query.js.map +3 -3
- package/dist/cjs/decorators/queryAll.js +143 -132
- package/dist/cjs/decorators/queryAll.js.map +3 -3
- package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js +2 -0
- package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js.map +2 -2
- package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js +2 -0
- package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +2 -2
- package/dist/cjs/elements/SwcAppMixin.js +17 -2
- package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
- package/dist/cjs/examples/RxJSOperatorsExample.js +285 -0
- package/dist/cjs/examples/RxJSOperatorsExample.js.map +7 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/router/ElementRouter.js +4 -0
- package/dist/cjs/router/ElementRouter.js.map +2 -2
- package/dist/cjs/types/window.d.js.map +1 -1
- package/dist/esm/SwcAppEngine.js +3 -1
- package/dist/esm/SwcAppEngine.js.map +2 -2
- package/dist/esm/decorators/addEventListener.js.map +2 -2
- package/dist/esm/decorators/applyAttribute.js +66 -43
- package/dist/esm/decorators/applyAttribute.js.map +2 -2
- package/dist/esm/decorators/applyClass.js +110 -43
- package/dist/esm/decorators/applyClass.js.map +3 -3
- package/dist/esm/decorators/applyNode.js +200 -112
- package/dist/esm/decorators/applyNode.js.map +2 -2
- package/dist/esm/decorators/applyProperty.js +49 -45
- package/dist/esm/decorators/applyProperty.js.map +2 -2
- package/dist/esm/decorators/applyStyle.js +92 -37
- package/dist/esm/decorators/applyStyle.js.map +3 -3
- package/dist/esm/decorators/{changedAttributeThis.js → changedAttribute.js} +3 -3
- package/dist/esm/decorators/changedAttribute.js.map +7 -0
- package/dist/esm/decorators/elementDefine.js +79 -29
- package/dist/esm/decorators/elementDefine.js.map +2 -2
- package/dist/esm/decorators/emitCustomEvent.js +80 -52
- package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
- package/dist/esm/decorators/index.js +1 -1
- package/dist/esm/decorators/index.js.map +1 -1
- package/dist/esm/decorators/publishSwcAppMessage.js +5 -5
- package/dist/esm/decorators/publishSwcAppMessage.js.map +3 -3
- package/dist/esm/decorators/query.js +133 -147
- package/dist/esm/decorators/query.js.map +3 -3
- package/dist/esm/decorators/queryAll.js +143 -132
- package/dist/esm/decorators/queryAll.js.map +3 -3
- package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js +2 -0
- package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js.map +2 -2
- package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js +2 -0
- package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +2 -2
- package/dist/esm/elements/SwcAppMixin.js +18 -3
- package/dist/esm/elements/SwcAppMixin.js.map +2 -2
- package/dist/esm/examples/RxJSOperatorsExample.js +266 -0
- package/dist/esm/examples/RxJSOperatorsExample.js.map +7 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +2 -2
- package/dist/esm/router/ElementRouter.js +4 -0
- package/dist/esm/router/ElementRouter.js.map +2 -2
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +1118 -633
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
- package/dist/types/SwcAppEngine.d.ts.map +1 -1
- package/dist/types/decorators/addEventListener.d.ts +19 -15
- package/dist/types/decorators/addEventListener.d.ts.map +1 -1
- package/dist/types/decorators/applyAttribute.d.ts +45 -26
- package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
- package/dist/types/decorators/applyClass.d.ts +19 -38
- package/dist/types/decorators/applyClass.d.ts.map +1 -1
- package/dist/types/decorators/applyNode.d.ts +175 -32
- package/dist/types/decorators/applyNode.d.ts.map +1 -1
- package/dist/types/decorators/applyProperty.d.ts +38 -25
- package/dist/types/decorators/applyProperty.d.ts.map +1 -1
- package/dist/types/decorators/applyStyle.d.ts +10 -9
- package/dist/types/decorators/applyStyle.d.ts.map +1 -1
- package/dist/types/decorators/{changedAttributeThis.d.ts → changedAttribute.d.ts} +2 -2
- package/dist/types/decorators/changedAttribute.d.ts.map +1 -0
- package/dist/types/decorators/elementDefine.d.ts.map +1 -1
- package/dist/types/decorators/emitCustomEvent.d.ts +6 -12
- package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
- package/dist/types/decorators/index.d.ts +1 -1
- package/dist/types/decorators/index.d.ts.map +1 -1
- package/dist/types/decorators/publishSwcAppMessage.d.ts +1 -1
- package/dist/types/decorators/publishSwcAppMessage.d.ts.map +1 -1
- package/dist/types/decorators/query.d.ts +16 -29
- package/dist/types/decorators/query.d.ts.map +1 -1
- package/dist/types/decorators/queryAll.d.ts +16 -23
- package/dist/types/decorators/queryAll.d.ts.map +1 -1
- package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts +1 -0
- package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts.map +1 -1
- package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +2 -0
- package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +1 -1
- package/dist/types/elements/SwcAppMixin.d.ts +4 -4
- package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
- package/dist/types/examples/RxJSOperatorsExample.d.ts +94 -0
- package/dist/types/examples/RxJSOperatorsExample.d.ts.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/router/ElementRouter.d.ts.map +1 -1
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +1118 -633
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
- package/package.json +1 -1
- package/src/SwcAppEngine.ts +3 -1
- package/src/decorators/addEventListener.ts +31 -25
- package/src/decorators/applyAttribute.ts +164 -86
- package/src/decorators/applyClass.ts +161 -41
- package/src/decorators/applyNode.ts +408 -108
- package/src/decorators/applyProperty.ts +100 -89
- package/src/decorators/applyStyle.ts +131 -37
- package/src/decorators/{changedAttributeThis.ts → changedAttribute.ts} +1 -1
- package/src/decorators/elementDefine.ts +96 -30
- package/src/decorators/emitCustomEvent.ts +92 -60
- package/src/decorators/index.ts +1 -1
- package/src/decorators/publishSwcAppMessage.ts +1 -1
- package/src/decorators/query.ts +155 -162
- package/src/decorators/queryAll.ts +157 -139
- package/src/decorators/subscribeSwcAppMessageWhileConnected.ts +1 -0
- package/src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts +3 -1
- package/src/elements/SwcAppMixin.ts +43 -24
- package/src/examples/RxJSOperatorsExample.ts +279 -0
- package/src/index.ts +2 -0
- package/src/router/ElementRouter.ts +4 -0
- package/src/types/window.d.ts +3 -0
- package/dist/cjs/decorators/changedAttributeThis.js.map +0 -7
- package/dist/esm/decorators/changedAttributeThis.js.map +0 -7
- package/dist/types/decorators/changedAttributeThis.d.ts.map +0 -1
|
@@ -1,165 +1,183 @@
|
|
|
1
1
|
import { ReflectUtils } from '@dooboostore/core';
|
|
2
2
|
import { getElementConfig, ensureInit } from './elementDefine';
|
|
3
3
|
import { SwcUtils } from '../utils/Utils';
|
|
4
|
-
import {
|
|
4
|
+
import { SwcQueryOptions, HelperHostSet } from '../types';
|
|
5
|
+
|
|
6
|
+
export interface QueryAllOptions extends SwcQueryOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Filter function to determine whether to include the element.
|
|
9
|
+
* If it returns false, the element is skipped.
|
|
10
|
+
*/
|
|
11
|
+
filter?: (target: HTMLElement, meta: { currentThis: any, helper: HelperHostSet }) => boolean;
|
|
12
|
+
}
|
|
5
13
|
|
|
6
14
|
export interface QueryAllMetadata {
|
|
7
15
|
propertyKey: string | symbol;
|
|
8
|
-
selector: string;
|
|
9
|
-
options:
|
|
16
|
+
selector: string | ((currentThis: any, helper: HelperHostSet) => NodeList | Element | Element[] | null);
|
|
17
|
+
options: QueryAllOptions;
|
|
10
18
|
}
|
|
11
19
|
|
|
12
20
|
export const QUERY_ALL_METADATA_KEY = Symbol.for('simple-web-component:query-all');
|
|
13
21
|
|
|
14
|
-
export function queryAll(target:
|
|
15
|
-
export function queryAll(selector: string, options?:
|
|
22
|
+
export function queryAll(target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor): PropertyDescriptor | void;
|
|
23
|
+
export function queryAll(selector: string | ((currentThis: any, helper: HelperHostSet) => NodeList | Element | Element[] | null), options?: QueryAllOptions): PropertyDecorator;
|
|
24
|
+
export function queryAll(options?: QueryAllOptions): PropertyDecorator;
|
|
16
25
|
/**
|
|
17
26
|
* @queryAll decorator to inject a list of elements into a class property.
|
|
27
|
+
*
|
|
28
|
+
* Supports both string selectors and function-based selectors:
|
|
29
|
+
* - String selector: @queryAll('.item')
|
|
30
|
+
* - Function selector: @queryAll((currentThis, helper) => currentThis.shadowRoot?.querySelectorAll('.item'))
|
|
31
|
+
*
|
|
32
|
+
* Supports filtering:
|
|
33
|
+
* - @queryAll('.item', { filter: (target, meta) => target.hasAttribute('active') })
|
|
18
34
|
*/
|
|
19
|
-
export function queryAll(selectorOrTarget
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
queries.push({ propertyKey, selector: selectorOrTarget, options });
|
|
35
|
+
export function queryAll(selectorOrTarget?: string | ((currentThis: any, helper: HelperHostSet) => NodeList | Element | Element[] | null) | Object, optionsOrPropertyKey?: QueryAllOptions | string | symbol, descriptor?: PropertyDescriptor): any {
|
|
36
|
+
// Bare decorator: @queryAll
|
|
37
|
+
if (descriptor !== undefined && (typeof optionsOrPropertyKey === 'string' || typeof optionsOrPropertyKey === 'symbol')) {
|
|
38
|
+
throw new Error(`@queryAll decorator cannot be used on methods. (Method: ${String(optionsOrPropertyKey)})`);
|
|
39
|
+
}
|
|
40
|
+
// With selector
|
|
41
|
+
if (typeof selectorOrTarget === 'string' || typeof selectorOrTarget === 'function') {
|
|
42
|
+
return (targetObj: Object, propertyKey: string | symbol, descriptor?: never): void => {
|
|
43
|
+
if (descriptor !== undefined) {
|
|
44
|
+
throw new Error(`@queryAll decorator cannot be used on methods. (Method: ${String(propertyKey)})`);
|
|
45
|
+
}
|
|
32
46
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
47
|
+
const constructor = targetObj.constructor;
|
|
48
|
+
let queries = ReflectUtils.getMetadata<QueryAllMetadata[]>(QUERY_ALL_METADATA_KEY, constructor);
|
|
49
|
+
if (!queries) {
|
|
50
|
+
queries = [];
|
|
51
|
+
ReflectUtils.defineMetadata(QUERY_ALL_METADATA_KEY, queries, constructor);
|
|
52
|
+
}
|
|
53
|
+
queries.push({ propertyKey, selector: selectorOrTarget as any, options: optionsOrPropertyKey as QueryAllOptions || {} });
|
|
37
54
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
55
|
+
Object.defineProperty(targetObj, propertyKey, {
|
|
56
|
+
get(this: HTMLElement) {
|
|
57
|
+
ensureInit(this);
|
|
58
|
+
const config = getElementConfig(this);
|
|
59
|
+
const win = config?.window || window;
|
|
60
|
+
const hostSet = SwcUtils.getHelperAndHostSet(win, this);
|
|
61
|
+
|
|
62
|
+
// Resolve selector - can be string or function
|
|
63
|
+
let resolvedSelector: string;
|
|
64
|
+
let resolvedElements: HTMLElement[] = [];
|
|
65
|
+
|
|
66
|
+
if (typeof selectorOrTarget === 'function') {
|
|
67
|
+
const result = (selectorOrTarget as any)(this, hostSet);
|
|
68
|
+
// If function returns NodeList or Element[], convert to array
|
|
69
|
+
if (result instanceof win.NodeList) {
|
|
70
|
+
resolvedElements = Array.from(result).filter(el => el instanceof win.HTMLElement) as HTMLElement[];
|
|
71
|
+
} else if (Array.isArray(result)) {
|
|
72
|
+
resolvedElements = result.filter(el => el instanceof win.HTMLElement) as HTMLElement[];
|
|
47
73
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (r === 'light' || r === 'all') results.push(it);
|
|
51
|
-
if ((r === 'shadow' || r === 'all') && it.shadowRoot) results.push(it.shadowRoot);
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
return results;
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
// --- Special Selectors: HostSet ---
|
|
58
|
-
const hostSet = SwcUtils.getHostSet(this);
|
|
59
|
-
if (selector === '$hosts') return applyRoot(hostSet.$hosts);
|
|
60
|
-
if (selector === '$appHosts') return applyRoot(hostSet.$appHosts);
|
|
61
|
-
if (selector === '$host') return applyRoot(hostSet.$host);
|
|
62
|
-
if (selector === '$parentHost') return applyRoot(hostSet.$parentHost);
|
|
63
|
-
if (selector === '$appHost') return applyRoot(hostSet.$appHost);
|
|
64
|
-
if (selector === '$firstHost') return applyRoot(hostSet.$firstHost);
|
|
65
|
-
if (selector === '$lastHost') return applyRoot(hostSet.$lastHost);
|
|
66
|
-
if (selector === '$firstAppHost') return applyRoot(hostSet.$firstAppHost);
|
|
67
|
-
if (selector === '$lastAppHost') return applyRoot(hostSet.$lastAppHost);
|
|
68
|
-
|
|
69
|
-
// --- Special Selectors: Env ---
|
|
70
|
-
const config = getElementConfig(this);
|
|
71
|
-
const win = config?.window || window;
|
|
72
|
-
if (selector === '$window') return [win];
|
|
73
|
-
if (selector === '$document') return [win.document];
|
|
74
|
-
if (selector === '$this') return applyRoot(this);
|
|
74
|
+
} else {
|
|
75
|
+
resolvedSelector = selectorOrTarget;
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
77
|
+
const r = (optionsOrPropertyKey as QueryAllOptions)?.root || 'auto';
|
|
78
|
+
const applyRoot = (t: any): any[] => {
|
|
79
|
+
if (!t) return [];
|
|
80
|
+
const items = Array.isArray(t) ? t : [t];
|
|
81
|
+
const results: any[] = [];
|
|
82
|
+
items.forEach(it => {
|
|
83
|
+
if (!(it instanceof HTMLElement)) {
|
|
84
|
+
results.push(it);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (r === 'auto') results.push(it.shadowRoot || it);
|
|
88
|
+
else {
|
|
89
|
+
if (r === 'light' || r === 'all') results.push(it);
|
|
90
|
+
if ((r === 'shadow' || r === 'all') && it.shadowRoot) results.push(it.shadowRoot);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
return results;
|
|
94
|
+
};
|
|
92
95
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
96
|
+
// --- Special Selectors: HostSet ---
|
|
97
|
+
if (resolvedSelector === '$hosts') resolvedElements = applyRoot(hostSet.$hosts).filter(el => el instanceof HTMLElement);
|
|
98
|
+
else if (resolvedSelector === '$appHosts') resolvedElements = applyRoot(hostSet.$appHosts).filter(el => el instanceof HTMLElement);
|
|
99
|
+
else if (resolvedSelector === '$host') resolvedElements = applyRoot(hostSet.$host).filter(el => el instanceof HTMLElement);
|
|
100
|
+
else if (resolvedSelector === '$parentHost') resolvedElements = applyRoot(hostSet.$parentHost).filter(el => el instanceof HTMLElement);
|
|
101
|
+
else if (resolvedSelector === '$appHost') resolvedElements = applyRoot(hostSet.$appHost).filter(el => el instanceof HTMLElement);
|
|
102
|
+
else if (resolvedSelector === '$firstHost') resolvedElements = applyRoot(hostSet.$firstHost).filter(el => el instanceof HTMLElement);
|
|
103
|
+
else if (resolvedSelector === '$lastHost') resolvedElements = applyRoot(hostSet.$lastHost).filter(el => el instanceof HTMLElement);
|
|
104
|
+
else if (resolvedSelector === '$firstAppHost') resolvedElements = applyRoot(hostSet.$firstAppHost).filter(el => el instanceof HTMLElement);
|
|
105
|
+
else if (resolvedSelector === '$lastAppHost') resolvedElements = applyRoot(hostSet.$lastAppHost).filter(el => el instanceof HTMLElement);
|
|
106
|
+
// --- Special Selectors: Env ---
|
|
107
|
+
else if (resolvedSelector === '$window') return [win];
|
|
108
|
+
else if (resolvedSelector === '$document') return [win.document];
|
|
109
|
+
else if (resolvedSelector === '$this') resolvedElements = applyRoot(this).filter(el => el instanceof HTMLElement);
|
|
110
|
+
// --- Standard Selectors ---
|
|
111
|
+
else {
|
|
112
|
+
if (r === 'shadow') resolvedElements = this.shadowRoot ? (Array.from(this.shadowRoot.querySelectorAll(resolvedSelector)) as HTMLElement[]) : [];
|
|
113
|
+
else if (r === 'light') resolvedElements = Array.from(this.querySelectorAll(resolvedSelector)) as HTMLElement[];
|
|
114
|
+
else if (r === 'all') {
|
|
115
|
+
const sNodes = this.shadowRoot ? (Array.from(this.shadowRoot.querySelectorAll(resolvedSelector)) as HTMLElement[]) : [];
|
|
116
|
+
const lNodes = Array.from(this.querySelectorAll(resolvedSelector)) as HTMLElement[];
|
|
117
|
+
resolvedElements = [...sNodes, ...lNodes];
|
|
118
|
+
}
|
|
119
|
+
else resolvedElements = (Array.from((this.shadowRoot || this).querySelectorAll(resolvedSelector)) as HTMLElement[]);
|
|
120
|
+
}
|
|
103
121
|
}
|
|
104
|
-
targets.forEach(t => (t as Element).remove());
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
enumerable: true,
|
|
108
|
-
configurable: true
|
|
109
|
-
});
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
122
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if (propertyKey !== undefined && (typeof propertyKey === 'string' || typeof propertyKey === 'symbol')) {
|
|
121
|
-
return queryAll('$this', {})(targetOrOptions, propertyKey);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (typeof targetOrOptions === 'object' && targetOrOptions !== null) {
|
|
125
|
-
return queryAll('$this', targetOrOptions as SwcQueryOptions);
|
|
126
|
-
} else {
|
|
127
|
-
return queryAll('$this', {});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
123
|
+
// Apply filter if provided
|
|
124
|
+
if ((optionsOrPropertyKey as QueryAllOptions)?.filter) {
|
|
125
|
+
resolvedElements = resolvedElements.filter(el => {
|
|
126
|
+
if (!(el instanceof win.HTMLElement)) return true;
|
|
127
|
+
return (optionsOrPropertyKey as QueryAllOptions).filter!(el, { currentThis: this, helper: hostSet });
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
130
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
131
|
+
return resolvedElements;
|
|
132
|
+
},
|
|
133
|
+
set(this: HTMLElement, nv: any) {
|
|
134
|
+
ensureInit(this);
|
|
135
|
+
if (nv === null || nv === undefined || (Array.isArray(nv) && nv.length === 0)) {
|
|
136
|
+
const config = getElementConfig(this);
|
|
137
|
+
const win = config?.window || window;
|
|
138
|
+
const hostSet = SwcUtils.getHelperAndHostSet(win, this);
|
|
139
|
+
|
|
140
|
+
// Resolve selector - can be string or function
|
|
141
|
+
if (typeof selectorOrTarget === 'function') {
|
|
142
|
+
// Get elements from function and remove them
|
|
143
|
+
const result = (selectorOrTarget as any)(this, hostSet);
|
|
144
|
+
if (result instanceof win.NodeList) {
|
|
145
|
+
Array.from(result).forEach(el => {
|
|
146
|
+
if (el instanceof win.Element) (el as Element).remove();
|
|
147
|
+
});
|
|
148
|
+
} else if (Array.isArray(result)) {
|
|
149
|
+
result.forEach(el => {
|
|
150
|
+
if (el instanceof win.Element) (el as Element).remove();
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const resolvedSelector = selectorOrTarget;
|
|
157
|
+
|
|
158
|
+
if (resolvedSelector.startsWith('$') && resolvedSelector !== '$this') return;
|
|
147
159
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
const r = (optionsOrPropertyKey as SwcQueryOptions)?.root || 'auto';
|
|
161
|
+
let targets: (Element | Node)[] = [];
|
|
162
|
+
if (r === 'shadow') targets = this.shadowRoot ? Array.from(this.shadowRoot.querySelectorAll(resolvedSelector)) : [];
|
|
163
|
+
else if (r === 'light') targets = Array.from(this.querySelectorAll(resolvedSelector));
|
|
164
|
+
else if (r === 'all') {
|
|
165
|
+
const sNodes = this.shadowRoot ? Array.from(this.shadowRoot.querySelectorAll(resolvedSelector)) : [];
|
|
166
|
+
const lNodes = Array.from(this.querySelectorAll(resolvedSelector));
|
|
167
|
+
targets = [...sNodes, ...lNodes];
|
|
168
|
+
} else {
|
|
169
|
+
targets = Array.from((this.shadowRoot || this).querySelectorAll(resolvedSelector));
|
|
170
|
+
}
|
|
171
|
+
targets.forEach(t => (t as Element).remove());
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
enumerable: true,
|
|
175
|
+
configurable: true
|
|
176
|
+
});
|
|
177
|
+
};
|
|
162
178
|
}
|
|
179
|
+
// Without selector (defaults to $this)
|
|
180
|
+
return queryAll('$this', selectorOrTarget as SwcQueryOptions);
|
|
163
181
|
}
|
|
164
182
|
|
|
165
183
|
export const getQueryAllMetadata = (target: any): QueryAllMetadata[] | undefined => {
|
|
@@ -66,6 +66,7 @@ export function subscribeSwcAppMessageWhileConnected(targetOrMessageTypeOrOption
|
|
|
66
66
|
return createSubscribeSwcAppMessageWhileConnected(options, messageType);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
export const receiveMessage = subscribeSwcAppMessageWhileConnected;
|
|
69
70
|
// Helper function to retrieve message subscribers metadata
|
|
70
71
|
export const getSubscribeSwcAppMessageWhileConnectedMetadata = (target: any): SwcAppMessageSubscriberMetadata[] | undefined => {
|
|
71
72
|
const constructor = target instanceof Function ? target : target.constructor;
|
|
@@ -13,8 +13,9 @@ export interface SwcAppRouteChangeSubscriberMetadata {
|
|
|
13
13
|
|
|
14
14
|
export interface SwcAppRouteChangeOptions {
|
|
15
15
|
path?: RoutePathType;
|
|
16
|
-
filter?: (router: Router, meta: {currentThis: any
|
|
16
|
+
filter?: (router: Router, meta: { currentThis: any; helper: HelperHostSet }) => boolean;
|
|
17
17
|
order?: number;
|
|
18
|
+
valueKey?: symbol | string;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
function createSubscribeSwcAppRouteChangeWhileConnected(options?: SwcAppRouteChangeOptions): MethodDecorator {
|
|
@@ -74,6 +75,7 @@ export function subscribeSwcAppRouteChangeWhileConnected(targetOrOptions?: any,
|
|
|
74
75
|
|
|
75
76
|
return createSubscribeSwcAppRouteChangeWhileConnected(options);
|
|
76
77
|
}
|
|
78
|
+
export const changedRoute = subscribeSwcAppRouteChangeWhileConnected;
|
|
77
79
|
|
|
78
80
|
// Helper function to retrieve route change subscribers metadata
|
|
79
81
|
export const getSubscribeSwcAppRouteChangeWhileConnectedMetadata = (target: any): SwcAppRouteChangeSubscriberMetadata[] => {
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import {SwcAppInterface, SwcAppMessage} from
|
|
2
|
-
import {findAllLifecycleMetadata, getSubscribeSwcAppMessageWhileConnectedMetadata, getSubscribeSwcAppRouteChangeWhileConnectedMetadata, ON_CONNECTED_SWC_APP_METADATA_KEY} from
|
|
3
|
-
import {SwcAppEngine, SwcAttributeConfigType, SwcConfigType} from
|
|
4
|
-
import {debounceTimeIntervalLock, FunctionUtils, Subscription} from
|
|
5
|
-
import {RouterEventType} from
|
|
6
|
-
import {SwcUtils} from
|
|
1
|
+
import { SwcAppInterface, SwcAppMessage } from '../types';
|
|
2
|
+
import { APPLY_NODE_METADATA_KEY, findAllLifecycleMetadata, getSubscribeSwcAppMessageWhileConnectedMetadata, getSubscribeSwcAppRouteChangeWhileConnectedMetadata, ON_CONNECTED_SWC_APP_METADATA_KEY, SUBSCRIBE_SWC_APP_ROUTE_CHANGE_WHILE_CONNECTED_METADATA_KEY } from '../decorators';
|
|
3
|
+
import { SwcAppEngine, SwcAttributeConfigType, SwcConfigType } from '../SwcAppEngine';
|
|
4
|
+
import { debounceTimeIntervalLock, FunctionUtils, Subscription } from '@dooboostore/core';
|
|
5
|
+
import { RouterEventType } from '@dooboostore/core-web';
|
|
6
|
+
import { SwcUtils } from '../utils/Utils';
|
|
7
7
|
|
|
8
8
|
export const isSSR = (i: HTMLElement) => {
|
|
9
9
|
return i.hasAttribute('swc-use-ssr');
|
|
10
|
-
}
|
|
10
|
+
};
|
|
11
11
|
export const setSSRAttribute = (i: HTMLElement) => {
|
|
12
12
|
i.setAttribute('swc-use-ssr', (i as any)._swcId ?? '');
|
|
13
|
-
}
|
|
13
|
+
};
|
|
14
14
|
export const removeSSRAttribute = (i: HTMLElement) => {
|
|
15
15
|
i.removeAttribute('swc-use-ssr');
|
|
16
|
-
}
|
|
16
|
+
};
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* SwcAppMixin: SwcApp 기능을 모든 HTMLElement에 추가할 수 있는 Mixin
|
|
20
|
-
*
|
|
20
|
+
*
|
|
21
21
|
* 사용 예:
|
|
22
22
|
* @elementDefine('custom-app', { window: w })
|
|
23
23
|
* class CustomApp extends SwcAppMixin(w.HTMLElement) implements SwcAppInterface {
|
|
24
24
|
* // 추가 기능 구현
|
|
25
25
|
* }
|
|
26
26
|
*/
|
|
27
|
-
export function SwcAppMixin<T extends { new(...args: any[]): HTMLElement }>(Base: T) {
|
|
27
|
+
export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Base: T) {
|
|
28
28
|
return class SwcAppMixinClass extends Base implements SwcAppInterface {
|
|
29
29
|
__swc_engine = new SwcAppEngine(this as any);
|
|
30
30
|
_swc_connected_instance = new Set<any>();
|
|
@@ -45,7 +45,7 @@ export function SwcAppMixin<T extends { new(...args: any[]): HTMLElement }>(Base
|
|
|
45
45
|
|
|
46
46
|
constructor(...args: any[]) {
|
|
47
47
|
super(...args);
|
|
48
|
-
console.log('[SWC-APP-MIXIN] constructor')
|
|
48
|
+
console.log('[SWC-APP-MIXIN] constructor');
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
get simpleApplication() {
|
|
@@ -68,12 +68,12 @@ export function SwcAppMixin<T extends { new(...args: any[]): HTMLElement }>(Base
|
|
|
68
68
|
if (this._childrenRouteChangedInterval) {
|
|
69
69
|
this.config.window.clearInterval(this._childrenRouteChangedInterval);
|
|
70
70
|
}
|
|
71
|
-
const intervalConfig = {setInterval: this.config.window.setInterval.bind(this.config.window), clearInterval: this.config.window.clearInterval.bind(this.config.window)};
|
|
71
|
+
const intervalConfig = { setInterval: this.config.window.setInterval.bind(this.config.window), clearInterval: this.config.window.clearInterval.bind(this.config.window) };
|
|
72
72
|
this._childrenRouteChangedInterval = debounceTimeIntervalLock(
|
|
73
73
|
() => this._routeChangeInvocations === 0,
|
|
74
74
|
() => {
|
|
75
75
|
this._childrenRouteChangedInterval = null;
|
|
76
|
-
this.config.onChildrenRouteChanged?.(re, this)
|
|
76
|
+
this.config.onChildrenRouteChanged?.(re, this);
|
|
77
77
|
},
|
|
78
78
|
this.config?.childrenConnectedDoneCheckIntervalTime ?? 30,
|
|
79
79
|
intervalConfig
|
|
@@ -81,15 +81,23 @@ export function SwcAppMixin<T extends { new(...args: any[]): HTMLElement }>(Base
|
|
|
81
81
|
|
|
82
82
|
try {
|
|
83
83
|
const routeChangeSubscribers = getSubscribeSwcAppRouteChangeWhileConnectedMetadata(instance);
|
|
84
|
+
|
|
84
85
|
if (routeChangeSubscribers.length > 0) {
|
|
85
|
-
console.log('[SWC-MIXIN] Route change subscribers found')
|
|
86
|
-
|
|
86
|
+
console.log('[SWC-MIXIN] Route change subscribers found');
|
|
87
|
+
|
|
87
88
|
// Subscribers are already sorted by order from getSubscribeSwcAppRouteChangeWhileConnectedMetadata
|
|
88
89
|
// Execute subscribers in order, stop if one returns a value
|
|
89
90
|
for (const metadata of routeChangeSubscribers) {
|
|
90
91
|
const methodName = metadata.propertyKey;
|
|
91
92
|
let pathPattern = metadata.options?.path as any;
|
|
92
93
|
const filter = metadata.options?.filter;
|
|
94
|
+
const extractValue = (v: any) => {
|
|
95
|
+
const keyToUse = metadata.options?.valueKey ?? SUBSCRIBE_SWC_APP_ROUTE_CHANGE_WHILE_CONNECTED_METADATA_KEY;
|
|
96
|
+
if (v && typeof v === 'object' && keyToUse in v) {
|
|
97
|
+
return v[keyToUse];
|
|
98
|
+
}
|
|
99
|
+
return v;
|
|
100
|
+
};
|
|
93
101
|
|
|
94
102
|
if (typeof pathPattern === 'function') {
|
|
95
103
|
pathPattern = (pathPattern as Function)(instance);
|
|
@@ -116,10 +124,11 @@ export function SwcAppMixin<T extends { new(...args: any[]): HTMLElement }>(Base
|
|
|
116
124
|
}
|
|
117
125
|
|
|
118
126
|
const hostSet = SwcUtils.getHelperAndHostSet(this.config.window, this);
|
|
119
|
-
const filterPassed = !filter || filter(this.router!, {helper:hostSet, currentThis:instance});
|
|
127
|
+
const filterPassed = !filter || filter(this.router!, { helper: hostSet, currentThis: instance });
|
|
120
128
|
|
|
121
129
|
if (pathMatched && filterPassed && instance[methodName]) {
|
|
122
|
-
const result = await instance[methodName]({...re, pathData: pathData});
|
|
130
|
+
const result = extractValue(await instance[methodName]({ ...re, pathData: pathData }));
|
|
131
|
+
// if (typeof result === 'object'
|
|
123
132
|
// If handler returns a value, stop propagation to next handlers
|
|
124
133
|
if (result !== undefined && result !== null) {
|
|
125
134
|
break;
|
|
@@ -158,12 +167,12 @@ export function SwcAppMixin<T extends { new(...args: any[]): HTMLElement }>(Base
|
|
|
158
167
|
if (this._childrenConnectedDoneInterval) {
|
|
159
168
|
this.config.window.clearInterval(this._childrenConnectedDoneInterval);
|
|
160
169
|
}
|
|
161
|
-
const intervalConfig = {setInterval: this.config.window.setInterval.bind(this.config.window), clearInterval: this.config.window.clearInterval.bind(this.config.window)};
|
|
170
|
+
const intervalConfig = { setInterval: this.config.window.setInterval.bind(this.config.window), clearInterval: this.config.window.clearInterval.bind(this.config.window) };
|
|
162
171
|
this._childrenConnectedDoneInterval = debounceTimeIntervalLock(
|
|
163
172
|
() => this._connectedInvocations === 0,
|
|
164
173
|
() => {
|
|
165
174
|
this._childrenConnectedDoneInterval = null;
|
|
166
|
-
this.config.onChildrenConnectedDone?.(this)
|
|
175
|
+
this.config.onChildrenConnectedDone?.(this);
|
|
167
176
|
},
|
|
168
177
|
this.config?.childrenConnectedDoneCheckIntervalTime ?? 30,
|
|
169
178
|
intervalConfig
|
|
@@ -213,7 +222,7 @@ export function SwcAppMixin<T extends { new(...args: any[]): HTMLElement }>(Base
|
|
|
213
222
|
}
|
|
214
223
|
|
|
215
224
|
async connect(config?: SwcAttributeConfigType) {
|
|
216
|
-
console.log('[SWC-MIXIN] connect')
|
|
225
|
+
console.log('[SWC-MIXIN] connect');
|
|
217
226
|
const swcConfig = {
|
|
218
227
|
routeType: 'element',
|
|
219
228
|
window: config?.window,
|
|
@@ -224,7 +233,7 @@ export function SwcAppMixin<T extends { new(...args: any[]): HTMLElement }>(Base
|
|
|
224
233
|
|
|
225
234
|
// Safari is 속성 처리
|
|
226
235
|
this._connected_safari_and_standby.forEach((instance: any) => {
|
|
227
|
-
this._connected(instance, {noIncrements: true});
|
|
236
|
+
this._connected(instance, { noIncrements: true });
|
|
228
237
|
});
|
|
229
238
|
|
|
230
239
|
// 라우터 변경 구독
|
|
@@ -258,7 +267,17 @@ export function SwcAppMixin<T extends { new(...args: any[]): HTMLElement }>(Base
|
|
|
258
267
|
context: this,
|
|
259
268
|
args: SwcUtils.getHelperAndHostSet(win, this)
|
|
260
269
|
});
|
|
261
|
-
|
|
270
|
+
if (userConfig instanceof Promise) {
|
|
271
|
+
userConfig
|
|
272
|
+
.then(resolvedConfig => {
|
|
273
|
+
this.connect(resolvedConfig);
|
|
274
|
+
})
|
|
275
|
+
.catch(e => {
|
|
276
|
+
console.error('[SWC-MIXIN] Script execution failed:', e);
|
|
277
|
+
});
|
|
278
|
+
} else {
|
|
279
|
+
this.connect(userConfig);
|
|
280
|
+
}
|
|
262
281
|
} catch (e) {
|
|
263
282
|
console.error('[SWC-MIXIN] Script execution failed:', e);
|
|
264
283
|
}
|
|
@@ -273,7 +292,7 @@ export function SwcAppMixin<T extends { new(...args: any[]): HTMLElement }>(Base
|
|
|
273
292
|
// 부모 클래스의 disconnectedCallback 호출
|
|
274
293
|
// @ts-ignore
|
|
275
294
|
super.disconnectedCallback?.();
|
|
276
|
-
|
|
295
|
+
|
|
277
296
|
this._routerSubscription?.unsubscribe();
|
|
278
297
|
this._routerSubscription = undefined;
|
|
279
298
|
this._lastRouterEvent = undefined;
|