@dooboostore/simple-web-component 1.0.19 → 1.0.22
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 +2759 -201
- package/dist/cjs/decorators/addEventListener.js +8 -4
- package/dist/cjs/decorators/addEventListener.js.map +2 -2
- package/dist/cjs/decorators/{appendChild.js → applyNode.js} +26 -18
- package/dist/cjs/decorators/applyNode.js.map +7 -0
- package/dist/cjs/decorators/attribute.js +162 -0
- package/dist/cjs/decorators/attribute.js.map +7 -0
- package/dist/cjs/decorators/{changedAttribute.js → changedAttributeHost.js} +11 -11
- package/dist/cjs/decorators/changedAttributeHost.js.map +7 -0
- package/dist/cjs/decorators/classList.js +15 -5
- package/dist/cjs/decorators/classList.js.map +2 -2
- package/dist/cjs/decorators/elementDefine.js +124 -46
- package/dist/cjs/decorators/elementDefine.js.map +3 -3
- package/dist/cjs/decorators/emitCustomEvent.js +8 -7
- package/dist/cjs/decorators/emitCustomEvent.js.map +2 -2
- package/dist/cjs/decorators/index.js +3 -3
- package/dist/cjs/decorators/index.js.map +2 -2
- package/dist/cjs/decorators/lifecycles.js +8 -4
- package/dist/cjs/decorators/lifecycles.js.map +2 -2
- package/dist/cjs/decorators/onConnectedInnerHtml.js +4 -4
- package/dist/cjs/decorators/onConnectedInnerHtml.js.map +2 -2
- package/dist/cjs/decorators/query.js +9 -5
- package/dist/cjs/decorators/query.js.map +2 -2
- package/dist/cjs/decorators/queryAll.js +9 -5
- package/dist/cjs/decorators/queryAll.js.map +2 -2
- package/dist/cjs/decorators/setAttribute.js +51 -21
- package/dist/cjs/decorators/setAttribute.js.map +2 -2
- package/dist/cjs/decorators/style.js +4 -4
- package/dist/cjs/decorators/style.js.map +2 -2
- package/dist/cjs/elements/SwcAppEngine.js +8 -8
- package/dist/cjs/elements/SwcAppEngine.js.map +3 -3
- package/dist/cjs/elements/SwcAppMixin.js +28 -1
- package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
- package/dist/cjs/elements/SwcAsync.js +6 -6
- package/dist/cjs/elements/SwcAsync.js.map +2 -2
- package/dist/cjs/elements/SwcChoose.js +6 -6
- package/dist/cjs/elements/SwcChoose.js.map +2 -2
- package/dist/cjs/elements/SwcIf.js +6 -6
- package/dist/cjs/elements/SwcIf.js.map +2 -2
- package/dist/cjs/elements/SwcLoop.js +6 -6
- package/dist/cjs/elements/SwcLoop.js.map +2 -2
- package/dist/cjs/elements/register.js +19 -18
- package/dist/cjs/elements/register.js.map +2 -2
- package/dist/cjs/index.js +6 -17
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/router/ElementRouter.js +7 -7
- package/dist/cjs/router/ElementRouter.js.map +2 -2
- package/dist/cjs/types.js.map +2 -2
- package/dist/esm/decorators/addEventListener.js +5 -1
- package/dist/esm/decorators/addEventListener.js.map +2 -2
- package/dist/esm/decorators/{appendChild.js → applyNode.js} +23 -15
- package/dist/esm/decorators/applyNode.js.map +7 -0
- package/dist/esm/decorators/attribute.js +143 -0
- package/dist/esm/decorators/attribute.js.map +7 -0
- package/dist/esm/decorators/{changedAttribute.js → changedAttributeHost.js} +4 -4
- package/dist/esm/decorators/changedAttributeHost.js.map +7 -0
- package/dist/esm/decorators/classList.js +12 -2
- package/dist/esm/decorators/classList.js.map +2 -2
- package/dist/esm/decorators/elementDefine.js +119 -41
- package/dist/esm/decorators/elementDefine.js.map +2 -2
- package/dist/esm/decorators/emitCustomEvent.js +5 -4
- package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
- package/dist/esm/decorators/index.js +3 -3
- package/dist/esm/decorators/index.js.map +1 -1
- package/dist/esm/decorators/lifecycles.js +5 -1
- package/dist/esm/decorators/lifecycles.js.map +2 -2
- package/dist/esm/decorators/onConnectedInnerHtml.js +1 -1
- package/dist/esm/decorators/onConnectedInnerHtml.js.map +1 -1
- package/dist/esm/decorators/query.js +6 -2
- package/dist/esm/decorators/query.js.map +2 -2
- package/dist/esm/decorators/queryAll.js +6 -2
- package/dist/esm/decorators/queryAll.js.map +2 -2
- package/dist/esm/decorators/setAttribute.js +47 -17
- package/dist/esm/decorators/setAttribute.js.map +2 -2
- package/dist/esm/decorators/style.js +1 -1
- package/dist/esm/decorators/style.js.map +1 -1
- package/dist/esm/elements/SwcAppEngine.js +4 -4
- package/dist/esm/elements/SwcAppEngine.js.map +2 -2
- package/dist/esm/elements/SwcAppMixin.js +28 -1
- package/dist/esm/elements/SwcAppMixin.js.map +2 -2
- package/dist/esm/elements/SwcAsync.js +3 -3
- package/dist/esm/elements/SwcAsync.js.map +2 -2
- package/dist/esm/elements/SwcChoose.js +3 -3
- package/dist/esm/elements/SwcChoose.js.map +2 -2
- package/dist/esm/elements/SwcIf.js +3 -3
- package/dist/esm/elements/SwcIf.js.map +2 -2
- package/dist/esm/elements/SwcLoop.js +3 -3
- package/dist/esm/elements/SwcLoop.js.map +2 -2
- package/dist/esm/elements/register.js +7 -6
- package/dist/esm/elements/register.js.map +2 -2
- package/dist/esm/index.js +6 -17
- package/dist/esm/index.js.map +2 -2
- package/dist/esm/router/ElementRouter.js +2 -2
- package/dist/esm/router/ElementRouter.js.map +1 -1
- package/dist/esm/types.js.map +2 -2
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +5444 -3317
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
- package/dist/types/decorators/addEventListener.d.ts +6 -0
- package/dist/types/decorators/addEventListener.d.ts.map +1 -1
- package/dist/types/decorators/applyNode.d.ts +38 -0
- package/dist/types/decorators/applyNode.d.ts.map +1 -0
- package/dist/types/decorators/attribute.d.ts +29 -0
- package/dist/types/decorators/attribute.d.ts.map +1 -0
- package/dist/types/decorators/{changedAttribute.d.ts → changedAttributeHost.d.ts} +6 -2
- package/dist/types/decorators/changedAttributeHost.d.ts.map +1 -0
- package/dist/types/decorators/classList.d.ts +25 -0
- package/dist/types/decorators/classList.d.ts.map +1 -1
- package/dist/types/decorators/elementDefine.d.ts.map +1 -1
- package/dist/types/decorators/emitCustomEvent.d.ts +14 -2
- package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
- package/dist/types/decorators/index.d.ts +3 -3
- package/dist/types/decorators/index.d.ts.map +1 -1
- package/dist/types/decorators/lifecycles.d.ts +2 -0
- package/dist/types/decorators/lifecycles.d.ts.map +1 -1
- package/dist/types/decorators/query.d.ts +6 -0
- package/dist/types/decorators/query.d.ts.map +1 -1
- package/dist/types/decorators/queryAll.d.ts +6 -0
- package/dist/types/decorators/queryAll.d.ts.map +1 -1
- package/dist/types/decorators/setAttribute.d.ts +8 -0
- package/dist/types/decorators/setAttribute.d.ts.map +1 -1
- package/dist/types/elements/SwcAppEngine.d.ts +5 -4
- package/dist/types/elements/SwcAppEngine.d.ts.map +1 -1
- package/dist/types/elements/SwcAppMixin.d.ts +1 -1
- package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
- package/dist/types/elements/register.d.ts +1 -1
- package/dist/types/elements/register.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -14
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/router/ElementRouter.d.ts +1 -1
- package/dist/types/router/ElementRouter.d.ts.map +1 -1
- package/dist/types/types.d.ts +3 -1
- package/dist/types/types.d.ts.map +1 -1
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +5444 -3317
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
- package/package.json +10 -5
- package/src/decorators/addEventListener.ts +10 -1
- package/src/decorators/applyNode.ts +127 -0
- package/src/decorators/attribute.ts +192 -0
- package/src/decorators/{changedAttribute.ts → changedAttributeHost.ts} +6 -2
- package/src/decorators/classList.ts +33 -1
- package/src/decorators/elementDefine.ts +148 -47
- package/src/decorators/emitCustomEvent.ts +14 -6
- package/src/decorators/index.ts +3 -3
- package/src/decorators/lifecycles.ts +4 -2
- package/src/decorators/onConnectedInnerHtml.ts +1 -1
- package/src/decorators/query.ts +10 -1
- package/src/decorators/queryAll.ts +10 -1
- package/src/decorators/setAttribute.ts +57 -17
- package/src/decorators/style.ts +1 -1
- package/src/elements/SwcAppEngine.ts +10 -8
- package/src/elements/SwcAppMixin.ts +34 -2
- package/src/elements/SwcAsync.ts +3 -3
- package/src/elements/SwcChoose.ts +3 -3
- package/src/elements/SwcIf.ts +3 -3
- package/src/elements/SwcLoop.ts +3 -3
- package/src/elements/register.ts +8 -6
- package/src/index.ts +8 -16
- package/src/router/ElementRouter.ts +2 -2
- package/src/types.ts +3 -1
- package/dist/cjs/decorators/appendChild.js.map +0 -7
- package/dist/cjs/decorators/changedAttribute.js.map +0 -7
- package/dist/cjs/decorators/replaceChildren.js +0 -79
- package/dist/cjs/decorators/replaceChildren.js.map +0 -7
- package/dist/esm/decorators/appendChild.js.map +0 -7
- package/dist/esm/decorators/changedAttribute.js.map +0 -7
- package/dist/esm/decorators/replaceChildren.js +0 -60
- package/dist/esm/decorators/replaceChildren.js.map +0 -7
- package/dist/types/decorators/appendChild.d.ts +0 -17
- package/dist/types/decorators/appendChild.d.ts.map +0 -1
- package/dist/types/decorators/changedAttribute.d.ts.map +0 -1
- package/dist/types/decorators/replaceChildren.d.ts +0 -9
- package/dist/types/decorators/replaceChildren.d.ts.map +0 -1
- package/src/decorators/appendChild.ts +0 -86
- package/src/decorators/replaceChildren.ts +0 -64
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
import { ReflectUtils } from '@dooboostore/core
|
|
2
|
-
import { FunctionUtils } from '@dooboostore/core
|
|
1
|
+
import { ReflectUtils } from '@dooboostore/core';
|
|
2
|
+
import { FunctionUtils } from '@dooboostore/core';
|
|
3
3
|
import { getOnConnectedInnerHtmlMetadata } from './onConnectedInnerHtml';
|
|
4
4
|
import { getAddEventListenerMetadata } from './addEventListener';
|
|
5
|
-
import { 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 } from './lifecycles';
|
|
5
|
+
import { ON_CONSTRUCTOR_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 } from './lifecycles';
|
|
6
6
|
import { getEmitCustomEventMetadataList } from './emitCustomEvent';
|
|
7
|
-
import { findAllAttributeChangedMetadata } from './
|
|
7
|
+
import { findAllAttributeChangedMetadata } from './changedAttributeHost';
|
|
8
8
|
import { findAllSetAttributeMetadata } from './setAttribute';
|
|
9
|
-
import {
|
|
10
|
-
import { findAllAppendChildMetadata } from './appendChild';
|
|
11
|
-
import { findAllClassListMetadata } from './classList';
|
|
12
|
-
import { findAllStyleMetadata } from './style';
|
|
9
|
+
import { findAllAttributeMetadata } from './attribute';
|
|
13
10
|
import { SwcUtils } from '../utils/Utils';
|
|
14
11
|
import { HTML_TAG_ENTRIES, DOM_EVENT_NAMES } from '../config/config';
|
|
15
12
|
import { SituationTypeContainer, SituationTypeContainers } from '@dooboostore/simple-boot/decorators/inject/Inject';
|
|
16
13
|
import { InjectSituationType, HostSet } from '../types';
|
|
17
14
|
|
|
18
|
-
// --- Core Interfaces & Types
|
|
15
|
+
// --- Core Interfaces & Types ---
|
|
19
16
|
|
|
20
17
|
export const ELEMENT_CONFIG_KEY = Symbol('simple-web-component:element-config');
|
|
21
18
|
|
|
@@ -46,6 +43,12 @@ export const ensureInit = (inst: any) => {
|
|
|
46
43
|
// Call constructor script if present
|
|
47
44
|
const hostSet = SwcUtils.getHostSet(inst);
|
|
48
45
|
inst._executeSwcScript?.('swc-on-constructor', hostSet);
|
|
46
|
+
|
|
47
|
+
// Call @onConstructor lifecycle methods
|
|
48
|
+
const cMethods = findAllLifecycleMetadata(inst, ON_CONSTRUCTOR_METADATA_KEY);
|
|
49
|
+
if (cMethods) {
|
|
50
|
+
for (const m of cMethods) (inst)._invokeLifecycleMethod(m, hostSet);
|
|
51
|
+
}
|
|
49
52
|
}
|
|
50
53
|
};
|
|
51
54
|
|
|
@@ -159,7 +162,9 @@ const setupPrototype = (proto: any) => {
|
|
|
159
162
|
if (oldHandler) el.removeEventListener(eventName, oldHandler);
|
|
160
163
|
|
|
161
164
|
const handler = async (event: any) => {
|
|
162
|
-
|
|
165
|
+
console.log('execute handler', event);
|
|
166
|
+
const parent = SwcUtils.findNearestSwcHost(el);
|
|
167
|
+
const hostSet = SwcUtils.getHostSet(parent || el);
|
|
163
168
|
const conf = getElementConfig(this);
|
|
164
169
|
const currentWin = (this as any)._resolveWindow(conf);
|
|
165
170
|
const helpers = SwcUtils.getHelperSet(currentWin);
|
|
@@ -180,13 +185,19 @@ const setupPrototype = (proto: any) => {
|
|
|
180
185
|
|
|
181
186
|
proto.__swc_executeAttributeEvent = async function (el: HTMLElement, attrName: string, script: string, event: Event) {
|
|
182
187
|
ensureInit(this);
|
|
183
|
-
|
|
188
|
+
|
|
189
|
+
console.log('execute handler2', event);
|
|
190
|
+
const parent = SwcUtils.findNearestSwcHost(el);
|
|
191
|
+
const hostSet = SwcUtils.getHostSet(parent || el);
|
|
184
192
|
const conf = getElementConfig(this);
|
|
185
193
|
const currentWin = (this as any)._resolveWindow(conf);
|
|
186
194
|
const currentHelpers = SwcUtils.getHelperSet(currentWin);
|
|
195
|
+
const detail = (event as CustomEvent).detail;
|
|
187
196
|
const args = {
|
|
188
197
|
event,
|
|
189
|
-
$
|
|
198
|
+
$event: event,
|
|
199
|
+
$data: detail,
|
|
200
|
+
$detail: detail,
|
|
190
201
|
...hostSet,
|
|
191
202
|
...currentHelpers,
|
|
192
203
|
$el: el,
|
|
@@ -219,14 +230,17 @@ export const elementDefine =
|
|
|
219
230
|
}
|
|
220
231
|
|
|
221
232
|
const emitCustomEventList = getEmitCustomEventMetadataList(constructor) || [];
|
|
233
|
+
const emitHostCustomEventList = emitCustomEventList.filter(meta => meta.selector === ':host' || meta.selector === '');
|
|
222
234
|
const addEventListenerList = getAddEventListenerMetadata(constructor) || [];
|
|
235
|
+
const addHostEventListenerList = addEventListenerList.filter(meta => meta.selector === ':host' || meta.selector === '');
|
|
223
236
|
const attrChangeMap = findAllAttributeChangedMetadata(constructor);
|
|
237
|
+
const attributeList = findAllAttributeMetadata(constructor);
|
|
224
238
|
|
|
225
239
|
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'];
|
|
226
240
|
const swcOnEvents = DOM_EVENT_NAMES.map(e => `swc-on-${e}`);
|
|
227
241
|
|
|
228
242
|
// Collect all observed attributes from all decorators
|
|
229
|
-
const mergedObservedAttributes = [...new Set([...(metadata.observedAttributes ?? []), ...attrChangeMap.keys(), ...Array.from(findAllSetAttributeMetadata(constructor).values()).map(it => it.name), ...
|
|
243
|
+
const mergedObservedAttributes = [...new Set([...(metadata.observedAttributes ?? []), ...attrChangeMap.keys(), ...Array.from(findAllSetAttributeMetadata(constructor).values()).map(it => it.name), ...attributeList.map(it => it.options.name || String(it.propertyKey)), ...emitHostCustomEventList.map(it => (it.options as any).attributeName).filter(Boolean), ...swcLifecycleAttributes, ...swcOnEvents])];
|
|
230
244
|
|
|
231
245
|
const connectedInnerHtmlList = getOnConnectedInnerHtmlMetadata(constructor) || [];
|
|
232
246
|
|
|
@@ -251,7 +265,23 @@ export const elementDefine =
|
|
|
251
265
|
for (const m of bMethods) (this as any)._invokeLifecycleMethod(m, hostSet);
|
|
252
266
|
}
|
|
253
267
|
|
|
254
|
-
|
|
268
|
+
// Initialize @attribute fields (DOM <-> JS Sync)
|
|
269
|
+
attributeList.forEach(meta => {
|
|
270
|
+
const attrName = meta.options.name || String(meta.propertyKey);
|
|
271
|
+
if (meta.options.connectedInitialize === true) {
|
|
272
|
+
// JS -> DOM (FORCE OVERWRITE with JS value)
|
|
273
|
+
(this as any).__swc_syncing_init = true;
|
|
274
|
+
try {
|
|
275
|
+
const memoryVal = (this as any)[meta.privateKey];
|
|
276
|
+
if (memoryVal !== undefined) {
|
|
277
|
+
(this as any)[meta.propertyKey] = memoryVal; // Trigger setter to update DOM
|
|
278
|
+
}
|
|
279
|
+
} finally {
|
|
280
|
+
(this as any).__swc_syncing_init = false;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// else: Do NOT sync - Keep the default value from class initialization
|
|
284
|
+
});
|
|
255
285
|
|
|
256
286
|
if (connectedInnerHtmlList.length > 0) {
|
|
257
287
|
let sContent = '',
|
|
@@ -275,7 +305,76 @@ export const elementDefine =
|
|
|
275
305
|
globalDelegatedRoots.add(root);
|
|
276
306
|
}
|
|
277
307
|
|
|
308
|
+
// Separate delegate and non-delegate listeners
|
|
309
|
+
const delegateListeners: typeof addEventListenerList = [];
|
|
310
|
+
const nonDelegateListeners: typeof addEventListenerList = [];
|
|
311
|
+
|
|
278
312
|
addEventListenerList.forEach(meta => {
|
|
313
|
+
if (meta.options.delegate && meta.selector !== ':window' && meta.selector !== ':document' && meta.selector !== ':parentHost' && meta.selector !== ':appHost' && meta.selector !== ':firstHost' && meta.selector !== ':lastHost' && meta.selector !== ':firstAppHost' && meta.selector !== ':lastAppHost' && meta.selector !== ':hosts' && meta.selector !== ':appHosts' && meta.selector !== ':host' && meta.selector !== '') {
|
|
314
|
+
delegateListeners.push(meta);
|
|
315
|
+
} else {
|
|
316
|
+
nonDelegateListeners.push(meta);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
// Group delegate listeners by (type, root) combination
|
|
321
|
+
const delegatesByTypeAndRoot = new Map<string, any[]>();
|
|
322
|
+
delegateListeners.forEach(meta => {
|
|
323
|
+
const r = meta.options.root || 'auto';
|
|
324
|
+
const rootKey = `${meta.type}:${r}`;
|
|
325
|
+
if (!delegatesByTypeAndRoot.has(rootKey)) {
|
|
326
|
+
delegatesByTypeAndRoot.set(rootKey, []);
|
|
327
|
+
}
|
|
328
|
+
delegatesByTypeAndRoot.get(rootKey)!.push(meta);
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
// Register unified handlers for delegate listeners
|
|
332
|
+
delegatesByTypeAndRoot.forEach((metaList, typeRootKey) => {
|
|
333
|
+
const [type, rStr] = typeRootKey.split(':');
|
|
334
|
+
const r = rStr === 'auto' ? 'auto' : rStr;
|
|
335
|
+
const opts = { capture: metaList[0].options.capture, once: metaList[0].options.once, passive: metaList[0].options.passive };
|
|
336
|
+
|
|
337
|
+
const bindRoots: (HTMLElement | ShadowRoot)[] = [];
|
|
338
|
+
if (r === 'auto') bindRoots.push(this.shadowRoot || (this as any));
|
|
339
|
+
else if (r === 'light') bindRoots.push(this as any);
|
|
340
|
+
else if (r === 'shadow' && this.shadowRoot) bindRoots.push(this.shadowRoot);
|
|
341
|
+
else if (r === 'all') {
|
|
342
|
+
bindRoots.push(this as any);
|
|
343
|
+
if (this.shadowRoot) bindRoots.push(this.shadowRoot);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
bindRoots.forEach(br => {
|
|
347
|
+
// Sort: stopPropagation handlers first (more specific/terminal actions)
|
|
348
|
+
const sortedMetaList = [...metaList].sort((a, b) => {
|
|
349
|
+
const aStop = a.options.stopPropagation ? 1 : 0;
|
|
350
|
+
const bStop = b.options.stopPropagation ? 1 : 0;
|
|
351
|
+
return bStop - aStop; // stopPropagation: true comes first
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
const unifiedHandler = async (event: Event) => {
|
|
355
|
+
for (const meta of sortedMetaList) {
|
|
356
|
+
const { selector, options } = meta;
|
|
357
|
+
const matchedEl = (event.target as HTMLElement).closest(selector);
|
|
358
|
+
if (matchedEl && (br as any).contains(matchedEl)) {
|
|
359
|
+
if (options.stopPropagation) event.stopPropagation();
|
|
360
|
+
if (options.stopImmediatePropagation) event.stopImmediatePropagation();
|
|
361
|
+
if (options.preventDefault) event.preventDefault();
|
|
362
|
+
const currentHostSet = SwcUtils.getHostSet(this as any);
|
|
363
|
+
const args = { event, ...currentHostSet, $el: matchedEl, $root: br };
|
|
364
|
+
await (this as any)[meta.propertyKey](event, currentHostSet, matchedEl, args);
|
|
365
|
+
|
|
366
|
+
// Stop processing if event propagation was stopped
|
|
367
|
+
if ((event as any).cancelBubble) break;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
br.addEventListener(type, unifiedHandler, opts);
|
|
372
|
+
(this as any)._boundListeners.push({ target: br, type, handler: unifiedHandler, options: opts });
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
// Process non-delegate listeners
|
|
377
|
+
nonDelegateListeners.forEach(meta => {
|
|
279
378
|
const { selector, type, options } = meta;
|
|
280
379
|
const opts = { capture: options.capture, once: options.once, passive: options.passive };
|
|
281
380
|
const bindTargets: EventTarget[] = [];
|
|
@@ -301,34 +400,7 @@ export const elementDefine =
|
|
|
301
400
|
else if (selector === ':hosts') hostSet.$hosts.forEach(applyRootOption);
|
|
302
401
|
else if (selector === ':appHosts') hostSet.$appHosts.forEach(applyRootOption);
|
|
303
402
|
else if (selector === ':host' || !selector) applyRootOption(this);
|
|
304
|
-
else
|
|
305
|
-
const bindRoots: (HTMLElement | ShadowRoot)[] = [];
|
|
306
|
-
if (r === 'auto') bindRoots.push(this.shadowRoot || (this as any));
|
|
307
|
-
else if (r === 'light') bindRoots.push(this as any);
|
|
308
|
-
else if (r === 'shadow' && this.shadowRoot) bindRoots.push(this.shadowRoot);
|
|
309
|
-
else if (r === 'all') {
|
|
310
|
-
bindRoots.push(this as any);
|
|
311
|
-
if (this.shadowRoot) bindRoots.push(this.shadowRoot);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
bindRoots.forEach(br => {
|
|
315
|
-
const handler = async (event: Event) => {
|
|
316
|
-
const matchedEl = (event.target as HTMLElement).closest(selector);
|
|
317
|
-
if (matchedEl && (br as any).contains(matchedEl)) {
|
|
318
|
-
if (options.stopPropagation) event.stopPropagation();
|
|
319
|
-
if (options.stopImmediatePropagation) event.stopImmediatePropagation();
|
|
320
|
-
if (options.preventDefault) event.preventDefault();
|
|
321
|
-
const currentHostSet = SwcUtils.getHostSet(this as any);
|
|
322
|
-
const args = { event, ...currentHostSet, $el: matchedEl, $root: br };
|
|
323
|
-
await (this as any)._invokeLifecycleMethod(meta.propertyKey, currentHostSet, [event, currentHostSet, matchedEl, args]);
|
|
324
|
-
}
|
|
325
|
-
};
|
|
326
|
-
br.addEventListener(type, handler, opts);
|
|
327
|
-
if (options.removeOnDisconnected === true || (br !== this && br !== this.shadowRoot)) {
|
|
328
|
-
(this as any)._boundListeners.push({ target: br, type, handler, options: opts });
|
|
329
|
-
}
|
|
330
|
-
});
|
|
331
|
-
} else {
|
|
403
|
+
else {
|
|
332
404
|
const searchRoots: (HTMLElement | ShadowRoot)[] = [];
|
|
333
405
|
if (r === 'auto') searchRoots.push(this.shadowRoot || (this as any));
|
|
334
406
|
else if (r === 'light') searchRoots.push(this as any);
|
|
@@ -350,7 +422,7 @@ export const elementDefine =
|
|
|
350
422
|
if (options.preventDefault) event.preventDefault();
|
|
351
423
|
const currentHostSet = SwcUtils.getHostSet(this as any);
|
|
352
424
|
const args = { event, ...currentHostSet, $el: t, $root: t };
|
|
353
|
-
await (this as any)
|
|
425
|
+
await (this as any)[meta.propertyKey](event, currentHostSet, args);
|
|
354
426
|
};
|
|
355
427
|
t.addEventListener(type, handler, opts);
|
|
356
428
|
if (options.removeOnDisconnected === true || t === currentWin || t === currentWin.document) {
|
|
@@ -359,13 +431,33 @@ export const elementDefine =
|
|
|
359
431
|
});
|
|
360
432
|
});
|
|
361
433
|
|
|
434
|
+
addHostEventListenerList.forEach(meta => {
|
|
435
|
+
const { type, options } = meta;
|
|
436
|
+
const opts = { capture: options.capture, once: options.once, passive: options.passive };
|
|
437
|
+
|
|
438
|
+
const handler = async (event: Event) => {
|
|
439
|
+
if (options.stopPropagation) event.stopPropagation();
|
|
440
|
+
if (options.stopImmediatePropagation) event.stopImmediatePropagation();
|
|
441
|
+
if (options.preventDefault) event.preventDefault();
|
|
442
|
+
const currentHostSet = SwcUtils.getHostSet(this as any);
|
|
443
|
+
const args = { event, ...currentHostSet, $el: this, $root: this.getRootNode() };
|
|
444
|
+
await (this as any)[meta.propertyKey](event, currentHostSet, args);
|
|
445
|
+
};
|
|
446
|
+
this.addEventListener(type, handler, opts);
|
|
447
|
+
if (options.removeOnDisconnected === true) {
|
|
448
|
+
(this as any)._boundListeners.push({ target: this, type, handler, options: opts });
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
|
|
362
452
|
if (originalConnected) originalConnected.apply(this);
|
|
453
|
+
|
|
363
454
|
const aMethods = findAllLifecycleMetadata(this, ON_AFTER_CONNECTED_METADATA_KEY);
|
|
364
455
|
if (aMethods) {
|
|
365
456
|
for (const m of aMethods) (this as any)._invokeLifecycleMethod(m, hostSet);
|
|
366
457
|
}
|
|
367
458
|
(this as any)._executeSwcScript('swc-on-connected', hostSet);
|
|
368
459
|
(this as any)._executeSwcScript('swc-on-after-connected', hostSet);
|
|
460
|
+
(this as any).__swc_connected = true;
|
|
369
461
|
};
|
|
370
462
|
|
|
371
463
|
const originalDisconnected = proto.disconnectedCallback;
|
|
@@ -390,6 +482,7 @@ export const elementDefine =
|
|
|
390
482
|
}
|
|
391
483
|
(this as any)._executeSwcScript('swc-on-disconnected', hostSet);
|
|
392
484
|
(this as any)._executeSwcScript('swc-on-after-disconnected', hostSet);
|
|
485
|
+
(this as any).__swc_connected = false;
|
|
393
486
|
};
|
|
394
487
|
|
|
395
488
|
const originalAdopted = proto.adoptedCallback;
|
|
@@ -415,18 +508,26 @@ export const elementDefine =
|
|
|
415
508
|
proto.attributeChangedCallback = function (name: string, old: string | null, newVal: string | null) {
|
|
416
509
|
if (originalAttributeChanged) originalAttributeChanged.apply(this, [name, old, newVal]);
|
|
417
510
|
|
|
511
|
+
const hSet = SwcUtils.getHostSet(this as any);
|
|
512
|
+
|
|
513
|
+
// Handle swc-on-* events
|
|
418
514
|
if (name.startsWith('swc-on-') && !swcLifecycleAttributes.includes(name)) {
|
|
419
515
|
if (newVal !== null) {
|
|
420
|
-
const
|
|
421
|
-
const eventName = customEventMeta ? customEventMeta.type : name.substring(7);
|
|
516
|
+
const eventName = name.substring(7);
|
|
422
517
|
(this as any)._bindAttributeEvent(this as any, name, newVal, eventName);
|
|
423
518
|
}
|
|
424
519
|
}
|
|
425
520
|
|
|
521
|
+
// Handle @emitHostCustomEvent attribute changes
|
|
522
|
+
const hostCustomEventMeta = emitHostCustomEventList.find(it => (it.options as any).attributeName === name);
|
|
523
|
+
if (hostCustomEventMeta && newVal !== null) {
|
|
524
|
+
(this as any)._bindAttributeEvent(this as any, name, newVal, hostCustomEventMeta.type);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// Handle @changedAttribute callbacks
|
|
426
528
|
const mKeys = attrChangeMap.get(name);
|
|
427
529
|
if (mKeys && Array.isArray(mKeys)) {
|
|
428
|
-
const
|
|
429
|
-
for (const key of mKeys) (this as any)._invokeLifecycleMethod(key, hSet, [newVal, old, name]);
|
|
530
|
+
for (const key of mKeys) (this as any)[key](newVal, old, name, hSet);
|
|
430
531
|
}
|
|
431
532
|
};
|
|
432
533
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { ReflectUtils } from '@dooboostore/core
|
|
1
|
+
import { ReflectUtils } from '@dooboostore/core';
|
|
2
2
|
import { SpecialSelector, SwcQueryOptions } from '../types';
|
|
3
3
|
import { ensureInit, getElementConfig } from './elementDefine';
|
|
4
4
|
import { SwcUtils } from '../utils/Utils';
|
|
5
5
|
|
|
6
6
|
export interface EmitCustomEventBaseOptions {
|
|
7
|
-
attributeName?: string;
|
|
8
7
|
bubbles?: boolean;
|
|
9
8
|
composed?: boolean;
|
|
10
9
|
cancelable?: boolean;
|
|
@@ -14,7 +13,7 @@ export interface EmitCustomEventMetadata {
|
|
|
14
13
|
propertyKey: string | symbol;
|
|
15
14
|
selector: string;
|
|
16
15
|
type: string;
|
|
17
|
-
options: EmitCustomEventBaseOptions & SwcQueryOptions;
|
|
16
|
+
options: (EmitCustomEventBaseOptions & SwcQueryOptions) | (EmitCustomEventBaseOptions & SwcQueryOptions & { attributeName?: string });
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
export const EMIT_CUSTOM_EVENT_METADATA_KEY = Symbol('simple-web-component:emit-custom-event');
|
|
@@ -29,9 +28,6 @@ export function emitCustomEvent(selectorOrTarget: string, type: string, options:
|
|
|
29
28
|
|
|
30
29
|
const fullOptions: any = { ...options, type };
|
|
31
30
|
|
|
32
|
-
if (!fullOptions.attributeName) {
|
|
33
|
-
fullOptions.attributeName = `swc-on-${type}`;
|
|
34
|
-
}
|
|
35
31
|
if (fullOptions.bubbles === undefined) fullOptions.bubbles = true;
|
|
36
32
|
if (fullOptions.composed === undefined) fullOptions.composed = true;
|
|
37
33
|
|
|
@@ -103,3 +99,15 @@ export const getEmitCustomEventMetadataList = (target: any): EmitCustomEventMeta
|
|
|
103
99
|
const constructor = target instanceof Function ? target : target.constructor;
|
|
104
100
|
return ReflectUtils.getMetadata(EMIT_CUSTOM_EVENT_METADATA_KEY, constructor);
|
|
105
101
|
};
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @emitCustomEventHost decorator - simplified version of @emitCustomEvent for :host selector
|
|
105
|
+
* Usage: @emitCustomEventHost('navigate')
|
|
106
|
+
* Usage: @emitCustomEventHost('navigate', { attributeName: 'on-navigate' })
|
|
107
|
+
*
|
|
108
|
+
* The attributeName option is used to automatically observe attributes for this event.
|
|
109
|
+
* For example, { attributeName: 'on-navigate' } will add 'on-navigate' to observedAttributes.
|
|
110
|
+
*/
|
|
111
|
+
export function emitCustomEventHost(type: string, options?: EmitCustomEventBaseOptions & SwcQueryOptions & { attributeName?: string }): MethodDecorator {
|
|
112
|
+
return emitCustomEvent(':host', type, options);
|
|
113
|
+
}
|
package/src/decorators/index.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export * from './addEventListener';
|
|
2
|
+
export * from './attribute';
|
|
2
3
|
export * from './elementDefine';
|
|
3
|
-
export * from './
|
|
4
|
+
export * from './changedAttributeHost';
|
|
4
5
|
export * from './setAttribute';
|
|
5
6
|
export * from './emitCustomEvent';
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './appendChild';
|
|
7
|
+
export * from './applyNode';
|
|
8
8
|
export * from './lifecycles';
|
|
9
9
|
export * from './query';
|
|
10
10
|
export * from './queryAll';
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { ReflectUtils } from '@dooboostore/core
|
|
2
|
-
import { ON_ATTRIBUTE_CHANGED_METADATA_KEY } from './
|
|
1
|
+
import { ReflectUtils } from '@dooboostore/core';
|
|
2
|
+
import { ON_ATTRIBUTE_CHANGED_METADATA_KEY } from './changedAttributeHost';
|
|
3
3
|
import { SET_ATTRIBUTE_METADATA_KEY } from './setAttribute';
|
|
4
4
|
|
|
5
|
+
export const ON_CONSTRUCTOR_METADATA_KEY = Symbol('simple-web-component:on-constructor');
|
|
5
6
|
export const ON_BEFORE_CONNECTED_METADATA_KEY = Symbol('simple-web-component:on-before-connected');
|
|
6
7
|
export const ON_AFTER_CONNECTED_METADATA_KEY = Symbol('simple-web-component:on-after-connected');
|
|
7
8
|
export const ON_BEFORE_DISCONNECTED_METADATA_KEY = Symbol('simple-web-component:on-before-disconnected');
|
|
@@ -24,6 +25,7 @@ function createLifecycleDecorator(metadataKey: symbol): MethodDecorator {
|
|
|
24
25
|
};
|
|
25
26
|
}
|
|
26
27
|
|
|
28
|
+
export const onConstructor = createLifecycleDecorator(ON_CONSTRUCTOR_METADATA_KEY);
|
|
27
29
|
export const onBeforeConnected = createLifecycleDecorator(ON_BEFORE_CONNECTED_METADATA_KEY);
|
|
28
30
|
export const onAfterConnected = createLifecycleDecorator(ON_AFTER_CONNECTED_METADATA_KEY);
|
|
29
31
|
export const onConnected = onAfterConnected;
|
package/src/decorators/query.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReflectUtils } from '@dooboostore/core
|
|
1
|
+
import { ReflectUtils } from '@dooboostore/core';
|
|
2
2
|
import { getElementConfig, ensureInit } from './elementDefine';
|
|
3
3
|
import { SwcUtils } from '../utils/Utils';
|
|
4
4
|
import { SpecialSelector, SwcQueryOptions } from '../types';
|
|
@@ -108,3 +108,12 @@ export const getQueryMetadata = (target: any): QueryMetadata[] | undefined => {
|
|
|
108
108
|
const constructor = target instanceof Function ? target : target.constructor;
|
|
109
109
|
return ReflectUtils.getMetadata(QUERY_METADATA_KEY, constructor);
|
|
110
110
|
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* @hostQuery decorator - simplified version of @query for :host selector
|
|
114
|
+
* Usage: @hostQuery()
|
|
115
|
+
* Usage: @hostQuery({ root: 'shadow' })
|
|
116
|
+
*/
|
|
117
|
+
export function queryHost(options?: SwcQueryOptions): PropertyDecorator {
|
|
118
|
+
return query(':host', options);
|
|
119
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReflectUtils } from '@dooboostore/core
|
|
1
|
+
import { ReflectUtils } from '@dooboostore/core';
|
|
2
2
|
import { getElementConfig, ensureInit } from './elementDefine';
|
|
3
3
|
import { SwcUtils } from '../utils/Utils';
|
|
4
4
|
import { SpecialSelector, SwcQueryOptions } from '../types';
|
|
@@ -107,3 +107,12 @@ export const getQueryAllMetadata = (target: any): QueryAllMetadata[] | undefined
|
|
|
107
107
|
const constructor = target instanceof Function ? target : target.constructor;
|
|
108
108
|
return ReflectUtils.getMetadata(QUERY_ALL_METADATA_KEY, constructor);
|
|
109
109
|
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* @hostQueryAll decorator - simplified version of @queryAll for :host selector
|
|
113
|
+
* Usage: @hostQueryAll()
|
|
114
|
+
* Usage: @hostQueryAll({ root: 'shadow' })
|
|
115
|
+
*/
|
|
116
|
+
export function queryAllHost(options?: SwcQueryOptions): PropertyDecorator {
|
|
117
|
+
return queryAll(':host', options);
|
|
118
|
+
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { ReflectUtils } from '@dooboostore/core
|
|
1
|
+
import { ReflectUtils } from '@dooboostore/core';
|
|
2
2
|
import { ensureInit, getElementConfig } from './elementDefine';
|
|
3
3
|
import { SwcUtils } from '../utils/Utils';
|
|
4
|
+
import { SwcQueryOptions } from '../types';
|
|
4
5
|
|
|
5
6
|
export interface SetAttributeMetadata {
|
|
6
7
|
propertyKey: string | symbol;
|
|
7
8
|
selector: string;
|
|
8
9
|
name: string;
|
|
10
|
+
options: SwcQueryOptions;
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
export const SET_ATTRIBUTE_METADATA_KEY = Symbol('simple-web-component:set-attribute');
|
|
@@ -15,7 +17,9 @@ export const SET_ATTRIBUTE_METADATA_KEY = Symbol('simple-web-component:set-attri
|
|
|
15
17
|
* Usage: @setAttribute(':host', 'count')
|
|
16
18
|
* Usage: @setAttribute('#child', 'disabled')
|
|
17
19
|
*/
|
|
18
|
-
export function setAttribute(selector: string, name: string): MethodDecorator
|
|
20
|
+
export function setAttribute(selector: string, name: string): MethodDecorator;
|
|
21
|
+
export function setAttribute(selector: string, name: string, options?: SwcQueryOptions): MethodDecorator;
|
|
22
|
+
export function setAttribute(selector: string, name: string, options: SwcQueryOptions = {}): MethodDecorator {
|
|
19
23
|
return (target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
|
|
20
24
|
const constructor = target.constructor;
|
|
21
25
|
let metaList = ReflectUtils.getOwnMetadata(SET_ATTRIBUTE_METADATA_KEY, constructor) as Map<string | symbol, SetAttributeMetadata>;
|
|
@@ -23,7 +27,7 @@ export function setAttribute(selector: string, name: string): MethodDecorator {
|
|
|
23
27
|
metaList = new Map<string | symbol, SetAttributeMetadata>();
|
|
24
28
|
ReflectUtils.defineMetadata(SET_ATTRIBUTE_METADATA_KEY, metaList, constructor);
|
|
25
29
|
}
|
|
26
|
-
metaList.set(propertyKey, { propertyKey, selector, name });
|
|
30
|
+
metaList.set(propertyKey, { propertyKey, selector, name, options });
|
|
27
31
|
|
|
28
32
|
const original = descriptor.value;
|
|
29
33
|
descriptor.value = async function (...args: any[]) {
|
|
@@ -34,22 +38,50 @@ export function setAttribute(selector: string, name: string): MethodDecorator {
|
|
|
34
38
|
const conf = getElementConfig(this);
|
|
35
39
|
const currentWin = (this as any)._resolveWindow?.(conf) || ((typeof window !== 'undefined' ? window : undefined) as Window);
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
else if (selector === ':window') targetEl = currentWin as any;
|
|
40
|
-
else if (selector === ':document') targetEl = currentWin.document as any;
|
|
41
|
-
else if (selector === ':parentHost') targetEl = hostSet.$parentHost;
|
|
42
|
-
else if (selector === ':appHost') targetEl = hostSet.$appHost;
|
|
43
|
-
else if (selector === ':firstHost') targetEl = hostSet.$firstHost;
|
|
44
|
-
else if (selector === ':lastHost') targetEl = hostSet.$lastHost;
|
|
45
|
-
else if (selector === ':firstAppHost') targetEl = hostSet.$firstAppHost;
|
|
46
|
-
else if (selector === ':lastAppHost') targetEl = hostSet.$lastAppHost;
|
|
47
|
-
else targetEl = (this.shadowRoot || (this as any)).querySelector(selector);
|
|
41
|
+
const targetEls: any[] = [];
|
|
42
|
+
const r = options.root || 'auto';
|
|
48
43
|
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
|
|
44
|
+
const applyRoot = (t: any) => {
|
|
45
|
+
if (!t) return;
|
|
46
|
+
if (r === 'auto') {
|
|
47
|
+
targetEls.push((t as any).shadowRoot || t);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (r === 'light' || r === 'all') targetEls.push(t);
|
|
51
|
+
if ((r === 'shadow' || r === 'all') && (t as any).shadowRoot) targetEls.push((t as any).shadowRoot);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
if (selector === ':window') targetEls.push(currentWin);
|
|
55
|
+
else if (selector === ':document') targetEls.push(currentWin.document as any);
|
|
56
|
+
else if (selector === ':parentHost') applyRoot(hostSet.$parentHost);
|
|
57
|
+
else if (selector === ':appHost') applyRoot(hostSet.$appHost);
|
|
58
|
+
else if (selector === ':firstHost') applyRoot(hostSet.$firstHost);
|
|
59
|
+
else if (selector === ':lastHost') applyRoot(hostSet.$lastHost);
|
|
60
|
+
else if (selector === ':firstAppHost') applyRoot(hostSet.$firstAppHost);
|
|
61
|
+
else if (selector === ':lastAppHost') applyRoot(hostSet.$lastAppHost);
|
|
62
|
+
else if (selector === ':hosts') hostSet.$hosts.forEach(applyRoot);
|
|
63
|
+
else if (selector === ':appHosts') hostSet.$appHosts.forEach(applyRoot);
|
|
64
|
+
else if (selector === ':host' || !selector) applyRoot(this);
|
|
65
|
+
else {
|
|
66
|
+
const roots: any[] = [];
|
|
67
|
+
if (r === 'shadow') {
|
|
68
|
+
if ((this as any).shadowRoot) roots.push((this as any).shadowRoot);
|
|
69
|
+
} else if (r === 'light') {
|
|
70
|
+
roots.push(this as any);
|
|
71
|
+
} else if (r === 'all') {
|
|
72
|
+
roots.push(this as any);
|
|
73
|
+
if ((this as any).shadowRoot) roots.push((this as any).shadowRoot);
|
|
74
|
+
} else {
|
|
75
|
+
roots.push((this as any).shadowRoot || (this as any));
|
|
76
|
+
}
|
|
77
|
+
roots.forEach(root => targetEls.push(...root.querySelectorAll(selector)));
|
|
52
78
|
}
|
|
79
|
+
|
|
80
|
+
targetEls.forEach(targetEl => {
|
|
81
|
+
if (!targetEl || typeof (targetEl as any).setAttribute !== 'function') return;
|
|
82
|
+
if (res === null) (targetEl as any).removeAttribute(name);
|
|
83
|
+
else (targetEl as any).setAttribute(name, String(res));
|
|
84
|
+
})
|
|
53
85
|
}
|
|
54
86
|
return res;
|
|
55
87
|
};
|
|
@@ -71,3 +103,11 @@ export const findAllSetAttributeMetadata = (target: any): Map<string | symbol, S
|
|
|
71
103
|
});
|
|
72
104
|
return result;
|
|
73
105
|
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @setAttributeHost decorator - simplified version of @setAttribute for :host selector
|
|
109
|
+
* Usage: @setAttributeHost('aria-disabled')
|
|
110
|
+
*/
|
|
111
|
+
export function setAttributeHost(name: string, options?: SwcQueryOptions): MethodDecorator {
|
|
112
|
+
return setAttribute(':host', name, options);
|
|
113
|
+
}
|
package/src/decorators/style.ts
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { SimpleApplication } from '@dooboostore/simple-boot/SimpleApplication';
|
|
2
|
-
import { PathRouter } from '@dooboostore/core-web
|
|
3
|
-
import { HashRouter } from '@dooboostore/core-web
|
|
2
|
+
import { PathRouter } from '@dooboostore/core-web';
|
|
3
|
+
import { HashRouter } from '@dooboostore/core-web';
|
|
4
4
|
import { ElementRouter } from '../router/ElementRouter';
|
|
5
5
|
import { SimOption } from '@dooboostore/simple-boot/SimOption';
|
|
6
|
-
import { Router, RouterEventType } from '@dooboostore/core-web
|
|
7
|
-
import { Subscription } from '@dooboostore/core
|
|
8
|
-
import { ConstructorType,
|
|
9
|
-
import { FunctionUtils } from '@dooboostore/core
|
|
6
|
+
import { Router, RouterEventType } from '@dooboostore/core-web';
|
|
7
|
+
import { Subscription } from '@dooboostore/core';
|
|
8
|
+
import { ConstructorType, OptionalType } from '@dooboostore/core';
|
|
9
|
+
import { FunctionUtils } from '@dooboostore/core';
|
|
10
10
|
import { SwcUtils } from '../utils/Utils';
|
|
11
11
|
|
|
12
12
|
export type SwcConfigType = {
|
|
13
|
-
rootRouter: ConstructorType<any> |
|
|
13
|
+
rootRouter: ConstructorType<any> | symbol;
|
|
14
14
|
routeType: 'path' | 'hash' | 'element';
|
|
15
|
+
connectMode?: 'direct' | 'swap';
|
|
15
16
|
path?: string;
|
|
16
17
|
window: Window;
|
|
17
18
|
};
|
|
18
19
|
|
|
19
|
-
export type SwcAttributeConfigType =
|
|
20
|
+
export type SwcAttributeConfigType = OptionalType<SwcConfigType, 'routeType' | 'window'>;
|
|
20
21
|
|
|
21
22
|
export class SwcAppEngine {
|
|
22
23
|
public simpleApplication?: SimpleApplication;
|
|
@@ -87,6 +88,7 @@ export class SwcAppEngine {
|
|
|
87
88
|
// Rendering
|
|
88
89
|
const data = this.simpleApplication.sim(_config.rootRouter);
|
|
89
90
|
if (data instanceof Node) {
|
|
91
|
+
// console.warn('[SWC-APP-ENGINE] Rendering failed: Root element is not a DocumentFragment.', data);
|
|
90
92
|
if (this.host.shadowRoot) this.host.shadowRoot.replaceChildren(data);
|
|
91
93
|
else this.host.replaceChildren(data);
|
|
92
94
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { SwcAppEngine, SwcAttributeConfigType } from './SwcAppEngine';
|
|
2
|
+
import {SwcAppInterface} from "../types";
|
|
2
3
|
|
|
3
4
|
export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Base: T) {
|
|
4
|
-
return class extends Base {
|
|
5
|
+
return class extends Base implements SwcAppInterface{
|
|
5
6
|
__swc_engine = new SwcAppEngine(this as any);
|
|
6
7
|
|
|
7
8
|
get simpleApplication() {
|
|
@@ -12,7 +13,38 @@ export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Bas
|
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
async connect(config?: SwcAttributeConfigType) {
|
|
15
|
-
|
|
16
|
+
const mode = config?.connectMode || 'direct';
|
|
17
|
+
|
|
18
|
+
if (mode !== 'swap') {
|
|
19
|
+
await this.__swc_engine.connect(config);
|
|
20
|
+
this.setAttribute('swc-connect-mode', 'direct');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const parent = this.parentNode;
|
|
25
|
+
if (!parent) {
|
|
26
|
+
await this.__swc_engine.connect(config);
|
|
27
|
+
this.setAttribute('swc-connect-mode', 'direct');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const clonedApp = this.cloneNode(true) as any;
|
|
32
|
+
clonedApp.style.display = 'none';
|
|
33
|
+
parent.insertBefore(clonedApp, this.nextSibling);
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
await clonedApp.connect({ ...(config || {}), connectMode: 'direct' });
|
|
37
|
+
if (this.parentNode) {
|
|
38
|
+
this.parentNode.removeChild(this);
|
|
39
|
+
}
|
|
40
|
+
clonedApp.setAttribute('swc-connect-mode', 'swap');
|
|
41
|
+
clonedApp.style.display = '';
|
|
42
|
+
} catch (e) {
|
|
43
|
+
if (clonedApp.parentNode) {
|
|
44
|
+
clonedApp.parentNode.removeChild(clonedApp);
|
|
45
|
+
}
|
|
46
|
+
throw e;
|
|
47
|
+
}
|
|
16
48
|
}
|
|
17
49
|
|
|
18
50
|
connectedCallback() {
|