@dooboostore/simple-web-component 1.0.17 → 1.0.18

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.
Files changed (63) hide show
  1. package/README.md +75 -107
  2. package/dist/cjs/decorators/appendChild.js +48 -0
  3. package/dist/cjs/decorators/appendChild.js.map +7 -0
  4. package/dist/cjs/decorators/elementDefine.js +85 -7
  5. package/dist/cjs/decorators/elementDefine.js.map +2 -2
  6. package/dist/cjs/decorators/index.js +2 -1
  7. package/dist/cjs/decorators/index.js.map +2 -2
  8. package/dist/cjs/decorators/{innerHtml.js → onConnectedInnerHtml.js} +8 -8
  9. package/dist/cjs/decorators/onConnectedInnerHtml.js.map +7 -0
  10. package/dist/cjs/decorators/query.js +16 -0
  11. package/dist/cjs/decorators/query.js.map +2 -2
  12. package/dist/cjs/decorators/queryAll.js +18 -0
  13. package/dist/cjs/decorators/queryAll.js.map +2 -2
  14. package/dist/cjs/decorators/replaceChildren.js +53 -0
  15. package/dist/cjs/decorators/replaceChildren.js.map +7 -0
  16. package/dist/cjs/index.js +11 -1
  17. package/dist/cjs/index.js.map +2 -2
  18. package/dist/esm/decorators/appendChild.js +29 -0
  19. package/dist/esm/decorators/appendChild.js.map +7 -0
  20. package/dist/esm/decorators/elementDefine.js +85 -7
  21. package/dist/esm/decorators/elementDefine.js.map +2 -2
  22. package/dist/esm/decorators/index.js +2 -1
  23. package/dist/esm/decorators/index.js.map +2 -2
  24. package/dist/esm/decorators/{innerHtml.js → onConnectedInnerHtml.js} +5 -5
  25. package/dist/esm/decorators/onConnectedInnerHtml.js.map +7 -0
  26. package/dist/esm/decorators/query.js +16 -0
  27. package/dist/esm/decorators/query.js.map +2 -2
  28. package/dist/esm/decorators/queryAll.js +18 -0
  29. package/dist/esm/decorators/queryAll.js.map +2 -2
  30. package/dist/esm/decorators/replaceChildren.js +34 -0
  31. package/dist/esm/decorators/replaceChildren.js.map +7 -0
  32. package/dist/esm/index.js +7 -1
  33. package/dist/esm/index.js.map +2 -2
  34. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +181 -11
  35. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +3 -3
  36. package/dist/types/decorators/appendChild.d.ts +17 -0
  37. package/dist/types/decorators/appendChild.d.ts.map +1 -0
  38. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  39. package/dist/types/decorators/index.d.ts +2 -1
  40. package/dist/types/decorators/index.d.ts.map +1 -1
  41. package/dist/types/decorators/onConnectedInnerHtml.d.ts +15 -0
  42. package/dist/types/decorators/onConnectedInnerHtml.d.ts.map +1 -0
  43. package/dist/types/decorators/query.d.ts.map +1 -1
  44. package/dist/types/decorators/queryAll.d.ts.map +1 -1
  45. package/dist/types/decorators/replaceChildren.d.ts +9 -0
  46. package/dist/types/decorators/replaceChildren.d.ts.map +1 -0
  47. package/dist/types/index.d.ts +4 -1
  48. package/dist/types/index.d.ts.map +1 -1
  49. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +181 -11
  50. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +3 -3
  51. package/package.json +1 -1
  52. package/src/decorators/appendChild.ts +42 -0
  53. package/src/decorators/elementDefine.ts +90 -7
  54. package/src/decorators/index.ts +2 -1
  55. package/src/decorators/{innerHtml.ts → onConnectedInnerHtml.ts} +7 -6
  56. package/src/decorators/query.ts +12 -0
  57. package/src/decorators/queryAll.ts +16 -0
  58. package/src/decorators/replaceChildren.ts +35 -0
  59. package/src/index.ts +4 -1
  60. package/dist/cjs/decorators/innerHtml.js.map +0 -7
  61. package/dist/esm/decorators/innerHtml.js.map +0 -7
  62. package/dist/types/decorators/innerHtml.d.ts +0 -12
  63. package/dist/types/decorators/innerHtml.d.ts.map +0 -1
