@dooboostore/simple-web-component 1.0.30 → 1.0.32

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 (93) hide show
  1. package/README.md +220 -1
  2. package/dist/cjs/decorators/applyStyle.js +1 -1
  3. package/dist/cjs/decorators/applyStyle.js.map +2 -2
  4. package/dist/cjs/decorators/attribute.js +17 -1
  5. package/dist/cjs/decorators/attribute.js.map +2 -2
  6. package/dist/cjs/decorators/elementDefine.js +29 -12
  7. package/dist/cjs/decorators/elementDefine.js.map +3 -3
  8. package/dist/cjs/elements/SwcAppEngine.js +3 -3
  9. package/dist/cjs/elements/SwcAppEngine.js.map +2 -2
  10. package/dist/cjs/elements/SwcAppMixin.js +1 -8
  11. package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
  12. package/dist/cjs/elements/SwcAsync.js +71 -78
  13. package/dist/cjs/elements/SwcAsync.js.map +2 -2
  14. package/dist/cjs/elements/SwcChoose.js +66 -81
  15. package/dist/cjs/elements/SwcChoose.js.map +2 -2
  16. package/dist/cjs/elements/SwcIf.js +52 -96
  17. package/dist/cjs/elements/SwcIf.js.map +2 -2
  18. package/dist/cjs/elements/SwcLoop.js +60 -103
  19. package/dist/cjs/elements/SwcLoop.js.map +2 -2
  20. package/dist/cjs/elements/SwcSubTemplates.js +0 -27
  21. package/dist/cjs/elements/SwcSubTemplates.js.map +2 -2
  22. package/dist/cjs/elements/register.js +314 -343
  23. package/dist/cjs/elements/register.js.map +2 -2
  24. package/dist/cjs/router/ElementRouter.js +1 -8
  25. package/dist/cjs/router/ElementRouter.js.map +2 -2
  26. package/dist/cjs/types.js.map +1 -1
  27. package/dist/cjs/utils/Utils.js +31 -24
  28. package/dist/cjs/utils/Utils.js.map +2 -2
  29. package/dist/esm/decorators/applyStyle.js +1 -1
  30. package/dist/esm/decorators/applyStyle.js.map +2 -2
  31. package/dist/esm/decorators/attribute.js +18 -2
  32. package/dist/esm/decorators/attribute.js.map +2 -2
  33. package/dist/esm/decorators/elementDefine.js +27 -10
  34. package/dist/esm/decorators/elementDefine.js.map +3 -3
  35. package/dist/esm/elements/SwcAppEngine.js +3 -3
  36. package/dist/esm/elements/SwcAppEngine.js.map +2 -2
  37. package/dist/esm/elements/SwcAppMixin.js +1 -8
  38. package/dist/esm/elements/SwcAppMixin.js.map +2 -2
  39. package/dist/esm/elements/SwcAsync.js +72 -60
  40. package/dist/esm/elements/SwcAsync.js.map +2 -2
  41. package/dist/esm/elements/SwcChoose.js +67 -63
  42. package/dist/esm/elements/SwcChoose.js.map +2 -2
  43. package/dist/esm/elements/SwcIf.js +53 -78
  44. package/dist/esm/elements/SwcIf.js.map +2 -2
  45. package/dist/esm/elements/SwcLoop.js +61 -85
  46. package/dist/esm/elements/SwcLoop.js.map +2 -2
  47. package/dist/esm/elements/SwcSubTemplates.js +0 -8
  48. package/dist/esm/elements/SwcSubTemplates.js.map +2 -2
  49. package/dist/esm/elements/register.js +246 -275
  50. package/dist/esm/elements/register.js.map +2 -2
  51. package/dist/esm/router/ElementRouter.js +1 -8
  52. package/dist/esm/router/ElementRouter.js.map +2 -2
  53. package/dist/esm/types.js.map +1 -1
  54. package/dist/esm/utils/Utils.js +31 -24
  55. package/dist/esm/utils/Utils.js.map +2 -2
  56. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +2223 -2009
  57. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
  58. package/dist/types/decorators/attribute.d.ts.map +1 -1
  59. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  60. package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
  61. package/dist/types/elements/SwcAsync.d.ts +1 -11
  62. package/dist/types/elements/SwcAsync.d.ts.map +1 -1
  63. package/dist/types/elements/SwcChoose.d.ts +1 -13
  64. package/dist/types/elements/SwcChoose.d.ts.map +1 -1
  65. package/dist/types/elements/SwcIf.d.ts +1 -13
  66. package/dist/types/elements/SwcIf.d.ts.map +1 -1
  67. package/dist/types/elements/SwcLoop.d.ts +1 -13
  68. package/dist/types/elements/SwcLoop.d.ts.map +1 -1
  69. package/dist/types/elements/SwcSubTemplates.d.ts +6 -6
  70. package/dist/types/elements/SwcSubTemplates.d.ts.map +1 -1
  71. package/dist/types/elements/register.d.ts.map +1 -1
  72. package/dist/types/router/ElementRouter.d.ts.map +1 -1
  73. package/dist/types/types.d.ts +11 -1
  74. package/dist/types/types.d.ts.map +1 -1
  75. package/dist/types/utils/Utils.d.ts +10 -0
  76. package/dist/types/utils/Utils.d.ts.map +1 -1
  77. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +2223 -2009
  78. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
  79. package/package.json +3 -3
  80. package/src/decorators/applyStyle.ts +1 -1
  81. package/src/decorators/attribute.ts +35 -30
  82. package/src/decorators/elementDefine.ts +32 -10
  83. package/src/elements/SwcAppEngine.ts +3 -3
  84. package/src/elements/SwcAppMixin.ts +6 -27
  85. package/src/elements/SwcAsync.ts +75 -57
  86. package/src/elements/SwcChoose.ts +69 -77
  87. package/src/elements/SwcIf.ts +50 -75
  88. package/src/elements/SwcLoop.ts +56 -82
  89. package/src/elements/SwcSubTemplates.ts +6 -6
  90. package/src/elements/register.ts +234 -285
  91. package/src/router/ElementRouter.ts +1 -12
  92. package/src/types.ts +9 -2
  93. package/src/utils/Utils.ts +48 -37
