@dooboostore/simple-web-component 1.0.31 → 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.
- package/dist/cjs/decorators/applyStyle.js +1 -1
- package/dist/cjs/decorators/applyStyle.js.map +2 -2
- package/dist/cjs/decorators/attribute.js +17 -1
- package/dist/cjs/decorators/attribute.js.map +2 -2
- package/dist/cjs/decorators/elementDefine.js +26 -9
- package/dist/cjs/decorators/elementDefine.js.map +3 -3
- package/dist/cjs/elements/SwcAppMixin.js +1 -1
- package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
- package/dist/cjs/elements/SwcAsync.js +69 -57
- package/dist/cjs/elements/SwcAsync.js.map +2 -2
- package/dist/cjs/elements/SwcChoose.js +66 -60
- package/dist/cjs/elements/SwcChoose.js.map +2 -2
- package/dist/cjs/elements/SwcIf.js +51 -66
- package/dist/cjs/elements/SwcIf.js.map +2 -2
- package/dist/cjs/elements/SwcLoop.js +58 -78
- package/dist/cjs/elements/SwcLoop.js.map +2 -2
- package/dist/cjs/elements/register.js +310 -335
- package/dist/cjs/elements/register.js.map +2 -2
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/utils/Utils.js +7 -13
- package/dist/cjs/utils/Utils.js.map +2 -2
- package/dist/esm/decorators/applyStyle.js +1 -1
- package/dist/esm/decorators/applyStyle.js.map +2 -2
- package/dist/esm/decorators/attribute.js +18 -2
- package/dist/esm/decorators/attribute.js.map +2 -2
- package/dist/esm/decorators/elementDefine.js +24 -7
- package/dist/esm/decorators/elementDefine.js.map +3 -3
- package/dist/esm/elements/SwcAppMixin.js +1 -1
- package/dist/esm/elements/SwcAppMixin.js.map +2 -2
- package/dist/esm/elements/SwcAsync.js +70 -58
- package/dist/esm/elements/SwcAsync.js.map +2 -2
- package/dist/esm/elements/SwcChoose.js +67 -61
- package/dist/esm/elements/SwcChoose.js.map +2 -2
- package/dist/esm/elements/SwcIf.js +52 -67
- package/dist/esm/elements/SwcIf.js.map +2 -2
- package/dist/esm/elements/SwcLoop.js +59 -79
- package/dist/esm/elements/SwcLoop.js.map +2 -2
- package/dist/esm/elements/register.js +239 -264
- package/dist/esm/elements/register.js.map +2 -2
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils/Utils.js +7 -13
- package/dist/esm/utils/Utils.js.map +2 -2
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +2623 -2422
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
- package/dist/types/decorators/attribute.d.ts.map +1 -1
- package/dist/types/decorators/elementDefine.d.ts.map +1 -1
- package/dist/types/elements/register.d.ts.map +1 -1
- package/dist/types/types.d.ts +8 -1
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils/Utils.d.ts.map +1 -1
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +2623 -2422
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
- package/package.json +1 -1
- package/src/decorators/applyStyle.ts +1 -1
- package/src/decorators/attribute.ts +35 -30
- package/src/decorators/elementDefine.ts +26 -7
- package/src/elements/SwcAppMixin.ts +1 -1
- package/src/elements/SwcAsync.ts +75 -69
- package/src/elements/SwcChoose.ts +67 -80
- package/src/elements/SwcIf.ts +51 -76
- package/src/elements/SwcLoop.ts +56 -87
- package/src/elements/register.ts +235 -307
- package/src/types.ts +6 -1
- package/src/utils/Utils.ts +11 -17
package/src/elements/SwcIf.ts
CHANGED
|
@@ -1,101 +1,79 @@
|
|
|
1
1
|
import { changedAttributeHost } from '../decorators/changedAttributeHost';
|
|
2
2
|
import { SwcUtils } from '../utils/Utils';
|
|
3
|
-
import { FunctionUtils } from '@dooboostore/core';
|
|
3
|
+
import { FunctionUtils, ActionExpression } from '@dooboostore/core';
|
|
4
|
+
import { ConvertUtils } from '@dooboostore/core-web';
|
|
5
|
+
import { SwcIfInterface } from '../types';
|
|
6
|
+
import { attributeHost } from '../decorators';
|
|
7
|
+
|
|
8
|
+
class SwcIf extends HTMLTemplateElement implements SwcIfInterface {
|
|
9
|
+
@attributeHost('value')
|
|
10
|
+
_value: any;
|
|
11
|
+
|
|
12
|
+
@attributeHost('replace-wrap')
|
|
13
|
+
_replaceWrap: string | null;
|
|
4
14
|
|
|
5
|
-
class SwcIf extends HTMLTemplateElement {
|
|
6
|
-
private _value = false;
|
|
7
15
|
private _nodes: Node[] = [];
|
|
8
16
|
|
|
9
17
|
get value(): boolean {
|
|
10
18
|
return this._value;
|
|
11
19
|
}
|
|
20
|
+
|
|
12
21
|
set value(nv: any) {
|
|
13
|
-
this._value =
|
|
14
|
-
this.
|
|
22
|
+
// this._value = nv;
|
|
23
|
+
this.refresh(nv);
|
|
15
24
|
}
|
|
16
25
|
|
|
17
|
-
private
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
26
|
+
private replaceExpressions(html: string, groupArgs: any, context: any, wrap?: string | null): string {
|
|
27
|
+
const config = wrap ? { wrapExpression: wrap } : undefined;
|
|
28
|
+
const ae = new ActionExpression(html, config);
|
|
29
|
+
const filterOptions = wrap ? { type: 'replace' as const, wrap } : 'replace';
|
|
30
|
+
const win = this.ownerDocument?.defaultView || window;
|
|
31
|
+
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
for (const expr of ae.getExpressions(filterOptions)) {
|
|
34
|
+
try {
|
|
35
|
+
const value = FunctionUtils.executeReturn({
|
|
36
|
+
script: ConvertUtils.decodeHtmlEntity(expr.script, win.document),
|
|
37
|
+
context,
|
|
38
|
+
args: groupArgs
|
|
39
|
+
});
|
|
40
|
+
ae.replace(expr, String(value));
|
|
41
|
+
} catch (e) {
|
|
42
|
+
console.error(`[SWC] Failed to execute ${expr.original}:`, e);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return ae.getUnprocessedTemplate();
|
|
21
46
|
}
|
|
22
47
|
|
|
23
48
|
@changedAttributeHost('value')
|
|
24
|
-
private
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
this.value = false;
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
49
|
+
private setValue(valueAttr?: string | null) {
|
|
50
|
+
this.refresh();
|
|
51
|
+
}
|
|
30
52
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const win = this.ownerDocument?.defaultView || window;
|
|
35
|
-
const result = FunctionUtils.executeReturn({
|
|
36
|
-
script,
|
|
37
|
-
context: this,
|
|
38
|
-
args: SwcUtils.getHelperAndHostSet(win, this)
|
|
39
|
-
});
|
|
40
|
-
this.value = result;
|
|
41
|
-
} else {
|
|
42
|
-
// 일반 문자열 값
|
|
43
|
-
this.value = Boolean(valueAttr);
|
|
44
|
-
}
|
|
53
|
+
@changedAttributeHost('replace-wrap')
|
|
54
|
+
private setReplaceWrap(replaceWrapAttr?: string | null) {
|
|
55
|
+
this.refresh();
|
|
45
56
|
}
|
|
46
57
|
|
|
47
|
-
|
|
58
|
+
refresh(value = this._value) {
|
|
48
59
|
this.cleanup();
|
|
49
60
|
const portal = this.parentElement;
|
|
50
|
-
if (!portal) return;
|
|
61
|
+
if (!portal || !value) return;
|
|
51
62
|
|
|
52
63
|
const win = this.ownerDocument?.defaultView || window;
|
|
53
64
|
const helperSet = SwcUtils.getHelperAndHostSet(win, this);
|
|
54
65
|
|
|
55
|
-
let
|
|
56
|
-
|
|
57
|
-
targetTpl = this;
|
|
58
|
-
} else {
|
|
59
|
-
targetTpl = this.content.querySelector('template[is="swc-default"]') as HTMLTemplateElement;
|
|
60
|
-
}
|
|
66
|
+
let htmlString = this.innerHTML;
|
|
67
|
+
const groupArgs = { ...helperSet, $value: value };
|
|
61
68
|
|
|
62
|
-
|
|
63
|
-
const clone = targetTpl.content.cloneNode(true) as DocumentFragment;
|
|
64
|
-
// If it's the host template, remove sub-templates from clone
|
|
65
|
-
if (targetTpl === this) {
|
|
66
|
-
clone.querySelectorAll('template[is^="swc-"]').forEach(t => t.remove());
|
|
67
|
-
}
|
|
69
|
+
htmlString = this.replaceExpressions(htmlString, groupArgs, this, this._replaceWrap);
|
|
68
70
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
// if (node instanceof HTMLElement) (node as any).__swc_host = this; // 제거: 부모 체인 유지
|
|
76
|
-
this._executeCloneCallback('on-clone-node', { ...groupArgs, $node: node, $nodeIndex: nodeIdx, $isElement: node.nodeType === 1 });
|
|
77
|
-
|
|
78
|
-
// Attribute {{ }} 치환 - SwcChoose처럼 동적 치환
|
|
79
|
-
if (node instanceof HTMLElement) {
|
|
80
|
-
Array.from(node.attributes).forEach(attr => {
|
|
81
|
-
const value = attr.value || '';
|
|
82
|
-
if (value.startsWith('{{') && value.endsWith('}}')) {
|
|
83
|
-
const script = value.slice(2, -2).trim();
|
|
84
|
-
const result = FunctionUtils.executeReturn({
|
|
85
|
-
script,
|
|
86
|
-
context: node,
|
|
87
|
-
args: { ...groupArgs, $value: this._value }
|
|
88
|
-
});
|
|
89
|
-
node.setAttribute(attr.name, String(result));
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
this._executeCloneCallback('on-clone-nodes', groupArgs);
|
|
96
|
-
|
|
97
|
-
portal.insertBefore(clone, this.nextSibling);
|
|
98
|
-
}
|
|
71
|
+
const result = this.ownerDocument?.createElement('template') || document.createElement('template');
|
|
72
|
+
result.innerHTML = htmlString;
|
|
73
|
+
const processedFragment = result.content;
|
|
74
|
+
|
|
75
|
+
this._nodes = Array.from(processedFragment.childNodes);
|
|
76
|
+
portal.insertBefore(processedFragment, this.nextSibling);
|
|
99
77
|
}
|
|
100
78
|
|
|
101
79
|
private cleanup() {
|
|
@@ -103,9 +81,6 @@ class SwcIf extends HTMLTemplateElement {
|
|
|
103
81
|
this._nodes = [];
|
|
104
82
|
}
|
|
105
83
|
|
|
106
|
-
connectedCallback() {
|
|
107
|
-
this.refreshValue();
|
|
108
|
-
}
|
|
109
84
|
disconnectedCallback() {
|
|
110
85
|
this.cleanup();
|
|
111
86
|
}
|
package/src/elements/SwcLoop.ts
CHANGED
|
@@ -1,59 +1,61 @@
|
|
|
1
1
|
import { changedAttributeHost } from '../decorators/changedAttributeHost';
|
|
2
2
|
import { SwcUtils } from '../utils/Utils';
|
|
3
|
-
import { FunctionUtils } from '@dooboostore/core';
|
|
3
|
+
import { FunctionUtils, ActionExpression } from '@dooboostore/core';
|
|
4
|
+
import { ConvertUtils } from '@dooboostore/core-web';
|
|
5
|
+
import { attributeHost } from '../decorators';
|
|
4
6
|
|
|
5
7
|
class SwcLoop extends HTMLTemplateElement {
|
|
6
|
-
|
|
8
|
+
@attributeHost('value')
|
|
9
|
+
_value: any[];
|
|
10
|
+
|
|
11
|
+
@attributeHost('replace-wrap')
|
|
12
|
+
_replaceWrap: string | null;
|
|
13
|
+
|
|
7
14
|
private _nodeGroups: Node[][] = [];
|
|
8
15
|
|
|
9
16
|
get value(): any[] {
|
|
10
17
|
return this._value;
|
|
11
18
|
}
|
|
12
19
|
set value(nv: any[]) {
|
|
13
|
-
this._value = Array.isArray(nv) ? [...nv] : [];
|
|
14
|
-
this.
|
|
20
|
+
// this._value = Array.isArray(nv) ? [...nv] : [];
|
|
21
|
+
this.refresh(nv);
|
|
15
22
|
}
|
|
16
23
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const script = this.getAttribute(attr);
|
|
21
|
-
if (!script) return;
|
|
22
|
-
FunctionUtils.execute({ script, context: this, args });
|
|
24
|
+
@changedAttributeHost('value')
|
|
25
|
+
private setValue() {
|
|
26
|
+
this.refresh();
|
|
23
27
|
}
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
this.
|
|
29
|
+
@changedAttributeHost('replace-wrap')
|
|
30
|
+
private setReplaceWrap() {
|
|
31
|
+
this.refresh();
|
|
28
32
|
}
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
this.value = [];
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
// Parse {{ }} braces
|
|
38
|
-
if (script.startsWith('{{') && script.endsWith('}}')) {
|
|
39
|
-
script = script.slice(2, -2).trim();
|
|
40
|
-
}
|
|
34
|
+
private replaceExpressions(html: string, groupArgs: any, context: any, wrap?: string | null): string {
|
|
35
|
+
const config = wrap ? { wrapExpression: wrap } : undefined;
|
|
36
|
+
const ae = new ActionExpression(html, config);
|
|
37
|
+
const filterOptions = wrap ? { type: 'replace' as const, wrap } : 'replace';
|
|
41
38
|
const win = this.ownerDocument?.defaultView || window;
|
|
42
|
-
const res = FunctionUtils.executeReturn({
|
|
43
|
-
script,
|
|
44
|
-
context: this,
|
|
45
|
-
args: SwcUtils.getHelperAndHostSet(win, this)
|
|
46
|
-
});
|
|
47
39
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
40
|
+
// @ts-ignore
|
|
41
|
+
for (const expr of ae.getExpressions(filterOptions)) {
|
|
42
|
+
try {
|
|
43
|
+
const value = FunctionUtils.executeReturn({
|
|
44
|
+
script: ConvertUtils.decodeHtmlEntity(expr.script, win.document),
|
|
45
|
+
context,
|
|
46
|
+
args: groupArgs
|
|
47
|
+
});
|
|
48
|
+
ae.replace(expr, String(value));
|
|
49
|
+
} catch (e) {
|
|
50
|
+
console.error(`[SWC] Failed to execute ${expr.original}:`, e);
|
|
51
|
+
}
|
|
52
52
|
}
|
|
53
|
+
return ae.getUnprocessedTemplate();
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
|
|
56
|
-
this.
|
|
56
|
+
refresh(value = this._value) {
|
|
57
|
+
this.cleanup();
|
|
58
|
+
if (value?.length<=0) return;
|
|
57
59
|
const portal = this.parentElement;
|
|
58
60
|
if (!portal) return;
|
|
59
61
|
|
|
@@ -61,63 +63,30 @@ class SwcLoop extends HTMLTemplateElement {
|
|
|
61
63
|
const helperSet = SwcUtils.getHelperAndHostSet(win, this);
|
|
62
64
|
const fragment = win.document.createDocumentFragment();
|
|
63
65
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const clone = defaultTpl.content.cloneNode(true);
|
|
68
|
-
const nodes = Array.from(clone.childNodes);
|
|
69
|
-
this._nodeGroups.push(nodes);
|
|
70
|
-
fragment.appendChild(clone);
|
|
71
|
-
}
|
|
72
|
-
} else {
|
|
73
|
-
this._value.forEach((item, index) => {
|
|
74
|
-
const clone = this.content.cloneNode(true) as DocumentFragment;
|
|
75
|
-
// Filter out sub-templates
|
|
76
|
-
const subTemplates = clone.querySelectorAll('template[is^="swc-"]');
|
|
77
|
-
subTemplates.forEach(t => t.remove());
|
|
78
|
-
|
|
79
|
-
const nodes = Array.from(clone.childNodes);
|
|
80
|
-
const elements = nodes.filter(n => n.nodeType === 1) as HTMLElement[];
|
|
81
|
-
|
|
82
|
-
const groupArgs = { ...helperSet, $item: item, $index: index, $value: this._value, $nodes: nodes, $elements: elements, $firstElement: elements[0] };
|
|
83
|
-
|
|
84
|
-
nodes.forEach((node, nodeIdx) => {
|
|
85
|
-
this._executeCloneCallback('on-clone-node', { ...groupArgs, $node: node, $nodeIndex: nodeIdx, $isElement: node.nodeType === 1 });
|
|
86
|
-
|
|
87
|
-
// Attribute {{ }} 치환 - SwcChoose처럼 동적 치환
|
|
88
|
-
if (node instanceof HTMLElement) {
|
|
89
|
-
Array.from(node.attributes).forEach(attr => {
|
|
90
|
-
const value = attr.value || '';
|
|
91
|
-
if (value.startsWith('{{') && value.endsWith('}}')) {
|
|
92
|
-
const script = value.slice(2, -2).trim();
|
|
93
|
-
const result = FunctionUtils.executeReturn({
|
|
94
|
-
script,
|
|
95
|
-
context: node,
|
|
96
|
-
args: groupArgs
|
|
97
|
-
});
|
|
98
|
-
node.setAttribute(attr.name, String(result));
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
});
|
|
66
|
+
value.forEach((item, index) => {
|
|
67
|
+
let htmlString = this.innerHTML;
|
|
68
|
+
const groupArgs = { ...helperSet, $item: item, $index: index, $value: this._value };
|
|
103
69
|
|
|
104
|
-
|
|
105
|
-
this._nodeGroups.push(nodes);
|
|
106
|
-
fragment.appendChild(clone);
|
|
107
|
-
});
|
|
108
|
-
}
|
|
70
|
+
htmlString = this.replaceExpressions(htmlString, groupArgs, this, this._replaceWrap);
|
|
109
71
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
72
|
+
const temp = this.ownerDocument?.createElement('template') || document.createElement('template');
|
|
73
|
+
temp.innerHTML = htmlString;
|
|
74
|
+
|
|
75
|
+
const content = temp.content;
|
|
76
|
+
const nodes = Array.from(content.childNodes);
|
|
77
|
+
this._nodeGroups.push(nodes);
|
|
78
|
+
fragment.appendChild(content);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
portal.insertBefore(fragment, this.nextSibling);
|
|
115
82
|
}
|
|
116
83
|
|
|
117
|
-
|
|
118
|
-
this.
|
|
84
|
+
private cleanup() {
|
|
85
|
+
this._nodeGroups.forEach(nodes => nodes.forEach(n => n.parentElement?.removeChild(n)));
|
|
86
|
+
this._nodeGroups = [];
|
|
119
87
|
}
|
|
88
|
+
|
|
120
89
|
disconnectedCallback() {
|
|
121
|
-
this.
|
|
90
|
+
this.cleanup();
|
|
122
91
|
}
|
|
123
92
|
}
|