@dooboostore/simple-web-component 1.0.31 → 1.0.33

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 (100) hide show
  1. package/README.md +280 -43
  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 +27 -10
  7. package/dist/cjs/decorators/elementDefine.js.map +3 -3
  8. package/dist/cjs/decorators/index.js +3 -1
  9. package/dist/cjs/decorators/index.js.map +2 -2
  10. package/dist/cjs/decorators/publishSwcAppMessage.js +86 -0
  11. package/dist/cjs/decorators/publishSwcAppMessage.js.map +7 -0
  12. package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js +62 -0
  13. package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js.map +7 -0
  14. package/dist/cjs/decorators/{subscribeSwcAppRouteChange.js → subscribeSwcAppRouteChangeWhileConnected.js} +16 -16
  15. package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +7 -0
  16. package/dist/cjs/elements/SwcAppMixin.js +32 -3
  17. package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
  18. package/dist/cjs/elements/SwcAsync.js +69 -57
  19. package/dist/cjs/elements/SwcAsync.js.map +2 -2
  20. package/dist/cjs/elements/SwcChoose.js +66 -60
  21. package/dist/cjs/elements/SwcChoose.js.map +2 -2
  22. package/dist/cjs/elements/SwcIf.js +51 -66
  23. package/dist/cjs/elements/SwcIf.js.map +2 -2
  24. package/dist/cjs/elements/SwcLoop.js +58 -78
  25. package/dist/cjs/elements/SwcLoop.js.map +2 -2
  26. package/dist/cjs/elements/register.js +310 -335
  27. package/dist/cjs/elements/register.js.map +2 -2
  28. package/dist/cjs/types.js.map +1 -1
  29. package/dist/cjs/utils/Utils.js +7 -13
  30. package/dist/cjs/utils/Utils.js.map +2 -2
  31. package/dist/esm/decorators/applyStyle.js +1 -1
  32. package/dist/esm/decorators/applyStyle.js.map +2 -2
  33. package/dist/esm/decorators/attribute.js +18 -2
  34. package/dist/esm/decorators/attribute.js.map +2 -2
  35. package/dist/esm/decorators/elementDefine.js +25 -8
  36. package/dist/esm/decorators/elementDefine.js.map +3 -3
  37. package/dist/esm/decorators/index.js +3 -1
  38. package/dist/esm/decorators/index.js.map +2 -2
  39. package/dist/esm/decorators/publishSwcAppMessage.js +67 -0
  40. package/dist/esm/decorators/publishSwcAppMessage.js.map +7 -0
  41. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js +43 -0
  42. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js.map +7 -0
  43. package/dist/esm/decorators/{subscribeSwcAppRouteChange.js → subscribeSwcAppRouteChangeWhileConnected.js} +13 -13
  44. package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +7 -0
  45. package/dist/esm/elements/SwcAppMixin.js +32 -3
  46. package/dist/esm/elements/SwcAppMixin.js.map +2 -2
  47. package/dist/esm/elements/SwcAsync.js +70 -58
  48. package/dist/esm/elements/SwcAsync.js.map +2 -2
  49. package/dist/esm/elements/SwcChoose.js +67 -61
  50. package/dist/esm/elements/SwcChoose.js.map +2 -2
  51. package/dist/esm/elements/SwcIf.js +52 -67
  52. package/dist/esm/elements/SwcIf.js.map +2 -2
  53. package/dist/esm/elements/SwcLoop.js +59 -79
  54. package/dist/esm/elements/SwcLoop.js.map +2 -2
  55. package/dist/esm/elements/register.js +239 -264
  56. package/dist/esm/elements/register.js.map +2 -2
  57. package/dist/esm/types.js.map +1 -1
  58. package/dist/esm/utils/Utils.js +7 -13
  59. package/dist/esm/utils/Utils.js.map +2 -2
  60. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +2804 -2498
  61. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
  62. package/dist/types/decorators/attribute.d.ts.map +1 -1
  63. package/dist/types/decorators/elementDefine.d.ts +1 -0
  64. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  65. package/dist/types/decorators/index.d.ts +3 -1
  66. package/dist/types/decorators/index.d.ts.map +1 -1
  67. package/dist/types/decorators/publishSwcAppMessage.d.ts +13 -0
  68. package/dist/types/decorators/publishSwcAppMessage.d.ts.map +1 -0
  69. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts +16 -0
  70. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts.map +1 -0
  71. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +18 -0
  72. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +1 -0
  73. package/dist/types/elements/SwcAppMixin.d.ts +3 -0
  74. package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
  75. package/dist/types/elements/register.d.ts.map +1 -1
  76. package/dist/types/types.d.ts +14 -1
  77. package/dist/types/types.d.ts.map +1 -1
  78. package/dist/types/utils/Utils.d.ts.map +1 -1
  79. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +2804 -2498
  80. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
  81. package/package.json +4 -4
  82. package/src/decorators/applyStyle.ts +1 -1
  83. package/src/decorators/attribute.ts +35 -30
  84. package/src/decorators/elementDefine.ts +28 -8
  85. package/src/decorators/index.ts +3 -1
  86. package/src/decorators/publishSwcAppMessage.ts +100 -0
  87. package/src/decorators/subscribeSwcAppMessageWhileConnected.ts +73 -0
  88. package/src/decorators/{subscribeSwcAppRouteChange.ts → subscribeSwcAppRouteChangeWhileConnected.ts} +19 -19
  89. package/src/elements/SwcAppMixin.ts +43 -4
  90. package/src/elements/SwcAsync.ts +75 -69
  91. package/src/elements/SwcChoose.ts +67 -80
  92. package/src/elements/SwcIf.ts +51 -76
  93. package/src/elements/SwcLoop.ts +56 -87
  94. package/src/elements/register.ts +235 -307
  95. package/src/types.ts +14 -1
  96. package/src/utils/Utils.ts +11 -17
  97. package/dist/cjs/decorators/subscribeSwcAppRouteChange.js.map +0 -7
  98. package/dist/esm/decorators/subscribeSwcAppRouteChange.js.map +0 -7
  99. package/dist/types/decorators/subscribeSwcAppRouteChange.d.ts +0 -18
  100. package/dist/types/decorators/subscribeSwcAppRouteChange.d.ts.map +0 -1