package/README.md CHANGED
@@ -42,13 +42,13 @@ Registers the class as a custom element.
42
42
  | `observedAttributes` | `string[]` | (Optional) Extra attributes to observe. |
43
43
  | `window` | `Window` | (Optional) Custom window object (useful for SSR). |
44
44
 
45
- ### 2. `@innerHtml(options?)`
46
- Defines the template for the component.
45
+ ### 2. `@onConnectedInnerHtml(options?)`
46
+ Defines the template for the component. Executed when the component is connected to the DOM.
47
47
 
48
48
  ```typescript
49
49
  @elementDefine('my-el')
50
50
  class MyEl extends HTMLElement {
51
- @innerHtml({ useShadow: true })
51
+ @onConnectedInnerHtml({ useShadow: true })
52
52
  render() {
53
53
  return `<style>:host { color: blue; }</style><div>Hello World</div>`;
54
54
  }
@@ -80,7 +80,7 @@ class MyCounter extends HTMLElement {
80
80
  ```
81
81
 
82
82
  ### 4. Powerful Queries (`@query`, `@queryAll`)
83
- Inject internal elements directly into properties. Supports the **`:host`** selector.
83
+ Inject internal elements directly into properties. Supports the **`:host`** selector and precise root control. Assigning `null` or `[]` to these properties will surgically remove the target elements from the DOM.
84
84
 
85
85
  | Root Option | Description |
86
86
  |---|---|
@@ -89,24 +89,14 @@ Inject internal elements directly into properties. Supports the **`:host`** sele
89
89
  | `light` | **Strictly** search in Light DOM (`this`). |
90
90
  | `all` | Search in **both** Shadow and Light DOM. |
91
91
 
92
- Inject elements directly into properties. Supports `:host` and scoped root control.
93
-
94
92
  ```typescript
95
- @elementDefine('query-demo')
96
- class QueryDemo extends HTMLElement {
97
- @query('.title') titleEl!: HTMLElement;
98
- @queryAll('.items') list!: NodeListOf<HTMLElement>;
99
-
100
- // Reference the component itself
101
- @query(':host') self!: HTMLElement;
102
-
103
- // Root options: 'light' | 'shadow' | 'all' | 'auto' (default)
104
- @query('.btn', { root: 'shadow' }) shadowBtn!: HTMLButtonElement;
105
- }
93
+ @query('.title') titleEl!: HTMLElement;
94
+ @query('.btn', { root: 'shadow' }) shadowBtn!: HTMLButtonElement;
95
+ @query(':host') self!: HTMLElement; // References the component itself
106
96
  ```
107
97
 
108
98
  ### 5. Smart Event Binding (`@addEventListener`)
109
- Bind events declaratively with support for **Event Delegation**.
99
+ Bind events declaratively with support for **Event Delegation** and special targets like `:window` and `:document`.
110
100
 