@@ -7,11 +7,11 @@ var __decorate = function(decorators, target, key, desc) {
7
7
  var __metadata = function(k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
- import { elementDefine } from "../decorators/elementDefine.js";
10
+ import { elementDefine, attributeHost, changedAttributeHost } from "../decorators/index.js";
11
11
  import { SwcAppMixin } from "./SwcAppMixin.js";
12
12
  import { SwcUtils } from "../utils/Utils.js";
13
- import { FunctionUtils } from "@dooboostore/core";
14
- import { changedAttributeHost } from "../decorators/changedAttributeHost.js";
13
+ import { FunctionUtils, ActionExpression } from "@dooboostore/core";
14
+ import { ConvertUtils } from "@dooboostore/core-web";
15
15
  const registerAllElements = (w) => {
16
16
  const { HTMLElement: _HTMLElement, HTMLTemplateElement: _HTMLTemplateElement, DocumentFragment: _DocumentFragment, Node: _Node, Element: _Element, HTMLAnchorElement: _HTMLAnchorElement, HTMLAreaElement: _HTMLAreaElement, HTMLAudioElement: _HTMLAudioElement, HTMLBaseElement: _HTMLBaseElement, HTMLButtonElement: _HTMLButtonElement, HTMLCanvasElement: _HTMLCanvasElement, HTMLDataElement: _HTMLDataElement, HTMLDataListElement: _HTMLDataListElement, HTMLDetailsElement: _HTMLDetailsElement, HTMLDialogElement: _HTMLDialogElement, HTMLDivElement: _HTMLDivElement, HTMLDListElement: _HTMLDListElement, HTMLEmbedElement: _HTMLEmbedElement, HTMLFieldSetElement: _HTMLFieldSetElement, HTMLFormElement: _HTMLFormElement, HTMLHRElement: _HTMLHRElement, HTMLIFrameElement: _HTMLIFrameElement, HTMLImageElement: _HTMLImageElement, HTMLInputElement: _HTMLInputElement, HTMLLabelElement: _HTMLLabelElement, HTMLLegendElement: _HTMLLegendElement, HTMLLIElement: _HTMLLIElement, HTMLLinkElement: _HTMLLinkElement, HTMLMapElement: _HTMLMapElement, HTMLMetaElement: _HTMLMetaElement, HTMLMeterElement: _HTMLMeterElement, HTMLModElement: _HTMLModElement, HTMLObjectElement: _HTMLObjectElement, HTMLOListElement: _HTMLOListElement, HTMLOptGroupElement: _HTMLOptGroupElement, HTMLOptionElement: _HTMLOptionElement, HTMLOutputElement: _HTMLOutputElement, HTMLParagraphElement: _HTMLParagraphElement, HTMLParamElement: _HTMLParamElement, HTMLPictureElement: _HTMLPictureElement, HTMLPreElement: _HTMLPreElement, HTMLProgressElement: _HTMLProgressElement, HTMLQuoteElement: _HTMLQuoteElement, HTMLScriptElement: _HTMLScriptElement, HTMLSelectElement: _HTMLSelectElement, HTMLSlotElement: _HTMLSlotElement, HTMLSourceElement: _HTMLSourceElement, HTMLSpanElement: _HTMLSpanElement, HTMLStyleElement: _HTMLStyleElement, HTMLTableElement: _HTMLTableElement, HTMLTableSectionElement: _HTMLTableSectionElement, HTMLTableCellElement: _HTMLTableCellElement, HTMLTextAreaElement: _HTMLTextAreaElement, HTMLTimeElement: _HTMLTimeElement, HTMLTitleElement: _HTMLTitleElement, HTMLTableRowElement: _HTMLTableRowElement, HTMLTrackElement: _HTMLTrackElement, HTMLUListElement: _HTMLUListElement, HTMLVideoElement: _HTMLVideoElement, HTMLHeadingElement: _HTMLHeadingElement, HTMLBodyElement: _HTMLBodyElement } = w;
17
17
  const HTMLElement = _HTMLElement;
@@ -113,220 +113,173 @@ const registerAllElements = (w) => {
113
113
  let SwcIf = class SwcIf extends HTMLTemplateElement {
114
114
  constructor() {
115
115
  super(...arguments);
116
- this._value = false;
117
116
  this._nodes = [];
118
117
  }
119
118
  get value() {
120
119
  return this._value;
121
120
  }
122
121
  set value(nv) {
123
- this._value = Boolean(nv);
124
- this.render();
122
+ this.refresh(nv);
125
123
  }
126
- _resolvePortal() {
127
- const portalScript = this.getAttribute("on-get-portal");
128
- if (!portalScript)
129
- return this.parentElement;
124
+ replaceExpressions(html, groupArgs, context, wrap) {
125
+ const config = wrap ? { wrapExpression: wrap } : void 0;
126
+ const ae = new ActionExpression(html, config);
127
+ const filterOptions = wrap ? { type: "replace", wrap } : "replace";
130
128
  const win = this.ownerDocument?.defaultView || window;
131
- const res = FunctionUtils.executeReturn({
132
- script: portalScript,
133
- context: this,
134
- args: SwcUtils.getHelperAndHostSet(win, this)
135
- });
136
- if (res instanceof HTMLElement)
137
- return res;
138
- if (typeof res === "string")
139
- return win.document.querySelector(res);
140
- return this.parentElement;
141
- }
142
- _executeCloneCallback(attr, args) {
143
- const script = this.getAttribute(attr);
144
- if (!script)
145
- return;
146
- FunctionUtils.execute({ script, context: this, args });
147
- }
148
- refreshValue() {
149
- const script = this.getAttribute("on-get-value");
150
- if (!script) {
151
- this.value = false;
152
- return;
153
- }
154
- const win = this.ownerDocument?.defaultView || window;
155
- const res = FunctionUtils.executeReturn({
156
- script,
157
- context: this,
158
- args: SwcUtils.getHelperAndHostSet(win, this)
159
- });
160
- if (res instanceof Promise) {
161
- res.then((v) => this.value = v).catch(() => this.value = false);
162
- } else {
163
- this.value = res;
129
+ for (const expr of ae.getExpressions(filterOptions)) {
130
+ try {
131
+ const value = FunctionUtils.executeReturn({
132
+ script: ConvertUtils.decodeHtmlEntity(expr.script, win.document),
133
+ context,
134
+ args: groupArgs
135
+ });
136
+ ae.replace(expr, String(value));
137
+ } catch (e) {
138
+ console.error(`[SWC] Failed to execute ${expr.original}:`, e);
139
+ }
164
140
  }
141
+ return ae.getUnprocessedTemplate();
142
+ }
143
+ setValue(valueAttr) {
144
+ this.refresh();
165
145
  }
166
- render() {
146
+ setReplaceWrap(replaceWrapAttr) {
147
+ this.refresh();
148
+ }
149
+ refresh(value = this._value) {
167
150
  this.cleanup();
168
- const portal = this._resolvePortal();
169
- if (!portal)
151
+ const portal = this.parentElement;
152
+ if (!portal || !value)
170
153
  return;
171
154
  const win = this.ownerDocument?.defaultView || window;
172
155
  const helperSet = SwcUtils.getHelperAndHostSet(win, this);
173
- let targetTpl = null;
174
- if (this._value) {
175
- targetTpl = this;
176
- } else {
177
- targetTpl = this.content.querySelector('template[is="swc-default"]');
178
- }
179
- if (targetTpl) {
180
- const clone = targetTpl.content.cloneNode(true);
181
- if (targetTpl === this) {
182
- clone.querySelectorAll('template[is^="swc-"]').forEach((t) => t.remove());
183
- }
184
- this._nodes = Array.from(clone.childNodes);
185
- const elements = this._nodes.filter((n) => n.nodeType === 1);
186
- const groupArgs = { ...helperSet, $value: this._value, $nodes: this._nodes, $elements: elements, $firstElement: elements[0] };
187
- this._nodes.forEach((node, nodeIdx) => {
188
- if (node instanceof HTMLElement)
189
- node.__swc_host = this;
190
- this._executeCloneCallback("on-clone-node", { ...groupArgs, $node: node, $nodeIndex: nodeIdx, $isElement: node.nodeType === 1 });
191
- });
192
- this._executeCloneCallback("on-clone-nodes", groupArgs);
193
- if (portal === this.parentElement) {
194
- portal.insertBefore(clone, this.nextSibling);
195
- } else {
196
- portal.appendChild(clone);
197
- }
198
- }
156
+ let htmlString = this.innerHTML;
157
+ const groupArgs = { ...helperSet, $value: value };
158
+ htmlString = this.replaceExpressions(htmlString, groupArgs, this, this._replaceWrap);
159
+ const result = this.ownerDocument?.createElement("template") || document.createElement("template");
160
+ result.innerHTML = htmlString;
161
+ const processedFragment = result.content;
162
+ this._nodes = Array.from(processedFragment.childNodes);
163
+ portal.insertBefore(processedFragment, this.nextSibling);
199
164
  }
200
165
  cleanup() {
201
166
  this._nodes.forEach((n) => n.parentElement?.removeChild(n));
202
167
  this._nodes = [];
203
168
  }
204
- connectedCallback() {
205
- this.refreshValue();
206
- }
207
169
  disconnectedCallback() {
208
170
  this.cleanup();
209
171
  }
210
172
  };
211
173
  __decorate([
212
- changedAttributeHost("on-get-value"),
174
+ attributeHost("value"),
175
+ __metadata("design:type", Object)
176
+ ], SwcIf.prototype, "_value", void 0);
177
+ __decorate([
178
+ attributeHost("replace-wrap"),
179
+ __metadata("design:type", String)
180
+ ], SwcIf.prototype, "_replaceWrap", void 0);
181
+ __decorate([
182
+ changedAttributeHost("value"),
213
183
  __metadata("design:type", Function),
214
- __metadata("design:paramtypes", []),
184
+ __metadata("design:paramtypes", [String]),
185
+ __metadata("design:returntype", void 0)
186
+ ], SwcIf.prototype, "setValue", null);
187
+ __decorate([
188
+ changedAttributeHost("replace-wrap"),
189
+ __metadata("design:type", Function),
190
+ __metadata("design:paramtypes", [String]),
215
191
  __metadata("design:returntype", void 0)
216
- ], SwcIf.prototype, "refreshValue", null);
192
+ ], SwcIf.prototype, "setReplaceWrap", null);
217
193
  SwcIf = __decorate([
218
194
  elementDefine("swc-if", { extends: "template", window: w })
219
195
  ], SwcIf);
220
196
  let SwcLoop = class SwcLoop extends HTMLTemplateElement {
221
197
  constructor() {
222
198
  super(...arguments);
223
- this._value = [];
224
199
  this._nodeGroups = [];
225
200
  }
226
201
  get value() {
227
202
  return this._value;
228
203
  }
229
204
  set value(nv) {
230
- this._value = Array.isArray(nv) ? [...nv] : [];
231
- this.render();
205
+ this.refresh(nv);
232
206
  }
233
- _resolvePortal() {
234
- const portalScript = this.getAttribute("on-get-portal");
235
- if (!portalScript)
236
- return this.parentElement;
237
- const win = this.ownerDocument?.defaultView || window;
238
- const res = FunctionUtils.executeReturn({
239
- script: portalScript,
240
- context: this,
241
- args: SwcUtils.getHelperAndHostSet(win, this)
242
- });
243
- if (res instanceof HTMLElement)
244
- return res;
245
- if (typeof res === "string")
246
- return win.document.querySelector(res);
247
- return this.parentElement;
248
- }
249
- _executeCloneCallback(attr, args) {
250
- const script = this.getAttribute(attr);
251
- if (!script)
252
- return;
253
- FunctionUtils.execute({ script, context: this, args });
207
+ setValue() {
208
+ this.refresh();
254
209
  }
255
- _cleanup() {
256
- this._nodeGroups.forEach((nodes) => nodes.forEach((n) => n.parentElement?.removeChild(n)));
257
- this._nodeGroups = [];
210
+ setReplaceWrap() {
211
+ this.refresh();
258
212
  }
259
- refreshValue() {
260
- const script = this.getAttribute("on-get-value");
261
- if (!script) {
262
- this.value = [];
263
- return;
264
- }
213
+ replaceExpressions(html, groupArgs, context, wrap) {
214
+ const config = wrap ? { wrapExpression: wrap } : void 0;
215
+ const ae = new ActionExpression(html, config);
216
+ const filterOptions = wrap ? { type: "replace", wrap } : "replace";
265
217
  const win = this.ownerDocument?.defaultView || window;
266
- const res = FunctionUtils.executeReturn({
267
- script,
268
- context: this,
269
- args: SwcUtils.getHelperAndHostSet(win, this)
270
- });
271
- if (res instanceof Promise) {
272
- res.then((v) => this.value = v).catch(() => this.value = []);
273
- } else {
274
- this.value = res;
218
+ for (const expr of ae.getExpressions(filterOptions)) {
219
+ try {
220
+ const value = FunctionUtils.executeReturn({
221
+ script: ConvertUtils.decodeHtmlEntity(expr.script, win.document),
222
+ context,
223
+ args: groupArgs
224
+ });
225
+ ae.replace(expr, String(value));
226
+ } catch (e) {
227
+ console.error(`[SWC] Failed to execute ${expr.original}:`, e);
228
+ }
275
229
  }
230
+ return ae.getUnprocessedTemplate();
276
231
  }
277
- render() {
278
- this._cleanup();
279
- const portal = this._resolvePortal();
232
+ refresh(value = this._value) {
233
+ this.cleanup();
234
+ if (value?.length <= 0)
235
+ return;
236
+ const portal = this.parentElement;
280
237
  if (!portal)
281
238
  return;
282
239
  const win = this.ownerDocument?.defaultView || window;
283
240
  const helperSet = SwcUtils.getHelperAndHostSet(win, this);
284
241
  const fragment = win.document.createDocumentFragment();
285
- if (this._value.length === 0) {
286
- const defaultTpl = this.content.querySelector('template[is="swc-default"]');
287
- if (defaultTpl) {
288
- const clone = defaultTpl.content.cloneNode(true);
289
- const nodes = Array.from(clone.childNodes);
290
- this._nodeGroups.push(nodes);
291
- fragment.appendChild(clone);
292
- }
293
- } else {
294
- this._value.forEach((item, index) => {
295
- const clone = this.content.cloneNode(true);
296
- const subTemplates = clone.querySelectorAll('template[is^="swc-"]');
297
- subTemplates.forEach((t) => t.remove());
298
- const nodes = Array.from(clone.childNodes);
299
- const elements = nodes.filter((n) => n.nodeType === 1);
300
- const groupArgs = { ...helperSet, $item: item, $index: index, $value: this._value, $nodes: nodes, $elements: elements, $firstElement: elements[0] };
301
- nodes.forEach((node, nodeIdx) => {
302
- if (node instanceof HTMLElement)
303
- node.__swc_host = this;
304
- this._executeCloneCallback("on-clone-node", { ...groupArgs, $node: node, $nodeIndex: nodeIdx, $isElement: node.nodeType === 1 });
305
- });
306
- this._executeCloneCallback("on-clone-nodes", groupArgs);
307
- this._nodeGroups.push(nodes);
308
- fragment.appendChild(clone);
309
- });
310
- }
311
- if (portal === this.parentElement) {
312
- portal.insertBefore(fragment, this.nextSibling);
313
- } else {
314
- portal.appendChild(fragment);
315
- }
242
+ value.forEach((item, index) => {
243
+ let htmlString = this.innerHTML;
244
+ const groupArgs = { ...helperSet, $item: item, $index: index, $value: this._value };
245
+ htmlString = this.replaceExpressions(htmlString, groupArgs, this, this._replaceWrap);
246
+ const temp = this.ownerDocument?.createElement("template") || document.createElement("template");
247
+ temp.innerHTML = htmlString;
248
+ const content = temp.content;
249
+ const nodes = Array.from(content.childNodes);
250
+ this._nodeGroups.push(nodes);
251
+ fragment.appendChild(content);
252
+ });
253
+ portal.insertBefore(fragment, this.nextSibling);
316
254
  }
317
- connectedCallback() {
318
- this.refreshValue();
255
+ cleanup() {
256
+ this._nodeGroups.forEach((nodes) => nodes.forEach((n) => n.parentElement?.removeChild(n)));
257
+ this._nodeGroups = [];
319
258
  }
320
259
  disconnectedCallback() {
321
- this._cleanup();
260
+ this.cleanup();
322
261
  }
323
262
  };
324
263
  __decorate([
325
- changedAttributeHost("on-get-value"),
264
+ attributeHost("value"),
265
+ __metadata("design:type", Array)
266
+ ], SwcLoop.prototype, "_value", void 0);
267
+ __decorate([
268
+ attributeHost("replace-wrap"),
269
+ __metadata("design:type", String)
270
+ ], SwcLoop.prototype, "_replaceWrap", void 0);
271
+ __decorate([
272
+ changedAttributeHost("value"),
273
+ __metadata("design:type", Function),
274
+ __metadata("design:paramtypes", []),
275
+ __metadata("design:returntype", void 0)
276
+ ], SwcLoop.prototype, "setValue", null);
277
+ __decorate([
278
+ changedAttributeHost("replace-wrap"),
326
279
  __metadata("design:type", Function),
327
280
  __metadata("design:paramtypes", []),
328
281
  __metadata("design:returntype", void 0)
329
- ], SwcLoop.prototype, "refreshValue", null);
282
+ ], SwcLoop.prototype, "setReplaceWrap", null);
330
283
  SwcLoop = __decorate([
331
284
  elementDefine("swc-loop", { extends: "template", window: w })
332
285
  ], SwcLoop);
@@ -334,56 +287,64 @@ const registerAllElements = (w) => {
334
287
  constructor() {
335
288
  super(...arguments);
336
289
  this._nodes = [];
337
- this._value = null;
338
290
  this._previousTemplate = null;
339
291
  }
340
292
  get value() {
341
293
  return this._value;
342
294
  }
343
295
  set value(nv) {
344
- this._value = nv;
345
- this.render();
296
+ this.refresh(nv);
346
297
  }
347
- _executeCloneCallback(attr, args) {
348
- const script = this.getAttribute(attr);
349
- if (!script)
350
- return;
351
- FunctionUtils.execute({ script, context: this, args });
298
+ setValue() {
299
+ this.refresh();
352
300
  }
353
- refresh(valueAttr) {
354
- valueAttr ?? (valueAttr = this.getAttribute("value"));
355
- if (valueAttr === null) {
356
- this.value = null;
357
- return;
358
- }
359
- if (valueAttr.startsWith("{{") && valueAttr.endsWith("}}")) {
360
- const script = valueAttr.slice(2, -2).trim();
361
- const win = this.ownerDocument?.defaultView || window;
362
- const result = FunctionUtils.executeReturn({ script, context: this, args: SwcUtils.getHelperAndHostSet(win, this) });
363
- this.value = result;
364
- } else {
365
- this.value = valueAttr;
301
+ setReplaceWrap(replaceWrapAttr) {
302
+ this.refresh();
303
+ }
304
+ replaceExpressions(html, groupArgs, context, wrap) {
305
+ const config = wrap ? { wrapExpression: wrap } : void 0;
306
+ const ae = new ActionExpression(html, config);
307
+ const filterOptions = wrap ? { type: "replace", wrap } : "replace";
308
+ const win = this.ownerDocument?.defaultView || window;
309
+ for (const expr of ae.getExpressions(filterOptions)) {
310
+ try {
311
+ const value = FunctionUtils.executeReturn({
312
+ script: ConvertUtils.decodeHtmlEntity(expr.script, win.document),
313
+ context,
314
+ args: groupArgs
315
+ });
316
+ ae.replace(expr, String(value));
317
+ } catch (e) {
318
+ console.error(`[SWC] Failed to execute ${expr.original}:`, e);
319
+ }
366
320
  }
321
+ return ae.getUnprocessedTemplate();
367
322
  }
368
- render() {
323
+ refresh(value = this._value) {
324
+ const portal = this.parentElement;
325
+ if (!portal)
326
+ return;
369
327
  const win = this.ownerDocument?.defaultView || window;
370
328
  const helperSet = SwcUtils.getHelperAndHostSet(win, this);
329
+ const groupArgs = { ...helperSet, $value: value };
371
330
  const templates = Array.from(this.content.querySelectorAll("template"));
372
331
  let selected = null;
373
332
  for (const t of templates) {
374
333
  if (t.getAttribute("is") === "swc-when") {
334
+ const attrVal = t.getAttribute("value") || "";
375
335
  let matches = false;
376
- const value = t.getAttribute("value") || "";
377
- if (value.startsWith("{{") && value.endsWith("}}")) {
378
- const script = value.slice(2, -2).trim();
336
+ const ae = new ActionExpression(attrVal);
337
+ const expr = ae.getFirstExpression("replace");
338
+ if (expr) {
339
+ const decodedScript = ConvertUtils.decodeHtmlEntity(expr.script, win.document);
379
340
  const result = FunctionUtils.executeReturn({
380
- script,
341
+ script: decodedScript,
381
342
  context: t,
382
- args: { ...helperSet, $value: this._value }
343
+ args: groupArgs
383
344
  });
384
- matches = result === true;
345
+ matches = !!result;
385
346
  } else {
386
- matches = String(value) === String(this._value);
347
+ matches = String(attrVal) === String(value);
387
348
  }
388
349
  if (matches) {
389
350
  selected = t;
@@ -392,56 +353,53 @@ const registerAllElements = (w) => {
392
353
  }
393
354
  }
394
355
  const target = selected || this.content.querySelector('template[is="swc-otherwise"]');
395
- const targetHasSkipIfSame = target?.hasAttribute("skip-if-same");
396
- const shouldSkip = (this.hasAttribute("skip-if-same") || targetHasSkipIfSame) && this._previousTemplate === target;
397
- if (shouldSkip) {
356
+ const skipValue = target?.getAttribute?.("skip-if-same");
357
+ const skipValue2 = this._previousTemplate?.getAttribute?.("skip-if-same");
358
+ const hasSkipIfSame = target?.hasAttribute?.("skip-if-same");
359
+ const isSame = this._previousTemplate === target;
360
+ if (hasSkipIfSame && isSame) {
398
361
  return;
399
362
  }
400
363
  this.cleanup();
401
364
  this._previousTemplate = target;
402
365
  if (target) {
403
- const clone = target.content.cloneNode(true);
404
- this._nodes = Array.from(clone.childNodes);
405
- const elements = this._nodes.filter((n) => n.nodeType === 1);
406
- const groupArgs = { ...helperSet, $value: this._value, $nodes: this._nodes, $elements: elements, $firstElement: elements[0] };
407
- this._nodes.forEach((n, nodeIdx) => {
408
- this._executeCloneCallback("on-clone-node", { ...groupArgs, $node: n, $nodeIndex: nodeIdx, $isElement: n.nodeType === 1 });
409
- if (n instanceof HTMLElement) {
410
- Array.from(n.attributes).forEach((attr) => {
411
- const value = attr.value || "";
412
- if (value.startsWith("{{") && value.endsWith("}}")) {
413
- const script = value.slice(2, -2).trim();
414
- const result = FunctionUtils.executeReturn({
415
- script,
416
- context: n,
417
- args: { ...groupArgs, $value: this._value }
418
- });
419
- n.setAttribute(attr.name, String(result));
420
- }
421
- });
422
- }
423
- });
424
- this._executeCloneCallback("on-clone-nodes", groupArgs);
425
- this.parentElement?.insertBefore(clone, this.nextSibling);
366
+ let htmlString = target.innerHTML;
367
+ htmlString = this.replaceExpressions(htmlString, groupArgs, this, this._replaceWrap);
368
+ const result = this.ownerDocument?.createElement("template") || document.createElement("template");
369
+ result.innerHTML = htmlString;
370
+ const processedFragment = result.content;
371
+ this._nodes = Array.from(processedFragment.childNodes);
372
+ portal.insertBefore(processedFragment, this.nextSibling);
426
373
  }
427
374
  }
428
375
  cleanup() {
429
376
  this._nodes.forEach((n) => n.parentElement?.removeChild(n));
430
377
  this._nodes = [];
431
378
  }
432
- connectedCallback() {
433
- this.refresh();
434
- }
435
379
  disconnectedCallback() {
436
380
  this.cleanup();
437
381
  }
438
382
  };
383
+ __decorate([
384
+ attributeHost("value"),
385
+ __metadata("design:type", Object)
386
+ ], SwcChoose.prototype, "_value", void 0);
387
+ __decorate([
388
+ attributeHost("replace-wrap"),
389
+ __metadata("design:type", String)
390
+ ], SwcChoose.prototype, "_replaceWrap", void 0);
439
391
  __decorate([
440
392
  changedAttributeHost("value"),
441
393
  __metadata("design:type", Function),
394
+ __metadata("design:paramtypes", []),
395
+ __metadata("design:returntype", void 0)
396
+ ], SwcChoose.prototype, "setValue", null);
397
+ __decorate([
398
+ changedAttributeHost("replace-wrap"),
399
+ __metadata("design:type", Function),
442
400
  __metadata("design:paramtypes", [String]),
443
401
  __metadata("design:returntype", void 0)
444
- ], SwcChoose.prototype, "refresh", null);
402
+ ], SwcChoose.prototype, "setReplaceWrap", null);
445
403
  SwcChoose = __decorate([
446
404
  elementDefine("swc-choose", { extends: "template", window: w })
447
405
  ], SwcChoose);
@@ -449,93 +407,106 @@ const registerAllElements = (w) => {
449
407
  constructor() {
450
408
  super(...arguments);
451
409
  this._nodes = [];
452
- this._value = null;
453
410
  }
454
- _resolvePortal() {
455
- const portalScript = this.getAttribute("on-get-portal");
456
- if (!portalScript)
457
- return this.parentElement;
458
- const win = this.ownerDocument?.defaultView || window;
459
- const res = FunctionUtils.executeReturn({
460
- script: portalScript,
461
- context: this,
462
- args: SwcUtils.getHelperAndHostSet(win, this)
463
- });
464
- if (res instanceof HTMLElement)
465
- return res;
466
- if (typeof res === "string")
467
- return win.document.querySelector(res);
468
- return this.parentElement;
469
- }
470
- _executeCloneCallback(attr, args) {
471
- const script = this.getAttribute(attr);
472
- if (!script)
473
- return;
474
- FunctionUtils.execute({ script, context: this, args });
411
+ get value() {
412
+ return this._value;
413
+ }
414
+ set value(nv) {
415
+ this.executeAsync(nv);
416
+ }
417
+ setValue(valueAttr) {
418
+ this.executeAsync(this._value);
475
419
  }
476
- refresh() {
477
- const script = this.getAttribute("on-get-value");
478
- if (!script) {
479
- this.render("default");
420
+ setReplaceWrap() {
421
+ this.executeAsync(this._value);
422
+ }
423
+ executeAsync(result = this._value) {
424
+ if (result === void 0 || result === null) {
425
+ this.refresh("default");
480
426
  return;
481
427
  }
482
- const win = this.ownerDocument?.defaultView || window;
483
- const result = FunctionUtils.executeReturn({ script, context: this, args: SwcUtils.getHelperAndHostSet(win, this) });
484
428
  if (result instanceof Promise) {
485
- this.render("loading");
429
+ this.refresh("loading");
486
430
  result.then((v) => {
487
- this._value = v;
488
- this.render("success");
489
- }).catch((e) => this.render("error"));
431
+ this.resultValue = v;
432
+ this.refresh("success");
433
+ }).catch((e) => {
434
+ console.error("[SWC-ASYNC] Promise rejected:", e);
435
+ this.resultValue = e;
436
+ this.refresh("error");
437
+ });
490
438
  } else {
491
- this._value = result;
492
- this.render("success");
439
+ this.resultValue = result;
440
+ this.refresh("success");
441
+ }
442
+ }
443
+ replaceExpressions(html, groupArgs, context, wrap) {
444
+ const config = wrap ? { wrapExpression: wrap } : void 0;
445
+ const ae = new ActionExpression(html, config);
446
+ const filterOptions = wrap ? { type: "replace", wrap } : "replace";
447
+ const win = this.ownerDocument?.defaultView || window;
448
+ for (const expr of ae.getExpressions(filterOptions)) {
449
+ try {
450
+ const value = FunctionUtils.executeReturn({
451
+ script: ConvertUtils.decodeHtmlEntity(expr.script, win.document),
452
+ context,
453
+ args: groupArgs
454
+ });
455
+ ae.replace(expr, String(value));
456
+ } catch (e) {
457
+ console.error(`[SWC] Failed to execute ${expr.original}:`, e);
458
+ }
493
459
  }
460
+ return ae.getUnprocessedTemplate();
494
461
  }
495
- render(state) {
462
+ refresh(state = "default") {
463
+ console.log("rrrrrrrrrrrrrrrrr", state);
496
464
  this.cleanup();
497
- const portal = this._resolvePortal();
465
+ const portal = this.parentElement;
498
466
  if (!portal)
499
467
  return;
500
468
  const win = this.ownerDocument?.defaultView || window;
501
469
  const helperSet = SwcUtils.getHelperAndHostSet(win, this);
502
470
  const t = this.content.querySelector(`template[is="swc-${state}"]`);
503
471
  if (t) {
504
- const clone = t.content.cloneNode(true);
505
- this._nodes = Array.from(clone.childNodes);
506
- const elements = this._nodes.filter((n) => n.nodeType === 1);
507
- const groupArgs = { ...helperSet, $value: this._value, $nodes: this._nodes, $elements: elements, $firstElement: elements[0], $state: state };
508
- this._nodes.forEach((n, nodeIdx) => {
509
- if (n instanceof HTMLElement)
510
- n.__swc_host = this;
511
- this._executeCloneCallback("on-clone-node", { ...groupArgs, $node: n, $nodeIndex: nodeIdx, $isElement: n.nodeType === 1 });
512
- });
513
- this._executeCloneCallback("on-clone-nodes", groupArgs);
514
- if (portal === this.parentElement) {
515
- portal.insertBefore(clone, this.nextSibling);
516
- } else {
517
- portal.appendChild(clone);
518
- }
472
+ let htmlString = t.innerHTML;
473
+ const groupArgs = { ...helperSet, $value: this._value, $state: state };
474
+ htmlString = this.replaceExpressions(htmlString, groupArgs, this, this._replaceWrap);
475
+ const temp = this.ownerDocument?.createElement("template") || document.createElement("template");
476
+ temp.innerHTML = htmlString;
477
+ const content = temp.content;
478
+ this._nodes = Array.from(content.childNodes);
479
+ portal.insertBefore(content, this.nextSibling);
519
480
  }
520
481
  }
521
482
  cleanup() {
522
483
  this._nodes.forEach((n) => n.parentElement?.removeChild(n));
523
484
  this._nodes = [];
524
485
  }
525
- connectedCallback() {
526
- console.log("[SwcAsync] connectedCallback called");
527
- this.refresh();
528
- }
529
486
  disconnectedCallback() {
530
487
  this.cleanup();
531
488
  }
532
489
  };
533
490
  __decorate([
534
- changedAttributeHost("on-get-value"),
491
+ attributeHost("value"),
492
+ __metadata("design:type", Object)
493
+ ], SwcAsync.prototype, "_value", void 0);
494
+ __decorate([
495
+ attributeHost("replace-wrap"),
496
+ __metadata("design:type", String)
497
+ ], SwcAsync.prototype, "_replaceWrap", void 0);
498
+ __decorate([
499
+ changedAttributeHost("value"),
500
+ __metadata("design:type", Function),
501
+ __metadata("design:paramtypes", [String]),
502
+ __metadata("design:returntype", void 0)
503
+ ], SwcAsync.prototype, "setValue", null);
504
+ __decorate([
505
+ changedAttributeHost("replace-wrap"),
535
506
  __metadata("design:type", Function),
536
507
  __metadata("design:paramtypes", []),
537
508
  __metadata("design:returntype", void 0)
538
- ], SwcAsync.prototype, "refresh", null);
509
+ ], SwcAsync.prototype, "setReplaceWrap", null);
539
510
  SwcAsync = __decorate([
540
511
  elementDefine("swc-async", { extends: "template", window: w })
541
512
  ], SwcAsync);