@@ -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,212 +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
- _executeCloneCallback(attr, args) {
127
- const script = this.getAttribute(attr);
128
- if (!script)
129
- return;
130
- FunctionUtils.execute({ script, context: this, args });
131
- }
132
- refreshValue(valueAttr) {
133
- valueAttr ?? (valueAttr = this.getAttribute("value"));
134
- if (valueAttr === null) {
135
- this.value = false;
136
- return;
137
- }
138
- if (valueAttr.startsWith("{{") && valueAttr.endsWith("}}")) {
139
- const script = valueAttr.slice(2, -2).trim();
140
- const win = this.ownerDocument?.defaultView || window;
141
- const result = FunctionUtils.executeReturn({
142
- script,
143
- context: this,
144
- args: SwcUtils.getHelperAndHostSet(win, this)
145
- });
146
- this.value = result;
147
- } else {
148
- this.value = Boolean(valueAttr);
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";
128
+ const win = this.ownerDocument?.defaultView || window;
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
+ }
149
140
  }
141
+ return ae.getUnprocessedTemplate();
142
+ }
143
+ setValue(valueAttr) {
144
+ this.refresh();
150
145
  }
151
- render() {
146
+ setReplaceWrap(replaceWrapAttr) {
147
+ this.refresh();
148
+ }
149
+ refresh(value = this._value) {
152
150
  this.cleanup();
153
151
  const portal = this.parentElement;
154
- if (!portal)
152
+ if (!portal || !value)
155
153
  return;
156
154
  const win = this.ownerDocument?.defaultView || window;
157
155
  const helperSet = SwcUtils.getHelperAndHostSet(win, this);
158
- let targetTpl = null;
159
- if (this._value) {
160
- targetTpl = this;
161
- } else {
162
- targetTpl = this.content.querySelector('template[is="swc-default"]');
163
- }
164
- if (targetTpl) {
165
- const clone = targetTpl.content.cloneNode(true);
166
- if (targetTpl === this) {
167
- clone.querySelectorAll('template[is^="swc-"]').forEach((t) => t.remove());
168
- }
169
- this._nodes = Array.from(clone.childNodes);
170
- const elements = this._nodes.filter((n) => n.nodeType === 1);
171
- const groupArgs = { ...helperSet, $value: this._value, $nodes: this._nodes, $elements: elements, $firstElement: elements[0] };
172
- this._nodes.forEach((node, nodeIdx) => {
173
- this._executeCloneCallback("on-clone-node", { ...groupArgs, $node: node, $nodeIndex: nodeIdx, $isElement: node.nodeType === 1 });
174
- if (node instanceof HTMLElement) {
175
- Array.from(node.attributes).forEach((attr) => {
176
- const value = attr.value || "";
177
- if (value.startsWith("{{") && value.endsWith("}}")) {
178
- const script = value.slice(2, -2).trim();
179
- const result = FunctionUtils.executeReturn({
180
- script,
181
- context: node,
182
- args: { ...groupArgs, $value: this._value }
183
- });
184
- node.setAttribute(attr.name, String(result));
185
- }
186
- });
187
- }
188
- });
189
- this._executeCloneCallback("on-clone-nodes", groupArgs);
190
- portal.insertBefore(clone, this.nextSibling);
191
- }
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);
192
164
  }