111
101
  ```typescript
112
102
  @elementDefine('event-demo')
@@ -115,11 +105,55 @@ class EventDemo extends HTMLElement {
115
105
  @addEventListener('.static-btn', 'click')
116
106
  onStaticClick(event: MouseEvent) { ... }
117
107
 
118
- // 2. Event Delegation (Works for dynamic nodes added LATER)
108
+ // 2. Event Delegation (Handles dynamic nodes)
119
109
  @addEventListener('.item', 'click', { delegate: true })
120
110
  onItemClick(event: MouseEvent, { $host }: HostSet, target: HTMLElement) {
121
111
  console.log('Clicked dynamic item:', target.textContent);
122
112
  }
113
+
114
+ // 3. Global Events with Auto-Cleanup
115
+ @addEventListener(':window', 'resize', { removeOnDisconnected: true })
116
+ onResize() { ... }
117
+ }
118
+ ```
119
+
120
+ ### 6. `@replaceChildren(selector)`
121
+ Surgically replaces the children of a target element with the method's return value (`string`, `Node`, or `Array<Node|string>`).
122
+
123
+ ```typescript
124
+ @elementDefine('surgical-demo')
125
+ class SurgicalDemo extends HTMLElement {
126
+ // Replaces all children of #display-area with the new content
127
+ @replaceChildren('#display-area')
128
+ updateView(title: string) {
129
+ return `<h2>${title}</h2><p>Updated successfully.</p>`;
130
+ }
131
+ }
132
+ ```
133
+
134
+ ### 7. `@appendChild(selector, options?)`
135
+ Appends or inserts the method's return value relative to a target element.
136
+ - **position**: `'lastChild'` (default), `'firstChild'`, `'nextSibling'`, `'previousSibling'`.
137
+
138
+ ```typescript
139
+ @elementDefine('list-manager')
140
+ class ListManager extends HTMLElement {
141
+ // Prepends a new item to the top of the #my-list element
142
+ @appendChild('#my-list', { position: 'firstChild' })
143
+ addNewItem(text: string) {
144
+ return `<li>${text}</li>`;
145
+ }
146
+ }
147
+ ```
148
+
149
+ ```typescript
150
+ @elementDefine('list-manager')
151
+ class ListManager extends HTMLElement {
152
+ // Prepends a new item to the top of the #my-list element
153
+ @appendChild('#my-list', { position: 'firstChild' })
154
+ addNewItem(text: string) {
155
+ return `<li>${text}</li>`;
156
+ }
123
157
  }
124
158
  ```
125
159
 
@@ -130,14 +164,13 @@ class EventDemo extends HTMLElement {
130
164
  SWC provides a revolutionary way to build SPAs where **each component scope is an independent application**.
131
165
 
132
166
  ### 1. Isolated App Scopes (Micro-Frontends)
133
- Use the `<swc-app>` tag to create an isolated universe. Each instance has its own **DI Container** and **Router**. You can run multiple independent SPAs on a single page without URL conflicts.
167
+ Use the `<swc-app>` tag to create an isolated universe. Each instance has its own **DI Container** and **Router**.
134
168
 
135
169
  ```html
136
170
  <!-- index.html -->
137
171
  <swc-app swc-get-application-config="myAppConfig(this)"></swc-app>
138
172
 
139
173
  <script>
140
- // This function returns the configuration needed to bootstrap the SWC App
141
174
  window.myAppConfig = (host) => {
142
175
  return {
143
176
  rootRouter: RootRouter, // The entry point class (must be @Sim)
@@ -147,35 +180,24 @@ Use the `<swc-app>` tag to create an isolated universe. Each instance has its ow
147
180
  };
148
181
  };
149
182
 
150
- // 4. External Control (Anywhere in your JS)
183
+ // External Control
151
184
  function navigateFromOutside() {
152
185
  const app = document.querySelector('swc-app');
153
- // Programmatically trigger routing from outside the component
154
186
  app.routing('/users/detail/2');
155
187
  }
156
188
  </script>
157
-
158
- <button onclick="navigateFromOutside()">External Link to User 2</button>
159
189
  ```
160
190
 
161
191
  ### 2. DI-Powered Routing
162
- Define routes using decorators. Components are automatically instantiated and managed by the DI container.
163
-
164
192
  ```typescript
165
- import { Router } from '@dooboostore/simple-boot/decorators/route/Router';
166
- import { Sim } from '@dooboostore/simple-boot/decorators/SimDecorator';
167
-
168
193
  @Sim
169
194
  @Router({
170
195
  path: '/users',
171
- route: {
172
- '/list': UserList,
173
- '/detail/:id': UserDetail
174
- }
196
+ route: { '/list': UserList, '/detail/:id': UserDetail }
175
197
  })
176
198
  @elementDefine('user-router')
177
199
  class UserRouter extends HTMLElement implements RouterAction.CanActivate {
178
- @innerHtml({ useShadow: true })
200
+ @onConnectedInnerHtml({ useShadow: true })
179
201
  render() {
180
202
  return `<header>User System</header><main><slot></slot></main>`;
181
203
  }
@@ -185,21 +207,17 @@ class UserRouter extends HTMLElement implements RouterAction.CanActivate {
185
207
  }
186
208
  }
187
209
 
188
- // Pure Service (Business Logic)
189
210
  @Sim
190
211
  class UserService {
191
- async getProfile(id: string) {
192
- return { id, name: 'Standard User' };
193
- }
212
+ async getProfile(id: string) { return { id, name: 'Standard User' }; }
194
213
  }
195
214
 
196
- // Example Page Components
197
215
  @Sim
198
216
  @elementDefine('user-list')
199
217
  class UserList extends HTMLElement {
200
218
  constructor(private router: Router, private userService: UserService) { super(); }
201
219
 
202
- @innerHtml
220
+ @onConnectedInnerHtml
203
221
  render() {
204
222
  return `
205
223
  <ul><li>User A</li><li>User B</li></ul>
@@ -220,22 +238,18 @@ class UserDetail extends HTMLElement {
220
238
  console.log('Viewing User:', profile.name);
221
239
  }
222
240
 
223
- @innerHtml
241
+ @onConnectedInnerHtml
224
242
  render() { return `<div>User Detail View <button swc-on-click="$host.router.back()">Back</button></div>`; }
225
243
  }
