@dooboostore/simple-web-component 1.0.21 → 1.0.23
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 +1113 -95
- package/dist/cjs/decorators/addEventListener.js +4 -0
- package/dist/cjs/decorators/addEventListener.js.map +2 -2
- package/dist/cjs/decorators/applyNode.js +174 -0
- package/dist/cjs/decorators/applyNode.js.map +7 -0
- package/dist/cjs/decorators/attribute.js +30 -10
- package/dist/cjs/decorators/attribute.js.map +3 -3
- package/dist/cjs/decorators/{changedAttribute.js → changedAttributeHost.js} +6 -6
- package/dist/cjs/decorators/changedAttributeHost.js.map +7 -0
- package/dist/cjs/decorators/classList.js +45 -15
- package/dist/cjs/decorators/classList.js.map +2 -2
- package/dist/cjs/decorators/elementDefine.js +107 -57
- package/dist/cjs/decorators/elementDefine.js.map +2 -2
- package/dist/cjs/decorators/emitCustomEvent.js +4 -3
- package/dist/cjs/decorators/emitCustomEvent.js.map +2 -2
- package/dist/cjs/decorators/index.js +2 -4
- package/dist/cjs/decorators/index.js.map +2 -2
- package/dist/cjs/decorators/lifecycles.js +29 -0
- package/dist/cjs/decorators/lifecycles.js.map +2 -2
- package/dist/cjs/decorators/query.js +5 -1
- package/dist/cjs/decorators/query.js.map +2 -2
- package/dist/cjs/decorators/queryAll.js +5 -1
- package/dist/cjs/decorators/queryAll.js.map +2 -2
- package/dist/cjs/decorators/setAttribute.js +5 -1
- package/dist/cjs/decorators/setAttribute.js.map +2 -2
- package/dist/cjs/decorators/style.js +39 -13
- package/dist/cjs/decorators/style.js.map +2 -2
- package/dist/cjs/elements/SwcAppEngine.js.map +2 -2
- package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
- package/dist/cjs/elements/SwcAsync.js +2 -2
- package/dist/cjs/elements/SwcAsync.js.map +2 -2
- package/dist/cjs/elements/SwcChoose.js +2 -2
- package/dist/cjs/elements/SwcChoose.js.map +2 -2
- package/dist/cjs/elements/SwcIf.js +2 -2
- package/dist/cjs/elements/SwcIf.js.map +2 -2
- package/dist/cjs/elements/SwcLoop.js +2 -2
- package/dist/cjs/elements/SwcLoop.js.map +2 -2
- package/dist/cjs/elements/register.js +6 -5
- package/dist/cjs/elements/register.js.map +2 -2
- package/dist/cjs/index.js +6 -18
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/types.js.map +2 -2
- package/dist/cjs/utils/TemplateUtils.js +6 -0
- package/dist/cjs/utils/TemplateUtils.js.map +2 -2
- package/dist/esm/decorators/addEventListener.js +4 -0
- package/dist/esm/decorators/addEventListener.js.map +2 -2
- package/dist/esm/decorators/applyNode.js +155 -0
- package/dist/esm/decorators/applyNode.js.map +7 -0
- package/dist/esm/decorators/attribute.js +30 -10
- package/dist/esm/decorators/attribute.js.map +3 -3
- package/dist/esm/decorators/{changedAttribute.js → changedAttributeHost.js} +3 -3
- package/dist/esm/decorators/changedAttributeHost.js.map +7 -0
- package/dist/esm/decorators/classList.js +45 -15
- package/dist/esm/decorators/classList.js.map +2 -2
- package/dist/esm/decorators/elementDefine.js +106 -56
- package/dist/esm/decorators/elementDefine.js.map +2 -2
- package/dist/esm/decorators/emitCustomEvent.js +4 -3
- package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
- package/dist/esm/decorators/index.js +2 -4
- package/dist/esm/decorators/index.js.map +2 -2
- package/dist/esm/decorators/lifecycles.js +29 -0
- package/dist/esm/decorators/lifecycles.js.map +2 -2
- package/dist/esm/decorators/query.js +5 -1
- package/dist/esm/decorators/query.js.map +2 -2
- package/dist/esm/decorators/queryAll.js +5 -1
- package/dist/esm/decorators/queryAll.js.map +2 -2
- package/dist/esm/decorators/setAttribute.js +5 -1
- package/dist/esm/decorators/setAttribute.js.map +2 -2
- package/dist/esm/decorators/style.js +39 -13
- package/dist/esm/decorators/style.js.map +2 -2
- package/dist/esm/elements/SwcAppEngine.js.map +2 -2
- package/dist/esm/elements/SwcAppMixin.js.map +2 -2
- package/dist/esm/elements/SwcAsync.js +2 -2
- package/dist/esm/elements/SwcAsync.js.map +2 -2
- package/dist/esm/elements/SwcChoose.js +2 -2
- package/dist/esm/elements/SwcChoose.js.map +2 -2
- package/dist/esm/elements/SwcIf.js +2 -2
- package/dist/esm/elements/SwcIf.js.map +2 -2
- package/dist/esm/elements/SwcLoop.js +2 -2
- package/dist/esm/elements/SwcLoop.js.map +2 -2
- package/dist/esm/elements/register.js +6 -5
- package/dist/esm/elements/register.js.map +2 -2
- package/dist/esm/index.js +6 -18
- package/dist/esm/index.js.map +2 -2
- package/dist/esm/types.js.map +2 -2
- package/dist/esm/utils/TemplateUtils.js +6 -0
- package/dist/esm/utils/TemplateUtils.js.map +2 -2
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +385 -206
- 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 +121 -0
- package/dist/types/decorators/applyNode.d.ts.map +1 -0
- package/dist/types/decorators/attribute.d.ts +6 -0
- package/dist/types/decorators/attribute.d.ts.map +1 -1
- 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 +32 -5
- 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 +2 -4
- package/dist/types/decorators/index.d.ts.map +1 -1
- package/dist/types/decorators/lifecycles.d.ts +16 -0
- package/dist/types/decorators/lifecycles.d.ts.map +1 -1
- package/dist/types/decorators/query.d.ts +6 -3
- 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 +5 -0
- package/dist/types/decorators/setAttribute.d.ts.map +1 -1
- package/dist/types/decorators/style.d.ts +28 -3
- package/dist/types/decorators/style.d.ts.map +1 -1
- package/dist/types/elements/SwcAppEngine.d.ts.map +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 -15
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/types.d.ts +2 -1
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils/TemplateUtils.d.ts +5 -0
- package/dist/types/utils/TemplateUtils.d.ts.map +1 -1
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +385 -206
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
- package/package.json +3 -3
- package/src/decorators/addEventListener.ts +9 -0
- package/src/decorators/applyNode.ts +290 -0
- package/src/decorators/attribute.ts +46 -12
- package/src/decorators/{changedAttribute.ts → changedAttributeHost.ts} +5 -1
- package/src/decorators/classList.ts +71 -16
- package/src/decorators/elementDefine.ts +130 -63
- package/src/decorators/emitCustomEvent.ts +13 -5
- package/src/decorators/index.ts +2 -4
- package/src/decorators/lifecycles.ts +43 -1
- package/src/decorators/query.ts +9 -2
- package/src/decorators/queryAll.ts +9 -0
- package/src/decorators/setAttribute.ts +8 -0
- package/src/decorators/style.ts +64 -13
- package/src/elements/SwcAppEngine.ts +1 -0
- package/src/elements/SwcAppMixin.ts +2 -1
- package/src/elements/SwcAsync.ts +2 -2
- package/src/elements/SwcChoose.ts +2 -2
- package/src/elements/SwcIf.ts +2 -2
- package/src/elements/SwcLoop.ts +2 -2
- package/src/elements/register.ts +7 -5
- package/src/index.ts +8 -17
- package/src/types.ts +2 -1
- package/src/utils/TemplateUtils.ts +9 -0
- package/dist/cjs/decorators/appendChild.js +0 -92
- package/dist/cjs/decorators/appendChild.js.map +0 -7
- package/dist/cjs/decorators/changedAttribute.js.map +0 -7
- package/dist/cjs/decorators/onConnectedInnerHtml.js +0 -48
- package/dist/cjs/decorators/onConnectedInnerHtml.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 +0 -73
- package/dist/esm/decorators/appendChild.js.map +0 -7
- package/dist/esm/decorators/changedAttribute.js.map +0 -7
- package/dist/esm/decorators/onConnectedInnerHtml.js +0 -29
- package/dist/esm/decorators/onConnectedInnerHtml.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/onConnectedInnerHtml.d.ts +0 -15
- package/dist/types/decorators/onConnectedInnerHtml.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/onConnectedInnerHtml.ts +0 -42
- package/src/decorators/replaceChildren.ts +0 -64
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import { ReflectUtils } from '@dooboostore/core';
|
|
2
2
|
import { FunctionUtils } from '@dooboostore/core';
|
|
3
|
-
import { getOnConnectedInnerHtmlMetadata } from './onConnectedInnerHtml';
|
|
4
3
|
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';
|
|
4
|
+
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, getOnConnectedInnerHtmlMetadata } from './lifecycles';
|
|
6
5
|
import { getEmitCustomEventMetadataList } from './emitCustomEvent';
|
|
7
|
-
import { findAllAttributeChangedMetadata } from './
|
|
6
|
+
import { findAllAttributeChangedMetadata } from './changedAttributeHost';
|
|
8
7
|
import { findAllSetAttributeMetadata } from './setAttribute';
|
|
9
|
-
import { findAllReplaceChildrenMetadata } from './replaceChildren';
|
|
10
|
-
import { findAllAppendChildMetadata } from './appendChild';
|
|
11
|
-
import { findAllClassListMetadata } from './classList';
|
|
12
|
-
import { findAllStyleMetadata } from './style';
|
|
13
8
|
import { findAllAttributeMetadata } from './attribute';
|
|
14
9
|
import { SwcUtils } from '../utils/Utils';
|
|
15
10
|
import { HTML_TAG_ENTRIES, DOM_EVENT_NAMES } from '../config/config';
|
|
@@ -47,6 +42,12 @@ export const ensureInit = (inst: any) => {
|
|
|
47
42
|
// Call constructor script if present
|
|
48
43
|
const hostSet = SwcUtils.getHostSet(inst);
|
|
49
44
|
inst._executeSwcScript?.('swc-on-constructor', hostSet);
|
|
45
|
+
|
|
46
|
+
// Call @onConstructor lifecycle methods
|
|
47
|
+
const cMethods = findAllLifecycleMetadata(inst, ON_CONSTRUCTOR_METADATA_KEY);
|
|
48
|
+
if (cMethods) {
|
|
49
|
+
for (const m of cMethods) (inst)._invokeLifecycleMethod(m, hostSet);
|
|
50
|
+
}
|
|
50
51
|
}
|
|
51
52
|
};
|
|
52
53
|
|
|
@@ -160,7 +161,9 @@ const setupPrototype = (proto: any) => {
|
|
|
160
161
|
if (oldHandler) el.removeEventListener(eventName, oldHandler);
|
|
161
162
|
|
|
162
163
|
const handler = async (event: any) => {
|
|
163
|
-
|
|
164
|
+
console.log('execute handler', event);
|
|
165
|
+
const parent = SwcUtils.findNearestSwcHost(el);
|
|
166
|
+
const hostSet = SwcUtils.getHostSet(parent || el);
|
|
164
167
|
const conf = getElementConfig(this);
|
|
165
168
|
const currentWin = (this as any)._resolveWindow(conf);
|
|
166
169
|
const helpers = SwcUtils.getHelperSet(currentWin);
|
|
@@ -181,13 +184,19 @@ const setupPrototype = (proto: any) => {
|
|
|
181
184
|
|
|
182
185
|
proto.__swc_executeAttributeEvent = async function (el: HTMLElement, attrName: string, script: string, event: Event) {
|
|
183
186
|
ensureInit(this);
|
|
184
|
-
|
|
187
|
+
|
|
188
|
+
console.log('execute handler2', event);
|
|
189
|
+
const parent = SwcUtils.findNearestSwcHost(el);
|
|
190
|
+
const hostSet = SwcUtils.getHostSet(parent || el);
|
|
185
191
|
const conf = getElementConfig(this);
|
|
186
192
|
const currentWin = (this as any)._resolveWindow(conf);
|
|
187
193
|
const currentHelpers = SwcUtils.getHelperSet(currentWin);
|
|
194
|
+
const detail = (event as CustomEvent).detail;
|
|
188
195
|
const args = {
|
|
189
196
|
event,
|
|
190
|
-
$
|
|
197
|
+
$event: event,
|
|
198
|
+
$data: detail,
|
|
199
|
+
$detail: detail,
|
|
191
200
|
...hostSet,
|
|
192
201
|
...currentHelpers,
|
|
193
202
|
$el: el,
|
|
@@ -220,7 +229,9 @@ export const elementDefine =
|
|
|
220
229
|
}
|
|
221
230
|
|
|
222
231
|
const emitCustomEventList = getEmitCustomEventMetadataList(constructor) || [];
|
|
232
|
+
const emitHostCustomEventList = emitCustomEventList.filter(meta => meta.selector === ':host' || meta.selector === '');
|
|
223
233
|
const addEventListenerList = getAddEventListenerMetadata(constructor) || [];
|
|
234
|
+
const addHostEventListenerList = addEventListenerList.filter(meta => meta.selector === ':host' || meta.selector === '');
|
|
224
235
|
const attrChangeMap = findAllAttributeChangedMetadata(constructor);
|
|
225
236
|
const attributeList = findAllAttributeMetadata(constructor);
|
|
226
237
|
|
|
@@ -228,7 +239,7 @@ export const elementDefine =
|
|
|
228
239
|
const swcOnEvents = DOM_EVENT_NAMES.map(e => `swc-on-${e}`);
|
|
229
240
|
|
|
230
241
|
// Collect all observed attributes from all decorators
|
|
231
|
-
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)), ...
|
|
242
|
+
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])];
|
|
232
243
|
|
|
233
244
|
const connectedInnerHtmlList = getOnConnectedInnerHtmlMetadata(constructor) || [];
|
|
234
245
|
|
|
@@ -256,29 +267,19 @@ export const elementDefine =
|
|
|
256
267
|
// Initialize @attribute fields (DOM <-> JS Sync)
|
|
257
268
|
attributeList.forEach(meta => {
|
|
258
269
|
const attrName = meta.options.name || String(meta.propertyKey);
|
|
259
|
-
if (meta.options.connectedInitialize) {
|
|
260
|
-
// JS -> DOM (FORCE OVERWRITE)
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
(this as any).
|
|
264
|
-
|
|
270
|
+
if (meta.options.connectedInitialize === true) {
|
|
271
|
+
// JS -> DOM (FORCE OVERWRITE with JS value)
|
|
272
|
+
(this as any).__swc_syncing_init = true;
|
|
273
|
+
try {
|
|
274
|
+
const memoryVal = (this as any)[meta.privateKey];
|
|
275
|
+
if (memoryVal !== undefined) {
|
|
265
276
|
(this as any)[meta.propertyKey] = memoryVal; // Trigger setter to update DOM
|
|
266
|
-
} finally {
|
|
267
|
-
(this as any).__swc_syncing_init = false;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
} else if (meta.selector === ':host' || !meta.selector) {
|
|
271
|
-
// DOM -> JS (Pull from HTML)
|
|
272
|
-
const domVal = this.getAttribute(attrName);
|
|
273
|
-
if (domVal !== null) {
|
|
274
|
-
(this as any).__swc_syncing_init = true;
|
|
275
|
-
try {
|
|
276
|
-
(this as any)[meta.propertyKey] = domVal; // Update memory with DOM value
|
|
277
|
-
} finally {
|
|
278
|
-
(this as any).__swc_syncing_init = false;
|
|
279
277
|
}
|
|
278
|
+
} finally {
|
|
279
|
+
(this as any).__swc_syncing_init = false;
|
|
280
280
|
}
|
|
281
281
|
}
|
|
282
|
+
// else: Do NOT sync - Keep the default value from class initialization
|
|
282
283
|
});
|
|
283
284
|
|
|
284
285
|
if (connectedInnerHtmlList.length > 0) {
|
|
@@ -303,7 +304,76 @@ export const elementDefine =
|
|
|
303
304
|
globalDelegatedRoots.add(root);
|
|
304
305
|
}
|
|
305
306
|
|
|
307
|
+
// Separate delegate and non-delegate listeners
|
|
308
|
+
const delegateListeners: typeof addEventListenerList = [];
|
|
309
|
+
const nonDelegateListeners: typeof addEventListenerList = [];
|
|
310
|
+
|
|
306
311
|
addEventListenerList.forEach(meta => {
|
|
312
|
+
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 !== '') {
|
|
313
|
+
delegateListeners.push(meta);
|
|
314
|
+
} else {
|
|
315
|
+
nonDelegateListeners.push(meta);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
// Group delegate listeners by (type, root) combination
|
|
320
|
+
const delegatesByTypeAndRoot = new Map<string, any[]>();
|
|
321
|
+
delegateListeners.forEach(meta => {
|
|
322
|
+
const r = meta.options.root || 'auto';
|
|
323
|
+
const rootKey = `${meta.type}:${r}`;
|
|
324
|
+
if (!delegatesByTypeAndRoot.has(rootKey)) {
|
|
325
|
+
delegatesByTypeAndRoot.set(rootKey, []);
|
|
326
|
+
}
|
|
327
|
+
delegatesByTypeAndRoot.get(rootKey)!.push(meta);
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
// Register unified handlers for delegate listeners
|
|
331
|
+
delegatesByTypeAndRoot.forEach((metaList, typeRootKey) => {
|
|
332
|
+
const [type, rStr] = typeRootKey.split(':');
|
|
333
|
+
const r = rStr === 'auto' ? 'auto' : rStr;
|
|
334
|
+
const opts = { capture: metaList[0].options.capture, once: metaList[0].options.once, passive: metaList[0].options.passive };
|
|
335
|
+
|
|
336
|
+
const bindRoots: (HTMLElement | ShadowRoot)[] = [];
|
|
337
|
+
if (r === 'auto') bindRoots.push(this.shadowRoot || (this as any));
|
|
338
|
+
else if (r === 'light') bindRoots.push(this as any);
|
|
339
|
+
else if (r === 'shadow' && this.shadowRoot) bindRoots.push(this.shadowRoot);
|
|
340
|
+
else if (r === 'all') {
|
|
341
|
+
bindRoots.push(this as any);
|
|
342
|
+
if (this.shadowRoot) bindRoots.push(this.shadowRoot);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
bindRoots.forEach(br => {
|
|
346
|
+
// Sort: stopPropagation handlers first (more specific/terminal actions)
|
|
347
|
+
const sortedMetaList = [...metaList].sort((a, b) => {
|
|
348
|
+
const aStop = a.options.stopPropagation ? 1 : 0;
|
|
349
|
+
const bStop = b.options.stopPropagation ? 1 : 0;
|
|
350
|
+
return bStop - aStop; // stopPropagation: true comes first
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
const unifiedHandler = async (event: Event) => {
|
|
354
|
+
for (const meta of sortedMetaList) {
|
|
355
|
+
const { selector, options } = meta;
|
|
356
|
+
const matchedEl = (event.target as HTMLElement).closest(selector);
|
|
357
|
+
if (matchedEl && (br as any).contains(matchedEl)) {
|
|
358
|
+
if (options.stopPropagation) event.stopPropagation();
|
|
359
|
+
if (options.stopImmediatePropagation) event.stopImmediatePropagation();
|
|
360
|
+
if (options.preventDefault) event.preventDefault();
|
|
361
|
+
const currentHostSet = SwcUtils.getHostSet(this as any);
|
|
362
|
+
const args = { event, ...currentHostSet, $el: matchedEl, $root: br };
|
|
363
|
+
await (this as any)[meta.propertyKey](event, currentHostSet, matchedEl, args);
|
|
364
|
+
|
|
365
|
+
// Stop processing if event propagation was stopped
|
|
366
|
+
if ((event as any).cancelBubble) break;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
br.addEventListener(type, unifiedHandler, opts);
|
|
371
|
+
(this as any)._boundListeners.push({ target: br, type, handler: unifiedHandler, options: opts });
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
// Process non-delegate listeners
|
|
376
|
+
nonDelegateListeners.forEach(meta => {
|
|
307
377
|
const { selector, type, options } = meta;
|
|
308
378
|
const opts = { capture: options.capture, once: options.once, passive: options.passive };
|
|
309
379
|
const bindTargets: EventTarget[] = [];
|
|
@@ -329,34 +399,7 @@ export const elementDefine =
|
|
|
329
399
|
else if (selector === ':hosts') hostSet.$hosts.forEach(applyRootOption);
|
|
330
400
|
else if (selector === ':appHosts') hostSet.$appHosts.forEach(applyRootOption);
|
|
331
401
|
else if (selector === ':host' || !selector) applyRootOption(this);
|
|
332
|
-
else
|
|
333
|
-
const bindRoots: (HTMLElement | ShadowRoot)[] = [];
|
|
334
|
-
if (r === 'auto') bindRoots.push(this.shadowRoot || (this as any));
|
|
335
|
-
else if (r === 'light') bindRoots.push(this as any);
|
|
336
|
-
else if (r === 'shadow' && this.shadowRoot) bindRoots.push(this.shadowRoot);
|
|
337
|
-
else if (r === 'all') {
|
|
338
|
-
bindRoots.push(this as any);
|
|
339
|
-
if (this.shadowRoot) bindRoots.push(this.shadowRoot);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
bindRoots.forEach(br => {
|
|
343
|
-
const handler = async (event: Event) => {
|
|
344
|
-
const matchedEl = (event.target as HTMLElement).closest(selector);
|
|
345
|
-
if (matchedEl && (br as any).contains(matchedEl)) {
|
|
346
|
-
if (options.stopPropagation) event.stopPropagation();
|
|
347
|
-
if (options.stopImmediatePropagation) event.stopImmediatePropagation();
|
|
348
|
-
if (options.preventDefault) event.preventDefault();
|
|
349
|
-
const currentHostSet = SwcUtils.getHostSet(this as any);
|
|
350
|
-
const args = { event, ...currentHostSet, $el: matchedEl, $root: br };
|
|
351
|
-
await (this as any)._invokeLifecycleMethod(meta.propertyKey, currentHostSet, [event, currentHostSet, matchedEl, args]);
|
|
352
|
-
}
|
|
353
|
-
};
|
|
354
|
-
br.addEventListener(type, handler, opts);
|
|
355
|
-
if (options.removeOnDisconnected === true || (br !== this && br !== this.shadowRoot)) {
|
|
356
|
-
(this as any)._boundListeners.push({ target: br, type, handler, options: opts });
|
|
357
|
-
}
|
|
358
|
-
});
|
|
359
|
-
} else {
|
|
402
|
+
else {
|
|
360
403
|
const searchRoots: (HTMLElement | ShadowRoot)[] = [];
|
|
361
404
|
if (r === 'auto') searchRoots.push(this.shadowRoot || (this as any));
|
|
362
405
|
else if (r === 'light') searchRoots.push(this as any);
|
|
@@ -378,7 +421,7 @@ export const elementDefine =
|
|
|
378
421
|
if (options.preventDefault) event.preventDefault();
|
|
379
422
|
const currentHostSet = SwcUtils.getHostSet(this as any);
|
|
380
423
|
const args = { event, ...currentHostSet, $el: t, $root: t };
|
|
381
|
-
await (this as any)
|
|
424
|
+
await (this as any)[meta.propertyKey](event, currentHostSet, args);
|
|
382
425
|
};
|
|
383
426
|
t.addEventListener(type, handler, opts);
|
|
384
427
|
if (options.removeOnDisconnected === true || t === currentWin || t === currentWin.document) {
|
|
@@ -387,6 +430,24 @@ export const elementDefine =
|
|
|
387
430
|
});
|
|
388
431
|
});
|
|
389
432
|
|
|
433
|
+
addHostEventListenerList.forEach(meta => {
|
|
434
|
+
const { type, options } = meta;
|
|
435
|
+
const opts = { capture: options.capture, once: options.once, passive: options.passive };
|
|
436
|
+
|
|
437
|
+
const handler = async (event: Event) => {
|
|
438
|
+
if (options.stopPropagation) event.stopPropagation();
|
|
439
|
+
if (options.stopImmediatePropagation) event.stopImmediatePropagation();
|
|
440
|
+
if (options.preventDefault) event.preventDefault();
|
|
441
|
+
const currentHostSet = SwcUtils.getHostSet(this as any);
|
|
442
|
+
const args = { event, ...currentHostSet, $el: this, $root: this.getRootNode() };
|
|
443
|
+
await (this as any)[meta.propertyKey](event, currentHostSet, args);
|
|
444
|
+
};
|
|
445
|
+
this.addEventListener(type, handler, opts);
|
|
446
|
+
if (options.removeOnDisconnected === true) {
|
|
447
|
+
(this as any)._boundListeners.push({ target: this, type, handler, options: opts });
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
|
|
390
451
|
if (originalConnected) originalConnected.apply(this);
|
|
391
452
|
|
|
392
453
|
const aMethods = findAllLifecycleMetadata(this, ON_AFTER_CONNECTED_METADATA_KEY);
|
|
@@ -446,20 +507,26 @@ export const elementDefine =
|
|
|
446
507
|
proto.attributeChangedCallback = function (name: string, old: string | null, newVal: string | null) {
|
|
447
508
|
if (originalAttributeChanged) originalAttributeChanged.apply(this, [name, old, newVal]);
|
|
448
509
|
|
|
510
|
+
const hSet = SwcUtils.getHostSet(this as any);
|
|
511
|
+
|
|
449
512
|
// Handle swc-on-* events
|
|
450
513
|
if (name.startsWith('swc-on-') && !swcLifecycleAttributes.includes(name)) {
|
|
451
514
|
if (newVal !== null) {
|
|
452
|
-
const
|
|
453
|
-
const eventName = customEventMeta ? customEventMeta.type : name.substring(7);
|
|
515
|
+
const eventName = name.substring(7);
|
|
454
516
|
(this as any)._bindAttributeEvent(this as any, name, newVal, eventName);
|
|
455
517
|
}
|
|
456
518
|
}
|
|
457
519
|
|
|
520
|
+
// Handle @emitHostCustomEvent attribute changes
|
|
521
|
+
const hostCustomEventMeta = emitHostCustomEventList.find(it => (it.options as any).attributeName === name);
|
|
522
|
+
if (hostCustomEventMeta && newVal !== null) {
|
|
523
|
+
(this as any)._bindAttributeEvent(this as any, name, newVal, hostCustomEventMeta.type);
|
|
524
|
+
}
|
|
525
|
+
|
|
458
526
|
// Handle @changedAttribute callbacks
|
|
459
527
|
const mKeys = attrChangeMap.get(name);
|
|
460
528
|
if (mKeys && Array.isArray(mKeys)) {
|
|
461
|
-
const
|
|
462
|
-
for (const key of mKeys) (this as any)._invokeLifecycleMethod(key, hSet, [newVal, old, name]);
|
|
529
|
+
for (const key of mKeys) (this as any)[key](newVal, old, name, hSet);
|
|
463
530
|
}
|
|
464
531
|
};
|
|
465
532
|
|
|
@@ -4,7 +4,6 @@ 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,14 +1,12 @@
|
|
|
1
1
|
export * from './addEventListener';
|
|
2
2
|
export * from './attribute';
|
|
3
3
|
export * from './elementDefine';
|
|
4
|
-
export * from './
|
|
4
|
+
export * from './changedAttributeHost';
|
|
5
5
|
export * from './setAttribute';
|
|
6
6
|
export * from './emitCustomEvent';
|
|
7
|
-
export * from './
|
|
8
|
-
export * from './appendChild';
|
|
7
|
+
export * from './applyNode';
|
|
9
8
|
export * from './lifecycles';
|
|
10
9
|
export * from './query';
|
|
11
10
|
export * from './queryAll';
|
|
12
|
-
export * from './onConnectedInnerHtml';
|
|
13
11
|
export * from './classList';
|
|
14
12
|
export * from './style';
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ReflectUtils } from '@dooboostore/core';
|
|
2
|
-
import { ON_ATTRIBUTE_CHANGED_METADATA_KEY } from './
|
|
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');
|
|
@@ -9,9 +10,19 @@ export const ON_AFTER_DISCONNECTED_METADATA_KEY = Symbol('simple-web-component:o
|
|
|
9
10
|
export const ON_BEFORE_ADOPTED_METADATA_KEY = Symbol('simple-web-component:on-before-adopted');
|
|
10
11
|
export const ON_AFTER_ADOPTED_METADATA_KEY = Symbol('simple-web-component:on-after-adopted');
|
|
11
12
|
export const ON_ADD_EVENT_LISTENER_METADATA_KEY = Symbol('simple-web-component:on-add-event-listener');
|
|
13
|
+
export const INNER_HTML_METADATA_KEY = Symbol('simple-web-component:inner-html');
|
|
12
14
|
|
|
13
15
|
export const ATTRIBUTE_CHANGED_WILDCARD = '*';
|
|
14
16
|
|
|
17
|
+
export interface InnerHtmlOptions {
|
|
18
|
+
useShadow?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface InnerHtmlMetadata {
|
|
22
|
+
propertyKey: string | symbol;
|
|
23
|
+
options: InnerHtmlOptions;
|
|
24
|
+
}
|
|
25
|
+
|
|
15
26
|
function createLifecycleDecorator(metadataKey: symbol): MethodDecorator {
|
|
16
27
|
return (target: Object, propertyKey: string | symbol) => {
|
|
17
28
|
const constructor = target.constructor;
|
|
@@ -24,6 +35,7 @@ function createLifecycleDecorator(metadataKey: symbol): MethodDecorator {
|
|
|
24
35
|
};
|
|
25
36
|
}
|
|
26
37
|
|
|
38
|
+
export const onConstructor = createLifecycleDecorator(ON_CONSTRUCTOR_METADATA_KEY);
|
|
27
39
|
export const onBeforeConnected = createLifecycleDecorator(ON_BEFORE_CONNECTED_METADATA_KEY);
|
|
28
40
|
export const onAfterConnected = createLifecycleDecorator(ON_AFTER_CONNECTED_METADATA_KEY);
|
|
29
41
|
export const onConnected = onAfterConnected;
|
|
@@ -38,6 +50,31 @@ export const onAdopted = onAfterAdopted;
|
|
|
38
50
|
|
|
39
51
|
export const onAddEventListener = createLifecycleDecorator(ON_ADD_EVENT_LISTENER_METADATA_KEY);
|
|
40
52
|
|
|
53
|
+
/**
|
|
54
|
+
* @onConnectedInnerHtml decorator to define the initial HTML content when connected.
|
|
55
|
+
*/
|
|
56
|
+
export function onConnectedInnerHtml(options: InnerHtmlOptions): MethodDecorator;
|
|
57
|
+
export function onConnectedInnerHtml(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
58
|
+
export function onConnectedInnerHtml(arg1?: InnerHtmlOptions | Object, arg2?: string | symbol, arg3?: PropertyDescriptor): MethodDecorator | void {
|
|
59
|
+
const decorator = (options: InnerHtmlOptions, target: Object, propertyKey: string | symbol) => {
|
|
60
|
+
const constructor = target.constructor;
|
|
61
|
+
let list = ReflectUtils.getMetadata<InnerHtmlMetadata[]>(INNER_HTML_METADATA_KEY, constructor);
|
|
62
|
+
if (!list) {
|
|
63
|
+
list = [];
|
|
64
|
+
ReflectUtils.defineMetadata(INNER_HTML_METADATA_KEY, list, constructor);
|
|
65
|
+
}
|
|
66
|
+
list.push({ propertyKey, options });
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
if (arg2) {
|
|
70
|
+
return decorator({}, arg1!, arg2);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return (target: Object, propertyKey: string | symbol) => {
|
|
74
|
+
decorator((arg1 as InnerHtmlOptions) || {}, target, propertyKey);
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
41
78
|
/**
|
|
42
79
|
* 프로토타입 체인을 순회하며 모든 라이프사이클 메서드를 수집합니다.
|
|
43
80
|
*/
|
|
@@ -45,3 +82,8 @@ export const findAllLifecycleMetadata = <T = (string | symbol)[]>(target: any, m
|
|
|
45
82
|
const results = ReflectUtils.findAllMetadataFlatten(metadataKey, target);
|
|
46
83
|
return results.length > 0 ? (results as unknown as T) : undefined;
|
|
47
84
|
};
|
|
85
|
+
|
|
86
|
+
export const getOnConnectedInnerHtmlMetadata = (target: any): InnerHtmlMetadata[] | undefined => {
|
|
87
|
+
const constructor = target instanceof Function ? target : target.constructor;
|
|
88
|
+
return ReflectUtils.getMetadata(INNER_HTML_METADATA_KEY, constructor);
|
|
89
|
+
};
|
package/src/decorators/query.ts
CHANGED
|
@@ -3,8 +3,6 @@ import { getElementConfig, ensureInit } from './elementDefine';
|
|
|
3
3
|
import { SwcUtils } from '../utils/Utils';
|
|
4
4
|
import { SpecialSelector, SwcQueryOptions } from '../types';
|
|
5
5
|
|
|
6
|
-
export type QueryOptions = { root?: 'light' | 'shadow' | 'all' | 'auto' };
|
|
7
|
-
|
|
8
6
|
export interface QueryMetadata {
|
|
9
7
|
propertyKey: string | symbol;
|
|
10
8
|
selector: string;
|
|
@@ -108,3 +106,12 @@ export const getQueryMetadata = (target: any): QueryMetadata[] | undefined => {
|
|
|
108
106
|
const constructor = target instanceof Function ? target : target.constructor;
|
|
109
107
|
return ReflectUtils.getMetadata(QUERY_METADATA_KEY, constructor);
|
|
110
108
|
};
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @hostQuery decorator - simplified version of @query for :host selector
|
|
112
|
+
* Usage: @hostQuery()
|
|
113
|
+
* Usage: @hostQuery({ root: 'shadow' })
|
|
114
|
+
*/
|
|
115
|
+
export function queryHost(options?: SwcQueryOptions): PropertyDecorator {
|
|
116
|
+
return query(':host', options);
|
|
117
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -103,3 +103,11 @@ export const findAllSetAttributeMetadata = (target: any): Map<string | symbol, S
|
|
|
103
103
|
});
|
|
104
104
|
return result;
|
|
105
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,19 +1,24 @@
|
|
|
1
1
|
import { ReflectUtils } from '@dooboostore/core';
|
|
2
2
|
import { ensureInit } from './elementDefine';
|
|
3
3
|
import { SwcUtils } from '../utils/Utils';
|
|
4
|
+
import { SwcQueryOptions } from '../types';
|
|
4
5
|
|
|
5
6
|
export type StyleAction = 'set' | 'update' | 'remove';
|
|
6
7
|
|
|
8
|
+
export interface StyleOptions extends SwcQueryOptions {
|
|
9
|
+
}
|
|
10
|
+
|
|
7
11
|
export interface StyleMetadata {
|
|
8
12
|
propertyKey: string | symbol;
|
|
9
13
|
selector: string;
|
|
10
14
|
action: StyleAction;
|
|
15
|
+
options: StyleOptions;
|
|
11
16
|
}
|
|
12
17
|
|
|
13
18
|
export const STYLE_METADATA_KEY = Symbol('simple-web-component:style');
|
|
14
19
|
|
|
15
20
|
function createStyleDecorator(action: StyleAction) {
|
|
16
|
-
return (selector: string): MethodDecorator => {
|
|
21
|
+
return (selector: string, options: StyleOptions = {}): MethodDecorator => {
|
|
17
22
|
return (target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
|
|
18
23
|
const constructor = target.constructor;
|
|
19
24
|
let metaList = ReflectUtils.getOwnMetadata(STYLE_METADATA_KEY, constructor) as Map<string | symbol, StyleMetadata>;
|
|
@@ -21,21 +26,43 @@ function createStyleDecorator(action: StyleAction) {
|
|
|
21
26
|
metaList = new Map<string | symbol, StyleMetadata>();
|
|
22
27
|
ReflectUtils.defineMetadata(STYLE_METADATA_KEY, metaList, constructor);
|
|
23
28
|
}
|
|
24
|
-
metaList.set(propertyKey, { propertyKey, selector, action });
|
|
29
|
+
metaList.set(propertyKey, { propertyKey, selector, action, options });
|
|
25
30
|
|
|
26
31
|
const original = descriptor.value;
|
|
27
32
|
descriptor.value = async function (...args: any[]) {
|
|
28
33
|
ensureInit(this);
|
|
29
34
|
const res = await original.apply(this, args);
|
|
30
35
|
if (res !== undefined) {
|
|
36
|
+
const r = options.root || 'auto';
|
|
31
37
|
const hostSet = SwcUtils.getHostSet(this as any);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
else
|
|
38
|
+
const targetEls: HTMLElement[] = [];
|
|
39
|
+
|
|
40
|
+
if (selector === ':host' || !selector) {
|
|
41
|
+
targetEls.push(this as any);
|
|
42
|
+
} else if (selector === ':parentHost') {
|
|
43
|
+
if (hostSet.$parentHost) targetEls.push(hostSet.$parentHost);
|
|
44
|
+
} else if (selector === ':appHost') {
|
|
45
|
+
if (hostSet.$appHost) targetEls.push(hostSet.$appHost);
|
|
46
|
+
} else {
|
|
47
|
+
if (r === 'shadow') {
|
|
48
|
+
const found = this.shadowRoot?.querySelectorAll(selector);
|
|
49
|
+
if (found) targetEls.push(...found);
|
|
50
|
+
} else if (r === 'light') {
|
|
51
|
+
const found = (this as any).querySelectorAll(selector);
|
|
52
|
+
if (found) targetEls.push(...found);
|
|
53
|
+
} else if (r === 'all') {
|
|
54
|
+
const sFound = this.shadowRoot?.querySelectorAll(selector);
|
|
55
|
+
const lFound = (this as any).querySelectorAll(selector);
|
|
56
|
+
if (sFound) targetEls.push(...sFound);
|
|
57
|
+
if (lFound) targetEls.push(...lFound);
|
|
58
|
+
} else {
|
|
59
|
+
// auto
|
|
60
|
+
const found = (this.shadowRoot || (this as any)).querySelectorAll(selector);
|
|
61
|
+
if (found) targetEls.push(...found);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
37
64
|
|
|
38
|
-
|
|
65
|
+
targetEls.forEach(targetEl => {
|
|
39
66
|
if (action === 'set') {
|
|
40
67
|
targetEl.style.cssText = '';
|
|
41
68
|
if (typeof res === 'object' && res !== null) {
|
|
@@ -49,9 +76,9 @@ function createStyleDecorator(action: StyleAction) {
|
|
|
49
76
|
}
|
|
50
77
|
} else if (action === 'remove') {
|
|
51
78
|
const props = Array.isArray(res) ? res : [res];
|
|
52
|
-
props.forEach(p => targetEl
|
|
79
|
+
props.forEach(p => targetEl.style.removeProperty(String(p)));
|
|
53
80
|
}
|
|
54
|
-
}
|
|
81
|
+
});
|
|
55
82
|
}
|
|
56
83
|
return res;
|
|
57
84
|
};
|
|
@@ -62,20 +89,44 @@ function createStyleDecorator(action: StyleAction) {
|
|
|
62
89
|
/**
|
|
63
90
|
* @setStyle decorator to surgically set styles on a target element (replaces all existing styles).
|
|
64
91
|
* Usage: @setStyle('#box') getStyles() { return { color: 'red', display: 'block' }; }
|
|
92
|
+
* Usage: @setStyle('#box', { root: 'shadow' }) getStyles() { return { color: 'red' }; }
|
|
65
93
|
*/
|
|
66
|
-
export const setStyle = createStyleDecorator('set');
|
|
94
|
+
export const setStyle = (selector: string, options: StyleOptions = {}) => createStyleDecorator('set')(selector, options);
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @setStyleHost decorator - simplified version of @setStyle for :host selector.
|
|
98
|
+
* Usage: @setStyleHost getStyles() { return { color: 'red', display: 'block' }; }
|
|
99
|
+
* Usage: @setStyleHost({ root: 'shadow' }) getStyles() { return { color: 'red' }; }
|
|
100
|
+
*/
|
|
101
|
+
export const setStyleHost = (options: StyleOptions = {}) => createStyleDecorator('set')(':host', options);
|
|
67
102
|
|
|
68
103
|
/**
|
|
69
104
|
* @updateStyle decorator to surgically update styles on a target element (merges with existing styles).
|
|
70
105
|
* Usage: @updateStyle('#box') updateStyles() { return { color: 'blue' }; }
|
|
106
|
+
* Usage: @updateStyle('#box', { root: 'shadow' }) updateStyles() { return { color: 'blue' }; }
|
|
107
|
+
*/
|
|
108
|
+
export const updateStyle = (selector: string, options: StyleOptions = {}) => createStyleDecorator('update')(selector, options);
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @updateStyleHost decorator - simplified version of @updateStyle for :host selector.
|
|
112
|
+
* Usage: @updateStyleHost updateStyles() { return { color: 'blue' }; }
|
|
113
|
+
* Usage: @updateStyleHost({ root: 'shadow' }) updateStyles() { return { color: 'blue' }; }
|
|
71
114
|
*/
|
|
72
|
-
export const
|
|
115
|
+
export const updateStyleHost = (options: StyleOptions = {}) => createStyleDecorator('update')(':host', options);
|
|
73
116
|
|
|
74
117
|
/**
|
|
75
118
|
* @removeStyle decorator to surgically remove styles from a target element.
|
|
76
119
|
* Usage: @removeStyle('#box') clearStyles() { return ['color', 'display']; }
|
|
120
|
+
* Usage: @removeStyle('#box', { root: 'shadow' }) clearStyles() { return ['color']; }
|
|
121
|
+
*/
|
|
122
|
+
export const removeStyle = (selector: string, options: StyleOptions = {}) => createStyleDecorator('remove')(selector, options);
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @removeStyleHost decorator - simplified version of @removeStyle for :host selector.
|
|
126
|
+
* Usage: @removeStyleHost clearStyles() { return ['color', 'display']; }
|
|
127
|
+
* Usage: @removeStyleHost({ root: 'shadow' }) clearStyles() { return ['color']; }
|
|
77
128
|
*/
|
|
78
|
-
export const
|
|
129
|
+
export const removeStyleHost = (options: StyleOptions = {}) => createStyleDecorator('remove')(':host', options);
|
|
79
130
|
|
|
80
131
|
export const findAllStyleMetadata = (target: any): Map<string | symbol, StyleMetadata> => {
|
|
81
132
|
const result = new Map<string | symbol, StyleMetadata>();
|
|
@@ -88,6 +88,7 @@ export class SwcAppEngine {
|
|
|
88
88
|
// Rendering
|
|
89
89
|
const data = this.simpleApplication.sim(_config.rootRouter);
|
|
90
90
|
if (data instanceof Node) {
|
|
91
|
+
// console.warn('[SWC-APP-ENGINE] Rendering failed: Root element is not a DocumentFragment.', data);
|
|
91
92
|
if (this.host.shadowRoot) this.host.shadowRoot.replaceChildren(data);
|
|
92
93
|
else this.host.replaceChildren(data);
|
|
93
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() {
|
package/src/elements/SwcAsync.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { changedAttributeHost } from '../decorators/changedAttributeHost';
|
|
2
2
|
import { SwcUtils } from '../utils/Utils';
|
|
3
3
|
import { FunctionUtils } from '@dooboostore/core';
|
|
4
4
|
|
|
@@ -28,7 +28,7 @@ export class SwcAsync extends HTMLTemplateElement {
|
|
|
28
28
|
FunctionUtils.execute({ script, context: this, args });
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
@
|
|
31
|
+
@changedAttributeHost('on-get-value')
|
|
32
32
|
private refresh() {
|
|
33
33
|
const script = this.getAttribute('on-get-value');
|
|
34
34
|
if (!script) return;
|