193
165
  cleanup() {
194
166
  this._nodes.forEach((n) => n.parentElement?.removeChild(n));
195
167
  this._nodes = [];
196
168
  }
197
- connectedCallback() {
198
- this.refreshValue();
199
- }
200
169
  disconnectedCallback() {
201
170
  this.cleanup();
202
171
  }
203
172
  };
173
+ __decorate([
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);
204
181
  __decorate([
205
182
  changedAttributeHost("value"),
206
183
  __metadata("design:type", Function),
207
184
  __metadata("design:paramtypes", [String]),
208
185
  __metadata("design:returntype", void 0)
209
- ], SwcIf.prototype, "refreshValue", null);
186
+ ], SwcIf.prototype, "setValue", null);
187
+ __decorate([
188
+ changedAttributeHost("replace-wrap"),
189
+ __metadata("design:type", Function),
190
+ __metadata("design:paramtypes", [String]),
191
+ __metadata("design:returntype", void 0)
192
+ ], SwcIf.prototype, "setReplaceWrap", null);
210
193
  SwcIf = __decorate([
211
194
  elementDefine("swc-if", { extends: "template", window: w })
212
195
  ], SwcIf);
213
196
  let SwcLoop = class SwcLoop extends HTMLTemplateElement {
214
197
  constructor() {
215
198
  super(...arguments);
216
- this._value = [];
217
199
  this._nodeGroups = [];
218
200
  }
219
201
  get value() {
220
202
  return this._value;
221
203
  }
222
204
  set value(nv) {
223
- this._value = Array.isArray(nv) ? [...nv] : [];
224
- this.render();
205
+ this.refresh(nv);
225
206
  }
226
- _executeCloneCallback(attr, args) {
227
- const script = this.getAttribute(attr);
228
- if (!script)
229
- return;
230
- FunctionUtils.execute({ script, context: this, args });
207
+ setValue() {
208
+ this.refresh();
231
209
  }
232
- _cleanup() {
233
- this._nodeGroups.forEach((nodes) => nodes.forEach((n) => n.parentElement?.removeChild(n)));
234
- this._nodeGroups = [];
210
+ setReplaceWrap() {
211
+ this.refresh();
235
212
  }
236
- refreshValue() {
237
- let script = this.getAttribute("value");
238
- if (!script) {
239
- this.value = [];
240
- return;
241
- }
242
- if (script.startsWith("{{") && script.endsWith("}}")) {
243
- script = script.slice(2, -2).trim();
244
- }
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";
245
217
  const win = this.ownerDocument?.defaultView || window;
246
- const res = FunctionUtils.executeReturn({
247
- script,
248
- context: this,
249
- args: SwcUtils.getHelperAndHostSet(win, this)
250
- });
251
- if (res instanceof Promise) {
252
- res.then((v) => this.value = v).catch(() => this.value = []);
253
- } else {
254
- 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
+ }
255
229
  }
230
+ return ae.getUnprocessedTemplate();
256
231
  }
257
- render() {
258
- this._cleanup();
232
+ refresh(value = this._value) {
233
+ this.cleanup();
234
+ if (value?.length <= 0)
235
+ return;
259
236
  const portal = this.parentElement;
260
237
  if (!portal)
261
238
  return;
262
239
  const win = this.ownerDocument?.defaultView || window;
263
240
  const helperSet = SwcUtils.getHelperAndHostSet(win, this);
264
241
  const fragment = win.document.createDocumentFragment();
265
- if (this._value.length === 0) {
266
- const defaultTpl = this.content.querySelector('template[is="swc-default"]');
267
- if (defaultTpl) {
268
- const clone = defaultTpl.content.cloneNode(true);
269
- const nodes = Array.from(clone.childNodes);
270
- this._nodeGroups.push(nodes);
271
- fragment.appendChild(clone);
272
- }
273
- } else {
274
- this._value.forEach((item, index) => {
275
- const clone = this.content.cloneNode(true);
276
- const subTemplates = clone.querySelectorAll('template[is^="swc-"]');
277
- subTemplates.forEach((t) => t.remove());
278
- const nodes = Array.from(clone.childNodes);
279
- const elements = nodes.filter((n) => n.nodeType === 1);
280
- const groupArgs = { ...helperSet, $item: item, $index: index, $value: this._value, $nodes: nodes, $elements: elements, $firstElement: elements[0] };
281
- nodes.forEach((node, nodeIdx) => {
282
- this._executeCloneCallback("on-clone-node", { ...groupArgs, $node: node, $nodeIndex: nodeIdx, $isElement: node.nodeType === 1 });
283
- if (node instanceof HTMLElement) {
284
- Array.from(node.attributes).forEach((attr) => {
285
- const value = attr.value || "";
286
- if (value.startsWith("{{") && value.endsWith("}}")) {
287
- const script = value.slice(2, -2).trim();
288
- const result = FunctionUtils.executeReturn({
289
- script,
290
- context: node,
291
- args: groupArgs
292
- });
293
- node.setAttribute(attr.name, String(result));
294
- }
295
- });
296
- }
297
- });
298
- this._executeCloneCallback("on-clone-nodes", groupArgs);
299
- this._nodeGroups.push(nodes);
300
- fragment.appendChild(clone);
301
- });
302
- }
303
- if (portal === this.parentElement) {
304
- portal.insertBefore(fragment, this.nextSibling);
305
- } else {
306
- portal.appendChild(fragment);
307
- }
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);
308
254
  }
309
- connectedCallback() {
310
- this.refreshValue();
255
+ cleanup() {
256
+ this._nodeGroups.forEach((nodes) => nodes.forEach((n) => n.parentElement?.removeChild(n)));
257
+ this._nodeGroups = [];
311
258
  }
312
259
  disconnectedCallback() {
313
- this._cleanup();
260
+ this.cleanup();
314
261
  }
315
262
  };
263
+ __decorate([
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);
316
271
  __decorate([
317
272
  changedAttributeHost("value"),
318
273
  __metadata("design:type", Function),
319
274
  __metadata("design:paramtypes", []),
320
275
  __metadata("design:returntype", void 0)
321
- ], SwcLoop.prototype, "refreshValue", null);
276
+ ], SwcLoop.prototype, "setValue", null);
277
+ __decorate([
278
+ changedAttributeHost("replace-wrap"),
279
+ __metadata("design:type", Function),
280
+ __metadata("design:paramtypes", []),
281
+ __metadata("design:returntype", void 0)
282
+ ], SwcLoop.prototype, "setReplaceWrap", null);
322
283
  SwcLoop = __decorate([
323
284
  elementDefine("swc-loop", { extends: "template", window: w })
324
285
  ], SwcLoop);
@@ -326,57 +287,64 @@ const registerAllElements = (w) => {
326
287
  constructor() {
327
288
  super(...arguments);
328
289
  this._nodes = [];
329
- this._value = null;
330
290
  this._previousTemplate = null;
331
291
  }
332
292
  get value() {
333
293
  return this._value;
334
294
  }
335
295
  set value(nv) {
336
- this._value = nv;
337
- this.render();
296
+ this.refresh(nv);
338
297
  }
339
- _executeCloneCallback(attr, args) {
340
- const script = this.getAttribute(attr);
341
- if (!script)
342
- return;
343
- FunctionUtils.execute({ script, context: this, args });
298
+ setValue() {
299
+ this.refresh();
344
300
  }
345
- refresh(valueAttr) {
346
- valueAttr ?? (valueAttr = this.getAttribute("value"));
347
- if (valueAttr === null) {
348
- this.value = null;
349
- return;
350
- }
351
- if (valueAttr.startsWith("{{") && valueAttr.endsWith("}}")) {
352
- const script = valueAttr.slice(2, -2).trim();
353
- const win = this.ownerDocument?.defaultView || window;
354
- const helperAndHostSet = SwcUtils.getHelperAndHostSet(win, SwcUtils.findNearestSwcHost(this));
355
- const result = FunctionUtils.executeReturn({ script, context: this, args: helperAndHostSet });
356
- this.value = result;
357
- } else {
358
- 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
+ }
359
320
  }
321
+ return ae.getUnprocessedTemplate();
360
322
  }
361
- render() {
323
+ refresh(value = this._value) {
324
+ const portal = this.parentElement;
325
+ if (!portal)
326
+ return;
362
327
  const win = this.ownerDocument?.defaultView || window;
363
328
  const helperSet = SwcUtils.getHelperAndHostSet(win, this);
329
+ const groupArgs = { ...helperSet, $value: value };
364
330
  const templates = Array.from(this.content.querySelectorAll("template"));
365
331
  let selected = null;
366
332
  for (const t of templates) {
367
333
  if (t.getAttribute("is") === "swc-when") {
334
+ const attrVal = t.getAttribute("value") || "";
368
335
  let matches = false;
369
- const value = t.getAttribute("value") || "";
370
- if (value.startsWith("{{") && value.endsWith("}}")) {
371
- 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);
372
340
  const result = FunctionUtils.executeReturn({
373
- script,
341
+ script: decodedScript,
374
342
  context: t,
375
- args: { ...helperSet, $value: this._value }
343
+ args: groupArgs
376
344
  });
377
- matches = result === true;
345
+ matches = !!result;
378
346
  } else {
379
- matches = String(value) === String(this._value);
347
+ matches = String(attrVal) === String(value);
380
348
  }
381
349
  if (matches) {
382
350
  selected = t;
@@ -385,56 +353,53 @@ const registerAllElements = (w) => {
385
353
  }
386
354
  }
387
355
  const target = selected || this.content.querySelector('template[is="swc-otherwise"]');
388
- const targetHasSkipIfSame = target?.hasAttribute("skip-if-same");
389
- const shouldSkip = (this.hasAttribute("skip-if-same") || targetHasSkipIfSame) && this._previousTemplate === target;
390
- 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) {
391
361
  return;
392
362
  }
393
363
  this.cleanup();
394
364
  this._previousTemplate = target;
395
365
  if (target) {
396
- const clone = target.content.cloneNode(true);
397
- this._nodes = Array.from(clone.childNodes);
398
- const elements = this._nodes.filter((n) => n.nodeType === 1);
399
- const groupArgs = { ...helperSet, $value: this._value, $nodes: this._nodes, $elements: elements, $firstElement: elements[0] };
400
- this._nodes.forEach((n, nodeIdx) => {
401
- this._executeCloneCallback("on-clone-node", { ...groupArgs, $node: n, $nodeIndex: nodeIdx, $isElement: n.nodeType === 1 });
402
- if (n instanceof HTMLElement) {
403
- Array.from(n.attributes).forEach((attr) => {
404
- const value = attr.value || "";
405
- if (value.startsWith("{{") && value.endsWith("}}")) {
406
- const script = value.slice(2, -2).trim();
407
- const result = FunctionUtils.executeReturn({
408
- script,
409
- context: n,
410
- args: { ...groupArgs, $value: this._value }
411
- });
412
- n.setAttribute(attr.name, String(result));
413
- }
414
- });
415
- }
416
- });
417
- this._executeCloneCallback("on-clone-nodes", groupArgs);
418
- 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);
419
373
  }
420
374
  }
421
375
  cleanup() {
422
376
  this._nodes.forEach((n) => n.parentElement?.removeChild(n));
423
377
  this._nodes = [];
424
378
  }
425
- connectedCallback() {
426
- this.refresh();
427
- }
428
379
  disconnectedCallback() {
429
380
  this.cleanup();
430
381
  }
431
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);
432
391
  __decorate([
433
392
  changedAttributeHost("value"),
434
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),
435
400
  __metadata("design:paramtypes", [String]),
436
401
  __metadata("design:returntype", void 0)
437
- ], SwcChoose.prototype, "refresh", null);
402
+ ], SwcChoose.prototype, "setReplaceWrap", null);
438
403
  SwcChoose = __decorate([
439
404
  elementDefine("swc-choose", { extends: "template", window: w })
440
405
  ], SwcChoose);
