@dooboostore/simple-web-component 1.0.46 → 1.0.48
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 +109 -11
- package/dist/cjs/bundle-entry.js +22 -0
- package/dist/cjs/bundle-entry.js.map +2 -2
- package/dist/cjs/decorators/addEventListener.js +45 -7
- package/dist/cjs/decorators/addEventListener.js.map +2 -2
- package/dist/cjs/decorators/elementDefine.js +225 -6
- package/dist/cjs/decorators/elementDefine.js.map +3 -3
- package/dist/cjs/decorators/index.js +2 -0
- package/dist/cjs/decorators/index.js.map +2 -2
- package/dist/cjs/decorators/mutationObserver.js +104 -0
- package/dist/cjs/decorators/mutationObserver.js.map +7 -0
- package/dist/cjs/decorators/query.js +13 -1
- package/dist/cjs/decorators/query.js.map +2 -2
- package/dist/cjs/decorators/resizeObserver.js +104 -0
- package/dist/cjs/decorators/resizeObserver.js.map +7 -0
- package/dist/cjs/examples/RxJSOperatorsExample.js +285 -0
- package/dist/cjs/examples/RxJSOperatorsExample.js.map +7 -0
- package/dist/esm/bundle-entry.js +8 -0
- package/dist/esm/bundle-entry.js.map +2 -2
- package/dist/esm/decorators/addEventListener.js +45 -7
- package/dist/esm/decorators/addEventListener.js.map +2 -2
- package/dist/esm/decorators/elementDefine.js +225 -6
- package/dist/esm/decorators/elementDefine.js.map +3 -3
- package/dist/esm/decorators/index.js +2 -0
- package/dist/esm/decorators/index.js.map +2 -2
- package/dist/esm/decorators/mutationObserver.js +85 -0
- package/dist/esm/decorators/mutationObserver.js.map +7 -0
- package/dist/esm/decorators/query.js +13 -1
- package/dist/esm/decorators/query.js.map +2 -2
- package/dist/esm/decorators/resizeObserver.js +85 -0
- package/dist/esm/decorators/resizeObserver.js.map +7 -0
- package/dist/esm/examples/RxJSOperatorsExample.js +266 -0
- package/dist/esm/examples/RxJSOperatorsExample.js.map +7 -0
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +5869 -157
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
- package/dist/types/bundle-entry.d.ts +3 -0
- package/dist/types/bundle-entry.d.ts.map +1 -1
- package/dist/types/decorators/addEventListener.d.ts +24 -5
- package/dist/types/decorators/addEventListener.d.ts.map +1 -1
- package/dist/types/decorators/elementDefine.d.ts +14 -0
- package/dist/types/decorators/elementDefine.d.ts.map +1 -1
- package/dist/types/decorators/index.d.ts +2 -0
- package/dist/types/decorators/index.d.ts.map +1 -1
- package/dist/types/decorators/mutationObserver.d.ts +36 -0
- package/dist/types/decorators/mutationObserver.d.ts.map +1 -0
- package/dist/types/decorators/query.d.ts +12 -0
- package/dist/types/decorators/query.d.ts.map +1 -1
- package/dist/types/decorators/resizeObserver.d.ts +37 -0
- package/dist/types/decorators/resizeObserver.d.ts.map +1 -0
- package/dist/types/examples/RxJSOperatorsExample.d.ts +94 -0
- package/dist/types/examples/RxJSOperatorsExample.d.ts.map +1 -0
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +5886 -178
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
- package/package.json +7 -8
- package/src/bundle-entry.ts +8 -0
- package/src/decorators/addEventListener.ts +52 -9
- package/src/decorators/elementDefine.ts +330 -47
- package/src/decorators/index.ts +2 -0
- package/src/decorators/mutationObserver.ts +128 -0
- package/src/decorators/query.ts +23 -0
- package/src/decorators/resizeObserver.ts +129 -0
- package/src/examples/RxJSOperatorsExample.ts +279 -0
- package/dist/cjs/elements/tt/SwcAppMixin.js +0 -1
- package/dist/cjs/elements/tt/SwcAppMixin.js.map +0 -7
- package/dist/cjs/elements/tt/SwcAsync.js +0 -1
- package/dist/cjs/elements/tt/SwcAsync.js.map +0 -7
- package/dist/cjs/elements/tt/SwcAsyncTemplate.js +0 -1
- package/dist/cjs/elements/tt/SwcAsyncTemplate.js.map +0 -7
- package/dist/cjs/elements/tt/SwcChoose.js +0 -1
- package/dist/cjs/elements/tt/SwcChoose.js.map +0 -7
- package/dist/cjs/elements/tt/SwcChooseTemplate.js +0 -1
- package/dist/cjs/elements/tt/SwcChooseTemplate.js.map +0 -7
- package/dist/cjs/elements/tt/SwcIf.js +0 -1
- package/dist/cjs/elements/tt/SwcIf.js.map +0 -7
- package/dist/cjs/elements/tt/SwcIfTemplate.js +0 -1
- package/dist/cjs/elements/tt/SwcIfTemplate.js.map +0 -7
- package/dist/cjs/elements/tt/SwcLoop.js +0 -1
- package/dist/cjs/elements/tt/SwcLoop.js.map +0 -7
- package/dist/cjs/elements/tt/SwcLoopTemplate.js +0 -1
- package/dist/cjs/elements/tt/SwcLoopTemplate.js.map +0 -7
- package/dist/cjs/elements/tt/SwcSubTemplates.js +0 -1
- package/dist/cjs/elements/tt/SwcSubTemplates.js.map +0 -7
- package/dist/cjs/elements/tt/register.js +0 -1
- package/dist/cjs/elements/tt/register.js.map +0 -7
- package/dist/esm/elements/tt/SwcAppMixin.js +0 -1
- package/dist/esm/elements/tt/SwcAppMixin.js.map +0 -7
- package/dist/esm/elements/tt/SwcAsync.js +0 -1
- package/dist/esm/elements/tt/SwcAsync.js.map +0 -7
- package/dist/esm/elements/tt/SwcAsyncTemplate.js +0 -1
- package/dist/esm/elements/tt/SwcAsyncTemplate.js.map +0 -7
- package/dist/esm/elements/tt/SwcChoose.js +0 -1
- package/dist/esm/elements/tt/SwcChoose.js.map +0 -7
- package/dist/esm/elements/tt/SwcChooseTemplate.js +0 -1
- package/dist/esm/elements/tt/SwcChooseTemplate.js.map +0 -7
- package/dist/esm/elements/tt/SwcIf.js +0 -1
- package/dist/esm/elements/tt/SwcIf.js.map +0 -7
- package/dist/esm/elements/tt/SwcIfTemplate.js +0 -1
- package/dist/esm/elements/tt/SwcIfTemplate.js.map +0 -7
- package/dist/esm/elements/tt/SwcLoop.js +0 -1
- package/dist/esm/elements/tt/SwcLoop.js.map +0 -7
- package/dist/esm/elements/tt/SwcLoopTemplate.js +0 -1
- package/dist/esm/elements/tt/SwcLoopTemplate.js.map +0 -7
- package/dist/esm/elements/tt/SwcSubTemplates.js +0 -1
- package/dist/esm/elements/tt/SwcSubTemplates.js.map +0 -7
- package/dist/esm/elements/tt/register.js +0 -1
- package/dist/esm/elements/tt/register.js.map +0 -7
- package/dist/types/elements/tt/SwcAppMixin.d.ts +0 -1
- package/dist/types/elements/tt/SwcAppMixin.d.ts.map +0 -1
- package/dist/types/elements/tt/SwcAsync.d.ts +0 -1
- package/dist/types/elements/tt/SwcAsync.d.ts.map +0 -1
- package/dist/types/elements/tt/SwcAsyncTemplate.d.ts +0 -1
- package/dist/types/elements/tt/SwcAsyncTemplate.d.ts.map +0 -1
- package/dist/types/elements/tt/SwcChoose.d.ts +0 -1
- package/dist/types/elements/tt/SwcChoose.d.ts.map +0 -1
- package/dist/types/elements/tt/SwcChooseTemplate.d.ts +0 -1
- package/dist/types/elements/tt/SwcChooseTemplate.d.ts.map +0 -1
- package/dist/types/elements/tt/SwcIf.d.ts +0 -1
- package/dist/types/elements/tt/SwcIf.d.ts.map +0 -1
- package/dist/types/elements/tt/SwcIfTemplate.d.ts +0 -1
- package/dist/types/elements/tt/SwcIfTemplate.d.ts.map +0 -1
- package/dist/types/elements/tt/SwcLoop.d.ts +0 -1
- package/dist/types/elements/tt/SwcLoop.d.ts.map +0 -1
- package/dist/types/elements/tt/SwcLoopTemplate.d.ts +0 -1
- package/dist/types/elements/tt/SwcLoopTemplate.d.ts.map +0 -1
- package/dist/types/elements/tt/SwcSubTemplates.d.ts +0 -1
- package/dist/types/elements/tt/SwcSubTemplates.d.ts.map +0 -1
- package/dist/types/elements/tt/register.d.ts +0 -1
- package/dist/types/elements/tt/register.d.ts.map +0 -1
- package/src/elements/tt/SwcAppMixin.ts +0 -13
- package/src/elements/tt/SwcAsync.ts +0 -139
- package/src/elements/tt/SwcAsyncTemplate.ts +0 -126
- package/src/elements/tt/SwcChoose.ts +0 -182
- package/src/elements/tt/SwcChooseTemplate.ts +0 -229
- package/src/elements/tt/SwcIf.ts +0 -145
- package/src/elements/tt/SwcIfTemplate.ts +0 -158
- package/src/elements/tt/SwcLoop.ts +0 -222
- package/src/elements/tt/SwcLoopTemplate.ts +0 -255
- package/src/elements/tt/SwcSubTemplates.ts +0 -6
- package/src/elements/tt/register.ts +0 -720
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { ReflectUtils } from '@dooboostore/core';
|
|
2
|
+
import { SpecialSelector, SwcQueryOptions, HelperHostSet } from '../types';
|
|
3
|
+
import { EventListenerSelector } from './addEventListener';
|
|
4
|
+
|
|
5
|
+
export interface MutationObserverBaseOptions extends MutationObserverInit, SwcQueryOptions {
|
|
6
|
+
// observe 대상 셀렉터. 기본값 $this (컴포넌트 자신)
|
|
7
|
+
// delegate: true 인 경우 root에 observer를 걸고 셀렉터 매칭 대상의 mutation만 콜백
|
|
8
|
+
// 셀렉터로 직접 지정한 경우 해당 요소들을 각각 observe
|
|
9
|
+
delegate?: boolean;
|
|
10
|
+
filter?: (matchedEls: HTMLElement[], meta: { currentThis: any, helper: HelperHostSet }) => boolean;
|
|
11
|
+
// observer 해제(disconnected) 시 호출되는 콜백. 첫 번째 인자는 observe된 target element, 두 번째는 사용자 옵션 객체.
|
|
12
|
+
removeObserver?: (target: Element, optionValue: MutationObserverBaseOptions) => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface MutationObserverMetadata {
|
|
16
|
+
propertyKey: string | symbol;
|
|
17
|
+
selector: EventListenerSelector;
|
|
18
|
+
options: MutationObserverBaseOptions;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const MUTATION_OBSERVER_METADATA_KEY = Symbol.for('simple-web-component:mutation-observer');
|
|
22
|
+
|
|
23
|
+
export function mutationObserver(target: SpecialSelector, options?: MutationObserverBaseOptions): MethodDecorator;
|
|
24
|
+
export function mutationObserver(selector: EventListenerSelector, options?: MutationObserverBaseOptions): MethodDecorator;
|
|
25
|
+
export function mutationObserver(options?: MutationObserverBaseOptions): MethodDecorator;
|
|
26
|
+
/**
|
|
27
|
+
* @mutationObserver decorator to observe DOM mutations.
|
|
28
|
+
*/
|
|
29
|
+
export function mutationObserver(selectorOrOptions?: EventListenerSelector | MutationObserverBaseOptions, maybeOptions?: MutationObserverBaseOptions): MethodDecorator {
|
|
30
|
+
return (targetObj: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
|
|
31
|
+
let selector: EventListenerSelector = '$this';
|
|
32
|
+
let options: MutationObserverBaseOptions = {};
|
|
33
|
+
|
|
34
|
+
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
35
|
+
selector = selectorOrOptions;
|
|
36
|
+
options = maybeOptions ?? {};
|
|
37
|
+
} else {
|
|
38
|
+
selector = '$this';
|
|
39
|
+
options = selectorOrOptions ?? {};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const constructor = targetObj.constructor;
|
|
43
|
+
|
|
44
|
+
let observers = ReflectUtils.getMetadata<MutationObserverMetadata[]>(MUTATION_OBSERVER_METADATA_KEY, constructor);
|
|
45
|
+
if (!observers) {
|
|
46
|
+
observers = [];
|
|
47
|
+
ReflectUtils.defineMetadata(MUTATION_OBSERVER_METADATA_KEY, observers, constructor);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
observers.push({ propertyKey, selector, options });
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function mutationObserverThis<TEvent extends Event = Event>(options?: MutationObserverBaseOptions): MethodDecorator {
|
|
55
|
+
return mutationObserver('$this', options);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ─── root별 delegate 헬퍼 (addEventListener와 동일 패턴) ───
|
|
59
|
+
|
|
60
|
+
export function mutationObserverDelegateLight(selector: EventListenerSelector, options?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator;
|
|
61
|
+
export function mutationObserverDelegateLight(options?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator;
|
|
62
|
+
export function mutationObserverDelegateLight(selectorOrOptions?: EventListenerSelector | Omit<MutationObserverBaseOptions, 'delegate'>, maybeOptions?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator {
|
|
63
|
+
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
64
|
+
return mutationObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'light', delegate: true});
|
|
65
|
+
}
|
|
66
|
+
return mutationObserver({...selectorOrOptions ?? {}, root: 'light', delegate: true});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function mutationObserverDelegateShadow(selector: EventListenerSelector, options?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator;
|
|
70
|
+
export function mutationObserverDelegateShadow(options?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator;
|
|
71
|
+
export function mutationObserverDelegateShadow(selectorOrOptions?: EventListenerSelector | Omit<MutationObserverBaseOptions, 'delegate'>, maybeOptions?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator {
|
|
72
|
+
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
73
|
+
return mutationObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'shadow', delegate: true});
|
|
74
|
+
}
|
|
75
|
+
return mutationObserver({...selectorOrOptions ?? {}, root: 'shadow', delegate: true});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function mutationObserverDelegateAll(selector: EventListenerSelector, options?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator;
|
|
79
|
+
export function mutationObserverDelegateAll(options?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator;
|
|
80
|
+
export function mutationObserverDelegateAll(selectorOrOptions?: EventListenerSelector | Omit<MutationObserverBaseOptions, 'delegate'>, maybeOptions?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator {
|
|
81
|
+
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
82
|
+
return mutationObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'all', delegate: true});
|
|
83
|
+
}
|
|
84
|
+
return mutationObserver({...selectorOrOptions ?? {}, root: 'all', delegate: true});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function mutationObserverDelegate(selector: EventListenerSelector, options?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator;
|
|
88
|
+
export function mutationObserverDelegate(options?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator;
|
|
89
|
+
export function mutationObserverDelegate(selectorOrOptions?: EventListenerSelector | Omit<MutationObserverBaseOptions, 'delegate'>, maybeOptions?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator {
|
|
90
|
+
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
91
|
+
return mutationObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'auto', delegate: true});
|
|
92
|
+
}
|
|
93
|
+
return mutationObserver({...selectorOrOptions ?? {}, root: 'auto', delegate: true});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ─── root별 일반 헬퍼 (delegate 없이, 셀렉터 생략 시 $this) ───
|
|
97
|
+
|
|
98
|
+
export function mutationObserverLight(selector: EventListenerSelector, options?: MutationObserverBaseOptions): MethodDecorator;
|
|
99
|
+
export function mutationObserverLight(options?: MutationObserverBaseOptions): MethodDecorator;
|
|
100
|
+
export function mutationObserverLight(selectorOrOptions?: EventListenerSelector | MutationObserverBaseOptions, maybeOptions?: MutationObserverBaseOptions): MethodDecorator {
|
|
101
|
+
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
102
|
+
return mutationObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'light'});
|
|
103
|
+
}
|
|
104
|
+
return mutationObserver({...selectorOrOptions ?? {}, root: 'light'});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function mutationObserverShadow(selector: EventListenerSelector, options?: MutationObserverBaseOptions): MethodDecorator;
|
|
108
|
+
export function mutationObserverShadow(options?: MutationObserverBaseOptions): MethodDecorator;
|
|
109
|
+
export function mutationObserverShadow(selectorOrOptions?: EventListenerSelector | MutationObserverBaseOptions, maybeOptions?: MutationObserverBaseOptions): MethodDecorator {
|
|
110
|
+
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
111
|
+
return mutationObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'shadow'});
|
|
112
|
+
}
|
|
113
|
+
return mutationObserver({...selectorOrOptions ?? {}, root: 'shadow'});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function mutationObserverAll(selector: EventListenerSelector, options?: MutationObserverBaseOptions): MethodDecorator;
|
|
117
|
+
export function mutationObserverAll(options?: MutationObserverBaseOptions): MethodDecorator;
|
|
118
|
+
export function mutationObserverAll(selectorOrOptions?: EventListenerSelector | MutationObserverBaseOptions, maybeOptions?: MutationObserverBaseOptions): MethodDecorator {
|
|
119
|
+
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
120
|
+
return mutationObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'all'});
|
|
121
|
+
}
|
|
122
|
+
return mutationObserver({...selectorOrOptions ?? {}, root: 'all'});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function getMutationObserverMetadata(target: any): MutationObserverMetadata[] | undefined {
|
|
126
|
+
const constructor = target instanceof Function ? target : target.constructor;
|
|
127
|
+
return ReflectUtils.getMetadata(MUTATION_OBSERVER_METADATA_KEY, constructor);
|
|
128
|
+
}
|
package/src/decorators/query.ts
CHANGED
|
@@ -177,3 +177,26 @@ export const getQueryMetadata = (target: any): QueryMetadata[] => {
|
|
|
177
177
|
const constructor = target instanceof Function ? target : target.constructor;
|
|
178
178
|
return ReflectUtils.getMetadata(QUERY_METADATA_KEY, constructor) ?? [];
|
|
179
179
|
};
|
|
180
|
+
|
|
181
|
+
// ─── root별 편의 데코레이터 ───
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* @queryShadow(selector, options?) — shadow DOM에서 단일 요소를 쿼리
|
|
185
|
+
*/
|
|
186
|
+
export function queryShadow(selector: string | ((currentThis: any, helper: HelperHostSet) => Node | NodeList | Element | Element[] | null), options?: Omit<QueryOptions, 'root'>): PropertyDecorator {
|
|
187
|
+
return query(selector, {...options ?? {}, root: 'shadow'});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @queryLight(selector, options?) — light DOM에서 단일 요소를 쿼리
|
|
192
|
+
*/
|
|
193
|
+
export function queryLight(selector: string | ((currentThis: any, helper: HelperHostSet) => Node | NodeList | Element | Element[] | null), options?: Omit<QueryOptions, 'root'>): PropertyDecorator {
|
|
194
|
+
return query(selector, {...options ?? {}, root: 'light'});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @queryAll(selector, options?) — shadow+light 모두에서 요소를 쿼리
|
|
199
|
+
*/
|
|
200
|
+
export function queryAllRoots(selector: string | ((currentThis: any, helper: HelperHostSet) => Node | NodeList | Element | Element[] | null), options?: Omit<QueryOptions, 'root'>): PropertyDecorator {
|
|
201
|
+
return query(selector, {...options ?? {}, root: 'all'});
|
|
202
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { ReflectUtils } from '@dooboostore/core';
|
|
2
|
+
import { SpecialSelector, SwcQueryOptions, HelperHostSet } from '../types';
|
|
3
|
+
import { EventListenerSelector } from './addEventListener';
|
|
4
|
+
|
|
5
|
+
export interface ResizeObserverOptions extends SwcQueryOptions {
|
|
6
|
+
// 관찰 대상 셀렉터. 기본값 $this (컴포넌트 자신)
|
|
7
|
+
// delegate: true 인 경우 루트에서 매칭 요소들의 크기 변화를 감지 (동적 요소 포함)
|
|
8
|
+
delegate?: boolean;
|
|
9
|
+
// ResizeObserver box 옵션
|
|
10
|
+
box?: 'content-box' | 'border-box' | 'device-pixel-content-box';
|
|
11
|
+
filter?: (matchedEls: HTMLElement[], meta: { currentThis: any, helper: HelperHostSet }) => boolean;
|
|
12
|
+
// observer 해제(disconnected) 시 호출되는 콜백. 첫 번째 인자는 observe된 target element, 두 번째는 사용자 옵션 객체.
|
|
13
|
+
removeObserver?: (target: Element, optionValue: ResizeObserverOptions) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ResizeObserverMetadata {
|
|
17
|
+
propertyKey: string | symbol;
|
|
18
|
+
selector: EventListenerSelector;
|
|
19
|
+
options: ResizeObserverOptions;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const RESIZE_OBSERVER_METADATA_KEY = Symbol.for('simple-web-component:resize-observer');
|
|
23
|
+
|
|
24
|
+
export function resizeObserver(target: SpecialSelector, options?: ResizeObserverOptions): MethodDecorator;
|
|
25
|
+
export function resizeObserver(selector: EventListenerSelector, options?: ResizeObserverOptions): MethodDecorator;
|
|
26
|
+
export function resizeObserver(options?: ResizeObserverOptions): MethodDecorator;
|
|
27
|
+
/**
|
|
28
|
+
* @resizeObserver decorator to observe element size changes.
|
|
29
|
+
*/
|
|
30
|
+
export function resizeObserver(selectorOrOptions?: EventListenerSelector | ResizeObserverOptions, maybeOptions?: ResizeObserverOptions): MethodDecorator {
|
|
31
|
+
return (targetObj: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
|
|
32
|
+
let selector: EventListenerSelector = '$this';
|
|
33
|
+
let options: ResizeObserverOptions = {};
|
|
34
|
+
|
|
35
|
+
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
36
|
+
selector = selectorOrOptions;
|
|
37
|
+
options = maybeOptions ?? {};
|
|
38
|
+
} else {
|
|
39
|
+
selector = '$this';
|
|
40
|
+
options = selectorOrOptions ?? {};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const constructor = targetObj.constructor;
|
|
44
|
+
|
|
45
|
+
let observers = ReflectUtils.getMetadata<ResizeObserverMetadata[]>(RESIZE_OBSERVER_METADATA_KEY, constructor);
|
|
46
|
+
if (!observers) {
|
|
47
|
+
observers = [];
|
|
48
|
+
ReflectUtils.defineMetadata(RESIZE_OBSERVER_METADATA_KEY, observers, constructor);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
observers.push({ propertyKey, selector, options });
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function resizeObserverThis(options?: ResizeObserverOptions): MethodDecorator {
|
|
56
|
+
return resizeObserver('$this', options);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ─── root별 delegate 헬퍼 ───
|
|
60
|
+
|
|
61
|
+
export function resizeObserverDelegateLight(selector: EventListenerSelector, options?: Omit<ResizeObserverOptions, 'delegate'>): MethodDecorator;
|
|
62
|
+
export function resizeObserverDelegateLight(options?: Omit<ResizeObserverOptions, 'delegate'>): MethodDecorator;
|
|
63
|
+
export function resizeObserverDelegateLight(selectorOrOptions?: EventListenerSelector | Omit<ResizeObserverOptions, 'delegate'>, maybeOptions?: Omit<ResizeObserverOptions, 'delegate'>): MethodDecorator {
|
|
64
|
+
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
65
|
+
return resizeObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'light', delegate: true});
|
|
66
|
+
}
|
|
67
|
+
return resizeObserver({...selectorOrOptions ?? {}, root: 'light', delegate: true});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function resizeObserverDelegateShadow(selector: EventListenerSelector, options?: Omit<ResizeObserverOptions, 'delegate'>): MethodDecorator;
|
|
71
|
+
export function resizeObserverDelegateShadow(options?: Omit<ResizeObserverOptions, 'delegate'>): MethodDecorator;
|
|
72
|
+
export function resizeObserverDelegateShadow(selectorOrOptions?: EventListenerSelector | Omit<ResizeObserverOptions, 'delegate'>, maybeOptions?: Omit<ResizeObserverOptions, 'delegate'>): MethodDecorator {
|
|
73
|
+
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
74
|
+
return resizeObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'shadow', delegate: true});
|
|
75
|
+
}
|
|
76
|
+
return resizeObserver({...selectorOrOptions ?? {}, root: 'shadow', delegate: true});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function resizeObserverDelegateAll(selector: EventListenerSelector, options?: Omit<ResizeObserverOptions, 'delegate'>): MethodDecorator;
|
|
80
|
+
export function resizeObserverDelegateAll(options?: Omit<ResizeObserverOptions, 'delegate'>): MethodDecorator;
|
|
81
|
+
export function resizeObserverDelegateAll(selectorOrOptions?: EventListenerSelector | Omit<ResizeObserverOptions, 'delegate'>, maybeOptions?: Omit<ResizeObserverOptions, 'delegate'>): MethodDecorator {
|
|
82
|
+
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
83
|
+
return resizeObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'all', delegate: true});
|
|
84
|
+
}
|
|
85
|
+
return resizeObserver({...selectorOrOptions ?? {}, root: 'all', delegate: true});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function resizeObserverDelegate(selector: EventListenerSelector, options?: Omit<ResizeObserverOptions, 'delegate'>): MethodDecorator;
|
|
89
|
+
export function resizeObserverDelegate(options?: Omit<ResizeObserverOptions, 'delegate'>): MethodDecorator;
|
|
90
|
+
export function resizeObserverDelegate(selectorOrOptions?: EventListenerSelector | Omit<ResizeObserverOptions, 'delegate'>, maybeOptions?: Omit<ResizeObserverOptions, 'delegate'>): MethodDecorator {
|
|
91
|
+
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
92
|
+
return resizeObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'auto', delegate: true});
|
|
93
|
+
}
|
|
94
|
+
return resizeObserver({...selectorOrOptions ?? {}, root: 'auto', delegate: true});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ─── root별 일반 헬퍼 (delegate 없이, 셀렉터 생략 시 $this) ───
|
|
98
|
+
|
|
99
|
+
export function resizeObserverLight(selector: EventListenerSelector, options?: ResizeObserverOptions): MethodDecorator;
|
|
100
|
+
export function resizeObserverLight(options?: ResizeObserverOptions): MethodDecorator;
|
|
101
|
+
export function resizeObserverLight(selectorOrOptions?: EventListenerSelector | ResizeObserverOptions, maybeOptions?: ResizeObserverOptions): MethodDecorator {
|
|
102
|
+
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
103
|
+
return resizeObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'light'});
|
|
104
|
+
}
|
|
105
|
+
return resizeObserver({...selectorOrOptions ?? {}, root: 'light'});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function resizeObserverShadow(selector: EventListenerSelector, options?: ResizeObserverOptions): MethodDecorator;
|
|
109
|
+
export function resizeObserverShadow(options?: ResizeObserverOptions): MethodDecorator;
|
|
110
|
+
export function resizeObserverShadow(selectorOrOptions?: EventListenerSelector | ResizeObserverOptions, maybeOptions?: ResizeObserverOptions): MethodDecorator {
|
|
111
|
+
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
112
|
+
return resizeObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'shadow'});
|
|
113
|
+
}
|
|
114
|
+
return resizeObserver({...selectorOrOptions ?? {}, root: 'shadow'});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function resizeObserverAll(selector: EventListenerSelector, options?: ResizeObserverOptions): MethodDecorator;
|
|
118
|
+
export function resizeObserverAll(options?: ResizeObserverOptions): MethodDecorator;
|
|
119
|
+
export function resizeObserverAll(selectorOrOptions?: EventListenerSelector | ResizeObserverOptions, maybeOptions?: ResizeObserverOptions): MethodDecorator {
|
|
120
|
+
if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
|
|
121
|
+
return resizeObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'all'});
|
|
122
|
+
}
|
|
123
|
+
return resizeObserver({...selectorOrOptions ?? {}, root: 'all'});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function getResizeObserverMetadata(target: any): ResizeObserverMetadata[] | undefined {
|
|
127
|
+
const constructor = target instanceof Function ? target : target.constructor;
|
|
128
|
+
return ReflectUtils.getMetadata(RESIZE_OBSERVER_METADATA_KEY, constructor);
|
|
129
|
+
}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: Using RxJS-like Operators with @addEventListener
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates how to use debounceTime, throttleTime, and distinctUntilChanged
|
|
5
|
+
* operators with the @addEventListener decorator.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { elementDefine, addEventListener } from '../decorators';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Example 1: Search Component with Debounce
|
|
12
|
+
*
|
|
13
|
+
* Waits 1 second after user stops typing before performing search.
|
|
14
|
+
* Prevents excessive API calls during typing.
|
|
15
|
+
*/
|
|
16
|
+
@elementDefine('search-component')
|
|
17
|
+
export class SearchComponent extends HTMLElement {
|
|
18
|
+
private results: any[] = [];
|
|
19
|
+
|
|
20
|
+
@addEventListener('$this', 'input', { debounceTime: 1000 })
|
|
21
|
+
async onSearchInput(event: Event) {
|
|
22
|
+
const input = event.target as HTMLInputElement;
|
|
23
|
+
const query = input.value.trim();
|
|
24
|
+
|
|
25
|
+
if (query.length > 2) {
|
|
26
|
+
try {
|
|
27
|
+
// Simulate API call
|
|
28
|
+
const response = await fetch(`/api/search?q=${encodeURIComponent(query)}`);
|
|
29
|
+
this.results = await response.json();
|
|
30
|
+
this.renderResults();
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.error('Search failed:', error);
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
this.results = [];
|
|
36
|
+
this.renderResults();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private renderResults() {
|
|
41
|
+
// Render search results
|
|
42
|
+
console.log('Rendering results:', this.results);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Example 2: Window Resize Handler with Throttle
|
|
48
|
+
*
|
|
49
|
+
* Recalculates layout at most 4 times per second (every 250ms).
|
|
50
|
+
* Prevents performance issues from excessive resize calculations.
|
|
51
|
+
*/
|
|
52
|
+
@elementDefine('responsive-layout')
|
|
53
|
+
export class ResponsiveLayout extends HTMLElement {
|
|
54
|
+
@addEventListener('$window', 'resize', { throttleTime: 250 })
|
|
55
|
+
onWindowResize(event: Event) {
|
|
56
|
+
const width = window.innerWidth;
|
|
57
|
+
const height = window.innerHeight;
|
|
58
|
+
|
|
59
|
+
console.log(`Window resized to: ${width}x${height}`);
|
|
60
|
+
this.updateLayout(width, height);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private updateLayout(width: number, height: number) {
|
|
64
|
+
// Update layout based on new dimensions
|
|
65
|
+
if (width < 768) {
|
|
66
|
+
this.classList.add('mobile');
|
|
67
|
+
this.classList.remove('desktop');
|
|
68
|
+
} else {
|
|
69
|
+
this.classList.add('desktop');
|
|
70
|
+
this.classList.remove('mobile');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Example 3: Form Input with Debounce + Distinct
|
|
77
|
+
*
|
|
78
|
+
* Validates field only when:
|
|
79
|
+
* 1. User stops typing (debounce 300ms)
|
|
80
|
+
* 2. AND the value actually changed (distinct)
|
|
81
|
+
*/
|
|
82
|
+
@elementDefine('form-input')
|
|
83
|
+
export class FormInput extends HTMLElement {
|
|
84
|
+
@addEventListener('$this', 'input', {
|
|
85
|
+
debounceTime: 300,
|
|
86
|
+
distinctUntilChanged: true
|
|
87
|
+
})
|
|
88
|
+
onFormInput(event: Event) {
|
|
89
|
+
const input = event.target as HTMLInputElement;
|
|
90
|
+
const fieldName = input.name;
|
|
91
|
+
const value = input.value;
|
|
92
|
+
|
|
93
|
+
console.log(`Validating ${fieldName}: ${value}`);
|
|
94
|
+
this.validateField(fieldName, value);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private validateField(name: string, value: string) {
|
|
98
|
+
// Perform validation
|
|
99
|
+
const isValid = value.length > 0;
|
|
100
|
+
console.log(`Field ${name} is ${isValid ? 'valid' : 'invalid'}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Example 4: Scroll Event with Throttle
|
|
106
|
+
*
|
|
107
|
+
* Checks if user scrolled to bottom at most 10 times per second.
|
|
108
|
+
* Prevents excessive "load more" API calls.
|
|
109
|
+
*/
|
|
110
|
+
@elementDefine('infinite-scroll')
|
|
111
|
+
export class InfiniteScroll extends HTMLElement {
|
|
112
|
+
private isLoading = false;
|
|
113
|
+
|
|
114
|
+
@addEventListener('$window', 'scroll', { throttleTime: 100 })
|
|
115
|
+
onScroll(event: Event) {
|
|
116
|
+
if (this.isLoading) return;
|
|
117
|
+
|
|
118
|
+
if (this.isNearBottom()) {
|
|
119
|
+
console.log('Near bottom, loading more content...');
|
|
120
|
+
this.loadMoreContent();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private isNearBottom(): boolean {
|
|
125
|
+
const scrollTop = window.scrollY;
|
|
126
|
+
const windowHeight = window.innerHeight;
|
|
127
|
+
const documentHeight = document.documentElement.scrollHeight;
|
|
128
|
+
|
|
129
|
+
return scrollTop + windowHeight >= documentHeight - 500;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private async loadMoreContent() {
|
|
133
|
+
this.isLoading = true;
|
|
134
|
+
try {
|
|
135
|
+
// Simulate API call
|
|
136
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
137
|
+
console.log('Content loaded');
|
|
138
|
+
} finally {
|
|
139
|
+
this.isLoading = false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Example 5: Custom Comparison with Distinct
|
|
146
|
+
*
|
|
147
|
+
* Only fires when the input value length changes.
|
|
148
|
+
* Ignores changes that don't affect the length.
|
|
149
|
+
*/
|
|
150
|
+
@elementDefine('length-tracker')
|
|
151
|
+
export class LengthTracker extends HTMLElement {
|
|
152
|
+
@addEventListener('$this', 'input', {
|
|
153
|
+
distinctUntilChanged: (prev: any, curr: any) => {
|
|
154
|
+
// Only consider it changed if the length differs
|
|
155
|
+
return prev?.length === curr?.length;
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
onInputChange(event: Event) {
|
|
159
|
+
const input = event.target as HTMLInputElement;
|
|
160
|
+
const length = input.value.length;
|
|
161
|
+
|
|
162
|
+
console.log(`Input length changed to: ${length}`);
|
|
163
|
+
this.updateLengthDisplay(length);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
private updateLengthDisplay(length: number) {
|
|
167
|
+
// Update UI with new length
|
|
168
|
+
const display = this.querySelector('.length-display');
|
|
169
|
+
if (display) {
|
|
170
|
+
display.textContent = `${length} characters`;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Example 6: Complex Scenario - Auto-save with Multiple Operators
|
|
177
|
+
*
|
|
178
|
+
* Combines debounce and distinct for intelligent auto-save:
|
|
179
|
+
* - Waits 2 seconds after user stops typing
|
|
180
|
+
* - Only saves if content actually changed
|
|
181
|
+
* - Prevents unnecessary save operations
|
|
182
|
+
*/
|
|
183
|
+
@elementDefine('auto-save-editor')
|
|
184
|
+
export class AutoSaveEditor extends HTMLElement {
|
|
185
|
+
private lastSavedContent = '';
|
|
186
|
+
|
|
187
|
+
@addEventListener('$this', 'input', {
|
|
188
|
+
debounceTime: 2000,
|
|
189
|
+
distinctUntilChanged: (prev: any, curr: any) => {
|
|
190
|
+
// Consider changed if the content is different
|
|
191
|
+
return prev === curr;
|
|
192
|
+
}
|
|
193
|
+
})
|
|
194
|
+
async onContentChange(event: Event) {
|
|
195
|
+
const textarea = event.target as HTMLTextAreaElement;
|
|
196
|
+
const content = textarea.value;
|
|
197
|
+
|
|
198
|
+
if (content !== this.lastSavedContent) {
|
|
199
|
+
console.log('Auto-saving content...');
|
|
200
|
+
await this.saveContent(content);
|
|
201
|
+
this.lastSavedContent = content;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
private async saveContent(content: string) {
|
|
206
|
+
try {
|
|
207
|
+
// Simulate API call
|
|
208
|
+
const response = await fetch('/api/save', {
|
|
209
|
+
method: 'POST',
|
|
210
|
+
headers: { 'Content-Type': 'application/json' },
|
|
211
|
+
body: JSON.stringify({ content })
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
if (response.ok) {
|
|
215
|
+
console.log('Content saved successfully');
|
|
216
|
+
this.showSaveIndicator();
|
|
217
|
+
}
|
|
218
|
+
} catch (error) {
|
|
219
|
+
console.error('Save failed:', error);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
private showSaveIndicator() {
|
|
224
|
+
const indicator = this.querySelector('.save-indicator');
|
|
225
|
+
if (indicator) {
|
|
226
|
+
indicator.classList.add('show');
|
|
227
|
+
setTimeout(() => indicator.classList.remove('show'), 2000);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Example 7: Keyboard Shortcut Handler with Throttle
|
|
234
|
+
*
|
|
235
|
+
* Prevents rapid repeated execution of keyboard shortcuts.
|
|
236
|
+
*/
|
|
237
|
+
@elementDefine('keyboard-handler')
|
|
238
|
+
export class KeyboardHandler extends HTMLElement {
|
|
239
|
+
@addEventListener('$document', 'keydown', {
|
|
240
|
+
throttleTime: 500,
|
|
241
|
+
filter: (event: KeyboardEvent) => {
|
|
242
|
+
// Only handle Ctrl+S or Cmd+S
|
|
243
|
+
return (event.ctrlKey || event.metaKey) && event.key === 's';
|
|
244
|
+
}
|
|
245
|
+
})
|
|
246
|
+
onSaveShortcut(event: KeyboardEvent) {
|
|
247
|
+
event.preventDefault();
|
|
248
|
+
console.log('Save shortcut triggered');
|
|
249
|
+
this.handleSave();
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
private handleSave() {
|
|
253
|
+
// Handle save operation
|
|
254
|
+
console.log('Saving...');
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Example 8: Mouse Move Tracking with Throttle
|
|
260
|
+
*
|
|
261
|
+
* Tracks mouse position at most 10 times per second.
|
|
262
|
+
* Useful for analytics or interactive features.
|
|
263
|
+
*/
|
|
264
|
+
@elementDefine('mouse-tracker')
|
|
265
|
+
export class MouseTracker extends HTMLElement {
|
|
266
|
+
@addEventListener('$document', 'mousemove', { throttleTime: 100 })
|
|
267
|
+
onMouseMove(event: MouseEvent) {
|
|
268
|
+
const x = event.clientX;
|
|
269
|
+
const y = event.clientY;
|
|
270
|
+
|
|
271
|
+
// Update cursor position indicator
|
|
272
|
+
this.updateCursorPosition(x, y);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
private updateCursorPosition(x: number, y: number) {
|
|
276
|
+
// Update UI with cursor position
|
|
277
|
+
console.log(`Cursor at: ${x}, ${y}`);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=SwcAppMixin.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=SwcAsync.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=SwcAsyncTemplate.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=SwcChoose.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=SwcChooseTemplate.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=SwcIf.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=SwcIfTemplate.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=SwcLoop.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=SwcLoopTemplate.js.map
|