@dooboostore/simple-web-component 1.0.34 → 1.0.36
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 +44 -51
- package/dist/cjs/decorators/addEventListener.js +12 -4
- package/dist/cjs/decorators/addEventListener.js.map +2 -2
- package/dist/cjs/decorators/applyAttribute.js +19 -18
- package/dist/cjs/decorators/applyAttribute.js.map +2 -2
- package/dist/cjs/decorators/applyClass.js +23 -22
- package/dist/cjs/decorators/applyClass.js.map +2 -2
- package/dist/cjs/decorators/applyNode.js +22 -17
- package/dist/cjs/decorators/applyNode.js.map +2 -2
- package/dist/cjs/decorators/applyStyle.js +20 -19
- package/dist/cjs/decorators/applyStyle.js.map +2 -2
- package/dist/cjs/decorators/attribute.js +17 -16
- package/dist/cjs/decorators/attribute.js.map +2 -2
- package/dist/cjs/decorators/{changedAttributeHost.js → changedAttributeThis.js} +6 -6
- package/dist/cjs/decorators/changedAttributeThis.js.map +7 -0
- package/dist/cjs/decorators/elementDefine.js +234 -188
- package/dist/cjs/decorators/elementDefine.js.map +2 -2
- package/dist/cjs/decorators/emitCustomEvent.js +24 -16
- package/dist/cjs/decorators/emitCustomEvent.js.map +2 -2
- package/dist/cjs/decorators/index.js +1 -1
- package/dist/cjs/decorators/index.js.map +1 -1
- package/dist/cjs/decorators/lifecycles.js +15 -17
- package/dist/cjs/decorators/lifecycles.js.map +2 -2
- package/dist/cjs/decorators/query.js +38 -60
- package/dist/cjs/decorators/query.js.map +2 -2
- package/dist/cjs/decorators/queryAll.js +31 -63
- package/dist/cjs/decorators/queryAll.js.map +2 -2
- package/dist/cjs/decorators/setProperty.js +13 -12
- package/dist/cjs/decorators/setProperty.js.map +2 -2
- package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js +2 -2
- package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +2 -2
- package/dist/cjs/elements/SwcAppEngine.js +8 -2
- package/dist/cjs/elements/SwcAppEngine.js.map +2 -2
- package/dist/cjs/elements/SwcAppMixin.js +120 -65
- package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
- package/dist/cjs/elements/SwcAsync.js +31 -21
- package/dist/cjs/elements/SwcAsync.js.map +2 -2
- package/dist/cjs/elements/SwcChoose.js +53 -34
- package/dist/cjs/elements/SwcChoose.js.map +2 -2
- package/dist/cjs/elements/SwcIf.js +54 -32
- package/dist/cjs/elements/SwcIf.js.map +2 -2
- package/dist/cjs/elements/SwcLoop.js +111 -37
- package/dist/cjs/elements/SwcLoop.js.map +2 -2
- package/dist/cjs/elements/register.js +249 -122
- package/dist/cjs/elements/register.js.map +2 -2
- package/dist/cjs/router/ElementRouter.js +4 -2
- package/dist/cjs/router/ElementRouter.js.map +1 -1
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/utils/Utils.js +31 -17
- package/dist/cjs/utils/Utils.js.map +2 -2
- package/dist/esm/decorators/addEventListener.js +12 -4
- package/dist/esm/decorators/addEventListener.js.map +2 -2
- package/dist/esm/decorators/applyAttribute.js +19 -18
- package/dist/esm/decorators/applyAttribute.js.map +2 -2
- package/dist/esm/decorators/applyClass.js +23 -22
- package/dist/esm/decorators/applyClass.js.map +2 -2
- package/dist/esm/decorators/applyNode.js +22 -17
- package/dist/esm/decorators/applyNode.js.map +2 -2
- package/dist/esm/decorators/applyStyle.js +20 -19
- package/dist/esm/decorators/applyStyle.js.map +2 -2
- package/dist/esm/decorators/attribute.js +17 -16
- package/dist/esm/decorators/attribute.js.map +2 -2
- package/dist/esm/decorators/{changedAttributeHost.js → changedAttributeThis.js} +3 -3
- package/dist/esm/decorators/changedAttributeThis.js.map +7 -0
- package/dist/esm/decorators/elementDefine.js +233 -187
- package/dist/esm/decorators/elementDefine.js.map +2 -2
- package/dist/esm/decorators/emitCustomEvent.js +24 -16
- package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
- package/dist/esm/decorators/index.js +1 -1
- package/dist/esm/decorators/index.js.map +1 -1
- package/dist/esm/decorators/lifecycles.js +15 -17
- package/dist/esm/decorators/lifecycles.js.map +2 -2
- package/dist/esm/decorators/query.js +38 -60
- package/dist/esm/decorators/query.js.map +2 -2
- package/dist/esm/decorators/queryAll.js +31 -63
- package/dist/esm/decorators/queryAll.js.map +2 -2
- package/dist/esm/decorators/setProperty.js +13 -12
- package/dist/esm/decorators/setProperty.js.map +2 -2
- package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js +2 -2
- package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +2 -2
- package/dist/esm/elements/SwcAppEngine.js +9 -2
- package/dist/esm/elements/SwcAppEngine.js.map +2 -2
- package/dist/esm/elements/SwcAppMixin.js +122 -66
- package/dist/esm/elements/SwcAppMixin.js.map +2 -2
- package/dist/esm/elements/SwcAsync.js +32 -22
- package/dist/esm/elements/SwcAsync.js.map +2 -2
- package/dist/esm/elements/SwcChoose.js +54 -35
- package/dist/esm/elements/SwcChoose.js.map +2 -2
- package/dist/esm/elements/SwcIf.js +55 -33
- package/dist/esm/elements/SwcIf.js.map +2 -2
- package/dist/esm/elements/SwcLoop.js +112 -38
- package/dist/esm/elements/SwcLoop.js.map +2 -2
- package/dist/esm/elements/register.js +250 -123
- package/dist/esm/elements/register.js.map +2 -2
- package/dist/esm/router/ElementRouter.js +5 -2
- package/dist/esm/router/ElementRouter.js.map +1 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils/Utils.js +31 -17
- package/dist/esm/utils/Utils.js.map +2 -2
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +563 -557
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
- package/dist/types/decorators/addEventListener.d.ts +5 -7
- package/dist/types/decorators/addEventListener.d.ts.map +1 -1
- package/dist/types/decorators/applyAttribute.d.ts +4 -4
- package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
- package/dist/types/decorators/applyClass.d.ts +6 -6
- package/dist/types/decorators/applyClass.d.ts.map +1 -1
- package/dist/types/decorators/applyNode.d.ts +7 -6
- package/dist/types/decorators/applyNode.d.ts.map +1 -1
- package/dist/types/decorators/applyStyle.d.ts +4 -4
- package/dist/types/decorators/applyStyle.d.ts.map +1 -1
- package/dist/types/decorators/attribute.d.ts +5 -5
- package/dist/types/decorators/attribute.d.ts.map +1 -1
- package/dist/types/decorators/changedAttributeThis.d.ts +18 -0
- package/dist/types/decorators/changedAttributeThis.d.ts.map +1 -0
- package/dist/types/decorators/elementDefine.d.ts.map +1 -1
- package/dist/types/decorators/emitCustomEvent.d.ts +11 -12
- package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
- package/dist/types/decorators/index.d.ts +1 -1
- package/dist/types/decorators/lifecycles.d.ts +10 -7
- package/dist/types/decorators/lifecycles.d.ts.map +1 -1
- package/dist/types/decorators/query.d.ts +17 -63
- package/dist/types/decorators/query.d.ts.map +1 -1
- package/dist/types/decorators/queryAll.d.ts +6 -63
- package/dist/types/decorators/queryAll.d.ts.map +1 -1
- package/dist/types/decorators/setProperty.d.ts +1 -1
- package/dist/types/decorators/setProperty.d.ts.map +1 -1
- package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +4 -5
- package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +1 -1
- package/dist/types/elements/SwcAppEngine.d.ts +4 -1
- package/dist/types/elements/SwcAppEngine.d.ts.map +1 -1
- package/dist/types/elements/SwcAppMixin.d.ts +11 -8
- package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
- package/dist/types/elements/register.d.ts.map +1 -1
- package/dist/types/types.d.ts +3 -2
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils/Utils.d.ts +11 -8
- package/dist/types/utils/Utils.d.ts.map +1 -1
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +563 -557
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
- package/package.json +3 -3
- package/src/decorators/addEventListener.ts +11 -9
- package/src/decorators/applyAttribute.ts +16 -15
- package/src/decorators/applyClass.ts +18 -17
- package/src/decorators/applyNode.ts +34 -21
- package/src/decorators/applyStyle.ts +17 -16
- package/src/decorators/attribute.ts +21 -20
- package/src/decorators/{changedAttributeHost.ts → changedAttributeThis.ts} +13 -14
- package/src/decorators/elementDefine.ts +402 -358
- package/src/decorators/emitCustomEvent.ts +40 -31
- package/src/decorators/index.ts +1 -1
- package/src/decorators/lifecycles.ts +11 -10
- package/src/decorators/query.ts +51 -124
- package/src/decorators/queryAll.ts +30 -127
- package/src/decorators/setProperty.ts +12 -11
- package/src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts +10 -10
- package/src/elements/SwcAppEngine.ts +10 -3
- package/src/elements/SwcAppMixin.ts +177 -97
- package/src/elements/SwcAsync.ts +32 -21
- package/src/elements/SwcChoose.ts +74 -37
- package/src/elements/SwcIf.ts +60 -23
- package/src/elements/SwcLoop.ts +141 -28
- package/src/elements/register.ts +300 -102
- package/src/types.ts +6 -5
- package/src/utils/Utils.ts +40 -23
- package/tsconfig.json +2 -2
- package/dist/cjs/decorators/changedAttributeHost.js.map +0 -7
- package/dist/esm/decorators/changedAttributeHost.js.map +0 -7
- package/dist/types/decorators/changedAttributeHost.d.ts +0 -19
- package/dist/types/decorators/changedAttributeHost.d.ts.map +0 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
1
|
+
import {ReflectUtils, FunctionUtils, ActionExpression} from '@dooboostore/core';
|
|
2
|
+
import {getAddEventListenerMetadata} from './addEventListener';
|
|
3
|
+
import {ON_INITIALIZE_METADATA_KEY, ON_BEFORE_CONNECTED_METADATA_KEY, ON_AFTER_CONNECTED_METADATA_KEY, ON_BEFORE_DISCONNECTED_METADATA_KEY, ON_AFTER_DISCONNECTED_METADATA_KEY, ON_BEFORE_ADOPTED_METADATA_KEY, ON_AFTER_ADOPTED_METADATA_KEY, findAllLifecycleMetadata, getOnConnectedInnerHtmlMetadata} from './lifecycles';
|
|
4
|
+
import {getEmitCustomEventMetadataList} from './emitCustomEvent';
|
|
5
|
+
import {findAllAttributeChangedMetadata, convertAttributeValue} from './changedAttributeThis';
|
|
6
|
+
import {findAllAttributeApplyMetadata} from './applyAttribute';
|
|
7
|
+
import {findAllAttributeMetadata, getAttributeValue} from './attribute';
|
|
8
|
+
import {getQueryMetadata} from './query';
|
|
9
|
+
import {getQueryAllMetadata} from './queryAll';
|
|
10
|
+
import {SwcUtils} from '../utils/Utils';
|
|
11
|
+
import {HTML_TAG_ENTRIES, DOM_EVENT_NAMES} from '../config/config';
|
|
12
|
+
import {SituationTypeContainer, SituationTypeContainers} from '@dooboostore/simple-boot/decorators/inject/Inject';
|
|
13
|
+
import {InjectSituationType, HostSet, HelperHostSet} from '../types';
|
|
14
|
+
import {ConvertUtils} from '@dooboostore/core-web';
|
|
15
15
|
|
|
16
16
|
// --- Core Interfaces & Types ---
|
|
17
17
|
|
|
@@ -48,13 +48,13 @@ export const ensureInit = (inst: any) => {
|
|
|
48
48
|
// });
|
|
49
49
|
|
|
50
50
|
const target = inst instanceof Function ? inst : inst.constructor;
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
// ╔════════════════════════════════════════════════════════════════════════════════╗
|
|
53
53
|
// ║ decorator 필드의 own property 삭제 ║
|
|
54
54
|
// ║ ║
|
|
55
55
|
// ║ 이유: ║
|
|
56
56
|
// ║ 1. TypeScript는 초기값이 있는 필드를 constructor에서 own property로 생성 ║
|
|
57
|
-
// ║ @
|
|
57
|
+
// ║ @attributeThis('id') myId: string = "default" → this.myId = "default" ║
|
|
58
58
|
// ║ ║
|
|
59
59
|
// ║ 2. JavaScript의 property lookup은 own property를 먼저 찾음 ║
|
|
60
60
|
// ║ - this.myId 접근 ║
|
|
@@ -67,13 +67,13 @@ export const ensureInit = (inst: any) => {
|
|
|
67
67
|
// ║ 4. own property를 삭제하면 JavaScript가 prototype의 getter를 찾게 됨 ║
|
|
68
68
|
// ║ → getter 호출됨 → DOM 속성 값 동기화됨 ║
|
|
69
69
|
// ╚════════════════════════════════════════════════════════════════════════════════╝
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
// @attribute 필드의 own property 삭제 → getter/setter 작동
|
|
72
72
|
const attributeList = findAllAttributeMetadata(target);
|
|
73
73
|
attributeList.forEach(meta => {
|
|
74
74
|
delete (inst as any)[meta.propertyKey];
|
|
75
75
|
});
|
|
76
|
-
|
|
76
|
+
|
|
77
77
|
// @query 필드의 own property 삭제 → getter 작동
|
|
78
78
|
const queryList = getQueryMetadata(target);
|
|
79
79
|
if (queryList) {
|
|
@@ -81,7 +81,7 @@ export const ensureInit = (inst: any) => {
|
|
|
81
81
|
delete (inst as any)[meta.propertyKey];
|
|
82
82
|
});
|
|
83
83
|
}
|
|
84
|
-
|
|
84
|
+
|
|
85
85
|
// @queryAll 필드의 own property 삭제 → getter 작동
|
|
86
86
|
const queryAllList = getQueryAllMetadata(target);
|
|
87
87
|
if (queryAllList) {
|
|
@@ -92,13 +92,13 @@ export const ensureInit = (inst: any) => {
|
|
|
92
92
|
|
|
93
93
|
// Call constructor script if present
|
|
94
94
|
const hostSet = SwcUtils.getHostSet(inst);
|
|
95
|
-
const appHosts = SwcUtils.
|
|
95
|
+
const appHosts = SwcUtils.findAllAppHostsIncludingSelfDirect(inst);
|
|
96
96
|
inst._executeSwcScript?.('swc-on-constructor', hostSet);
|
|
97
97
|
|
|
98
98
|
// Call @onInitialize lifecycle methods
|
|
99
99
|
const cMethods = findAllLifecycleMetadata(inst, ON_INITIALIZE_METADATA_KEY);
|
|
100
100
|
if (cMethods) {
|
|
101
|
-
for (const m of cMethods)
|
|
101
|
+
for (const m of cMethods) inst._invokeLifecycleMethod(m, hostSet);
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
};
|
|
@@ -116,7 +116,7 @@ const handleGlobalSwcEvent = async (event: Event) => {
|
|
|
116
116
|
if (!(node instanceof HTMLElement)) continue;
|
|
117
117
|
const script = node.getAttribute?.(attrName);
|
|
118
118
|
if (script && !getElementConfig(node)) {
|
|
119
|
-
const host: any = SwcUtils.
|
|
119
|
+
const host: any = SwcUtils.findNearestSwcHostIncludingSelf(node);
|
|
120
120
|
if (host && host.isConnected && typeof host.__swc_executeAttributeEvent === 'function') {
|
|
121
121
|
await host.__swc_executeAttributeEvent(node, attrName, script, event);
|
|
122
122
|
(event as any).__swc_handled = true;
|
|
@@ -134,8 +134,8 @@ function buildEnv(configWindow: Window) {
|
|
|
134
134
|
if ((win as any)?.[cls]) builtInTagMap.set((win as any)[cls], tag);
|
|
135
135
|
}
|
|
136
136
|
const domHelpers = SwcUtils.getHelperSet(win);
|
|
137
|
-
|
|
138
|
-
return {
|
|
137
|
+
|
|
138
|
+
return {win, doc, builtInTagMap, domHelpers};
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
const getHandlers = (inst: any) => {
|
|
@@ -155,8 +155,8 @@ const setupPrototype = (proto: any) => {
|
|
|
155
155
|
const conf = getElementConfig(this);
|
|
156
156
|
const currentWin = (this as any)._resolveWindow(conf);
|
|
157
157
|
const helpers = SwcUtils.getHelperSet(currentWin);
|
|
158
|
-
const args = {
|
|
159
|
-
FunctionUtils.execute({
|
|
158
|
+
const args = {...hostSet, ...helpers, ...extraArgs, $el: this, $root: this.getRootNode()};
|
|
159
|
+
FunctionUtils.execute({script, context: this, args});
|
|
160
160
|
} catch (e) {
|
|
161
161
|
console.error(`[SWC] Failed to execute ${attrName}:`, e);
|
|
162
162
|
}
|
|
@@ -166,12 +166,12 @@ const setupPrototype = (proto: any) => {
|
|
|
166
166
|
proto._resolveWindow = function (localConfig?: ElementConfig): Window {
|
|
167
167
|
ensureInit(this);
|
|
168
168
|
if (localConfig?.window) return localConfig.window;
|
|
169
|
-
const ancestors = SwcUtils.
|
|
169
|
+
const ancestors = SwcUtils.findAllSwcHostsIncludingSelf(this as any);
|
|
170
170
|
for (let i = ancestors.length - 1; i >= 0; i--) {
|
|
171
171
|
const aConf = getElementConfig(ancestors[i]);
|
|
172
172
|
if (aConf?.window) return aConf.window;
|
|
173
173
|
}
|
|
174
|
-
return getElementConfig(this).window ?? (typeof window !== 'undefined' ? window : undefined) as Window;
|
|
174
|
+
return getElementConfig(this).window ?? ((typeof window !== 'undefined' ? window : undefined) as Window);
|
|
175
175
|
};
|
|
176
176
|
|
|
177
177
|
proto._invokeLifecycleMethod = function (methodName: string | symbol, hostSet?: HostSet, extraArgs: any[] = []) {
|
|
@@ -182,7 +182,13 @@ const setupPrototype = (proto: any) => {
|
|
|
182
182
|
// console.log('---->hh',app, this, methodName);
|
|
183
183
|
if (app) {
|
|
184
184
|
const otherStorage = new Map<any, any>();
|
|
185
|
-
const situations = new SituationTypeContainers([new SituationTypeContainer({
|
|
185
|
+
const situations = new SituationTypeContainers([new SituationTypeContainer({situationType: InjectSituationType.HOST_SET, data: useHostSet}), new SituationTypeContainer({situationType: InjectSituationType.APP_HOST, data: useHostSet.$appHost}), new SituationTypeContainer({situationType: InjectSituationType.APP_HOSTS, data: useHostSet.$appHosts}), new SituationTypeContainer({
|
|
186
|
+
situationType: InjectSituationType.HOST,
|
|
187
|
+
data: useHostSet.$host
|
|
188
|
+
}), new SituationTypeContainer({situationType: InjectSituationType.HOSTS, data: useHostSet.$hosts}), new SituationTypeContainer({situationType: InjectSituationType.FIRST_HOST, data: useHostSet.$firstHost}), new SituationTypeContainer({situationType: InjectSituationType.LAST_HOST, data: useHostSet.$lastHost}), new SituationTypeContainer({
|
|
189
|
+
situationType: InjectSituationType.FIRST_APP_HOST,
|
|
190
|
+
data: useHostSet.$firstAppHost
|
|
191
|
+
}), new SituationTypeContainer({situationType: InjectSituationType.LAST_APP_HOST, data: useHostSet.$lastAppHost})]);
|
|
186
192
|
otherStorage.set(SituationTypeContainers, situations);
|
|
187
193
|
|
|
188
194
|
return app.simstanceManager.executeBindParameterSim(
|
|
@@ -227,7 +233,7 @@ const setupPrototype = (proto: any) => {
|
|
|
227
233
|
$el: el,
|
|
228
234
|
$root: this.getRootNode()
|
|
229
235
|
};
|
|
230
|
-
await FunctionUtils.execute({
|
|
236
|
+
await FunctionUtils.execute({script, context: el, args});
|
|
231
237
|
};
|
|
232
238
|
|
|
233
239
|
el.addEventListener(eventName, handler);
|
|
@@ -252,384 +258,422 @@ const setupPrototype = (proto: any) => {
|
|
|
252
258
|
$el: el,
|
|
253
259
|
$root: this.getRootNode()
|
|
254
260
|
};
|
|
255
|
-
await FunctionUtils.execute({
|
|
261
|
+
await FunctionUtils.execute({script, context: el, args});
|
|
256
262
|
};
|
|
257
263
|
};
|
|
258
264
|
|
|
259
265
|
export const elementDefine =
|
|
260
266
|
(name: string, config: Partial<ElementConfig> = {}): ClassDecorator =>
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
267
|
+
(constructor: any) => {
|
|
268
|
+
const {win, doc, builtInTagMap: BUILT_IN_TAG_MAP, domHelpers: SWC_DOM_HELPERS} = buildEnv(config.window);
|
|
269
|
+
const metadata: ElementMetadata = {...config, name, window: win};
|
|
264
270
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
271
|
+
if (!metadata.window) {
|
|
272
|
+
throw new Error('window is required');
|
|
273
|
+
}
|
|
268
274
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
275
|
+
let extendsTagName = metadata.extends;
|
|
276
|
+
if (!extendsTagName) {
|
|
277
|
+
let proto = constructor;
|
|
278
|
+
const BaseHTMLElement = (win as any).HTMLElement;
|
|
279
|
+
while (proto && proto !== BaseHTMLElement && proto !== Function.prototype) {
|
|
280
|
+
extendsTagName = BUILT_IN_TAG_MAP.get(proto);
|
|
281
|
+
if (extendsTagName) break;
|
|
282
|
+
proto = Object.getPrototypeOf(proto);
|
|
283
|
+
}
|
|
284
|
+
metadata.extends = extendsTagName;
|
|
277
285
|
}
|
|
278
|
-
metadata.extends = extendsTagName;
|
|
279
|
-
}
|
|
280
286
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
proto.connectedCallback = function () {
|
|
319
|
-
ensureInit(this);
|
|
320
|
-
|
|
321
|
-
const hostSet = SwcUtils.getHostSet(this as any);
|
|
322
|
-
const appHost = hostSet.$appHost;
|
|
323
|
-
const conf = getElementConfig(this);
|
|
324
|
-
const currentWin = (this as any)._resolveWindow(conf);
|
|
287
|
+
const emitCustomEventList = getEmitCustomEventMetadataList(constructor) || [];
|
|
288
|
+
const emitHostCustomEventList = emitCustomEventList.filter(meta => meta.selector === '$this' || meta.selector === '');
|
|
289
|
+
const addEventListenerList = getAddEventListenerMetadata(constructor) || [];
|
|
290
|
+
const attrChangeMap = findAllAttributeChangedMetadata(constructor);
|
|
291
|
+
const attributeList = findAllAttributeMetadata(constructor);
|
|
292
|
+
const applyAttributeMap = findAllAttributeApplyMetadata(constructor);
|
|
293
|
+
|
|
294
|
+
const swcLifecycleAttributes = ['swc-on-constructor', 'swc-on-connected', 'swc-on-disconnected', 'swc-on-before-connected', 'swc-on-after-connected', 'swc-on-before-disconnected', 'swc-on-after-disconnected', 'swc-on-before-adopted', 'swc-on-after-adopted', 'swc-on-attribute-changed'];
|
|
295
|
+
const swcOnEvents = DOM_EVENT_NAMES.map(e => `swc-on-${e}`);
|
|
296
|
+
|
|
297
|
+
const attributeApplyNames = Array.from(applyAttributeMap.values())
|
|
298
|
+
.map(it => it.options.name)
|
|
299
|
+
.filter(Boolean) as string[];
|
|
300
|
+
const hostAttributes = attributeList.filter(it => it.selector === '$this').map(it => it.options.name || String(it.propertyKey));
|
|
301
|
+
// Get original static observedAttributes before they're overwritten by Object.defineProperty
|
|
302
|
+
const originalStaticObservedAttributes = (constructor.observedAttributes ?? []) as string[];
|
|
303
|
+
const mergedObservedAttributes = [...new Set([...(metadata.observedAttributes ?? []), ...originalStaticObservedAttributes, ...attrChangeMap.keys(), ...attributeApplyNames, ...hostAttributes, ...emitHostCustomEventList.map(it => (it.options as any).attributeName).filter(Boolean), ...swcLifecycleAttributes, ...swcOnEvents])];
|
|
304
|
+
const connectedInnerHtmlList = getOnConnectedInnerHtmlMetadata(constructor) || [];
|
|
305
|
+
|
|
306
|
+
const proto = constructor.prototype;
|
|
307
|
+
setupPrototype(proto);
|
|
308
|
+
|
|
309
|
+
// 값을 기대하지않는다.
|
|
310
|
+
let helperHostSet: HelperHostSet | null = null;
|
|
311
|
+
const originalConnected = proto.connectedCallback;
|
|
312
|
+
proto.connectedCallback = async function () {
|
|
313
|
+
ensureInit(this);
|
|
314
|
+
// connected 됐을시 최신화
|
|
315
|
+
helperHostSet = SwcUtils.getHelperAndHostSet(win, this as any);
|
|
316
|
+
const appHost = helperHostSet.$appHost;
|
|
317
|
+
try {
|
|
318
|
+
if (appHost && typeof (appHost as any)._connected === 'function') {
|
|
319
|
+
await (appHost as any)._connected(this);
|
|
320
|
+
} else if (appHost && typeof (appHost as any)) {
|
|
321
|
+
(appHost as any)._connected_safari ??= [];
|
|
322
|
+
(appHost as any)._connected_safari.push(this);
|
|
323
|
+
}
|
|
325
324
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
this.attachShadow({ mode: mode as ShadowRootMode });
|
|
330
|
-
}
|
|
325
|
+
// const hostSet = SwcUtils.getHostSet(this as any);
|
|
326
|
+
const conf = getElementConfig(this);
|
|
327
|
+
const currentWin = (this as any)._resolveWindow(conf);
|
|
331
328
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
329
|
+
const shadowMode = conf?.useShadow || connectedInnerHtmlList.find(it => it.options.useShadow)?.options.useShadow;
|
|
330
|
+
if (shadowMode && !this.shadowRoot) {
|
|
331
|
+
const mode = shadowMode === true ? 'open' : shadowMode;
|
|
332
|
+
this.attachShadow({mode: mode as ShadowRootMode});
|
|
333
|
+
}
|
|
337
334
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
for (const meta of connectedInnerHtmlList) {
|
|
342
|
-
// const res = (this as any)[meta.propertyKey]();
|
|
343
|
-
const res = (this as any)._invokeLifecycleMethod(meta.propertyKey, hostSet);
|
|
344
|
-
// console.log('------res0', res);
|
|
345
|
-
// console.log('------res1', res1);
|
|
346
|
-
if (res !== undefined) {
|
|
347
|
-
if (meta.options.useShadow || conf?.useShadow) sContent += res;
|
|
348
|
-
else lContent += res;
|
|
335
|
+
const bMethods = findAllLifecycleMetadata(this, ON_BEFORE_CONNECTED_METADATA_KEY);
|
|
336
|
+
if (bMethods) {
|
|
337
|
+
for (const m of bMethods) await (this as any)._invokeLifecycleMethod(m, helperHostSet);
|
|
349
338
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
if (
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
339
|
+
(this as any)._executeSwcScript('swc-on-before-connected', helperHostSet);
|
|
340
|
+
|
|
341
|
+
if (connectedInnerHtmlList.length > 0) {
|
|
342
|
+
let sContent = '',
|
|
343
|
+
lContent = '';
|
|
344
|
+
for (const meta of connectedInnerHtmlList) {
|
|
345
|
+
// const res = (this as any)[meta.propertyKey]();
|
|
346
|
+
let res = await (this as any)._invokeLifecycleMethod(meta.propertyKey, helperHostSet);
|
|
347
|
+
const actionExpression = new ActionExpression(res, {
|
|
348
|
+
expression: {
|
|
349
|
+
replace: {
|
|
350
|
+
start: meta.options.replaceWrap?.start || '{%{',
|
|
351
|
+
end: meta.options.replaceWrap?.end || '}%}'
|
|
352
|
+
},
|
|
353
|
+
callReturn: {
|
|
354
|
+
start: meta.options.replaceWrap?.start || '{%{=',
|
|
355
|
+
end: meta.options.replaceWrap?.end || '}%}'
|
|
356
|
+
},
|
|
357
|
+
call: {
|
|
358
|
+
start: meta.options.replaceWrap?.start || '{%{@',
|
|
359
|
+
end: meta.options.replaceWrap?.end || '}%}'
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
actionExpression.getExpressions().filter(it => it.type === 'replace').forEach(it => {
|
|
365
|
+
try {
|
|
366
|
+
// const helperHostSet22 = SwcUtils.getHelperAndHostSet(win, this as any);
|
|
367
|
+
const sr = FunctionUtils.executeReturn({script: it.script, context: this, args: helperHostSet});
|
|
368
|
+
actionExpression.replace(it, sr);
|
|
369
|
+
} catch (e) {
|
|
370
|
+
console.error(`[SWC] Failed to execute connectedInnerHTML:`, e);
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
res = actionExpression.getUnprocessedTemplate();
|
|
358
374
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
375
|
+
if (res !== undefined) {
|
|
376
|
+
if (meta.options.useShadow || conf?.useShadow) sContent += res;
|
|
377
|
+
else lContent += res;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
try {
|
|
381
|
+
if (this.shadowRoot) {
|
|
382
|
+
this.shadowRoot.innerHTML = sContent;
|
|
383
|
+
}
|
|
384
|
+
if (lContent) {
|
|
385
|
+
this.innerHTML = lContent;
|
|
386
|
+
}
|
|
387
|
+
} catch (e) {
|
|
388
|
+
console.error('[ElementDefine] innerHTML setting error:', e);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
366
391
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
} else {
|
|
375
|
-
nonDelegateListeners.push(meta);
|
|
376
|
-
}
|
|
377
|
-
});
|
|
392
|
+
const root = this.getRootNode();
|
|
393
|
+
if (!globalDelegatedRoots.has(root)) {
|
|
394
|
+
DOM_EVENT_NAMES.forEach(type => {
|
|
395
|
+
root.addEventListener(type, handleGlobalSwcEvent);
|
|
396
|
+
});
|
|
397
|
+
globalDelegatedRoots.add(root);
|
|
398
|
+
}
|
|
378
399
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
const rootKey = `${meta.type}:${r}`;
|
|
383
|
-
if (!delegatesByTypeAndRoot.has(rootKey)) {
|
|
384
|
-
delegatesByTypeAndRoot.set(rootKey, []);
|
|
385
|
-
}
|
|
386
|
-
delegatesByTypeAndRoot.get(rootKey)!.push(meta);
|
|
387
|
-
});
|
|
400
|
+
// Separate delegate and non-delegate listeners
|
|
401
|
+
const delegateListeners: typeof addEventListenerList = [];
|
|
402
|
+
const nonDelegateListeners: typeof addEventListenerList = [];
|
|
388
403
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
else if (r === 'light') bindRoots.push(this as any);
|
|
397
|
-
else if (r === 'shadow' && this.shadowRoot) bindRoots.push(this.shadowRoot);
|
|
398
|
-
else if (r === 'all') {
|
|
399
|
-
bindRoots.push(this as any);
|
|
400
|
-
if (this.shadowRoot) bindRoots.push(this.shadowRoot);
|
|
401
|
-
}
|
|
404
|
+
addEventListenerList.forEach(meta => {
|
|
405
|
+
if (meta.options.delegate && meta.selector !== '$window' && meta.selector !== '$document' && meta.selector !== '$host' && meta.selector !== '$appHost' && meta.selector !== '$firstHost' && meta.selector !== '$lastHost' && meta.selector !== '$firstAppHost' && meta.selector !== '$lastAppHost' && meta.selector !== '$hosts' && meta.selector !== '$appHosts' && meta.selector !== '$this' && meta.selector !== '') {
|
|
406
|
+
delegateListeners.push(meta);
|
|
407
|
+
} else {
|
|
408
|
+
nonDelegateListeners.push(meta);
|
|
409
|
+
}
|
|
410
|
+
});
|
|
402
411
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
const
|
|
406
|
-
const
|
|
407
|
-
|
|
412
|
+
const delegatesByTypeAndRoot = new Map<string, any[]>();
|
|
413
|
+
delegateListeners.forEach(meta => {
|
|
414
|
+
const r = meta.options.root || 'auto';
|
|
415
|
+
const rootKey = `${meta.type}:${r}`;
|
|
416
|
+
if (!delegatesByTypeAndRoot.has(rootKey)) {
|
|
417
|
+
delegatesByTypeAndRoot.set(rootKey, []);
|
|
418
|
+
}
|
|
419
|
+
delegatesByTypeAndRoot.get(rootKey)!.push(meta);
|
|
408
420
|
});
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
421
|
+
|
|
422
|
+
delegatesByTypeAndRoot.forEach((metaList, typeRootKey) => {
|
|
423
|
+
const [type, rStr] = typeRootKey.split(':');
|
|
424
|
+
const r = rStr === 'auto' ? 'auto' : rStr;
|
|
425
|
+
const opts = {capture: metaList[0].options.capture, once: metaList[0].options.once, passive: metaList[0].options.passive};
|
|
426
|
+
|
|
427
|
+
const bindRoots: (HTMLElement | ShadowRoot)[] = [];
|
|
428
|
+
if (r === 'auto') bindRoots.push(this.shadowRoot || (this as any));
|
|
429
|
+
else if (r === 'light') bindRoots.push(this as any);
|
|
430
|
+
else if (r === 'shadow' && this.shadowRoot) bindRoots.push(this.shadowRoot);
|
|
431
|
+
else if (r === 'all') {
|
|
432
|
+
bindRoots.push(this as any);
|
|
433
|
+
if (this.shadowRoot) bindRoots.push(this.shadowRoot);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
bindRoots.forEach(br => {
|
|
437
|
+
const sortedMetaList = [...metaList].sort((a, b) => {
|
|
438
|
+
const aStop = a.options.stopPropagation ? 1 : 0;
|
|
439
|
+
const bStop = b.options.stopPropagation ? 1 : 0;
|
|
440
|
+
return bStop - aStop;
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
const unifiedHandler = async (event: Event) => {
|
|
444
|
+
for (const meta of sortedMetaList) {
|
|
445
|
+
const {selector, options} = meta;
|
|
446
|
+
const matchedEl = (event.target as HTMLElement).closest(selector);
|
|
447
|
+
if (matchedEl && (br as any).contains(matchedEl)) {
|
|
448
|
+
// Apply filter if specified
|
|
449
|
+
if (options.filter) {
|
|
450
|
+
const helper = SwcUtils.getHelperAndHostSet(currentWin, matchedEl);
|
|
451
|
+
if (!options.filter(event, helper)) {
|
|
452
|
+
continue; // Skip this listener if filter returns false
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
if (options.stopPropagation) event.stopPropagation();
|
|
456
|
+
if (options.stopImmediatePropagation) event.stopImmediatePropagation();
|
|
457
|
+
if (options.preventDefault) event.preventDefault();
|
|
458
|
+
const currentHostSet = SwcUtils.getHostSet(this as any);
|
|
459
|
+
const args = {event, ...currentHostSet, $el: matchedEl, $root: br};
|
|
460
|
+
await (this as any)[meta.propertyKey](event, {...currentHostSet, $matchedElement: matchedEl}, args);
|
|
461
|
+
if ((event as any).cancelBubble) break;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
br.addEventListener(type, unifiedHandler, opts);
|
|
466
|
+
(this as any)._boundListeners.push({target: br, type, handler: unifiedHandler, options: opts});
|
|
467
|
+
});
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
nonDelegateListeners.forEach(meta => {
|
|
471
|
+
const {selector, type, options} = meta;
|
|
472
|
+
const opts = {capture: options.capture, once: options.once, passive: options.passive};
|
|
473
|
+
const bindTargets: EventTarget[] = [];
|
|
474
|
+
const r = options.root || 'auto';
|
|
475
|
+
const applyRootOption = (target: any) => {
|
|
476
|
+
if (!target) return;
|
|
477
|
+
if (r === 'auto') {
|
|
478
|
+
bindTargets.push(target.shadowRoot || target);
|
|
479
|
+
} else {
|
|
480
|
+
if (r === 'light' || r === 'all') bindTargets.push(target);
|
|
481
|
+
if ((r === 'shadow' || r === 'all') && target.shadowRoot) bindTargets.push(target.shadowRoot);
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
if (selector === '$window') bindTargets.push(currentWin);
|
|
486
|
+
else if (selector === '$document') bindTargets.push(currentWin.document);
|
|
487
|
+
else if (selector === '$host') applyRootOption(helperHostSet.$host);
|
|
488
|
+
else if (selector === '$parentHost') applyRootOption(helperHostSet.$parentHost);
|
|
489
|
+
else if (selector === '$appHost') applyRootOption(helperHostSet.$appHost);
|
|
490
|
+
else if (selector === '$firstHost') applyRootOption(helperHostSet.$firstHost);
|
|
491
|
+
else if (selector === '$lastHost') applyRootOption(helperHostSet.$lastHost);
|
|
492
|
+
else if (selector === '$firstAppHost') applyRootOption(helperHostSet.$firstAppHost);
|
|
493
|
+
else if (selector === '$lastAppHost') applyRootOption(helperHostSet.$lastAppHost);
|
|
494
|
+
else if (selector === '$hosts') helperHostSet.$hosts.forEach(applyRootOption);
|
|
495
|
+
else if (selector === '$appHosts') helperHostSet.$appHosts.forEach(applyRootOption);
|
|
496
|
+
else if (selector === '$this' || !selector) applyRootOption(this);
|
|
497
|
+
else {
|
|
498
|
+
const searchRoots: (HTMLElement | ShadowRoot)[] = [];
|
|
499
|
+
if (r === 'auto') searchRoots.push(this.shadowRoot || (this as any));
|
|
500
|
+
else if (r === 'light') searchRoots.push(this as any);
|
|
501
|
+
else if (r === 'shadow' && this.shadowRoot) searchRoots.push(this.shadowRoot);
|
|
502
|
+
else if (r === 'all') {
|
|
503
|
+
searchRoots.push(this as any);
|
|
504
|
+
if (this.shadowRoot) searchRoots.push(this.shadowRoot);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
searchRoots.forEach(sr => {
|
|
508
|
+
sr.querySelectorAll(selector).forEach(el => bindTargets.push(el));
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
bindTargets.forEach(t => {
|
|
513
|
+
const handler = async (event: Event) => {
|
|
415
514
|
// Apply filter if specified
|
|
416
515
|
if (options.filter) {
|
|
417
|
-
const helper = SwcUtils.getHelperAndHostSet(currentWin,
|
|
418
|
-
if (!options.filter(event, helper)) {
|
|
419
|
-
|
|
516
|
+
const helper = SwcUtils.getHelperAndHostSet(currentWin, t as HTMLElement);
|
|
517
|
+
if (!options.filter(event, {currentThis: this, helper})) {
|
|
518
|
+
return; // Skip if filter returns false
|
|
420
519
|
}
|
|
421
520
|
}
|
|
422
521
|
if (options.stopPropagation) event.stopPropagation();
|
|
423
522
|
if (options.stopImmediatePropagation) event.stopImmediatePropagation();
|
|
424
523
|
if (options.preventDefault) event.preventDefault();
|
|
425
524
|
const currentHostSet = SwcUtils.getHostSet(this as any);
|
|
426
|
-
const args = {
|
|
427
|
-
await (this as any)[meta.propertyKey](event, currentHostSet,
|
|
428
|
-
|
|
525
|
+
const args = {event, ...currentHostSet, $el: t, $root: t};
|
|
526
|
+
await (this as any)[meta.propertyKey](event, {currentHostSet, $$matchedElement: event.currentTarget}, args);
|
|
527
|
+
};
|
|
528
|
+
t.addEventListener(type, handler, opts);
|
|
529
|
+
if (options.removeOnDisconnected === true || t === currentWin || t === currentWin.document) {
|
|
530
|
+
(this as any)._boundListeners.push({target: t, type, handler, options: opts});
|
|
429
531
|
}
|
|
430
|
-
}
|
|
431
|
-
};
|
|
432
|
-
br.addEventListener(type, unifiedHandler, opts);
|
|
433
|
-
(this as any)._boundListeners.push({ target: br, type, handler: unifiedHandler, options: opts });
|
|
434
|
-
});
|
|
435
|
-
});
|
|
436
|
-
|
|
437
|
-
nonDelegateListeners.forEach(meta => {
|
|
438
|
-
const { selector, type, options } = meta;
|
|
439
|
-
const opts = { capture: options.capture, once: options.once, passive: options.passive };
|
|
440
|
-
const bindTargets: EventTarget[] = [];
|
|
441
|
-
const r = options.root || 'auto';
|
|
442
|
-
const applyRootOption = (target: any) => {
|
|
443
|
-
if (!target) return;
|
|
444
|
-
if (r === 'auto') {
|
|
445
|
-
bindTargets.push(target.shadowRoot || target);
|
|
446
|
-
} else {
|
|
447
|
-
if (r === 'light' || r === 'all') bindTargets.push(target);
|
|
448
|
-
if ((r === 'shadow' || r === 'all') && target.shadowRoot) bindTargets.push(target.shadowRoot);
|
|
449
|
-
}
|
|
450
|
-
};
|
|
451
|
-
|
|
452
|
-
if (selector === ':window') bindTargets.push(currentWin);
|
|
453
|
-
else if (selector === ':document') bindTargets.push(currentWin.document);
|
|
454
|
-
else if (selector === ':parentHost') applyRootOption(hostSet.$parentHost);
|
|
455
|
-
else if (selector === ':appHost') applyRootOption(hostSet.$appHost);
|
|
456
|
-
else if (selector === ':firstHost') applyRootOption(hostSet.$firstHost);
|
|
457
|
-
else if (selector === ':lastHost') applyRootOption(hostSet.$lastHost);
|
|
458
|
-
else if (selector === ':firstAppHost') applyRootOption(hostSet.$firstAppHost);
|
|
459
|
-
else if (selector === ':lastAppHost') applyRootOption(hostSet.$lastAppHost);
|
|
460
|
-
else if (selector === ':hosts') hostSet.$hosts.forEach(applyRootOption);
|
|
461
|
-
else if (selector === ':appHosts') hostSet.$appHosts.forEach(applyRootOption);
|
|
462
|
-
else if (selector === ':host' || !selector) applyRootOption(this);
|
|
463
|
-
else {
|
|
464
|
-
const searchRoots: (HTMLElement | ShadowRoot)[] = [];
|
|
465
|
-
if (r === 'auto') searchRoots.push(this.shadowRoot || (this as any));
|
|
466
|
-
else if (r === 'light') searchRoots.push(this as any);
|
|
467
|
-
else if (r === 'shadow' && this.shadowRoot) searchRoots.push(this.shadowRoot);
|
|
468
|
-
else if (r === 'all') {
|
|
469
|
-
searchRoots.push(this as any);
|
|
470
|
-
if (this.shadowRoot) searchRoots.push(this.shadowRoot);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
searchRoots.forEach(sr => {
|
|
474
|
-
sr.querySelectorAll(selector).forEach(el => bindTargets.push(el));
|
|
532
|
+
});
|
|
475
533
|
});
|
|
476
|
-
}
|
|
477
534
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
535
|
+
if (originalConnected) await (originalConnected.apply(this));
|
|
536
|
+
|
|
537
|
+
const aMethods = findAllLifecycleMetadata(this, ON_AFTER_CONNECTED_METADATA_KEY);
|
|
538
|
+
if (aMethods) {
|
|
539
|
+
for (const m of aMethods) await (this as any)._invokeLifecycleMethod(m, helperHostSet);
|
|
540
|
+
}
|
|
541
|
+
(this as any)._executeSwcScript('swc-on-connected', helperHostSet);
|
|
542
|
+
(this as any)._executeSwcScript('swc-on-after-connected', helperHostSet);
|
|
543
|
+
(this as any).__swc_connected = true;
|
|
544
|
+
|
|
545
|
+
// Trigger @changedAttributeThis with while: 'connected'
|
|
546
|
+
for (let [name, metaList] of Array.from(attrChangeMap)) {
|
|
547
|
+
for (const meta of metaList) {
|
|
548
|
+
if (meta.options.while === 'connected') {
|
|
549
|
+
const val = getAttributeValue(this, name, {type: meta.options.type});
|
|
550
|
+
if (val !== null) {
|
|
551
|
+
await ((this as any)[meta.propertyKey](val, null, name, helperHostSet));
|
|
552
|
+
}
|
|
485
553
|
}
|
|
486
554
|
}
|
|
487
|
-
if (options.stopPropagation) event.stopPropagation();
|
|
488
|
-
if (options.stopImmediatePropagation) event.stopImmediatePropagation();
|
|
489
|
-
if (options.preventDefault) event.preventDefault();
|
|
490
|
-
const currentHostSet = SwcUtils.getHostSet(this as any);
|
|
491
|
-
const args = { event, ...currentHostSet, $el: t, $root: t };
|
|
492
|
-
await (this as any)[meta.propertyKey](event, currentHostSet, args);
|
|
493
|
-
};
|
|
494
|
-
t.addEventListener(type, handler, opts);
|
|
495
|
-
if (options.removeOnDisconnected === true || t === currentWin || t === currentWin.document) {
|
|
496
|
-
(this as any)._boundListeners.push({ target: t, type, handler, options: opts });
|
|
497
555
|
}
|
|
498
|
-
}
|
|
499
|
-
|
|
556
|
+
} finally {
|
|
557
|
+
if (appHost && typeof (appHost as any)._connectedDone === 'function') {
|
|
558
|
+
await (appHost as any)._connectedDone(this);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
};
|
|
500
562
|
|
|
501
|
-
|
|
563
|
+
const originalDisconnected = proto.disconnectedCallback;
|
|
564
|
+
proto.disconnectedCallback = function () {
|
|
565
|
+
// const helperHostSet = SwcUtils.getHelperAndHostSet(win, this as any);
|
|
566
|
+
// Remove from appHost LAST when disconnected
|
|
567
|
+
console.log('disconnnnnnnnnnnnnnnnnnn', helperHostSet, this)
|
|
568
|
+
const appHost = helperHostSet.$appHost;
|
|
569
|
+
if (appHost && typeof (appHost as any)._disconnected === 'function') {
|
|
570
|
+
(appHost as any)._disconnected(this);
|
|
571
|
+
}
|
|
502
572
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
(this as any)._executeSwcScript('swc-on-after-connected', hostSet);
|
|
509
|
-
(this as any).__swc_connected = true;
|
|
510
|
-
|
|
511
|
-
// Register to appHost LAST when all lifecycle completed
|
|
512
|
-
// console.log('!!!!!!!!!!!!!!', this, appHost)
|
|
513
|
-
const appHostss = SwcUtils.findAllParentAppHostsDirect(this)
|
|
514
|
-
// const nAppHostSet = SwcUtils.getHostSet(this as any);
|
|
515
|
-
if (appHost && typeof (appHost as any)._connected === 'function') {
|
|
516
|
-
(appHost as any)._connected(this);
|
|
517
|
-
} else if (appHost && typeof (appHost as any)) {
|
|
518
|
-
(appHost as any)._connected_safari ??= [];
|
|
519
|
-
(appHost as any)._connected_safari.push(this);
|
|
520
|
-
}
|
|
521
|
-
};
|
|
573
|
+
(this as any)._executeSwcScript('swc-on-before-disconnected', helperHostSet);
|
|
574
|
+
const bMethods = findAllLifecycleMetadata(this, ON_BEFORE_DISCONNECTED_METADATA_KEY);
|
|
575
|
+
if (bMethods) {
|
|
576
|
+
for (const m of bMethods) (this as any)._invokeLifecycleMethod(m, helperHostSet);
|
|
577
|
+
}
|
|
522
578
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
const bMethods = findAllLifecycleMetadata(this, ON_BEFORE_DISCONNECTED_METADATA_KEY);
|
|
528
|
-
if (bMethods) {
|
|
529
|
-
for (const m of bMethods) (this as any)._invokeLifecycleMethod(m, hostSet);
|
|
530
|
-
}
|
|
579
|
+
if ((this as any)._boundListeners) {
|
|
580
|
+
(this as any)._boundListeners.forEach((l: any) => l.target.removeEventListener(l.type, l.handler, l.options));
|
|
581
|
+
(this as any)._boundListeners = [];
|
|
582
|
+
}
|
|
531
583
|
|
|
532
|
-
|
|
533
|
-
(this as any)._boundListeners.forEach((l: any) => l.target.removeEventListener(l.type, l.handler, l.options));
|
|
534
|
-
(this as any)._boundListeners = [];
|
|
535
|
-
}
|
|
584
|
+
if (originalDisconnected) originalDisconnected.apply(this);
|
|
536
585
|
|
|
537
|
-
|
|
586
|
+
const aMethods = findAllLifecycleMetadata(this, ON_AFTER_DISCONNECTED_METADATA_KEY);
|
|
587
|
+
if (aMethods) {
|
|
588
|
+
for (const m of aMethods) (this as any)._invokeLifecycleMethod(m, helperHostSet);
|
|
589
|
+
}
|
|
590
|
+
(this as any)._executeSwcScript('swc-on-disconnected', helperHostSet);
|
|
591
|
+
(this as any)._executeSwcScript('swc-on-after-disconnected', helperHostSet);
|
|
592
|
+
(this as any).__swc_connected = false;
|
|
593
|
+
};
|
|
538
594
|
|
|
539
|
-
const
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
// Remove from appHost LAST when disconnected
|
|
548
|
-
const appHost = hostSet.$appHost;
|
|
549
|
-
if (appHost && typeof (appHost as any)._disconnected === 'function') {
|
|
550
|
-
(appHost as any)._disconnected(this);
|
|
551
|
-
}
|
|
552
|
-
};
|
|
595
|
+
const originalAdopted = proto.adoptedCallback;
|
|
596
|
+
proto.adoptedCallback = function () {
|
|
597
|
+
const hostSet = SwcUtils.getHostSet(this as any);
|
|
598
|
+
(this as any)._executeSwcScript('swc-on-before-adopted', hostSet);
|
|
599
|
+
const bMethods = findAllLifecycleMetadata(this, ON_BEFORE_ADOPTED_METADATA_KEY);
|
|
600
|
+
if (bMethods) {
|
|
601
|
+
for (const m of bMethods) (this as any)._invokeLifecycleMethod(m, hostSet);
|
|
602
|
+
}
|
|
553
603
|
|
|
554
|
-
|
|
555
|
-
proto.adoptedCallback = function () {
|
|
556
|
-
const hostSet = SwcUtils.getHostSet(this as any);
|
|
557
|
-
(this as any)._executeSwcScript('swc-on-before-adopted', hostSet);
|
|
558
|
-
const bMethods = findAllLifecycleMetadata(this, ON_BEFORE_ADOPTED_METADATA_KEY);
|
|
559
|
-
if (bMethods) {
|
|
560
|
-
for (const m of bMethods) (this as any)._invokeLifecycleMethod(m, hostSet);
|
|
561
|
-
}
|
|
604
|
+
if (originalAdopted) originalAdopted.apply(this);
|
|
562
605
|
|
|
563
|
-
|
|
606
|
+
const aMethods = findAllLifecycleMetadata(this, ON_AFTER_ADOPTED_METADATA_KEY);
|
|
607
|
+
if (aMethods) {
|
|
608
|
+
for (const m of aMethods) (this as any)._invokeLifecycleMethod(m, hostSet);
|
|
609
|
+
}
|
|
610
|
+
(this as any)._executeSwcScript('swc-on-adopted', hostSet);
|
|
611
|
+
(this as any)._executeSwcScript('swc-on-after-adopted', hostSet);
|
|
612
|
+
};
|
|
564
613
|
|
|
565
|
-
const
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
(this as any)._executeSwcScript('swc-on-after-adopted', hostSet);
|
|
571
|
-
};
|
|
614
|
+
const originalAttributeChanged = proto.attributeChangedCallback;
|
|
615
|
+
proto.attributeChangedCallback = function (name: string, old: string | null, newVal: string | null) {
|
|
616
|
+
if (originalAttributeChanged) originalAttributeChanged.apply(this, [name, old, newVal]);
|
|
617
|
+
|
|
618
|
+
const hSet = SwcUtils.getHostSet(this as any);
|
|
572
619
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
if (newVal !== null) {
|
|
582
|
-
const ae = new ActionExpression(newVal);
|
|
583
|
-
const expr = ae.getFirstExpression('call-return');
|
|
584
|
-
if (expr) {
|
|
585
|
-
const win = (this as any)._resolveWindow?.() || ((typeof window !== 'undefined' ? window : undefined) as any);
|
|
586
|
-
const helperAndHostSet = SwcUtils.getHelperAndHostSet(win,this as any);
|
|
587
|
-
try {
|
|
620
|
+
// Process expression directive before passing to handlers
|
|
621
|
+
let processedVal: any = newVal;
|
|
622
|
+
if (newVal !== null) {
|
|
623
|
+
const ae = new ActionExpression(newVal);
|
|
624
|
+
const expr = ae.getFirstExpression('callReturn');
|
|
625
|
+
if (expr) {
|
|
626
|
+
const win = (this as any)._resolveWindow?.() || ((typeof window !== 'undefined' ? window : undefined) as any);
|
|
627
|
+
const helperAndHostSet = SwcUtils.getHelperAndHostSet(win, this as any);
|
|
588
628
|
const script = ConvertUtils.decodeHtmlEntity(expr.script, win.document);
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
629
|
+
try {
|
|
630
|
+
const result = FunctionUtils.executeReturn({
|
|
631
|
+
script: script,
|
|
632
|
+
context: this,
|
|
633
|
+
args: helperAndHostSet
|
|
634
|
+
});
|
|
635
|
+
// Pass the result object directly without serialization
|
|
636
|
+
processedVal = result;
|
|
637
|
+
} catch (e) {
|
|
638
|
+
console.error(`[SWC] Failed to execute directive {{= ${expr.script} }} on attribute ${name}: ${helperAndHostSet}`, e);
|
|
639
|
+
processedVal = newVal;
|
|
640
|
+
}
|
|
599
641
|
}
|
|
600
642
|
}
|
|
601
|
-
}
|
|
602
643
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
644
|
+
if (name.startsWith('swc-on-') && !swcLifecycleAttributes.includes(name)) {
|
|
645
|
+
if (newVal !== null) {
|
|
646
|
+
const eventName = name.substring(7);
|
|
647
|
+
(this as any)._bindAttributeEvent(this as any, name, newVal, eventName);
|
|
648
|
+
}
|
|
607
649
|
}
|
|
608
|
-
}
|
|
609
650
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
651
|
+
const hostCustomEventMeta = emitHostCustomEventList.find(it => (it.options as any).attributeName === name);
|
|
652
|
+
if (hostCustomEventMeta && newVal !== null) {
|
|
653
|
+
(this as any)._bindAttributeEvent(this as any, name, newVal, hostCustomEventMeta.type);
|
|
654
|
+
}
|
|
614
655
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
656
|
+
const metaList = attrChangeMap.get(name);
|
|
657
|
+
if (metaList && Array.isArray(metaList)) {
|
|
658
|
+
for (const meta of metaList) {
|
|
659
|
+
if (meta.options.while === 'connected' && !(this as any).__swc_connected) {
|
|
660
|
+
continue;
|
|
661
|
+
}
|
|
662
|
+
const convertedVal = convertAttributeValue(processedVal, meta.options.type);
|
|
663
|
+
(this as any)[meta.propertyKey](convertedVal, old, name, hSet);
|
|
664
|
+
}
|
|
620
665
|
}
|
|
621
|
-
}
|
|
622
|
-
};
|
|
666
|
+
};
|
|
623
667
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
668
|
+
Object.defineProperty(constructor, 'observedAttributes', {
|
|
669
|
+
get: () => mergedObservedAttributes,
|
|
670
|
+
configurable: true
|
|
671
|
+
});
|
|
628
672
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
673
|
+
ReflectUtils.defineMetadata(ELEMENT_CONFIG_KEY, metadata, constructor);
|
|
674
|
+
const registry = metadata.customElementRegistry || (win as any)?.customElements;
|
|
675
|
+
if (registry && !registry.get(metadata.name)) {
|
|
676
|
+
registry.define(metadata.name, constructor as any, metadata.extends ? {extends: metadata.extends} : undefined);
|
|
677
|
+
}
|
|
678
|
+
return constructor;
|
|
679
|
+
};
|