@dooboostore/simple-web-component 1.0.47 → 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/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/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 +446 -13
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
- 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 +446 -13
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
- package/package.json +4 -4
- 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
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import {ActionExpression, FunctionUtils, ReflectUtils, Subject} from '@dooboostore/core';
|
|
2
2
|
import {debounceTime, distinctUntilChanged, throttleTime} from '@dooboostore/core/message/operators';
|
|
3
3
|
import {getAddEventListenerMetadata} from './addEventListener';
|
|
4
|
+
import {getMutationObserverMetadata} from './mutationObserver';
|
|
5
|
+
import type {MutationObserverBaseOptions, MutationObserverMetadata} from './mutationObserver';
|
|
6
|
+
import {getResizeObserverMetadata} from './resizeObserver';
|
|
7
|
+
import type {ResizeObserverMetadata} from './resizeObserver';
|
|
4
8
|
import {findAllLifecycleMetadata, findAllOnConnectedAfterMetadata, findAllOnConnectedBeforeMetadata, findAllOnConnectedMetadata, ON_AFTER_ADOPTED_METADATA_KEY, ON_AFTER_DISCONNECTED_METADATA_KEY, ON_BEFORE_ADOPTED_METADATA_KEY, ON_BEFORE_DISCONNECTED_METADATA_KEY, ON_CONNECTED_COMPLETED_METADATA_KEY, ON_INITIALIZE_METADATA_KEY} from './lifecycles';
|
|
5
9
|
import {getEmitCustomEventMetadataList} from './emitCustomEvent';
|
|
6
10
|
import {convertAttributeValue, findAllAttributeChangedMetadata} from './changedAttribute';
|
|
@@ -20,6 +24,16 @@ import {findAllPropertyMetadata} from "./applyProperty";
|
|
|
20
24
|
|
|
21
25
|
export const ELEMENT_CONFIG_KEY = Symbol.for('simple-web-component:element-config');
|
|
22
26
|
|
|
27
|
+
/** 바인딩된 이벤트 리스너 한 건 */
|
|
28
|
+
export interface BoundListener {
|
|
29
|
+
target: EventTarget;
|
|
30
|
+
type: string;
|
|
31
|
+
handler: EventListener;
|
|
32
|
+
options: AddEventListenerOptions;
|
|
33
|
+
onRemoves?: Array<{ fn: (target: EventTarget, optionValue: unknown) => void; opts: unknown }>;
|
|
34
|
+
subscription?: { unsubscribe: () => void };
|
|
35
|
+
}
|
|
36
|
+
|
|
23
37
|
export interface ElementConfig {
|
|
24
38
|
extends?: string;
|
|
25
39
|
observedAttributes?: string[];
|
|
@@ -42,7 +56,6 @@ export const ensureInit = (inst: any) => { // HTMLElement
|
|
|
42
56
|
if (!inst.__swc_initialized) {
|
|
43
57
|
inst._swcId = inst?.getAttribute?.('swc-use-ssr') ?? 's' + Math.random().toString(36).substring(2, 11).toLowerCase();
|
|
44
58
|
inst._emitHandlers = new Map();
|
|
45
|
-
inst._boundListeners = [];
|
|
46
59
|
inst.__swc_initialized = true;
|
|
47
60
|
// const attributeList = findAllQ(inst);
|
|
48
61
|
// attributeList.forEach(meta => {
|
|
@@ -318,8 +331,8 @@ const setupPrototype = (proto: any, win: Window) => {
|
|
|
318
331
|
export const elementDefine =
|
|
319
332
|
(name: string, config: Partial<ElementConfig> = {}): ClassDecorator =>
|
|
320
333
|
(constructor: any) => {
|
|
321
|
-
const {win, doc, builtInTagMap: BUILT_IN_TAG_MAP, domHelpers: SWC_DOM_HELPERS} = buildEnv(config.window);
|
|
322
|
-
const metadata: ElementMetadata = {...config, name, window: win};
|
|
334
|
+
const { win, doc, builtInTagMap: BUILT_IN_TAG_MAP, domHelpers: SWC_DOM_HELPERS } = buildEnv(config.window);
|
|
335
|
+
const metadata: ElementMetadata = { ...config, name, window: win };
|
|
323
336
|
|
|
324
337
|
if (!metadata.window) {
|
|
325
338
|
throw new Error('window is required');
|
|
@@ -340,6 +353,8 @@ export const elementDefine =
|
|
|
340
353
|
const emitCustomEventList = getEmitCustomEventMetadataList(constructor) || [];
|
|
341
354
|
const emitHostCustomEventList = emitCustomEventList.filter(meta => meta.selector === '$this' || meta.selector === '');
|
|
342
355
|
const addEventListenerList = getAddEventListenerMetadata(constructor) || [];
|
|
356
|
+
const mutationObserverList = getMutationObserverMetadata(constructor) || [];
|
|
357
|
+
const resizeObserverList = getResizeObserverMetadata(constructor) || [];
|
|
343
358
|
const attrChangeMap = findAllAttributeChangedMetadata(constructor);
|
|
344
359
|
const attributeList = findAllAttributeMetadata(constructor);
|
|
345
360
|
const applyAttributeMap = findAllAttributeApplyMetadata(constructor);
|
|
@@ -361,9 +376,22 @@ export const elementDefine =
|
|
|
361
376
|
|
|
362
377
|
// 값을 기대하지않는다.
|
|
363
378
|
let helperHostSet: HelperHostSet | null = null;
|
|
379
|
+
// 이벤트 리스너 / MutationObserver / ResizeObserver 인스턴스 (클로저 변수 — connected/disconnected 공유)
|
|
380
|
+
let boundListeners: BoundListener[] = [];
|
|
381
|
+
let shadowMutationObserver: MutationObserver | null = null;
|
|
382
|
+
let lightMutationObserver: MutationObserver | null = null;
|
|
383
|
+
let resizeObserver: ResizeObserver | null = null;
|
|
384
|
+
// 생성된 모든 track(Mutation)Observer (disconnected 시 정리)
|
|
385
|
+
let resizeObservers: Array<ResizeObserver | MutationObserver> = [];
|
|
386
|
+
// 메타별 removeObserver 콜백 목록 (disconnected 시 호출)
|
|
387
|
+
let removeObserverCallbacks: Array<{ fn: (target: Element, optionValue: unknown) => void; target: any; opts: unknown }> = [];
|
|
364
388
|
const originalConnected = proto.connectedCallback;
|
|
365
389
|
proto.connectedCallback = async function () {
|
|
366
390
|
ensureInit(this);
|
|
391
|
+
// 재연결 시 누적 방지 — 클로저 변수 리셋
|
|
392
|
+
boundListeners = [];
|
|
393
|
+
resizeObservers = [];
|
|
394
|
+
removeObserverCallbacks = [];
|
|
367
395
|
// connected 됐을시 최신화
|
|
368
396
|
helperHostSet = SwcUtils.getHelperAndHostSet(win, this as any);
|
|
369
397
|
const appHost = helperHostSet.$appHost;
|
|
@@ -383,7 +411,7 @@ export const elementDefine =
|
|
|
383
411
|
const conf = getElementConfig(this);
|
|
384
412
|
const currentWin = (this as any)._resolveWindow(conf);
|
|
385
413
|
|
|
386
|
-
const bMethods = findAllOnConnectedBeforeMetadata(this)
|
|
414
|
+
const bMethods = findAllOnConnectedBeforeMetadata(this); //.filter(it => useSsr ? !it.options.ssrFirst : true);
|
|
387
415
|
// console.log('beforeConnected', bMethods)
|
|
388
416
|
for (const m of bMethods) await (this as any)._invokeLifecycleMethod(m.propertyKey, helperHostSet);
|
|
389
417
|
(this as any)._executeSwcScript('swc-on-before-connected', helperHostSet);
|
|
@@ -398,19 +426,19 @@ export const elementDefine =
|
|
|
398
426
|
const mode = shadowMode === true ? 'open' : shadowMode;
|
|
399
427
|
console.log('tagName=', this.tagName, 'mode', mode, this.shadowRoot);
|
|
400
428
|
// if (this.tagName!=='INDEX-ROUTER') {
|
|
401
|
-
|
|
429
|
+
this.attachShadow({ mode: mode as ShadowRootMode });
|
|
402
430
|
// }
|
|
403
431
|
}
|
|
404
432
|
|
|
405
|
-
const stateContext: any = {...helperHostSet};
|
|
433
|
+
const stateContext: any = { ...helperHostSet };
|
|
406
434
|
findAllStateMetadata(this).forEach(it => {
|
|
407
|
-
stateContext[it.name] = this[it.propertyKey]
|
|
408
|
-
})
|
|
435
|
+
stateContext[it.name] = this[it.propertyKey];
|
|
436
|
+
});
|
|
409
437
|
|
|
410
438
|
const shadowChildren: Node[] = [];
|
|
411
439
|
const lightChildren: Node[] = [];
|
|
412
440
|
|
|
413
|
-
console.log('targetConnectList', this.tagName, targetConnectedList.length)
|
|
441
|
+
console.log('targetConnectList', this.tagName, targetConnectedList.length);
|
|
414
442
|
if (targetConnectedList.length > 0) {
|
|
415
443
|
// let sContent = '',
|
|
416
444
|
// lContent = '';
|
|
@@ -420,7 +448,7 @@ export const elementDefine =
|
|
|
420
448
|
// res = SwcUtils.projectProcessHtml(this, res);
|
|
421
449
|
if (typeof res === 'string') {
|
|
422
450
|
const htmlTemplateElement = doc.createElement('template');
|
|
423
|
-
htmlTemplateElement.innerHTML = res
|
|
451
|
+
htmlTemplateElement.innerHTML = res; //SwcUtils.projectProcessHtml(this._swcId, res, doc);
|
|
424
452
|
res = htmlTemplateElement.content;
|
|
425
453
|
}
|
|
426
454
|
|
|
@@ -428,7 +456,7 @@ export const elementDefine =
|
|
|
428
456
|
const nodes = Array.isArray(res) ? res : [res];
|
|
429
457
|
if (meta.options.useShadow || conf?.useShadow) {
|
|
430
458
|
shadowChildren.push(...nodes);
|
|
431
|
-
}else {
|
|
459
|
+
} else {
|
|
432
460
|
lightChildren.push(...nodes);
|
|
433
461
|
}
|
|
434
462
|
}
|
|
@@ -436,23 +464,22 @@ export const elementDefine =
|
|
|
436
464
|
try {
|
|
437
465
|
if (this.shadowRoot) {
|
|
438
466
|
const applyShadowChildren = SwcUtils.projectProcessHtml(this._swcId, shadowChildren, doc);
|
|
439
|
-
this.shadowRoot.replaceChildren(...applyShadowChildren)
|
|
467
|
+
this.shadowRoot.replaceChildren(...applyShadowChildren);
|
|
440
468
|
}
|
|
441
469
|
if (lightChildren.length) {
|
|
442
470
|
const applyLightChildren = SwcUtils.projectProcessHtml(this._swcId, lightChildren, doc);
|
|
443
|
-
this.replaceChildren(...applyLightChildren)
|
|
471
|
+
this.replaceChildren(...applyLightChildren);
|
|
444
472
|
}
|
|
445
|
-
|
|
446
473
|
} catch (e) {
|
|
447
474
|
console.error('[ElementDefine] innerHTML setting error:', e);
|
|
448
475
|
}
|
|
449
|
-
new ElementApply(this, {id: this._swcId}).apply({context: stateContext, bind: this});
|
|
476
|
+
new ElementApply(this, { id: this._swcId }).apply({ context: stateContext, bind: this });
|
|
450
477
|
} else {
|
|
451
|
-
new ElementApply(this, {id: this._swcId}).apply({exclude: {html: true, text: true, attribute: true}, context: stateContext, bind: this});
|
|
478
|
+
new ElementApply(this, { id: this._swcId }).apply({ exclude: { html: true, text: true, attribute: true }, context: stateContext, bind: this });
|
|
452
479
|
}
|
|
453
480
|
|
|
454
481
|
// global delegate event
|
|
455
|
-
const root = this.getRootNode()
|
|
482
|
+
const root = this.getRootNode();
|
|
456
483
|
if (!globalDelegatedRoots.has(root)) {
|
|
457
484
|
DOM_EVENT_NAMES.forEach(type => {
|
|
458
485
|
root.addEventListener(type, handleGlobalSwcEvent);
|
|
@@ -460,7 +487,6 @@ export const elementDefine =
|
|
|
460
487
|
globalDelegatedRoots.add(root);
|
|
461
488
|
}
|
|
462
489
|
|
|
463
|
-
|
|
464
490
|
// Separate delegate and non-delegate listeners
|
|
465
491
|
const delegateListeners: typeof addEventListenerList = [];
|
|
466
492
|
const nonDelegateListeners: typeof addEventListenerList = [];
|
|
@@ -488,7 +514,7 @@ export const elementDefine =
|
|
|
488
514
|
delegatesByTypeAndRoot.forEach((metaList, typeRootKey) => {
|
|
489
515
|
const [type, rStr] = typeRootKey.split(':');
|
|
490
516
|
const r = rStr === 'auto' ? 'auto' : rStr;
|
|
491
|
-
const opts = {capture: metaList[0].options.capture, once: metaList[0].options.once, passive: metaList[0].options.passive};
|
|
517
|
+
const opts = { capture: metaList[0].options.capture, once: metaList[0].options.once, passive: metaList[0].options.passive };
|
|
492
518
|
|
|
493
519
|
const bindRoots: (HTMLElement | ShadowRoot)[] = [];
|
|
494
520
|
if (r === 'auto') bindRoots.push(this.shadowRoot || (this as any));
|
|
@@ -508,7 +534,7 @@ export const elementDefine =
|
|
|
508
534
|
|
|
509
535
|
const unifiedHandler = async (event: Event) => {
|
|
510
536
|
for (const meta of sortedMetaList) {
|
|
511
|
-
const {selector, options} = meta;
|
|
537
|
+
const { selector, options } = meta;
|
|
512
538
|
const matchedEl = (event.target as HTMLElement)?.closest(selector);
|
|
513
539
|
if (matchedEl && (br as any).contains(matchedEl)) {
|
|
514
540
|
// Apply filter if specified
|
|
@@ -522,23 +548,30 @@ export const elementDefine =
|
|
|
522
548
|
if (options.stopImmediatePropagation) event.stopImmediatePropagation();
|
|
523
549
|
if (options.preventDefault) event.preventDefault();
|
|
524
550
|
const currentHostSet = SwcUtils.getHostSet(this as any);
|
|
525
|
-
const args = {event, ...currentHostSet, $el: matchedEl, $root: br};
|
|
526
|
-
await (this as any)[meta.propertyKey](event, {...currentHostSet, $matchedElement: matchedEl}, args);
|
|
551
|
+
const args = { event, ...currentHostSet, $el: matchedEl, $root: br };
|
|
552
|
+
await (this as any)[meta.propertyKey](event, { ...currentHostSet, $matchedElement: matchedEl }, args);
|
|
527
553
|
if ((event as any).cancelBubble) break;
|
|
528
554
|
}
|
|
529
555
|
}
|
|
530
556
|
};
|
|
531
557
|
br.addEventListener(type, unifiedHandler, opts);
|
|
532
|
-
|
|
558
|
+
// 각 메타의 removeListener를 메타 옵션과 함께 보관 (delegate 그룹은 여러 메타 가능)
|
|
559
|
+
const onRemoves: Array<{ fn: (target: Element, optionValue: any) => void; opts: any }> = [];
|
|
560
|
+
for (const m of sortedMetaList) {
|
|
561
|
+
if (m.options.removeListener) {
|
|
562
|
+
onRemoves.push({ fn: m.options.removeListener, opts: m.options });
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
boundListeners.push({ target: br, type, handler: unifiedHandler, options: opts, onRemoves });
|
|
533
566
|
});
|
|
534
567
|
});
|
|
535
568
|
|
|
536
569
|
nonDelegateListeners.forEach(meta => {
|
|
537
|
-
const {selector, type, options} = meta;
|
|
538
|
-
const opts = {capture: options.capture, once: options.once, passive: options.passive};
|
|
570
|
+
const { selector, type, options } = meta;
|
|
571
|
+
const opts = { capture: options.capture, once: options.once, passive: options.passive };
|
|
539
572
|
const bindTargets: EventTarget[] = [];
|
|
540
573
|
const r = options.root || 'auto';
|
|
541
|
-
|
|
574
|
+
|
|
542
575
|
// Resolve selector if it's a function
|
|
543
576
|
let resolvedSelector: string | null = null;
|
|
544
577
|
if (typeof selector === 'function') {
|
|
@@ -556,7 +589,7 @@ export const elementDefine =
|
|
|
556
589
|
} else {
|
|
557
590
|
resolvedSelector = selector;
|
|
558
591
|
}
|
|
559
|
-
|
|
592
|
+
|
|
560
593
|
const applyRootOption = (target: any) => {
|
|
561
594
|
if (!target) return;
|
|
562
595
|
if (r === 'auto') {
|
|
@@ -601,7 +634,7 @@ export const elementDefine =
|
|
|
601
634
|
// Apply filter if specified
|
|
602
635
|
if (options.filter) {
|
|
603
636
|
const helper = SwcUtils.getHelperAndHostSet(currentWin, t as HTMLElement);
|
|
604
|
-
if (!options.filter(event, {currentThis: this, helper})) {
|
|
637
|
+
if (!options.filter(event, { currentThis: this, helper })) {
|
|
605
638
|
return; // Skip if filter returns false
|
|
606
639
|
}
|
|
607
640
|
}
|
|
@@ -609,23 +642,23 @@ export const elementDefine =
|
|
|
609
642
|
if (options.stopImmediatePropagation) event.stopImmediatePropagation();
|
|
610
643
|
if (options.preventDefault) event.preventDefault();
|
|
611
644
|
const currentHostSet = SwcUtils.getHostSet(this as any);
|
|
612
|
-
const args = {event, ...currentHostSet, $el: t, $root: t};
|
|
613
|
-
await (this as any)[meta.propertyKey](event, {currentHostSet, $matchedElement: event.currentTarget}, args);
|
|
645
|
+
const args = { event, ...currentHostSet, $el: t, $root: t };
|
|
646
|
+
await (this as any)[meta.propertyKey](event, { currentHostSet, $matchedElement: event.currentTarget }, args);
|
|
614
647
|
};
|
|
615
|
-
|
|
648
|
+
|
|
616
649
|
// Create event stream with Observable-based operators
|
|
617
650
|
const eventSubject = new Subject<Event>();
|
|
618
651
|
let eventStream = eventSubject as any;
|
|
619
|
-
|
|
652
|
+
|
|
620
653
|
// Apply operators from @dooboostore/core/operators
|
|
621
654
|
if (options.debounceTime !== undefined && options.debounceTime > 0) {
|
|
622
655
|
eventStream = eventStream.pipe(debounceTime(options.debounceTime));
|
|
623
656
|
}
|
|
624
|
-
|
|
657
|
+
|
|
625
658
|
if (options.throttleTime !== undefined && options.throttleTime > 0) {
|
|
626
659
|
eventStream = eventStream.pipe(throttleTime(options.throttleTime));
|
|
627
660
|
}
|
|
628
|
-
|
|
661
|
+
|
|
629
662
|
if (options.distinctUntilChanged !== undefined && options.distinctUntilChanged !== false) {
|
|
630
663
|
if (typeof options.distinctUntilChanged === 'function') {
|
|
631
664
|
eventStream = eventStream.pipe(distinctUntilChanged(options.distinctUntilChanged));
|
|
@@ -633,7 +666,7 @@ export const elementDefine =
|
|
|
633
666
|
eventStream = eventStream.pipe(distinctUntilChanged());
|
|
634
667
|
}
|
|
635
668
|
}
|
|
636
|
-
|
|
669
|
+
|
|
637
670
|
// Subscribe to the event stream
|
|
638
671
|
const subscription = eventStream.subscribe({
|
|
639
672
|
next: (event: Event) => {
|
|
@@ -641,18 +674,230 @@ export const elementDefine =
|
|
|
641
674
|
},
|
|
642
675
|
error: (err: any) => console.error('Event stream error:', err)
|
|
643
676
|
});
|
|
644
|
-
|
|
677
|
+
|
|
645
678
|
// Create wrapper handler that emits to the subject
|
|
646
679
|
const wrappedHandler = (event: Event) => {
|
|
647
680
|
eventSubject.next(event);
|
|
648
681
|
};
|
|
649
|
-
|
|
682
|
+
|
|
650
683
|
t.addEventListener(type, wrappedHandler, opts);
|
|
651
|
-
|
|
684
|
+
const onRemoves: Array<{ fn: (target: Element, optionValue: any) => void; opts: any }> = options.removeListener ? [{ fn: options.removeListener, opts }] : [];
|
|
685
|
+
boundListeners.push({ target: t, type, handler: wrappedHandler, options: opts, subscription, onRemoves });
|
|
686
|
+
});
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
// ─── MutationObserver / ResizeObserver 처리 ───
|
|
690
|
+
// shadow/light 루트별로 각각 observer를 두고, 해당 루트에 데코레이터 메타가 있으면 observer를 생성한다.
|
|
691
|
+
// 두 루트 모두 있으면 observer 2개, 한쪽만 있으면 1개, 없으면 0개.
|
|
692
|
+
shadowMutationObserver = null;
|
|
693
|
+
lightMutationObserver = null;
|
|
694
|
+
resizeObserver = null;
|
|
695
|
+
|
|
696
|
+
// ResizeObserver: @resizeObserver 데코레이터가 하나라도 있으면 observer 하나 생성 (shadow 있으면 shadow 루트, 없으면 light)
|
|
697
|
+
if (resizeObserverList.length > 0) {
|
|
698
|
+
const root: HTMLElement | ShadowRoot = this.shadowRoot || (this as any);
|
|
699
|
+
resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[], obs: ResizeObserver) => {
|
|
700
|
+
for (const m of resizeObserverList) {
|
|
701
|
+
let matchedEls: HTMLElement[] = [];
|
|
702
|
+
if (m.options.delegate && typeof m.selector === 'string') {
|
|
703
|
+
const isThis = m.selector === '$this' || m.selector === '';
|
|
704
|
+
const matchesSel = (node: any): boolean => {
|
|
705
|
+
if (!node || node.nodeType !== 1) return false;
|
|
706
|
+
if (isThis) return true;
|
|
707
|
+
const el = node as HTMLElement;
|
|
708
|
+
return el.matches?.(m.selector as string) || !!el.closest?.(m.selector as string);
|
|
709
|
+
};
|
|
710
|
+
matchedEls = entries.map(e => e.target as HTMLElement).filter(matchesSel);
|
|
711
|
+
} else {
|
|
712
|
+
matchedEls = entries.map(e => e.target as HTMLElement).filter(t => t && t.nodeType === 1);
|
|
713
|
+
}
|
|
714
|
+
if (matchedEls.length === 0) continue;
|
|
715
|
+
if (m.options.filter) {
|
|
716
|
+
const helper = SwcUtils.getHelperAndHostSet(currentWin, this);
|
|
717
|
+
if (!m.options.filter(matchedEls, { currentThis: this, helper })) continue;
|
|
718
|
+
}
|
|
719
|
+
const hostSet = SwcUtils.getHostSet(this as any);
|
|
720
|
+
(this as any)[m.propertyKey](matchedEls, entries, obs, { ...hostSet, $root: root });
|
|
721
|
+
}
|
|
722
|
+
});
|
|
723
|
+
resizeObservers.push(resizeObserver);
|
|
724
|
+
// resizeObserver 메타별 removeObserver 수집
|
|
725
|
+
for (const m of resizeObserverList) {
|
|
726
|
+
if (m.options.removeObserver) {
|
|
727
|
+
removeObserverCallbacks.push({ fn: m.options.removeObserver, target: root, opts: m.options });
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
// MutationObserver: shadow/light 루트별 그룹핑
|
|
732
|
+
const shadowMetas = mutationObserverList.filter(m => {
|
|
733
|
+
const r = m.options.root || 'auto';
|
|
734
|
+
return this.shadowRoot && (r === 'shadow' || r === 'all' || r === 'auto');
|
|
735
|
+
});
|
|
736
|
+
const lightMetas = mutationObserverList.filter(m => {
|
|
737
|
+
const r = m.options.root || 'auto';
|
|
738
|
+
return r === 'light' || r === 'all' || (!this.shadowRoot && r === 'auto');
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
const setupMutationObserver = (root: HTMLElement | ShadowRoot, metas: MutationObserverMetadata[], resizeDelegates: ResizeObserverMetadata[] = []): MutationObserver | null => {
|
|
742
|
+
// mutation 메타가 없으면 observer 생성 안 함 (resize delegate는 보조)
|
|
743
|
+
if (metas.length === 0) return null;
|
|
744
|
+
|
|
745
|
+
// 사용자가 입력한 옵션 그대로 (아무것도 안 주면 childList 기본)
|
|
746
|
+
const initFrom = (o: MutationObserverBaseOptions): MutationObserverInit => {
|
|
747
|
+
const init: MutationObserverInit = {
|
|
748
|
+
childList: o.childList,
|
|
749
|
+
attributes: o.attributes,
|
|
750
|
+
characterData: o.characterData,
|
|
751
|
+
subtree: o.subtree,
|
|
752
|
+
attributeFilter: o.attributeFilter,
|
|
753
|
+
attributeOldValue: o.attributeOldValue,
|
|
754
|
+
characterDataOldValue: o.characterDataOldValue
|
|
755
|
+
};
|
|
756
|
+
// MutationObserver는 최소 1개는 true여야 함
|
|
757
|
+
if (!init.childList && !init.attributes && !init.characterData) init.childList = true;
|
|
758
|
+
return init;
|
|
759
|
+
};
|
|
760
|
+
|
|
761
|
+
const observer = new MutationObserver((mutations: MutationRecord[], obs: MutationObserver) => {
|
|
762
|
+
for (const meta of metas) {
|
|
763
|
+
const { selector, options } = meta;
|
|
764
|
+
let matchedEls: HTMLElement[] = [];
|
|
765
|
+
|
|
766
|
+
if (options.delegate && typeof selector === 'string') {
|
|
767
|
+
const isThis = selector === '$this' || selector === '';
|
|
768
|
+
const matchesSel = (node: any): boolean => {
|
|
769
|
+
if (!node || node.nodeType !== 1) return false;
|
|
770
|
+
if (isThis) return true;
|
|
771
|
+
const el = node as HTMLElement;
|
|
772
|
+
return el.matches?.(selector as string) || !!el.closest?.(selector as string);
|
|
773
|
+
};
|
|
774
|
+
matchedEls = mutations.flatMap(m => {
|
|
775
|
+
const els: HTMLElement[] = [];
|
|
776
|
+
if (matchesSel(m.target)) els.push(m.target as HTMLElement);
|
|
777
|
+
Array.from(m.addedNodes || [])
|
|
778
|
+
.filter(matchesSel)
|
|
779
|
+
.forEach(n => els.push(n as HTMLElement));
|
|
780
|
+
Array.from(m.removedNodes || [])
|
|
781
|
+
.filter(matchesSel)
|
|
782
|
+
.forEach(n => els.push(n as HTMLElement));
|
|
783
|
+
return els;
|
|
784
|
+
});
|
|
785
|
+
} else if (typeof selector === 'string') {
|
|
786
|
+
// non-delegate: observe 대상이 매칭 요소들이므로 그들의 mutation 대상 + 추가/제거 노드
|
|
787
|
+
const isThis = selector === '$this' || selector === '';
|
|
788
|
+
const matchesSel = (node: any): boolean => {
|
|
789
|
+
if (!node || node.nodeType !== 1) return false;
|
|
790
|
+
if (isThis) return true;
|
|
791
|
+
return (node as HTMLElement).matches?.(selector as string);
|
|
792
|
+
};
|
|
793
|
+
matchedEls = mutations.flatMap(m => {
|
|
794
|
+
const els: HTMLElement[] = [];
|
|
795
|
+
if (matchesSel(m.target)) els.push(m.target as HTMLElement);
|
|
796
|
+
Array.from(m.addedNodes || [])
|
|
797
|
+
.filter(matchesSel)
|
|
798
|
+
.forEach(n => els.push(n as HTMLElement));
|
|
799
|
+
Array.from(m.removedNodes || [])
|
|
800
|
+
.filter(matchesSel)
|
|
801
|
+
.forEach(n => els.push(n as HTMLElement));
|
|
802
|
+
return els;
|
|
803
|
+
});
|
|
804
|
+
} else {
|
|
805
|
+
matchedEls = mutations.map(m => m.target as HTMLElement).filter(t => t && t.nodeType === 1);
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
if (matchedEls.length === 0) continue;
|
|
809
|
+
if (options.filter) {
|
|
810
|
+
const helper = SwcUtils.getHelperAndHostSet(currentWin, this);
|
|
811
|
+
if (!options.filter(matchedEls, { currentThis: this, helper })) continue;
|
|
812
|
+
}
|
|
813
|
+
const hostSet = SwcUtils.getHostSet(this as any);
|
|
814
|
+
// 1번째: 매치된 element 배열, 2번째: 원본 mutations, 3번째: observer
|
|
815
|
+
(this as any)[meta.propertyKey](matchedEls, mutations, obs, { ...hostSet, $root: root });
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
// ─── resizeObserver delegate 동적 추적 ───
|
|
819
|
+
// 추가/삭제된 요소가 delegate 셀렉터와 매칭되면 resizeObserver에 observe/unobserve
|
|
820
|
+
if (resizeDelegates.length > 0 && resizeObserver) {
|
|
821
|
+
const handle = (n: Node, observe: boolean) => {
|
|
822
|
+
if (n.nodeType !== 1) return;
|
|
823
|
+
const el = n as HTMLElement;
|
|
824
|
+
for (const m of resizeDelegates) {
|
|
825
|
+
if (typeof m.selector !== 'string') continue;
|
|
826
|
+
const isThis = m.selector === '$this' || m.selector === '';
|
|
827
|
+
const matchesSel = (node: any): boolean => {
|
|
828
|
+
if (!node || node.nodeType !== 1) return false;
|
|
829
|
+
if (isThis) return true;
|
|
830
|
+
const e = node as HTMLElement;
|
|
831
|
+
return e.matches?.(m.selector as string) || !!e.closest?.(m.selector as string);
|
|
832
|
+
};
|
|
833
|
+
if (matchesSel(el)) {
|
|
834
|
+
if (observe) resizeObserver.observe(el, m.options.box ? { box: m.options.box } : undefined);
|
|
835
|
+
else resizeObserver.unobserve(el);
|
|
836
|
+
} else if (!isThis) {
|
|
837
|
+
el.querySelectorAll(m.selector).forEach(sub => {
|
|
838
|
+
if (observe) resizeObserver.observe(sub as HTMLElement, m.options.box ? { box: m.options.box } : undefined);
|
|
839
|
+
else resizeObserver.unobserve(sub as HTMLElement);
|
|
840
|
+
});
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
for (const m of mutations) {
|
|
845
|
+
Array.from(m.addedNodes || []).forEach(n => handle(n, true));
|
|
846
|
+
Array.from(m.removedNodes || []).forEach(n => handle(n, false));
|
|
847
|
+
}
|
|
848
|
+
}
|
|
652
849
|
});
|
|
850
|
+
|
|
851
|
+
// delegate 메타(mutation 또는 resize)가 하나라도 있으면 → 루트에 subtree observe 1개로 전부 감지 (콜백에서 메타별 매칭 처리)
|
|
852
|
+
const hasDelegate = metas.some(m => m.options.delegate) || resizeDelegates.some(m => m.options.delegate);
|
|
853
|
+
if (hasDelegate) {
|
|
854
|
+
observer.observe(root, { childList: true, subtree: true });
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
// non-delegate 메타: 셀렉터 매칭 요소들을 사용자 옵션 그대로 observe
|
|
858
|
+
const nonDelegateMetas = metas.filter(m => !m.options.delegate);
|
|
859
|
+
for (const m of nonDelegateMetas) {
|
|
860
|
+
const { selector, options } = m;
|
|
861
|
+
const mInit = initFrom(options);
|
|
862
|
+
if (typeof selector === 'string') {
|
|
863
|
+
if (selector === '$this' || selector === '') {
|
|
864
|
+
observer.observe(root, mInit);
|
|
865
|
+
} else {
|
|
866
|
+
root.querySelectorAll(selector).forEach(el => observer.observe(el as HTMLElement, mInit));
|
|
867
|
+
}
|
|
868
|
+
} else if (typeof selector === 'function') {
|
|
869
|
+
// 함수 셀렉터는 루트 관찰로 대체 (매칭 평가 불가)
|
|
870
|
+
observer.observe(root, mInit);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
return observer;
|
|
875
|
+
};
|
|
876
|
+
|
|
877
|
+
// resizeObserver delegate 메타도 루트별로 필터해서 넘김
|
|
878
|
+
const shadowResizeDelegateMetas = resizeObserverList.filter(m => {
|
|
879
|
+
if (!m.options.delegate) return false;
|
|
880
|
+
const r = m.options.root || 'auto';
|
|
881
|
+
return this.shadowRoot && (r === 'shadow' || r === 'all' || r === 'auto');
|
|
882
|
+
});
|
|
883
|
+
const lightResizeDelegateMetas = resizeObserverList.filter(m => {
|
|
884
|
+
if (!m.options.delegate) return false;
|
|
885
|
+
const r = m.options.root || 'auto';
|
|
886
|
+
return r === 'light' || r === 'all' || (!this.shadowRoot && r === 'auto');
|
|
653
887
|
});
|
|
654
888
|
|
|
655
|
-
if (
|
|
889
|
+
if (this.shadowRoot) shadowMutationObserver = setupMutationObserver(this.shadowRoot, shadowMetas, shadowResizeDelegateMetas);
|
|
890
|
+
lightMutationObserver = setupMutationObserver(this as any, lightMetas, lightResizeDelegateMetas);
|
|
891
|
+
|
|
892
|
+
// mutationObserver 메타별 removeObserver 수집
|
|
893
|
+
for (const m of mutationObserverList) {
|
|
894
|
+
if (m.options.removeObserver) {
|
|
895
|
+
const rootForM = this.shadowRoot && (m.options.root === 'shadow' || m.options.root === 'all' || (m.options.root === 'auto' && this.shadowRoot)) ? this.shadowRoot : (this as any);
|
|
896
|
+
removeObserverCallbacks.push({ fn: m.options.removeObserver, target: rootForM, opts: m.options });
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
if (originalConnected) await originalConnected.apply(this);
|
|
656
901
|
|
|
657
902
|
const aMethods = findAllOnConnectedAfterMetadata(this); //.filter(it => { return useSsr ? !it.options.ssrFirst : true; });
|
|
658
903
|
// console.log('afterConnected', this.tagName, aMethods, getOnConnectedAfterMetadata(this))
|
|
@@ -665,9 +910,9 @@ export const elementDefine =
|
|
|
665
910
|
for (let [name, metaList] of Array.from(attrChangeMap)) {
|
|
666
911
|
for (const meta of metaList) {
|
|
667
912
|
if (meta.options.while === 'connected') {
|
|
668
|
-
const val = getAttributeValue(this, name, {type: meta.options.type});
|
|
913
|
+
const val = getAttributeValue(this, name, { type: meta.options.type });
|
|
669
914
|
if (val !== null) {
|
|
670
|
-
await (
|
|
915
|
+
await (this as any)[meta.propertyKey](val, null, name, helperHostSet);
|
|
671
916
|
}
|
|
672
917
|
}
|
|
673
918
|
}
|
|
@@ -682,6 +927,9 @@ export const elementDefine =
|
|
|
682
927
|
}
|
|
683
928
|
};
|
|
684
929
|
|
|
930
|
+
/////////////////////////////////////////////////
|
|
931
|
+
// disconnectedCallback
|
|
932
|
+
////////////////////////////////////////////////
|
|
685
933
|
const originalDisconnected = proto.disconnectedCallback;
|
|
686
934
|
proto.disconnectedCallback = function () {
|
|
687
935
|
// const helperHostSet = SwcUtils.getHelperAndHostSet(win, this as any);
|
|
@@ -695,19 +943,54 @@ export const elementDefine =
|
|
|
695
943
|
(this as any)._executeSwcScript('swc-on-before-disconnected', helperHostSet);
|
|
696
944
|
const bMethods = findAllLifecycleMetadata(this, ON_BEFORE_DISCONNECTED_METADATA_KEY);
|
|
697
945
|
for (const m of bMethods) (this as any)._invokeLifecycleMethod(m.propertyKey, helperHostSet);
|
|
698
|
-
|
|
699
|
-
if (
|
|
700
|
-
|
|
946
|
+
// event listener 정리
|
|
947
|
+
if (boundListeners.length > 0) {
|
|
948
|
+
boundListeners.forEach((l: BoundListener) => {
|
|
701
949
|
l.target.removeEventListener(l.type, l.handler, l.options);
|
|
702
950
|
// Cleanup Observable subscription if present
|
|
703
951
|
if (l.subscription && typeof l.subscription.unsubscribe === 'function') {
|
|
704
952
|
l.subscription.unsubscribe();
|
|
705
953
|
}
|
|
954
|
+
// 사용자 정의 정리 콜백 호출
|
|
955
|
+
if (Array.isArray(l.onRemoves)) {
|
|
956
|
+
for (const r of l.onRemoves) {
|
|
957
|
+
try {
|
|
958
|
+
r.fn(l.target, r.opts);
|
|
959
|
+
} catch (e) {
|
|
960
|
+
console.error('[SWC] removeListener error:', e);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
}
|
|
706
964
|
});
|
|
707
|
-
|
|
965
|
+
boundListeners = [];
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
// MutationObserver / ResizeObserver 정리
|
|
969
|
+
const _obs: Array<MutationObserver | ResizeObserver | null> = [shadowMutationObserver, lightMutationObserver, resizeObserver, ...resizeObservers];
|
|
970
|
+
for (const o of _obs) {
|
|
971
|
+
try {
|
|
972
|
+
(o as any)?.disconnect?.();
|
|
973
|
+
} catch (e) {
|
|
974
|
+
console.error('[SWC] observer disconnect error:', e);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
shadowMutationObserver = null;
|
|
978
|
+
lightMutationObserver = null;
|
|
979
|
+
resizeObserver = null;
|
|
980
|
+
resizeObservers = [];
|
|
981
|
+
|
|
982
|
+
// 메타별 removeObserver 콜백 호출
|
|
983
|
+
for (const cb of removeObserverCallbacks) {
|
|
984
|
+
try {
|
|
985
|
+
cb.fn(cb.target, cb.opts);
|
|
986
|
+
} catch (e) {
|
|
987
|
+
console.error('[SWC] removeObserver error:', e);
|
|
988
|
+
}
|
|
708
989
|
}
|
|
990
|
+
removeObserverCallbacks = [];
|
|
709
991
|
|
|
710
|
-
|
|
992
|
+
// elementApply event listener 정리
|
|
993
|
+
new ElementApply(this, { id: this._swcId }).removeAllEventListener();
|
|
711
994
|
|
|
712
995
|
// globalDelegatedRoots remove
|
|
713
996
|
// const roots = [this, this.getRootNode()];
|
|
@@ -807,7 +1090,7 @@ export const elementDefine =
|
|
|
807
1090
|
ReflectUtils.defineMetadata(ELEMENT_CONFIG_KEY, metadata, constructor);
|
|
808
1091
|
const registry = metadata.customElementRegistry || (win as any)?.customElements;
|
|
809
1092
|
if (registry && !registry.get(metadata.name)) {
|
|
810
|
-
registry.define(metadata.name, constructor as any, metadata.extends ? {extends: metadata.extends} : undefined);
|
|
1093
|
+
registry.define(metadata.name, constructor as any, metadata.extends ? { extends: metadata.extends } : undefined);
|
|
811
1094
|
}
|
|
812
1095
|
return constructor;
|
|
813
1096
|
};
|