@dooboostore/simple-web-component 1.0.49 → 1.0.51
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 +790 -337
- package/dist/cjs/SwcAppEngine.js.map +2 -2
- package/dist/cjs/decorators/addEventListener.js +1925 -22
- package/dist/cjs/decorators/addEventListener.js.map +2 -2
- package/dist/cjs/decorators/applyAttribute.js +41 -47
- package/dist/cjs/decorators/applyAttribute.js.map +2 -2
- package/dist/cjs/decorators/applyClass.js +14 -11
- package/dist/cjs/decorators/applyClass.js.map +2 -2
- package/dist/cjs/decorators/applyNode.js +19 -21
- package/dist/cjs/decorators/applyNode.js.map +2 -2
- package/dist/cjs/decorators/applyProperty.js +24 -48
- package/dist/cjs/decorators/applyProperty.js.map +2 -2
- package/dist/cjs/decorators/applySlot.js +9 -8
- package/dist/cjs/decorators/applySlot.js.map +2 -2
- package/dist/cjs/decorators/applyStyle.js +14 -11
- package/dist/cjs/decorators/applyStyle.js.map +2 -2
- package/dist/cjs/decorators/around.js +124 -0
- package/dist/cjs/decorators/around.js.map +7 -0
- package/dist/cjs/decorators/changedAttribute.js +61 -24
- package/dist/cjs/decorators/changedAttribute.js.map +2 -2
- package/dist/cjs/decorators/elementDefine.js +240 -196
- package/dist/cjs/decorators/elementDefine.js.map +3 -3
- package/dist/cjs/decorators/emitCustomEvent.js +14 -12
- package/dist/cjs/decorators/emitCustomEvent.js.map +2 -2
- package/dist/cjs/decorators/eventMedia.js +112 -0
- package/dist/cjs/decorators/eventMedia.js.map +7 -0
- package/dist/cjs/decorators/fetch.js +278 -0
- package/dist/cjs/decorators/fetch.js.map +7 -0
- package/dist/cjs/decorators/index.js +8 -2
- package/dist/cjs/decorators/index.js.map +2 -2
- package/dist/cjs/decorators/intersectionObserver.js +76 -65
- package/dist/cjs/decorators/intersectionObserver.js.map +2 -2
- package/dist/cjs/decorators/lifecycles.js +11 -11
- package/dist/cjs/decorators/lifecycles.js.map +2 -2
- package/dist/cjs/decorators/mutationObserver.js +97 -90
- package/dist/cjs/decorators/mutationObserver.js.map +3 -3
- package/dist/cjs/decorators/parameter.js +156 -0
- package/dist/cjs/decorators/parameter.js.map +7 -0
- package/dist/cjs/decorators/publishSwcAppMessage.js +2 -2
- package/dist/cjs/decorators/publishSwcAppMessage.js.map +2 -2
- package/dist/cjs/decorators/query.js +11 -5
- package/dist/cjs/decorators/query.js.map +2 -2
- package/dist/cjs/decorators/requestAnimationFrame.js +115 -0
- package/dist/cjs/decorators/requestAnimationFrame.js.map +7 -0
- package/dist/cjs/decorators/resizeObserver.js +84 -69
- package/dist/cjs/decorators/resizeObserver.js.map +3 -3
- package/dist/cjs/decorators/setInterval.js +65 -22
- package/dist/cjs/decorators/setInterval.js.map +2 -2
- package/dist/cjs/decorators/setTimeout.js +68 -22
- package/dist/cjs/decorators/setTimeout.js.map +2 -2
- package/dist/cjs/decorators/state.js +13 -10
- package/dist/cjs/decorators/state.js.map +2 -2
- package/dist/cjs/decorators/{subscribeSwcAppMessageWhileConnected.js → subscribeSwcAppMessage.js} +20 -21
- package/dist/cjs/decorators/subscribeSwcAppMessage.js.map +7 -0
- package/dist/cjs/decorators/{subscribeSwcAppRouteChangeWhileConnected.js → subscribeSwcAppRouteChange.js} +23 -19
- package/dist/cjs/decorators/subscribeSwcAppRouteChange.js.map +7 -0
- package/dist/cjs/decorators/swcAppRoute.js +149 -0
- package/dist/cjs/decorators/swcAppRoute.js.map +7 -0
- package/dist/cjs/elements/SwcApp.js +70 -0
- package/dist/cjs/elements/SwcApp.js.map +2 -2
- package/dist/cjs/elements/SwcAppMixin.js +256 -67
- package/dist/cjs/elements/SwcAppMixin.js.map +3 -3
- package/dist/cjs/types/index.js +5 -1
- package/dist/cjs/types/index.js.map +2 -2
- package/dist/cjs/types/window.d.js.map +1 -1
- package/dist/cjs/utils/Utils.js +36 -15
- package/dist/cjs/utils/Utils.js.map +2 -2
- package/dist/esm/SwcAppEngine.js.map +2 -2
- package/dist/esm/decorators/addEventListener.js +1925 -22
- package/dist/esm/decorators/addEventListener.js.map +2 -2
- package/dist/esm/decorators/applyAttribute.js +41 -47
- package/dist/esm/decorators/applyAttribute.js.map +2 -2
- package/dist/esm/decorators/applyClass.js +14 -11
- package/dist/esm/decorators/applyClass.js.map +2 -2
- package/dist/esm/decorators/applyNode.js +20 -22
- package/dist/esm/decorators/applyNode.js.map +2 -2
- package/dist/esm/decorators/applyProperty.js +24 -48
- package/dist/esm/decorators/applyProperty.js.map +2 -2
- package/dist/esm/decorators/applySlot.js +9 -8
- package/dist/esm/decorators/applySlot.js.map +2 -2
- package/dist/esm/decorators/applyStyle.js +14 -11
- package/dist/esm/decorators/applyStyle.js.map +2 -2
- package/dist/esm/decorators/around.js +105 -0
- package/dist/esm/decorators/around.js.map +7 -0
- package/dist/esm/decorators/changedAttribute.js +61 -24
- package/dist/esm/decorators/changedAttribute.js.map +2 -2
- package/dist/esm/decorators/elementDefine.js +238 -194
- package/dist/esm/decorators/elementDefine.js.map +3 -3
- package/dist/esm/decorators/emitCustomEvent.js +15 -13
- package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
- package/dist/esm/decorators/eventMedia.js +94 -0
- package/dist/esm/decorators/eventMedia.js.map +7 -0
- package/dist/esm/decorators/fetch.js +259 -0
- package/dist/esm/decorators/fetch.js.map +7 -0
- package/dist/esm/decorators/index.js +8 -2
- package/dist/esm/decorators/index.js.map +2 -2
- package/dist/esm/decorators/intersectionObserver.js +76 -65
- package/dist/esm/decorators/intersectionObserver.js.map +2 -2
- package/dist/esm/decorators/lifecycles.js +11 -11
- package/dist/esm/decorators/lifecycles.js.map +2 -2
- package/dist/esm/decorators/mutationObserver.js +97 -90
- package/dist/esm/decorators/mutationObserver.js.map +3 -3
- package/dist/esm/decorators/parameter.js +137 -0
- package/dist/esm/decorators/parameter.js.map +7 -0
- package/dist/esm/decorators/publishSwcAppMessage.js +2 -2
- package/dist/esm/decorators/publishSwcAppMessage.js.map +2 -2
- package/dist/esm/decorators/query.js +11 -5
- package/dist/esm/decorators/query.js.map +2 -2
- package/dist/esm/decorators/requestAnimationFrame.js +96 -0
- package/dist/esm/decorators/requestAnimationFrame.js.map +7 -0
- package/dist/esm/decorators/resizeObserver.js +84 -69
- package/dist/esm/decorators/resizeObserver.js.map +2 -2
- package/dist/esm/decorators/setInterval.js +65 -23
- package/dist/esm/decorators/setInterval.js.map +2 -2
- package/dist/esm/decorators/setTimeout.js +68 -23
- package/dist/esm/decorators/setTimeout.js.map +2 -2
- package/dist/esm/decorators/state.js +13 -10
- package/dist/esm/decorators/state.js.map +2 -2
- package/dist/esm/decorators/subscribeSwcAppMessage.js +53 -0
- package/dist/esm/decorators/subscribeSwcAppMessage.js.map +7 -0
- package/dist/esm/decorators/{subscribeSwcAppRouteChangeWhileConnected.js → subscribeSwcAppRouteChange.js} +20 -16
- package/dist/esm/decorators/subscribeSwcAppRouteChange.js.map +7 -0
- package/dist/esm/decorators/swcAppRoute.js +130 -0
- package/dist/esm/decorators/swcAppRoute.js.map +7 -0
- package/dist/esm/elements/SwcApp.js +70 -0
- package/dist/esm/elements/SwcApp.js.map +2 -2
- package/dist/esm/elements/SwcAppMixin.js +258 -69
- package/dist/esm/elements/SwcAppMixin.js.map +3 -3
- package/dist/esm/types/index.js +5 -1
- package/dist/esm/types/index.js.map +2 -2
- package/dist/esm/utils/Utils.js +36 -15
- package/dist/esm/utils/Utils.js.map +2 -2
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +4395 -1266
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
- package/dist/types/SwcAppEngine.d.ts +1 -0
- package/dist/types/SwcAppEngine.d.ts.map +1 -1
- package/dist/types/decorators/addEventListener.d.ts +936 -11
- package/dist/types/decorators/addEventListener.d.ts.map +1 -1
- package/dist/types/decorators/applyAttribute.d.ts +27 -37
- package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
- package/dist/types/decorators/applyClass.d.ts +2 -2
- package/dist/types/decorators/applyClass.d.ts.map +1 -1
- package/dist/types/decorators/applyNode.d.ts +16 -16
- package/dist/types/decorators/applyNode.d.ts.map +1 -1
- package/dist/types/decorators/applyProperty.d.ts +28 -44
- package/dist/types/decorators/applyProperty.d.ts.map +1 -1
- package/dist/types/decorators/applySlot.d.ts.map +1 -1
- package/dist/types/decorators/applyStyle.d.ts +2 -2
- package/dist/types/decorators/applyStyle.d.ts.map +1 -1
- package/dist/types/decorators/around.d.ts +87 -0
- package/dist/types/decorators/around.d.ts.map +1 -0
- package/dist/types/decorators/changedAttribute.d.ts +22 -4
- package/dist/types/decorators/changedAttribute.d.ts.map +1 -1
- package/dist/types/decorators/elementDefine.d.ts.map +1 -1
- package/dist/types/decorators/emitCustomEvent.d.ts +0 -1
- package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
- package/dist/types/decorators/eventMedia.d.ts +48 -0
- package/dist/types/decorators/eventMedia.d.ts.map +1 -0
- package/dist/types/decorators/fetch.d.ts +139 -0
- package/dist/types/decorators/fetch.d.ts.map +1 -0
- package/dist/types/decorators/index.d.ts +8 -2
- package/dist/types/decorators/index.d.ts.map +1 -1
- package/dist/types/decorators/intersectionObserver.d.ts +32 -10
- package/dist/types/decorators/intersectionObserver.d.ts.map +1 -1
- package/dist/types/decorators/lifecycles.d.ts +8 -7
- package/dist/types/decorators/lifecycles.d.ts.map +1 -1
- package/dist/types/decorators/mutationObserver.d.ts +34 -12
- package/dist/types/decorators/mutationObserver.d.ts.map +1 -1
- package/dist/types/decorators/parameter.d.ts +113 -0
- package/dist/types/decorators/parameter.d.ts.map +1 -0
- package/dist/types/decorators/publishSwcAppMessage.d.ts +0 -1
- package/dist/types/decorators/publishSwcAppMessage.d.ts.map +1 -1
- package/dist/types/decorators/query.d.ts +7 -7
- package/dist/types/decorators/query.d.ts.map +1 -1
- package/dist/types/decorators/requestAnimationFrame.d.ts +47 -0
- package/dist/types/decorators/requestAnimationFrame.d.ts.map +1 -0
- package/dist/types/decorators/resizeObserver.d.ts +34 -12
- package/dist/types/decorators/resizeObserver.d.ts.map +1 -1
- package/dist/types/decorators/setInterval.d.ts +27 -5
- package/dist/types/decorators/setInterval.d.ts.map +1 -1
- package/dist/types/decorators/setTimeout.d.ts +27 -5
- package/dist/types/decorators/setTimeout.d.ts.map +1 -1
- package/dist/types/decorators/state.d.ts.map +1 -1
- package/dist/types/decorators/subscribeSwcAppMessage.d.ts +44 -0
- package/dist/types/decorators/subscribeSwcAppMessage.d.ts.map +1 -0
- package/dist/types/decorators/subscribeSwcAppRouteChange.d.ts +60 -0
- package/dist/types/decorators/subscribeSwcAppRouteChange.d.ts.map +1 -0
- package/dist/types/decorators/swcAppRoute.d.ts +94 -0
- package/dist/types/decorators/swcAppRoute.d.ts.map +1 -0
- package/dist/types/elements/SwcApp.d.ts.map +1 -1
- package/dist/types/elements/SwcAppMixin.d.ts +423 -388
- package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
- package/dist/types/types/index.d.ts +43 -4
- package/dist/types/types/index.d.ts.map +1 -1
- package/dist/types/utils/Utils.d.ts +15 -5
- package/dist/types/utils/Utils.d.ts.map +1 -1
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +4395 -1266
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
- package/package.json +8 -6
- package/src/SwcAppEngine.ts +1 -0
- package/src/decorators/addEventListener.ts +1086 -28
- package/src/decorators/applyAttribute.ts +82 -134
- package/src/decorators/applyClass.ts +14 -10
- package/src/decorators/applyNode.ts +39 -37
- package/src/decorators/applyProperty.ts +72 -100
- package/src/decorators/applySlot.ts +9 -8
- package/src/decorators/applyStyle.ts +14 -10
- package/src/decorators/around.ts +196 -0
- package/src/decorators/changedAttribute.ts +65 -26
- package/src/decorators/elementDefine.ts +298 -220
- package/src/decorators/emitCustomEvent.ts +17 -13
- package/src/decorators/eventMedia.ts +119 -0
- package/src/decorators/fetch.ts +454 -0
- package/src/decorators/index.ts +8 -2
- package/src/decorators/intersectionObserver.ts +108 -78
- package/src/decorators/lifecycles.ts +24 -22
- package/src/decorators/mutationObserver.ts +140 -104
- package/src/decorators/parameter.ts +212 -0
- package/src/decorators/publishSwcAppMessage.ts +3 -4
- package/src/decorators/query.ts +22 -14
- package/src/decorators/requestAnimationFrame.ts +149 -0
- package/src/decorators/resizeObserver.ts +119 -82
- package/src/decorators/setInterval.ts +90 -23
- package/src/decorators/setTimeout.ts +93 -23
- package/src/decorators/state.ts +19 -13
- package/src/decorators/subscribeSwcAppMessage.ts +106 -0
- package/src/decorators/subscribeSwcAppRouteChange.ts +131 -0
- package/src/decorators/swcAppRoute.ts +231 -0
- package/src/elements/SwcApp.ts +40 -10
- package/src/elements/SwcAppMixin.ts +329 -85
- package/src/types/index.ts +38 -5
- package/src/types/window.d.ts +2 -18
- package/src/utils/Utils.ts +50 -18
- package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js.map +0 -7
- package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +0 -7
- package/dist/cjs/examples/RxJSOperatorsExample.js +0 -285
- package/dist/cjs/examples/RxJSOperatorsExample.js.map +0 -7
- package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js +0 -54
- package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js.map +0 -7
- package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +0 -7
- package/dist/esm/examples/RxJSOperatorsExample.js +0 -266
- package/dist/esm/examples/RxJSOperatorsExample.js.map +0 -7
- package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts +0 -23
- package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts.map +0 -1
- package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +0 -31
- package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +0 -1
- package/dist/types/examples/RxJSOperatorsExample.d.ts +0 -94
- package/dist/types/examples/RxJSOperatorsExample.d.ts.map +0 -1
- package/src/decorators/subscribeSwcAppMessageWhileConnected.ts +0 -91
- package/src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts +0 -107
- package/src/examples/RxJSOperatorsExample.ts +0 -279
package/src/decorators/query.ts
CHANGED
|
@@ -39,7 +39,7 @@ export const resolveQueryElements = (
|
|
|
39
39
|
options: QueryOptions,
|
|
40
40
|
win: Window
|
|
41
41
|
): HTMLElement[] => {
|
|
42
|
-
const hostSet = SwcUtils.getHelperAndHostSet(
|
|
42
|
+
const hostSet = SwcUtils.getHelperAndHostSet(inst);
|
|
43
43
|
let all: HTMLElement[] = [];
|
|
44
44
|
|
|
45
45
|
if (typeof selector === 'function') {
|
|
@@ -95,10 +95,11 @@ export const pickElements = (
|
|
|
95
95
|
return all.length ? all[0] : null;
|
|
96
96
|
};
|
|
97
97
|
|
|
98
|
-
export function query(target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor): PropertyDescriptor | void;
|
|
99
98
|
export function query(selector: string, options?: QueryOptions): PropertyDecorator;
|
|
100
99
|
export function query(selector: QueryFnSelector, options?: QueryNonQueryOptions): PropertyDecorator;
|
|
101
|
-
export function query(options
|
|
100
|
+
export function query(options: QueryOptions): PropertyDecorator;
|
|
101
|
+
// bare(@query) 시그니처는 맨 뒤 — @attribute 와 같은 이유 (TS1240/TS1271)
|
|
102
|
+
export function query(target: Object, propertyKey: string | symbol): void;
|
|
102
103
|
/**
|
|
103
104
|
* @query decorator — 클래스 필드에 요소를 주입한다.
|
|
104
105
|
*
|
|
@@ -111,6 +112,10 @@ export function query(selectorOrTarget?: string | ((currentThis: any, helper: He
|
|
|
111
112
|
if (descriptor !== undefined && (typeof optionsOrPropertyKey === 'string' || typeof optionsOrPropertyKey === 'symbol')) {
|
|
112
113
|
throw new Error(`@query decorator cannot be used on methods. (Method: ${String(optionsOrPropertyKey)})`);
|
|
113
114
|
}
|
|
115
|
+
// bare: @query — 자기 자신($this). 빈 괄호 @query() 는 타입에서 막는다 (인자가 없으면 괄호도 없다)
|
|
116
|
+
if (selectorOrTarget && (typeof optionsOrPropertyKey === 'string' || typeof optionsOrPropertyKey === 'symbol')) {
|
|
117
|
+
return query('$this')(selectorOrTarget, optionsOrPropertyKey);
|
|
118
|
+
}
|
|
114
119
|
// With selector
|
|
115
120
|
if (typeof selectorOrTarget === 'string' || typeof selectorOrTarget === 'function') {
|
|
116
121
|
return (targetObj: Object, propertyKey: string | symbol, descriptor?: never): void => {
|
|
@@ -119,7 +124,7 @@ export function query(selectorOrTarget?: string | ((currentThis: any, helper: He
|
|
|
119
124
|
}
|
|
120
125
|
|
|
121
126
|
const constructor = targetObj.constructor;
|
|
122
|
-
let queries = ReflectUtils.
|
|
127
|
+
let queries = ReflectUtils.getOwnMetadata(QUERY_METADATA_KEY, constructor) as QueryMetadata[] | undefined;
|
|
123
128
|
if (!queries) {
|
|
124
129
|
queries = [];
|
|
125
130
|
ReflectUtils.defineMetadata(QUERY_METADATA_KEY, queries, constructor);
|
|
@@ -157,26 +162,29 @@ export function query(selectorOrTarget?: string | ((currentThis: any, helper: He
|
|
|
157
162
|
});
|
|
158
163
|
};
|
|
159
164
|
}
|
|
160
|
-
//
|
|
165
|
+
// 옵션만: $this
|
|
161
166
|
return query('$this', selectorOrTarget as QueryOptions);
|
|
162
167
|
}
|
|
163
168
|
|
|
164
169
|
export const getQueryMetadata = (target: any): QueryMetadata[] => {
|
|
165
|
-
const constructor = target
|
|
166
|
-
return ReflectUtils.
|
|
170
|
+
const constructor = typeof target === 'function' ? target : target.constructor;
|
|
171
|
+
return ReflectUtils.findAllMetadata<any[]>(QUERY_METADATA_KEY, constructor).flat();
|
|
167
172
|
};
|
|
168
173
|
|
|
169
174
|
// ─── queryAll (query의 pick:'all' 편의 래퍼 — 호환용) ───
|
|
170
175
|
export const QUERY_ALL_METADATA_KEY = QUERY_METADATA_KEY;
|
|
171
176
|
|
|
172
|
-
export function queryAll(target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor): PropertyDescriptor | void;
|
|
173
177
|
export function queryAll(selector: string, options?: Omit<QueryOptions, 'pick'>): PropertyDecorator;
|
|
174
178
|
export function queryAll(selector: QueryFnSelector, options?: Omit<QueryNonQueryOptions, 'pick'>): PropertyDecorator;
|
|
175
|
-
export function queryAll(options
|
|
179
|
+
export function queryAll(options: Omit<QueryOptions, 'pick'>): PropertyDecorator;
|
|
180
|
+
export function queryAll(target: Object, propertyKey: string | symbol): void;
|
|
176
181
|
export function queryAll(selectorOrTarget?: any, optionsOrPropertyKey?: any, descriptor?: PropertyDescriptor): any {
|
|
177
|
-
// bare(필드 직접 적용)는 query로 위임
|
|
178
182
|
if (descriptor !== undefined && (typeof optionsOrPropertyKey === 'string' || typeof optionsOrPropertyKey === 'symbol')) {
|
|
179
|
-
|
|
183
|
+
throw new Error(`@queryAll decorator cannot be used on methods. (Method: ${String(optionsOrPropertyKey)})`);
|
|
184
|
+
}
|
|
185
|
+
// bare: @queryAll — [$this]. 빈 괄호 @queryAll() 는 타입에서 막는다
|
|
186
|
+
if (selectorOrTarget && (typeof optionsOrPropertyKey === 'string' || typeof optionsOrPropertyKey === 'symbol')) {
|
|
187
|
+
return query('$this', { pick: 'all' })(selectorOrTarget, optionsOrPropertyKey);
|
|
180
188
|
}
|
|
181
189
|
if (typeof selectorOrTarget === 'string' || typeof selectorOrTarget === 'function') {
|
|
182
190
|
return query(selectorOrTarget, {...(optionsOrPropertyKey ?? {}), pick: 'all'});
|
|
@@ -235,9 +243,9 @@ export function queryAllAll(selector: string | QueryFnSelector, options?: QueryB
|
|
|
235
243
|
* first/last/even/odd/all/number를 모두 지원하는 데코레이터를 생성한다.
|
|
236
244
|
*
|
|
237
245
|
* @example
|
|
238
|
-
* @queryIn('shadow', 'even')('.item') // shadow DOM 짝수 인덱스들
|
|
239
|
-
* @queryIn('light', 2)('.item') // light DOM 3번째 요소
|
|
240
|
-
* @queryIn('all')('.item') // root all, pick 기본 first
|
|
246
|
+
* @(queryIn('shadow', 'even')('.item')) // shadow DOM 짝수 인덱스들 (호출이 이어지면 바깥 괄호 필요)
|
|
247
|
+
* @(queryIn('light', 2)('.item')) // light DOM 3번째 요소
|
|
248
|
+
* @(queryIn('all')('.item')) // root all, pick 기본 first
|
|
241
249
|
*/
|
|
242
250
|
export const queryIn = (root: SwcRootType, pick?: QueryPick) =>
|
|
243
251
|
(selector: string | QueryFnSelector, options?: QueryBaseOptions): PropertyDecorator =>
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { ReflectUtils } from '@dooboostore/core';
|
|
2
|
+
import { ensureInit } from './elementDefine';
|
|
3
|
+
import { SwcUtils } from '../utils/Utils';
|
|
4
|
+
import { ElementDefineLifeCycler, HelperHostSet } from '../types';
|
|
5
|
+
|
|
6
|
+
export const REQUEST_ANIMATION_FRAME_METADATA_KEY = Symbol.for('simple-web-component:request-animation-frame');
|
|
7
|
+
|
|
8
|
+
export type RequestAnimationFrameType = 'onConnected' | 'returnValue';
|
|
9
|
+
|
|
10
|
+
export interface RequestAnimationFrameOptions {
|
|
11
|
+
/**
|
|
12
|
+
* 'onConnected' - connect 시 자동으로 루프 시작 (매 프레임 데코레이트된 메서드를 직접 호출), disconnect 시 자동 정리.
|
|
13
|
+
* 'returnValue'(기본값) - 자동 시작 없음. 개발자가 이 메서드를 직접 호출해야 시작되고,
|
|
14
|
+
* 그 호출의 리턴값(또는 valueKey로 뽑은 값)이 실제로 매 프레임 호출될 함수가 된다.
|
|
15
|
+
*/
|
|
16
|
+
type?: RequestAnimationFrameType;
|
|
17
|
+
/** 루프 시작 직후 1회 호출 (디버깅/로깅용). id는 첫 requestAnimationFrame 반환값 - cleanup은 자동으로 처리되므로 직접 취소할 필요 없음. */
|
|
18
|
+
created?: (set: HelperHostSet, id: number) => void;
|
|
19
|
+
/**
|
|
20
|
+
* type:'returnValue' 전용 - 리턴값이 함수면 그 자체를, 객체면 이 키의 값이 함수일 때 그 값을
|
|
21
|
+
* "매 프레임 호출될 함수"로 사용한다. 안 주면 REQUEST_ANIMATION_FRAME_METADATA_KEY로 폴백한다 -
|
|
22
|
+
* applyAttribute.ts/applyNode.ts의 valueKey와 동일한 컨벤션.
|
|
23
|
+
*/
|
|
24
|
+
valueKey?: symbol | string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface RequestAnimationFrameMetadata {
|
|
28
|
+
propertyKey: string | symbol;
|
|
29
|
+
options: RequestAnimationFrameOptions;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 프레임 콜백 시그니처.
|
|
34
|
+
* - timestamp: 이번 프레임의 시각 (requestAnimationFrame이 넘겨주는 값)
|
|
35
|
+
* - prevValue: 직전 호출이 리턴한 값 (첫 호출에서는 undefined)
|
|
36
|
+
* 리턴값이 undefined/null이면 다음 프레임을 예약하지 않고 루프가 멈춘다 (개발자가 종료를 제어).
|
|
37
|
+
* undefined/null이 아닌 값을 리턴하면 그 값 그대로 다음 호출의 prevValue로 전달된다.
|
|
38
|
+
*/
|
|
39
|
+
export type FrameCallback = (timestamp: number, prevValue?: any) => any;
|
|
40
|
+
|
|
41
|
+
const getActiveEntries = (inst: any): number[] => (inst.__swc_requestAnimationFrameIds ??= []);
|
|
42
|
+
|
|
43
|
+
const startFrameLoop = (win: Window, entries: number[], frameFn: FrameCallback): number => {
|
|
44
|
+
let currentId = 0;
|
|
45
|
+
const step = (timestamp: number, prevValue?: any) => {
|
|
46
|
+
const idx = entries.indexOf(currentId);
|
|
47
|
+
if (idx >= 0) entries.splice(idx, 1);
|
|
48
|
+
let result: any;
|
|
49
|
+
try {
|
|
50
|
+
result = frameFn(timestamp, prevValue);
|
|
51
|
+
} catch (e) {
|
|
52
|
+
console.error('[SWC] requestAnimationFrame callback error:', e);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (result === undefined || result === null) return; // 개발자가 종료를 신호함 - 다음 프레임 예약 안 함
|
|
56
|
+
currentId = win.requestAnimationFrame(ts => step(ts, result));
|
|
57
|
+
entries.push(currentId);
|
|
58
|
+
};
|
|
59
|
+
currentId = win.requestAnimationFrame(ts => step(ts, undefined));
|
|
60
|
+
entries.push(currentId);
|
|
61
|
+
return currentId;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const applyRequestAnimationFrame = (options: RequestAnimationFrameOptions, target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor): PropertyDescriptor | void => {
|
|
65
|
+
const constructor = target.constructor;
|
|
66
|
+
const normalizedOptions: RequestAnimationFrameOptions = { ...options, type: options.type ?? 'returnValue' };
|
|
67
|
+
|
|
68
|
+
let metaList = ReflectUtils.getOwnMetadata(REQUEST_ANIMATION_FRAME_METADATA_KEY, constructor) as RequestAnimationFrameMetadata[];
|
|
69
|
+
if (!metaList) {
|
|
70
|
+
metaList = [];
|
|
71
|
+
ReflectUtils.defineMetadata(REQUEST_ANIMATION_FRAME_METADATA_KEY, metaList, constructor);
|
|
72
|
+
}
|
|
73
|
+
metaList.push({ propertyKey, options: normalizedOptions });
|
|
74
|
+
|
|
75
|
+
if (normalizedOptions.type === 'onConnected' || !descriptor) {
|
|
76
|
+
return; // LifeCycler가 connect/disconnect를 전담 - wrapping 불필요
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const original = descriptor.value;
|
|
80
|
+
descriptor.value = function (this: any, ...args: any[]) {
|
|
81
|
+
const res = original.apply(this, args);
|
|
82
|
+
// valueKey를 안 주면 이 데코레이터 전용 METADATA_KEY로 폴백 (applyAttribute.ts/applyNode.ts와 동일한 컨벤션)
|
|
83
|
+
const vk = normalizedOptions.valueKey ?? REQUEST_ANIMATION_FRAME_METADATA_KEY;
|
|
84
|
+
const frameFn: FrameCallback | undefined =
|
|
85
|
+
typeof res === 'function' ? res : res && typeof res === 'object' && typeof res[vk] === 'function' ? res[vk] : undefined;
|
|
86
|
+
|
|
87
|
+
if (frameFn) {
|
|
88
|
+
ensureInit(this);
|
|
89
|
+
const win = SwcUtils.resolveWindow(this);
|
|
90
|
+
const id = startFrameLoop(win, getActiveEntries(this), frameFn);
|
|
91
|
+
normalizedOptions.created?.(SwcUtils.getHelperAndHostSet(this), id);
|
|
92
|
+
}
|
|
93
|
+
return res;
|
|
94
|
+
};
|
|
95
|
+
return descriptor;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* type:'onConnected' - connect 시 자동으로 매 프레임 루프를 시작하고, disconnect 시 자동으로 cancelAnimationFrame 한다.
|
|
100
|
+
* type:'returnValue'(기본값) - 메서드를 감싸지 않는 대신, 호출될 때마다(개발자가 직접 호출) 원본 로직을
|
|
101
|
+
* 그대로 실행하고 리턴값(또는 valueKey로 뽑은 값)이 함수면 그 함수를 매 프레임 호출되는 루프로 등록한다.
|
|
102
|
+
* 원본 리턴값은 그대로 통과시키므로 다른 데코레이터와 같은 메서드에 스택해도 순서에 상관없이 안전하다.
|
|
103
|
+
*
|
|
104
|
+
* 옵션 없이 `@requestAnimationFrame` 그대로 붙여도 되고, `@requestAnimationFrame({...})`처럼 옵션을 줄 수도 있다.
|
|
105
|
+
*/
|
|
106
|
+
export function requestAnimationFrame(options: RequestAnimationFrameOptions): MethodDecorator;
|
|
107
|
+
export function requestAnimationFrame(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
108
|
+
export function requestAnimationFrame(optionsOrTarget?: RequestAnimationFrameOptions | Object, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
109
|
+
if (propertyKey !== undefined) {
|
|
110
|
+
// 옵션 없이: @requestAnimationFrame
|
|
111
|
+
applyRequestAnimationFrame({}, optionsOrTarget as Object, propertyKey, descriptor);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
// 옵션과 함께: @requestAnimationFrame({...})
|
|
115
|
+
return (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => {
|
|
116
|
+
return applyRequestAnimationFrame((optionsOrTarget as RequestAnimationFrameOptions) ?? {}, target, propertyKey, descriptor);
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export const findAllRequestAnimationFrameMetadata = (target: any): RequestAnimationFrameMetadata[] => {
|
|
121
|
+
const constructor = typeof target === 'function' ? target : target.constructor;
|
|
122
|
+
return (ReflectUtils.findAllMetadata<RequestAnimationFrameMetadata[]>(REQUEST_ANIMATION_FRAME_METADATA_KEY, constructor) || []).flat();
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export class RequestAnimationFrameLifeCycler implements ElementDefineLifeCycler {
|
|
126
|
+
onConnected(helperHostSet: HelperHostSet): void {
|
|
127
|
+
const inst = helperHostSet.$this;
|
|
128
|
+
inst.__swc_requestAnimationFrameIds = []; // 재연결 대비 리셋
|
|
129
|
+
const entries = getActiveEntries(inst);
|
|
130
|
+
for (const meta of findAllRequestAnimationFrameMetadata(inst)) {
|
|
131
|
+
if (meta.options.type !== 'onConnected') continue; // returnValue 타입은 수동 호출을 기다림
|
|
132
|
+
const frameFn: FrameCallback = (timestamp, prevValue) => inst[meta.propertyKey](timestamp, prevValue);
|
|
133
|
+
const id = startFrameLoop(helperHostSet.$w, entries, frameFn);
|
|
134
|
+
meta.options.created?.(helperHostSet, id);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
onDisconnected(helperHostSet: HelperHostSet): void {
|
|
139
|
+
const inst = helperHostSet.$this;
|
|
140
|
+
for (const id of inst.__swc_requestAnimationFrameIds ?? []) {
|
|
141
|
+
try {
|
|
142
|
+
helperHostSet.$w.cancelAnimationFrame(id);
|
|
143
|
+
} catch (e) {
|
|
144
|
+
console.error('[SWC] cancelAnimationFrame error:', e);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
inst.__swc_requestAnimationFrameIds = [];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { ReflectUtils } from '@dooboostore/core';
|
|
2
2
|
import { SpecialSelector, SwcQueryOptions, SwcFnSelector, SwcSelector, HelperHostSet } from '../types';
|
|
3
|
+
import { buildSwcParameterArgs } from './parameter';
|
|
3
4
|
|
|
4
5
|
// 공통 옵션 — root·delegate 없음
|
|
5
6
|
export interface ResizeObserverBaseOptions {
|
|
6
7
|
box?: 'content-box' | 'border-box' | 'device-pixel-content-box';
|
|
7
|
-
|
|
8
|
+
/** 매칭 시 핸들러 실행 여부 게이트. Promise<boolean>도 되어 async 판정 가능. false면 스킵. */
|
|
9
|
+
filter?: (matchedEls: HTMLElement[], meta: { currentThis: any, helper: HelperHostSet }) => boolean | Promise<boolean>;
|
|
10
|
+
/** filter 통과 후 핸들러 직전 훅. await되고, 리턴값은 @resizeObserverBeforeReturn 으로 핸들러에 주입된다. */
|
|
11
|
+
before?: (matchedEls: HTMLElement[], meta: { currentThis: any, helper: HelperHostSet }) => any | Promise<any>;
|
|
12
|
+
/** 핸들러가 성공/실패해도 항상 실행되는 정리 훅. ctx로 인자/결과/에러를 받는다. 에러는 로깅됨. */
|
|
13
|
+
finally?: (matchedEls: HTMLElement[], meta: { currentThis: any, helper: HelperHostSet }, ctx: { args: any[]; result?: any; error?: any }) => any | Promise<any>;
|
|
8
14
|
removeObserver?: (target: Element, optionValue: ResizeObserverOptions) => void;
|
|
9
15
|
}
|
|
10
16
|
|
|
@@ -26,112 +32,123 @@ export interface ResizeObserverMetadata {
|
|
|
26
32
|
|
|
27
33
|
export const RESIZE_OBSERVER_METADATA_KEY = Symbol.for('simple-web-component:resize-observer');
|
|
28
34
|
|
|
35
|
+
const applyResizeObserver = (selector: SwcSelector, options: ResizeObserverOptions, targetObj: Object, propertyKey: string | symbol): void => {
|
|
36
|
+
const constructor = targetObj.constructor;
|
|
37
|
+
let observers = ReflectUtils.getOwnMetadata(RESIZE_OBSERVER_METADATA_KEY, constructor) as ResizeObserverMetadata[] | undefined;
|
|
38
|
+
if (!observers) {
|
|
39
|
+
observers = [];
|
|
40
|
+
ReflectUtils.defineMetadata(RESIZE_OBSERVER_METADATA_KEY, observers, constructor);
|
|
41
|
+
}
|
|
42
|
+
observers.push({ propertyKey, selector, options });
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const resolveResizeObserverArgs = (
|
|
46
|
+
selectorOrOptions: SwcSelector | ResizeObserverOptions | undefined,
|
|
47
|
+
maybeOptions: ResizeObserverOptions | undefined,
|
|
48
|
+
extra: Partial<ResizeObserverOptions>
|
|
49
|
+
): { selector: SwcSelector; options: ResizeObserverOptions } => {
|
|
50
|
+
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
51
|
+
return { selector: selectorOrOptions, options: { ...(maybeOptions ?? {}), ...extra } };
|
|
52
|
+
}
|
|
53
|
+
return { selector: '$this', options: { ...(selectorOrOptions ?? {}), ...extra } };
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* bare(@decorator)와 factory(@decorator(...), 빈 괄호는 타입에서 막음) 호출을 모두 처리하는 공통 디스패처.
|
|
58
|
+
* extra는 Light/Shadow/All/Delegate 변형이 강제로 덧씌우는 옵션(root, delegate 등)이다.
|
|
59
|
+
*/
|
|
60
|
+
const dispatchResizeObserver = (
|
|
61
|
+
selectorOrOptionsOrTarget: SwcSelector | ResizeObserverOptions | Object | undefined,
|
|
62
|
+
maybeOptionsOrPropertyKey: ResizeObserverOptions | string | symbol | undefined,
|
|
63
|
+
descriptor: PropertyDescriptor | undefined,
|
|
64
|
+
extra: Partial<ResizeObserverOptions>
|
|
65
|
+
): MethodDecorator | void => {
|
|
66
|
+
if ((typeof maybeOptionsOrPropertyKey === 'string' || typeof maybeOptionsOrPropertyKey === 'symbol') && descriptor !== undefined) {
|
|
67
|
+
// 옵션 없이: @decorator
|
|
68
|
+
applyResizeObserver('$this', { ...extra }, selectorOrOptionsOrTarget as Object, maybeOptionsOrPropertyKey);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
// 옵션과 함께: @decorator(selector, options) / @decorator(options)
|
|
72
|
+
const { selector, options } = resolveResizeObserverArgs(
|
|
73
|
+
selectorOrOptionsOrTarget as SwcSelector | ResizeObserverOptions | undefined,
|
|
74
|
+
maybeOptionsOrPropertyKey as ResizeObserverOptions | undefined,
|
|
75
|
+
extra
|
|
76
|
+
);
|
|
77
|
+
return (targetObj: Object, propertyKey: string | symbol) => {
|
|
78
|
+
applyResizeObserver(selector, options, targetObj, propertyKey);
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
|
|
29
82
|
export function resizeObserver(target: SpecialSelector, options?: ResizeObserverQueryOptions): MethodDecorator;
|
|
30
83
|
export function resizeObserver(selector: string, options?: ResizeObserverQueryOptions): MethodDecorator;
|
|
31
84
|
export function resizeObserver(selector: SwcFnSelector, options?: ResizeObserverNonQueryOptions): MethodDecorator;
|
|
32
|
-
export function resizeObserver(options
|
|
85
|
+
export function resizeObserver(options: ResizeObserverQueryOptions): MethodDecorator;
|
|
86
|
+
export function resizeObserver(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
33
87
|
/**
|
|
34
88
|
* @resizeObserver decorator to observe element size changes.
|
|
89
|
+
* 옵션 없이 `@resizeObserver` 그대로 붙여도 되고, `@resizeObserver(...)`처럼 셀렉터/옵션을 줄 수도 있다.
|
|
35
90
|
*/
|
|
36
|
-
export function resizeObserver(
|
|
37
|
-
return (
|
|
38
|
-
let selector: SwcSelector = '$this';
|
|
39
|
-
let options: ResizeObserverOptions = {};
|
|
40
|
-
|
|
41
|
-
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
42
|
-
selector = selectorOrOptions;
|
|
43
|
-
options = maybeOptions ?? {};
|
|
44
|
-
} else {
|
|
45
|
-
selector = '$this';
|
|
46
|
-
options = selectorOrOptions ?? {};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const constructor = targetObj.constructor;
|
|
50
|
-
|
|
51
|
-
let observers = ReflectUtils.getMetadata<ResizeObserverMetadata[]>(RESIZE_OBSERVER_METADATA_KEY, constructor);
|
|
52
|
-
if (!observers) {
|
|
53
|
-
observers = [];
|
|
54
|
-
ReflectUtils.defineMetadata(RESIZE_OBSERVER_METADATA_KEY, observers, constructor);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
observers.push({ propertyKey, selector, options });
|
|
58
|
-
};
|
|
91
|
+
export function resizeObserver(selectorOrOptionsOrTarget?: SwcSelector | ResizeObserverOptions | Object, maybeOptionsOrPropertyKey?: ResizeObserverOptions | string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
92
|
+
return dispatchResizeObserver(selectorOrOptionsOrTarget, maybeOptionsOrPropertyKey, descriptor, {});
|
|
59
93
|
}
|
|
60
94
|
|
|
61
|
-
export function resizeObserverThis(options?: ResizeObserverQueryOptions): MethodDecorator {
|
|
62
|
-
return resizeObserver('$this', options);
|
|
63
|
-
}
|
|
64
95
|
|
|
65
96
|
// ─── root별 delegate 헬퍼 (root 주입 → 문자열 셀렉터 전용) ───
|
|
66
97
|
|
|
67
98
|
export function resizeObserverDelegateLight(selector: string, options?: Omit<ResizeObserverQueryOptions, 'delegate'>): MethodDecorator;
|
|
68
|
-
export function resizeObserverDelegateLight(options
|
|
69
|
-
export function resizeObserverDelegateLight(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
return resizeObserver({...selectorOrOptions ?? {}, root: 'light', delegate: true});
|
|
99
|
+
export function resizeObserverDelegateLight(options: Omit<ResizeObserverQueryOptions, 'delegate'>): MethodDecorator;
|
|
100
|
+
export function resizeObserverDelegateLight(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
101
|
+
export function resizeObserverDelegateLight(selectorOrOptionsOrTarget?: string | Omit<ResizeObserverQueryOptions, 'delegate'> | Object, maybeOptionsOrPropertyKey?: Omit<ResizeObserverQueryOptions, 'delegate'> | string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
102
|
+
return dispatchResizeObserver(selectorOrOptionsOrTarget as any, maybeOptionsOrPropertyKey as any, descriptor, { root: 'light', delegate: true });
|
|
74
103
|
}
|
|
75
104
|
|
|
76
105
|
export function resizeObserverDelegateShadow(selector: string, options?: Omit<ResizeObserverQueryOptions, 'delegate'>): MethodDecorator;
|
|
77
|
-
export function resizeObserverDelegateShadow(options
|
|
78
|
-
export function resizeObserverDelegateShadow(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
return resizeObserver({...selectorOrOptions ?? {}, root: 'shadow', delegate: true});
|
|
106
|
+
export function resizeObserverDelegateShadow(options: Omit<ResizeObserverQueryOptions, 'delegate'>): MethodDecorator;
|
|
107
|
+
export function resizeObserverDelegateShadow(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
108
|
+
export function resizeObserverDelegateShadow(selectorOrOptionsOrTarget?: string | Omit<ResizeObserverQueryOptions, 'delegate'> | Object, maybeOptionsOrPropertyKey?: Omit<ResizeObserverQueryOptions, 'delegate'> | string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
109
|
+
return dispatchResizeObserver(selectorOrOptionsOrTarget as any, maybeOptionsOrPropertyKey as any, descriptor, { root: 'shadow', delegate: true });
|
|
83
110
|
}
|
|
84
111
|
|
|
85
112
|
export function resizeObserverDelegateAll(selector: string, options?: Omit<ResizeObserverQueryOptions, 'delegate'>): MethodDecorator;
|
|
86
|
-
export function resizeObserverDelegateAll(options
|
|
87
|
-
export function resizeObserverDelegateAll(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
return resizeObserver({...selectorOrOptions ?? {}, root: 'all', delegate: true});
|
|
113
|
+
export function resizeObserverDelegateAll(options: Omit<ResizeObserverQueryOptions, 'delegate'>): MethodDecorator;
|
|
114
|
+
export function resizeObserverDelegateAll(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
115
|
+
export function resizeObserverDelegateAll(selectorOrOptionsOrTarget?: string | Omit<ResizeObserverQueryOptions, 'delegate'> | Object, maybeOptionsOrPropertyKey?: Omit<ResizeObserverQueryOptions, 'delegate'> | string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
116
|
+
return dispatchResizeObserver(selectorOrOptionsOrTarget as any, maybeOptionsOrPropertyKey as any, descriptor, { root: 'all', delegate: true });
|
|
92
117
|
}
|
|
93
118
|
|
|
94
119
|
export function resizeObserverDelegate(selector: string, options?: Omit<ResizeObserverQueryOptions, 'delegate'>): MethodDecorator;
|
|
95
|
-
export function resizeObserverDelegate(options
|
|
96
|
-
export function resizeObserverDelegate(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
return resizeObserver({...selectorOrOptions ?? {}, root: 'auto', delegate: true});
|
|
120
|
+
export function resizeObserverDelegate(options: Omit<ResizeObserverQueryOptions, 'delegate'>): MethodDecorator;
|
|
121
|
+
export function resizeObserverDelegate(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
122
|
+
export function resizeObserverDelegate(selectorOrOptionsOrTarget?: string | Omit<ResizeObserverQueryOptions, 'delegate'> | Object, maybeOptionsOrPropertyKey?: Omit<ResizeObserverQueryOptions, 'delegate'> | string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
123
|
+
return dispatchResizeObserver(selectorOrOptionsOrTarget as any, maybeOptionsOrPropertyKey as any, descriptor, { root: 'auto', delegate: true });
|
|
101
124
|
}
|
|
102
125
|
|
|
103
126
|
// ─── root별 일반 헬퍼 (delegate 없이, 셀렉터 생략 시 $this) ───
|
|
104
127
|
|
|
105
128
|
export function resizeObserverLight(selector: string, options?: ResizeObserverQueryOptions): MethodDecorator;
|
|
106
|
-
export function resizeObserverLight(options
|
|
107
|
-
export function resizeObserverLight(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
return resizeObserver({...selectorOrOptions ?? {}, root: 'light'});
|
|
129
|
+
export function resizeObserverLight(options: ResizeObserverQueryOptions): MethodDecorator;
|
|
130
|
+
export function resizeObserverLight(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
131
|
+
export function resizeObserverLight(selectorOrOptionsOrTarget?: string | ResizeObserverQueryOptions | Object, maybeOptionsOrPropertyKey?: ResizeObserverQueryOptions | string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
132
|
+
return dispatchResizeObserver(selectorOrOptionsOrTarget as any, maybeOptionsOrPropertyKey as any, descriptor, { root: 'light' });
|
|
112
133
|
}
|
|
113
134
|
|
|
114
135
|
export function resizeObserverShadow(selector: string, options?: ResizeObserverQueryOptions): MethodDecorator;
|
|
115
|
-
export function resizeObserverShadow(options
|
|
116
|
-
export function resizeObserverShadow(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
return resizeObserver({...selectorOrOptions ?? {}, root: 'shadow'});
|
|
136
|
+
export function resizeObserverShadow(options: ResizeObserverQueryOptions): MethodDecorator;
|
|
137
|
+
export function resizeObserverShadow(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
138
|
+
export function resizeObserverShadow(selectorOrOptionsOrTarget?: string | ResizeObserverQueryOptions | Object, maybeOptionsOrPropertyKey?: ResizeObserverQueryOptions | string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
139
|
+
return dispatchResizeObserver(selectorOrOptionsOrTarget as any, maybeOptionsOrPropertyKey as any, descriptor, { root: 'shadow' });
|
|
121
140
|
}
|
|
122
141
|
|
|
123
142
|
export function resizeObserverAll(selector: string, options?: ResizeObserverQueryOptions): MethodDecorator;
|
|
124
|
-
export function resizeObserverAll(options
|
|
125
|
-
export function resizeObserverAll(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
return resizeObserver({...selectorOrOptions ?? {}, root: 'all'});
|
|
143
|
+
export function resizeObserverAll(options: ResizeObserverQueryOptions): MethodDecorator;
|
|
144
|
+
export function resizeObserverAll(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
145
|
+
export function resizeObserverAll(selectorOrOptionsOrTarget?: string | ResizeObserverQueryOptions | Object, maybeOptionsOrPropertyKey?: ResizeObserverQueryOptions | string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
146
|
+
return dispatchResizeObserver(selectorOrOptionsOrTarget as any, maybeOptionsOrPropertyKey as any, descriptor, { root: 'all' });
|
|
130
147
|
}
|
|
131
148
|
|
|
132
149
|
export function getResizeObserverMetadata(target: any): ResizeObserverMetadata[] | undefined {
|
|
133
|
-
const constructor = target
|
|
134
|
-
return ReflectUtils.
|
|
150
|
+
const constructor = typeof target === 'function' ? target : target.constructor;
|
|
151
|
+
return ReflectUtils.findAllMetadata<any[]>(RESIZE_OBSERVER_METADATA_KEY, constructor).flat();
|
|
135
152
|
}
|
|
136
153
|
|
|
137
154
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -140,20 +157,21 @@ export function getResizeObserverMetadata(target: any): ResizeObserverMetadata[]
|
|
|
140
157
|
// elementDefine 이 수집된 ResizeObserverSet 으로 observer 를 생성하고,
|
|
141
158
|
// observe/unobserve 함수를 주입해 MutationObserver delegate 추적이 사용할 수 있게 한다.
|
|
142
159
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
143
|
-
import { ElementDefineLifeCycler, OnConnectedResult, ResizeObserverSet, ResizeObserverSetEntry } from '../types';
|
|
160
|
+
import { ElementDefineLifeCycler, inObserverScope, ObserverScope, OnConnectedResult, ResizeObserverSet, ResizeObserverSetEntry } from '../types';
|
|
144
161
|
import { SwcUtils } from '../utils/Utils';
|
|
145
162
|
|
|
146
163
|
export class ResizeObserverLifeCycler implements ElementDefineLifeCycler {
|
|
147
164
|
private readonly removeObserverCallbacksMap = new WeakMap<Element, Array<{ fn: (target: Element, opts: unknown) => void; target: any; opts: unknown }>>();
|
|
148
165
|
|
|
149
|
-
onConnected(helperHostSet: HelperHostSet): OnConnectedResult | void {
|
|
166
|
+
onConnected(helperHostSet: HelperHostSet, _set?: ResizeObserverSet, scope?: ObserverScope): OnConnectedResult | void {
|
|
150
167
|
const inst = helperHostSet.$this;
|
|
151
168
|
const currentWin = helperHostSet.$w;
|
|
152
169
|
|
|
153
|
-
|
|
170
|
+
// 'rest' 는 같은 connect 의 'self' 뒤에 오므로 이어 붙이고, 그 외(새 connect)는 새로 시작한다.
|
|
171
|
+
const removeObserverCallbacks = (scope === 'rest' && this.removeObserverCallbacksMap.get(inst)) || [];
|
|
154
172
|
this.removeObserverCallbacksMap.set(inst, removeObserverCallbacks);
|
|
155
173
|
|
|
156
|
-
const allMeta = getResizeObserverMetadata(inst) ?? [];
|
|
174
|
+
const allMeta = (getResizeObserverMetadata(inst) ?? []).filter(m => inObserverScope(m, scope));
|
|
157
175
|
if (allMeta.length === 0) return;
|
|
158
176
|
|
|
159
177
|
const root: HTMLElement | ShadowRoot = inst.shadowRoot || inst;
|
|
@@ -163,6 +181,9 @@ export class ResizeObserverLifeCycler implements ElementDefineLifeCycler {
|
|
|
163
181
|
if (m.options.removeObserver) removeObserverCallbacks.push({ fn: m.options.removeObserver, target: root, opts: m.options });
|
|
164
182
|
}
|
|
165
183
|
|
|
184
|
+
// non-delegate 메타별 observe 대상 — 콜백은 모든 메타가 공유하므로, 엔트리를 자기 대상에만 배달한다.
|
|
185
|
+
const metaTargets = new Map<typeof allMeta[number], WeakSet<Element>>();
|
|
186
|
+
|
|
166
187
|
// ── ResizeObserver 콜백 ──
|
|
167
188
|
const callback: ResizeObserverSetEntry['callback'] = (entries, obs) => {
|
|
168
189
|
for (const m of allMeta) {
|
|
@@ -175,14 +196,29 @@ export class ResizeObserverLifeCycler implements ElementDefineLifeCycler {
|
|
|
175
196
|
return el.matches?.(m.selector as string) || !!el.closest?.(m.selector as string);
|
|
176
197
|
});
|
|
177
198
|
} else {
|
|
178
|
-
|
|
199
|
+
const set = metaTargets.get(m);
|
|
200
|
+
matchedEls = entries.map(e => e.target as HTMLElement).filter(t => t && t.nodeType === 1 && !!set?.has(t));
|
|
179
201
|
}
|
|
180
202
|
if (matchedEls.length === 0) continue;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
203
|
+
const opts = m.options;
|
|
204
|
+
void (async () => {
|
|
205
|
+
const helper = SwcUtils.getHelperAndHostSet(inst);
|
|
206
|
+
if (opts.filter && !(await opts.filter(matchedEls, { currentThis: inst, helper }))) return;
|
|
207
|
+
const hostSet = SwcUtils.getHostSet(inst);
|
|
208
|
+
const helperSet = SwcUtils.getHelperSet(helperHostSet.$w);
|
|
209
|
+
// entries 도 이 메서드 대상 것만 (옵저버는 공유라 배치에 다른 대상 엔트리가 섞인다)
|
|
210
|
+
const legacyArgs = [matchedEls, entries.filter(e => matchedEls.includes(e.target as HTMLElement)), obs, { ...hostSet, $root: root }];
|
|
211
|
+
const buildArgs = (beforeReturn: any) => buildSwcParameterArgs(inst, m.propertyKey, {
|
|
212
|
+
hostSet, helperHostSet: helper, helperSet, resizeObserverBeforeReturn: beforeReturn
|
|
213
|
+
}, [...legacyArgs, beforeReturn]);
|
|
214
|
+
let args = buildArgs(undefined);
|
|
215
|
+
if (opts.before) { const br = await opts.before(matchedEls, { currentThis: inst, helper }); args = buildArgs(br); }
|
|
216
|
+
let result: any, error: any;
|
|
217
|
+
try { result = await inst[m.propertyKey](...args); }
|
|
218
|
+
catch (e) { error = e; }
|
|
219
|
+
finally { if (opts.finally) await opts.finally(matchedEls, { currentThis: inst, helper }, { args, result, error }); }
|
|
220
|
+
if (error) throw error;
|
|
221
|
+
})().catch(e => console.error('[SWC] resizeObserver handler error:', e));
|
|
186
222
|
}
|
|
187
223
|
};
|
|
188
224
|
|
|
@@ -219,6 +255,7 @@ export class ResizeObserverLifeCycler implements ElementDefineLifeCycler {
|
|
|
219
255
|
}
|
|
220
256
|
}
|
|
221
257
|
}
|
|
258
|
+
metaTargets.set(m, new WeakSet(targets));
|
|
222
259
|
for (const el of targets) resizeObserverSet.push({ target: el, options: m.options.box ? { box: m.options.box } : undefined, callback });
|
|
223
260
|
}
|
|
224
261
|
|