@@ -442,46 +407,60 @@ const registerAllElements = (w) => {
442
407
  constructor() {
443
408
  super(...arguments);
444
409
  this._nodes = [];
445
- this._value = null;
446
410
  }
447
- _executeCloneCallback(attr, args) {
448
- const script = this.getAttribute(attr);
449
- if (!script)
450
- return;
451
- 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);
452
419
  }
453
- refresh(valueAttr) {
454
- valueAttr ?? (valueAttr = this.getAttribute("value"));
455
- if (!valueAttr) {
456
- 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");
457
426
  return;
458
427
  }
459
- if (valueAttr.startsWith("{{") && valueAttr.endsWith("}}")) {
460
- const script = valueAttr.slice(2, -2).trim();
461
- const win = this.ownerDocument?.defaultView || window;
462
- const result = FunctionUtils.executeReturn({
463
- script,
464
- context: this,
465
- args: SwcUtils.getHelperAndHostSet(win, this)
428
+ if (result instanceof Promise) {
429
+ this.refresh("loading");
430
+ result.then((v) => {
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");
466
437
  });
467
- this.executeAsync(result);
468
438
  } else {
469
- this.executeAsync(valueAttr);
439
+ this.resultValue = result;
440
+ this.refresh("success");
470
441
  }
471
442
  }
472
- executeAsync(result) {
473
- if (result instanceof Promise) {
474
- this.render("loading");
475
- result.then((v) => {
476
- this._value = v;
477
- this.render("success");
478
- }).catch((e) => this.render("error"));
479
- } else {
480
- this._value = result;
481
- this.render("success");
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
+ }
482
459
  }
460
+ return ae.getUnprocessedTemplate();
483
461
  }
484
- render(state) {
462
+ refresh(state = "default") {
463
+ console.log("rrrrrrrrrrrrrrrrr", state);
485
464
  this.cleanup();
486
465
  const portal = this.parentElement;
487
466
  if (!portal)
@@ -490,48 +469,44 @@ const registerAllElements = (w) => {
490
469
  const helperSet = SwcUtils.getHelperAndHostSet(win, this);
491
470
  const t = this.content.querySelector(`template[is="swc-${state}"]`);
492
471
  if (t) {
493
- const clone = t.content.cloneNode(true);
494
- this._nodes = Array.from(clone.childNodes);
495
- const elements = this._nodes.filter((n) => n.nodeType === 1);
496
- const groupArgs = { ...helperSet, $value: this._value, $nodes: this._nodes, $elements: elements, $firstElement: elements[0], $state: state };
497
- this._nodes.forEach((n, nodeIdx) => {
498
- this._executeCloneCallback("on-clone-node", { ...groupArgs, $node: n, $nodeIndex: nodeIdx, $isElement: n.nodeType === 1 });
499
- if (n instanceof HTMLElement) {
500
- Array.from(n.attributes).forEach((attr) => {
501
- const value = attr.value || "";
502
- if (value.startsWith("{{") && value.endsWith("}}")) {
503
- const script = value.slice(2, -2).trim();
504
- const result = FunctionUtils.executeReturn({
505
- script,
506
- context: n,
507
- args: groupArgs
508
- });
509
- n.setAttribute(attr.name, String(result));
510
- }
511
- });
512
- }
513
- });
514
- this._executeCloneCallback("on-clone-nodes", groupArgs);
515
- portal.insertBefore(clone, this.nextSibling);
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);
516
480
  }
517
481
  }
518
482
  cleanup() {
519
483
  this._nodes.forEach((n) => n.parentElement?.removeChild(n));
520
484
  this._nodes = [];
521
485
  }
522
- connectedCallback() {
523
- this.refresh();
524
- }
525
486
  disconnectedCallback() {
526
487
  this.cleanup();
527
488
  }
528
489
  };
490
+ __decorate([
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);
529
498
  __decorate([
530
499
  changedAttributeHost("value"),
531
500
  __metadata("design:type", Function),
532
501
  __metadata("design:paramtypes", [String]),
533
502
  __metadata("design:returntype", void 0)
534
- ], SwcAsync.prototype, "refresh", null);
503
+ ], SwcAsync.prototype, "setValue", null);
504
+ __decorate([
505
+ changedAttributeHost("replace-wrap"),
506
+ __metadata("design:type", Function),
507
+ __metadata("design:paramtypes", []),
508
+ __metadata("design:returntype", void 0)
509
+ ], SwcAsync.prototype, "setReplaceWrap", null);
535
510
  SwcAsync = __decorate([
536
511
  elementDefine("swc-async", { extends: "template", window: w })
537
512
  ], SwcAsync);