226
244
  ```
227
245
 
228
246
  ### 3. Lifecycle @Inject
229
- Inject services or component context directly into lifecycle methods. This is the ultimate way to handle side effects cleanly.
230
-
231
247
  ```typescript
232
248
  import { Inject } from '@dooboostore/simple-boot/decorators/inject/Inject';
233
249
  import { InjectSituationType, onConnected, HostSet } from '@dooboostore/simple-web-component';
234
- import { Router } from '@dooboostore/core-web/routers/Router';
235
250
 
236
251
  @elementDefine('profile-page')
237
252
  class ProfilePage extends HTMLElement {
238
-
239
253
  @onConnected
240
254
  async init(
241
255
  @Inject({ situationType: InjectSituationType.HOST_SET }) hostSet: HostSet,
@@ -244,7 +258,6 @@ class ProfilePage extends HTMLElement {
244
258
  ) {
245
259
  console.log('App scope:', hostSet.$appHost);
246
260
  const user = await api.getProfile();
247
- // Navigate programmatically using injected router
248
261
  if (!user) router.go('/login');
249
262
  }
250
263
  }
@@ -271,36 +284,25 @@ Executed in **Parent -> Child** order.
271
284
 
272
285
  ---
273
286
 
274
- ## ⚡ Performance
275
- - **Zero "Deep Scan"**: Listeners are only bound to specific selectors.
276
- - **Surgical Updates**: Manipulate DOM directly in `@changedAttribute` instead of full re-renders.
277
- - **Zero Background Overhead**: No polling, no background observers.
278
-
279
- ---
280
-
281
- ---
282
-
283
287
  ## 🔄 Structural Directives (Advanced)
284
288
 
285
- SWC provides 4 core templates that empower your HTML without wrapper elements: `swc-loop`, `swc-if`, `swc-choose`, and `swc-async`. They all share a consistent, high-performance API.
289
+ SWC provides 4 core templates: `swc-loop`, `swc-if`, `swc-choose`, and `swc-async`.
286
290
 
287
291
  ### Common Attributes:
288
- - **`on-get-value`**: Script to fetch data (supports return-less expressions).
289
- - **`on-clone-nodes`**: Callback after a group of nodes is cloned (Args: `$index`, `$item`, `$nodes`, `$elements`, `$firstElement`, `$state`).
290
- - **`on-clone-node`**: Callback for each individual node (Args: `$node`, `$nodeIndex`, and all group args).
291
- - **`on-get-portal`**: Script that returns an `Element` or selector string to render content in a different part of the DOM.
292
+ - **`on-get-value`**: Script to fetch data.
293
+ - **`on-clone-nodes`**: Callback after a group of nodes is cloned.
294
+ - **`on-clone-node`**: Callback for each individual node.
295
+ - **`on-get-portal`**: Script that returns an `Element` or selector for portal rendering.
292
296
 
293
297
  ### 1. `swc-if` (Conditional Rendering)
294
- Renders content only when the condition is truthy. Supports a fallback `swc-default` state.
295
298
  ```html
296
299
  <template is="swc-if" on-get-value="isAdmin">
297
- <template is="swc-default"><p>Please login as admin.</p></template>
298
- <div class="admin-panel">Welcome, Master!</div>
300
+ <template is="swc-default"><p>Please login.</p></template>
301
+ <div class="admin-panel">Welcome!</div>
299
302
  </template>
300
303
  ```
301
304
 
302
305
  ### 2. `swc-loop` (High-Performance Iteration)
303
- Efficiently renders lists with surgical updates and index preservation.
304
306
  ```html
305
307
  <template is="swc-loop" on-get-value="users"
306
308
  on-clone-node="if($isElement) $node.querySelector('.name').textContent = $item.name">
@@ -310,64 +312,30 @@ Efficiently renders lists with surgical updates and index preservation.
310
312
  ```
311
313
 
312
314
  ### 3. `swc-choose` (Switch-Case Logic)
313
- Selects the first matching `swc-when` or falls back to `swc-otherwise`.
314
315
  ```html
315
316
  <template is="swc-choose" on-get-value="user.role">
316
- <template is="swc-default">Please select a role.</template>
317
+ <template is="swc-default">Select a role.</template>
317
318
  <template is="swc-when" value="admin">Admin Dashboard</template>
318
- <template is="swc-when" value="user">User Home</template>
319
319
  <template is="swc-otherwise">Access Denied</template>
320
320
  </template>
321
321
  ```
322
322
 
323
323
  ### 4. `swc-async` (Declarative Promises)
324
- Handles Promise states (Loading, Error, Success) without manual state management.
325
324
  ```html
326
- <template is="swc-async" on-get-value="fetchData()">
325
+ <template is="swc-async" on-get-value="fetchData()"
326
+ on-clone-node="if($isElement && $node.className === 'content') $node.textContent = $value?.title || $error?.message">
327
327
  <template is="swc-loading">🌀 Loading...</template>
328
- <template is="swc-error">❌ Error: {{$error.message}}</template>
329
- <template is="swc-success">✅ Data: {{$value.title}}</template>
330
- </template>
331
- ```
332
-
333
- ### Advanced: Integrated Portal Support
334
- All directives above support the **`on-get-portal`** attribute to render content elsewhere.
335
- ```html
336
- <template is="swc-if" on-get-value="showModal" on-get-portal="'body'">
337
- <div class="modal-overlay">I am rendered at the end of &lt;body&gt;!</div>
328
+ <template is="swc-error"><div class="content"></div></template>
329
+ <template is="swc-success"><div class="content"></div></template>
338
330
  </template>
339
331
  ```
340
332
 
341
333
  ---
342
334
 
343
- ## ⚡ Integrated Event & Query Selectors
344
-
345
- Both `@addEventListener` and `@query` support special selectors to navigate the environment and component hierarchy seamlessly.
346
-
347
- | Selector | Target Description |
348
- |---|---|
349
- | `:host` | The component itself (default for empty selector). |
350
- | `:parentHost` | The immediate parent SWC component. |
351
- | `:appHost` | The nearest parent `<swc-app>` instance. |
352
- | `:window` | The environment-aware global `window` object. |
353
- | `:document` | The environment-aware global `document` object. |
354
- | `:hosts` | Array of all SWC ancestors (Root -> Self). |
355
-
356
- ### Global Event Example
357
- ```typescript
358
- @elementDefine('auto-cleanup-demo')
359
- class CleanupDemo extends HTMLElement {
360
- // Automatically attaches to window and REMOVES on disconnectedCallback
361
- @addEventListener(':window', 'resize', { removeOnDisconnected: true })
362
- onResize(event: UIEvent) {
363
- console.log('Window resized!', this.id);
364
- }
365
- }
366
- ```
367
-
368
- ## ⚡ Performance Features
335
+ ## ⚡ Performance
336
+ - **Zero "Deep Scan"**: Listeners are only bound to specific selectors.
337
+ - **Surgical Updates**: Manipulate DOM directly in `@changedAttribute` instead of full re-renders.
369
338
  - **Smart Delegation**: Host-level delegation with `__swc_handled` duplicate protection.
370
- - **Index-Preserving Removal**: `SwcLoop` maintains stable indices during item removal for maximum UI consistency.
371
339
 
372
340
  ---
373
341
 
@@ -0,0 +1,48 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var appendChild_exports = {};
19
+ __export(appendChild_exports, {
20
+ APPEND_CHILD_METADATA_KEY: () => APPEND_CHILD_METADATA_KEY,
21
+ appendChild: () => appendChild,
22
+ findAllAppendChildMetadata: () => findAllAppendChildMetadata
23
+ });
24
+ module.exports = __toCommonJS(appendChild_exports);
25
+ var import_ReflectUtils = require("@dooboostore/core/reflect/ReflectUtils");
26
+ const APPEND_CHILD_METADATA_KEY = Symbol("simple-web-component:append-child");
27
+ function appendChild(selector, options = { position: "lastChild" }) {
28
+ return (target, propertyKey) => {
29
+ const constructor = target.constructor;
30
+ let meta = import_ReflectUtils.ReflectUtils.getOwnMetadata(APPEND_CHILD_METADATA_KEY, constructor);
31
+ if (!meta) {
32
+ meta = /* @__PURE__ */ new Map();
33
+ import_ReflectUtils.ReflectUtils.defineMetadata(APPEND_CHILD_METADATA_KEY, meta, constructor);
34
+ }
35
+ meta.set(propertyKey, { propertyKey, selector, options });
36
+ };
37
+ }
38
+ const findAllAppendChildMetadata = (target) => {
39
+ const result = /* @__PURE__ */ new Map();
40
+ const maps = import_ReflectUtils.ReflectUtils.findAllMetadata(APPEND_CHILD_METADATA_KEY, target);
41
+ maps.forEach((map) => {
42
+ if (map instanceof Map) {
43
+ map.forEach((v, k) => result.set(k, v));
44
+ }
45
+ });
46
+ return result;
47
+ };
48
+ //# sourceMappingURL=appendChild.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/decorators/appendChild.ts"],
4
+ "sourcesContent": ["import { ReflectUtils } from '@dooboostore/core/reflect/ReflectUtils';\n\nexport type AppendChildPosition = 'firstChild' | 'lastChild' | 'nextSibling' | 'previousSibling';\n\nexport interface AppendChildOptions {\n position?: AppendChildPosition;\n}\n\nexport interface AppendChildMetadata {\n propertyKey: string | symbol;\n selector: string;\n options: AppendChildOptions;\n}\n\nexport const APPEND_CHILD_METADATA_KEY = Symbol('simple-web-component:append-child');\n\n/**\n * @appendChild decorator to surgically add nodes to a target element.\n * Usage: @appendChild('#list') addItem() { return '<li>New Item</li>'; }\n */\nexport function appendChild(selector: string, options: AppendChildOptions = { position: 'lastChild' }): MethodDecorator {\n return (target: Object, propertyKey: string | symbol) => {\n const constructor = target.constructor;\n let meta = ReflectUtils.getOwnMetadata(APPEND_CHILD_METADATA_KEY, constructor) as Map<string | symbol, AppendChildMetadata>;\n if (!meta) {\n meta = new Map<string | symbol, AppendChildMetadata>();\n ReflectUtils.defineMetadata(APPEND_CHILD_METADATA_KEY, meta, constructor);\n }\n meta.set(propertyKey, { propertyKey, selector, options });\n };\n}\n\nexport const findAllAppendChildMetadata = (target: any): Map<string | symbol, AppendChildMetadata> => {\n const result = new Map<string | symbol, AppendChildMetadata>();\n const maps = ReflectUtils.findAllMetadata<Map<string | symbol, AppendChildMetadata>>(APPEND_CHILD_METADATA_KEY, target);\n maps.forEach(map => {\n if (map instanceof Map) {\n map.forEach((v, k) => result.set(k, v));\n }\n });\n return result;\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAA6B;AActB,MAAM,4BAA4B,OAAO,mCAAmC;AAM5E,SAAS,YAAY,UAAkB,UAA8B,EAAE,UAAU,YAAY,GAAoB;AACtH,SAAO,CAAC,QAAgB,gBAAiC;AACvD,UAAM,cAAc,OAAO;AAC3B,QAAI,OAAO,iCAAa,eAAe,2BAA2B,WAAW;AAC7E,QAAI,CAAC,MAAM;AACT,aAAO,oBAAI,IAA0C;AACrD,uCAAa,eAAe,2BAA2B,MAAM,WAAW;AAAA,IAC1E;AACA,SAAK,IAAI,aAAa,EAAE,aAAa,UAAU,QAAQ,CAAC;AAAA,EAC1D;AACF;AAEO,MAAM,6BAA6B,CAAC,WAA2D;AACpG,QAAM,SAAS,oBAAI,IAA0C;AAC7D,QAAM,OAAO,iCAAa,gBAA2D,2BAA2B,MAAM;AACtH,OAAK,QAAQ,SAAO;AAClB,QAAI,eAAe,KAAK;AACtB,UAAI,QAAQ,CAAC,GAAG,MAAM,OAAO,IAAI,GAAG,CAAC,CAAC;AAAA,IACxC;AAAA,EACF,CAAC;AACD,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -24,12 +24,14 @@ __export(elementDefine_exports, {
24
24
  module.exports = __toCommonJS(elementDefine_exports);
25
25
  var import_ReflectUtils = require("@dooboostore/core/reflect/ReflectUtils");
26
26
  var import_FunctionUtils = require("@dooboostore/core/function/FunctionUtils");
27
- var import_innerHtml = require("./innerHtml");
27
+ var import_onConnectedInnerHtml = require("./onConnectedInnerHtml");
28
28
  var import_addEventListener = require("./addEventListener");
29
29
  var import_lifecycles = require("./lifecycles");
30
30
  var import_emitCustomEvent = require("./emitCustomEvent");
31
31
  var import_changedAttribute = require("./changedAttribute");
32
32
  var import_setAttribute = require("./setAttribute");
33
+ var import_replaceChildren = require("./replaceChildren");
34
+ var import_appendChild = require("./appendChild");
33
35
  var import_Utils = require("../utils/Utils");
34
36
  var import_config = require("../config/config");
35
37
  var import_Inject = require("@dooboostore/simple-boot/decorators/inject/Inject");
@@ -71,10 +73,12 @@ const elementDefine = (inConfig) => (constructor) => {
71
73
  const addEventListenerList = (0, import_addEventListener.getAddEventListenerMetadata)(constructor) || [];
72
74
  const attrChangeMap = (0, import_changedAttribute.findAllAttributeChangedMetadata)(constructor);
73
75
  const setAttrMap = (0, import_setAttribute.findAllSetAttributeMetadata)(constructor);
76
+ const replaceChildrenMap = (0, import_replaceChildren.findAllReplaceChildrenMetadata)(constructor);
77
+ const appendChildMap = (0, import_appendChild.findAllAppendChildMetadata)(constructor);
74
78
  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"];
75
79
  const swcOnEvents = import_config.DOM_EVENT_NAMES.map((e) => `swc-on-${e}`);
76
80
  const mergedObservedAttributes = [.../* @__PURE__ */ new Set([...config.observedAttributes ?? [], ...attrChangeMap.keys(), ...setAttrMap.keys(), ...emitCustomEventList.map((it) => it.options.attributeName), ...swcLifecycleAttributes, ...swcOnEvents])];
77
- const innerHtmlList = (0, import_innerHtml.getInnerHtmlMetadataList)(constructor) || [];
81
+ const connectedInnerHtmlList = (0, import_onConnectedInnerHtml.getOnConnectedInnerHtmlMetadata)(constructor) || [];
78
82
  const NewClass = class extends constructor {
79
83
  _executeSwcScript(attrName, hostSet, extraArgs = {}) {
80
84
  const script = this.getAttribute(attrName);
@@ -141,7 +145,7 @@ const elementDefine = (inConfig) => (constructor) => {
141
145
  this._boundListeners = [];
142
146
  const hostSet = import_Utils.SwcUtils.getHostSet(this);
143
147
  this._executeSwcScript("swc-on-constructor", hostSet);
144
- if (innerHtmlList.some((it) => it.options.useShadow === true) && !this.shadowRoot) {
148
+ if (connectedInnerHtmlList.some((it) => it.options.useShadow === true) && !this.shadowRoot) {
145
149
  this.attachShadow({ mode: "open" });
146
150
  }
147
151
  }
@@ -161,9 +165,9 @@ const elementDefine = (inConfig) => (constructor) => {
161
165
  }
162
166
  if (typeof this.initCore === "function")
163
167
  this.initCore();
164
- if (innerHtmlList.length > 0) {
168
+ if (connectedInnerHtmlList.length > 0) {
165
169
  let sContent = "", lContent = "";
166
- for (const meta of innerHtmlList) {
170
+ for (const meta of connectedInnerHtmlList) {
167
171
  const res = await this[meta.propertyKey]();
168
172
  if (res !== void 0) {
169
173
  if (meta.options.useShadow)
@@ -207,8 +211,9 @@ const elementDefine = (inConfig) => (constructor) => {
207
211
  }
208
212
  };
209
213
  import_config.DOM_EVENT_NAMES.forEach((type) => {
210
- this.addEventListener(type, createDelegationHandler(this));
211
- this._boundListeners.push({ target: this, type, handler: createDelegationHandler(this) });
214
+ const handler = createDelegationHandler(this);
215
+ this.addEventListener(type, handler);
216
+ this._boundListeners.push({ target: this, type, handler });
212
217
  });
213
218
  const hasParentHost = import_Utils.SwcUtils.findAllSwcHosts(this).length > 0;
214
219
  if (!hasParentHost) {
@@ -410,6 +415,79 @@ const elementDefine = (inConfig) => (constructor) => {
410
415
  };
411
416
  }
412
417
  });
418
+ replaceChildrenMap.forEach((selector, methodName) => {
419
+ const original = NewClass.prototype[methodName];
420
+ if (typeof original === "function") {
421
+ NewClass.prototype[methodName] = function(...args) {
422
+ const res = original.apply(this, args);
423
+ if (res !== void 0) {
424
+ const conf = getElementConfig(this);
425
+ const currentWin = conf?.window || window;
426
+ const currentDoc = currentWin.document;
427
+ let targetEl = null;
428
+ if (selector === ":host" || !selector) {
429
+ targetEl = this;
430
+ } else {
431
+ targetEl = (this.shadowRoot || this).querySelector(selector);
432
+ }
433
+ if (targetEl) {
434
+ const nodes = Array.isArray(res) ? res : [res];
435
+ const normalizedNodes = nodes.map((n) => {
436
+ if (typeof n === "string") {
437
+ const t = currentDoc.createElement("template");
438
+ t.innerHTML = n;
439
+ return t.content;
440
+ }
441
+ return n;
442
+ });
443
+ targetEl.replaceChildren(...normalizedNodes);
444
+ }
445
+ }
446
+ return res;
447
+ };
448
+ }
449
+ });
450
+ appendChildMap.forEach((meta, methodName) => {
451
+ const { selector, options } = meta;
452
+ const original = NewClass.prototype[methodName];
453
+ if (typeof original === "function") {
454
+ NewClass.prototype[methodName] = function(...args) {
455
+ const res = original.apply(this, args);
456
+ if (res !== void 0) {
457
+ const conf = getElementConfig(this);
458
+ const currentWin = conf?.window || window;
459
+ const currentDoc = currentWin.document;
460
+ let targetEl = null;
461
+ if (selector === ":host" || !selector) {
462
+ targetEl = this;
463
+ } else {
464
+ targetEl = (this.shadowRoot || this).querySelector(selector);
465
+ }
466
+ if (targetEl) {
467
+ const nodes = Array.isArray(res) ? res : [res];
468
+ const normalizedNodes = nodes.map((n) => {
469
+ if (typeof n === "string") {
470
+ const t = currentDoc.createElement("template");
471
+ t.innerHTML = n;
472
+ return t.content;
473
+ }
474
+ return n;
475
+ });
476
+ const pos = options.position || "lastChild";
477
+ if (pos === "lastChild")
478
+ targetEl.append(...normalizedNodes);
479
+ else if (pos === "firstChild")
480
+ targetEl.prepend(...normalizedNodes);
481
+ else if (pos === "nextSibling")
482
+ targetEl.after(...normalizedNodes);
483
+ else if (pos === "previousSibling")
484
+ targetEl.before(...normalizedNodes);
485
+ }
486
+ }
487
+ return res;
488
+ };
489
+ }
490
+ });
413
491
  const originalProto = constructor.prototype;
414
492
  const newProto = NewClass.prototype;
415
493
  Object.getOwnPropertyNames(originalProto).forEach((name) => {