@oscarpalmer/abydon 0.12.0 → 0.14.0
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/abydon.full.js +1153 -0
- package/dist/constants.js +10 -0
- package/dist/fragment.js +60 -0
- package/dist/helpers/dom.js +28 -0
- package/dist/helpers/index.js +11 -0
- package/dist/index.js +6 -911
- package/dist/node/attribute/index.js +39 -0
- package/dist/node/attribute/value.js +56 -0
- package/dist/node/event.js +30 -0
- package/dist/node/index.js +52 -0
- package/dist/node/value.js +108 -0
- package/dist/parse.js +18 -0
- package/package.json +38 -27
- package/src/constants.ts +20 -0
- package/src/fragment.ts +63 -36
- package/src/helpers/dom.ts +5 -4
- package/src/helpers/index.ts +0 -9
- package/src/index.ts +13 -3
- package/src/models.ts +14 -11
- package/src/node/attribute/index.ts +28 -22
- package/src/node/attribute/value.ts +38 -42
- package/src/node/event.ts +12 -13
- package/src/node/index.ts +7 -7
- package/src/node/value.ts +169 -122
- package/src/{html.ts → parse.ts} +15 -17
- package/types/constants.d.ts +9 -0
- package/types/fragment.d.ts +3 -5
- package/types/helpers/index.d.ts +0 -3
- package/types/index.d.ts +4 -2
- package/types/models.d.ts +7 -9
- package/types/node/attribute/index.d.ts +2 -1
- package/types/node/attribute/value.d.ts +2 -1
- package/types/node/event.d.ts +1 -1
- package/types/node/value.d.ts +2 -2
- package/types/parse.d.ts +2 -0
- package/dist/fragment.mjs +0 -75
- package/dist/helpers/dom.mjs +0 -44
- package/dist/helpers/index.mjs +0 -25
- package/dist/html.mjs +0 -36
- package/dist/index.mjs +0 -6
- package/dist/node/attribute/index.mjs +0 -40
- package/dist/node/attribute/value.mjs +0 -89
- package/dist/node/event.mjs +0 -38
- package/dist/node/index.mjs +0 -60
- package/dist/node/value.mjs +0 -123
- package/types/html.d.ts +0 -4
- package/types/index.d.cts +0 -26
- /package/dist/{models.mjs → models.js} +0 -0
package/src/node/value.ts
CHANGED
|
@@ -1,12 +1,100 @@
|
|
|
1
1
|
import {isNullableOrWhitespace} from '@oscarpalmer/atoms/is';
|
|
2
|
-
import type {Key} from '@oscarpalmer/atoms/models';
|
|
3
2
|
import {getString} from '@oscarpalmer/atoms/string';
|
|
4
|
-
import
|
|
3
|
+
import type {Reactive} from '@oscarpalmer/mora';
|
|
4
|
+
import {isChildNode} from '@oscarpalmer/toretto/is';
|
|
5
5
|
import type {Fragment} from '../fragment';
|
|
6
|
-
import {compareArrays,
|
|
6
|
+
import {compareArrays, isFragment} from '../helpers';
|
|
7
7
|
import {createNodes, replaceNodes} from '../helpers/dom';
|
|
8
8
|
import type {FragmentData, FragmentItem} from '../models';
|
|
9
9
|
|
|
10
|
+
//
|
|
11
|
+
|
|
12
|
+
type Identifiers = {
|
|
13
|
+
next: unknown[];
|
|
14
|
+
previous: (unknown | undefined)[];
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type BaseItems = {
|
|
18
|
+
fragments: Fragment[];
|
|
19
|
+
templates: Fragment[];
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type ExtendedItems = {
|
|
23
|
+
next: Fragment[];
|
|
24
|
+
} & BaseItems;
|
|
25
|
+
|
|
26
|
+
//
|
|
27
|
+
|
|
28
|
+
function addToArray(
|
|
29
|
+
identifiers: Identifiers,
|
|
30
|
+
items: ExtendedItems,
|
|
31
|
+
nodes: ChildNode[],
|
|
32
|
+
added: boolean,
|
|
33
|
+
): void {
|
|
34
|
+
let position = nodes[0];
|
|
35
|
+
|
|
36
|
+
const before =
|
|
37
|
+
added && !identifiers.previous.includes(items.templates[0].identifier);
|
|
38
|
+
|
|
39
|
+
const next = items.next.flatMap(fragment =>
|
|
40
|
+
fragment.get().flatMap(node => ({
|
|
41
|
+
identifier: fragment.identifier,
|
|
42
|
+
value: node,
|
|
43
|
+
})),
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const {length} = next;
|
|
47
|
+
|
|
48
|
+
for (let index = 0; index < length; index += 1) {
|
|
49
|
+
const node = next[index];
|
|
50
|
+
|
|
51
|
+
if (!(added && identifiers.previous.includes(node.identifier))) {
|
|
52
|
+
if (index === 0 && before) {
|
|
53
|
+
position.before(node.value);
|
|
54
|
+
} else {
|
|
55
|
+
position.after(node.value);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
position = node.value;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function handleArray(
|
|
64
|
+
identifiers: Identifiers,
|
|
65
|
+
items: BaseItems,
|
|
66
|
+
nodes: ChildNode[],
|
|
67
|
+
): Partial<FragmentItem> {
|
|
68
|
+
const next = items.templates.map(
|
|
69
|
+
template =>
|
|
70
|
+
items.fragments?.find(
|
|
71
|
+
fragment => fragment.identifier === template.identifier,
|
|
72
|
+
) ?? template,
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const comparison = compareArrays(items.fragments ?? [], items.templates);
|
|
76
|
+
|
|
77
|
+
if (comparison !== 'removed') {
|
|
78
|
+
addToArray(identifiers, {...items, next}, nodes, comparison === 'added');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const toRemove =
|
|
82
|
+
items.fragments?.filter(
|
|
83
|
+
fragment => !identifiers.next.includes(fragment.identifier),
|
|
84
|
+
) ?? [];
|
|
85
|
+
|
|
86
|
+
const {length} = toRemove;
|
|
87
|
+
|
|
88
|
+
for (let index = 0; index < length; index += 1) {
|
|
89
|
+
toRemove[index].remove();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
fragments: next,
|
|
94
|
+
nodes: next.flatMap(fragment => fragment.get()),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
10
98
|
function removeFragments(fragments: Fragment[] | undefined): void {
|
|
11
99
|
if (fragments != null) {
|
|
12
100
|
const {length} = fragments;
|
|
@@ -18,15 +106,13 @@ function removeFragments(fragments: Fragment[] | undefined): void {
|
|
|
18
106
|
}
|
|
19
107
|
|
|
20
108
|
function setArray(
|
|
21
|
-
|
|
22
|
-
nodes: ChildNode[] | undefined,
|
|
109
|
+
item: FragmentItem,
|
|
23
110
|
comment: Comment,
|
|
24
|
-
text: Text,
|
|
25
111
|
value: unknown[],
|
|
26
112
|
): Partial<FragmentItem> | boolean {
|
|
27
113
|
if (value.length === 0) {
|
|
28
114
|
return {
|
|
29
|
-
nodes: setText(
|
|
115
|
+
nodes: setText(item, comment, value),
|
|
30
116
|
};
|
|
31
117
|
}
|
|
32
118
|
|
|
@@ -34,10 +120,10 @@ function setArray(
|
|
|
34
120
|
item => isFragment(item) && item.identifier != null,
|
|
35
121
|
) as Fragment[];
|
|
36
122
|
|
|
37
|
-
const
|
|
38
|
-
const
|
|
123
|
+
const next = templates.map(fragment => fragment.identifier) as unknown[];
|
|
124
|
+
const previous = item.fragments?.map(fragment => fragment.identifier) ?? [];
|
|
39
125
|
|
|
40
|
-
if (new Set(
|
|
126
|
+
if (new Set(next).size !== templates.length) {
|
|
41
127
|
templates = [];
|
|
42
128
|
}
|
|
43
129
|
|
|
@@ -45,16 +131,14 @@ function setArray(
|
|
|
45
131
|
|
|
46
132
|
if (
|
|
47
133
|
noTemplates ||
|
|
48
|
-
nodes == null ||
|
|
49
|
-
|
|
134
|
+
item.nodes == null ||
|
|
135
|
+
previous.some(identifier => identifier == null)
|
|
50
136
|
) {
|
|
51
137
|
return {
|
|
52
138
|
fragments: noTemplates ? undefined : templates,
|
|
53
139
|
nodes: setNodes(
|
|
54
|
-
|
|
55
|
-
nodes,
|
|
140
|
+
item,
|
|
56
141
|
comment,
|
|
57
|
-
text,
|
|
58
142
|
noTemplates
|
|
59
143
|
? value.flatMap(item => createNodes(item))
|
|
60
144
|
: templates.flatMap(template => template.get()),
|
|
@@ -62,84 +146,35 @@ function setArray(
|
|
|
62
146
|
};
|
|
63
147
|
}
|
|
64
148
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
149
|
+
return handleArray(
|
|
150
|
+
{
|
|
151
|
+
next,
|
|
152
|
+
previous,
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
templates,
|
|
156
|
+
fragments: item.fragments ?? [],
|
|
157
|
+
},
|
|
158
|
+
item.nodes,
|
|
70
159
|
);
|
|
71
|
-
|
|
72
|
-
const comparison = compareArrays(fragments ?? [], templates);
|
|
73
|
-
|
|
74
|
-
if (comparison !== 'removed') {
|
|
75
|
-
let position = nodes[0];
|
|
76
|
-
|
|
77
|
-
const before =
|
|
78
|
-
comparison === 'added' &&
|
|
79
|
-
!oldIdentifiers.includes(templates[0].identifier);
|
|
80
|
-
|
|
81
|
-
const items = next.flatMap(fragment =>
|
|
82
|
-
fragment.get().flatMap(node => ({
|
|
83
|
-
identifier: fragment.identifier,
|
|
84
|
-
value: node,
|
|
85
|
-
})),
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
const {length} = items;
|
|
89
|
-
|
|
90
|
-
for (let index = 0; index < length; index += 1) {
|
|
91
|
-
const item = items[index];
|
|
92
|
-
|
|
93
|
-
if (
|
|
94
|
-
comparison === 'dissimilar' ||
|
|
95
|
-
!oldIdentifiers.includes(item.identifier)
|
|
96
|
-
) {
|
|
97
|
-
if (index === 0 && before) {
|
|
98
|
-
position.before(item.value);
|
|
99
|
-
} else {
|
|
100
|
-
position.after(item.value);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
position = item.value;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const toRemove =
|
|
109
|
-
fragments?.filter(
|
|
110
|
-
fragment => !identifiers.includes(fragment.identifier as Key),
|
|
111
|
-
) ?? [];
|
|
112
|
-
|
|
113
|
-
const {length} = toRemove;
|
|
114
|
-
|
|
115
|
-
for (let index = 0; index < length; index += 1) {
|
|
116
|
-
toRemove[index].remove();
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return {
|
|
120
|
-
fragments: next,
|
|
121
|
-
nodes: next.flatMap(fragment => fragment.get()),
|
|
122
|
-
};
|
|
123
160
|
}
|
|
124
161
|
|
|
125
162
|
function setNodes(
|
|
126
|
-
|
|
127
|
-
nodes: ChildNode[] | undefined,
|
|
163
|
+
item: FragmentItem,
|
|
128
164
|
comment: Comment,
|
|
129
|
-
text: Text,
|
|
130
165
|
next: ChildNode[],
|
|
131
166
|
): ChildNode[] {
|
|
132
|
-
if (nodes == null) {
|
|
167
|
+
if (item.nodes == null) {
|
|
133
168
|
if (comment.parentNode != null) {
|
|
134
169
|
replaceNodes([comment], next);
|
|
135
|
-
} else if (text
|
|
136
|
-
replaceNodes([text], next);
|
|
170
|
+
} else if (item.text?.parentNode != null) {
|
|
171
|
+
replaceNodes([item.text], next);
|
|
137
172
|
}
|
|
138
173
|
} else {
|
|
139
|
-
replaceNodes(nodes, next);
|
|
174
|
+
replaceNodes(item.nodes, next);
|
|
140
175
|
}
|
|
141
176
|
|
|
142
|
-
removeFragments(fragments);
|
|
177
|
+
removeFragments(item.fragments);
|
|
143
178
|
|
|
144
179
|
return next;
|
|
145
180
|
}
|
|
@@ -147,75 +182,87 @@ function setNodes(
|
|
|
147
182
|
export function setReactiveValue(
|
|
148
183
|
data: FragmentData,
|
|
149
184
|
comment: Comment,
|
|
150
|
-
reactive: Reactive
|
|
185
|
+
reactive: Reactive<unknown>,
|
|
151
186
|
): void {
|
|
152
|
-
|
|
153
|
-
const text = new Text();
|
|
187
|
+
let item = data.items.find(item => item.nodes?.includes(comment));
|
|
154
188
|
|
|
155
|
-
|
|
156
|
-
let nodes: ChildNode[] | undefined;
|
|
189
|
+
item ??= {};
|
|
157
190
|
|
|
158
|
-
|
|
159
|
-
effect(() => {
|
|
160
|
-
const value = reactive.get();
|
|
191
|
+
item.text = new Text();
|
|
161
192
|
|
|
193
|
+
data.mora.subscribers.add(
|
|
194
|
+
reactive.subscribe(value => {
|
|
162
195
|
if (Array.isArray(value)) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
fragments = typeof result === 'boolean' ? undefined : result?.fragments;
|
|
166
|
-
|
|
167
|
-
nodes =
|
|
168
|
-
typeof result === 'boolean'
|
|
169
|
-
? result
|
|
170
|
-
? [text]
|
|
171
|
-
: undefined
|
|
172
|
-
: result?.nodes;
|
|
196
|
+
setReactiveValueForArray(item, comment, value);
|
|
173
197
|
} else {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
fragments = valueIsFragment ? [value] : undefined;
|
|
177
|
-
|
|
178
|
-
if (valueIsFragment || isChildNode(value)) {
|
|
179
|
-
nodes = setNodes(fragments, nodes, comment, text, createNodes(value));
|
|
180
|
-
} else {
|
|
181
|
-
nodes = setText(fragments, nodes, comment, text, value);
|
|
182
|
-
}
|
|
198
|
+
setReactiveValueForSingle(item, comment, value);
|
|
183
199
|
}
|
|
184
200
|
|
|
185
|
-
|
|
186
|
-
item.fragments = fragments;
|
|
187
|
-
item.nodes = [...(nodes ?? [comment])];
|
|
188
|
-
}
|
|
201
|
+
item.nodes = [...(item.nodes ?? [comment])];
|
|
189
202
|
}),
|
|
190
203
|
);
|
|
191
204
|
}
|
|
192
205
|
|
|
206
|
+
function setReactiveValueForArray(
|
|
207
|
+
item: FragmentItem,
|
|
208
|
+
comment: Comment,
|
|
209
|
+
value: unknown[],
|
|
210
|
+
): void {
|
|
211
|
+
const result = setArray(item, comment, value);
|
|
212
|
+
|
|
213
|
+
item.fragments = typeof result === 'boolean' ? undefined : result?.fragments;
|
|
214
|
+
|
|
215
|
+
if (typeof result === 'boolean') {
|
|
216
|
+
item.nodes = result ? item.text == null ? [] : [item.text] : undefined;
|
|
217
|
+
} else {
|
|
218
|
+
item.nodes = result?.nodes;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function setReactiveValueForSingle(
|
|
223
|
+
item: FragmentItem,
|
|
224
|
+
comment: Comment,
|
|
225
|
+
value: unknown,
|
|
226
|
+
): void {
|
|
227
|
+
const valueIsFragment = isFragment(value);
|
|
228
|
+
|
|
229
|
+
item.fragments = valueIsFragment ? [value] : undefined;
|
|
230
|
+
|
|
231
|
+
if (valueIsFragment || isChildNode(value)) {
|
|
232
|
+
item.nodes = setNodes(item, comment, createNodes(value));
|
|
233
|
+
} else {
|
|
234
|
+
item.nodes = setText(item, comment, value);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
193
238
|
function setText(
|
|
194
|
-
|
|
195
|
-
nodes: ChildNode[] | undefined,
|
|
239
|
+
item: FragmentItem,
|
|
196
240
|
comment: Comment,
|
|
197
|
-
text: Text,
|
|
198
241
|
value: unknown,
|
|
199
242
|
): ChildNode[] | undefined {
|
|
200
243
|
const isNullable = isNullableOrWhitespace(value);
|
|
201
244
|
|
|
202
|
-
text
|
|
245
|
+
if (item.text != null) {
|
|
246
|
+
item.text.textContent = isNullable ? '' : getString(value);
|
|
247
|
+
}
|
|
203
248
|
|
|
204
249
|
let result = false;
|
|
205
250
|
|
|
206
|
-
if (nodes != null) {
|
|
207
|
-
replaceNodes(nodes,
|
|
251
|
+
if (item.nodes != null) {
|
|
252
|
+
replaceNodes(item.nodes, isNullable ? [comment] : item.text == null ? [] : [item.text]);
|
|
208
253
|
|
|
209
254
|
result = !isNullable;
|
|
210
255
|
} else if (isNullable && comment.parentNode == null) {
|
|
211
|
-
text
|
|
212
|
-
} else if (!isNullable && text
|
|
213
|
-
|
|
256
|
+
item.text?.replaceWith(comment);
|
|
257
|
+
} else if (!isNullable && item?.text?.parentNode == null) {
|
|
258
|
+
if (item.text != null) {
|
|
259
|
+
comment.replaceWith(item.text);
|
|
260
|
+
}
|
|
214
261
|
|
|
215
262
|
result = true;
|
|
216
263
|
}
|
|
217
264
|
|
|
218
|
-
removeFragments(fragments);
|
|
265
|
+
removeFragments(item.fragments);
|
|
219
266
|
|
|
220
|
-
return result ? [text] : undefined;
|
|
267
|
+
return result ? item.text == null ? [] : [item.text] : undefined;
|
|
221
268
|
}
|
package/src/{html.ts → parse.ts}
RENAMED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {isNullableOrWhitespace} from '@oscarpalmer/atoms/is';
|
|
2
|
-
import {Fragment} from './fragment';
|
|
3
2
|
import type {FragmentData} from './models';
|
|
4
3
|
|
|
5
4
|
function handleExpression(
|
|
@@ -7,10 +6,6 @@ function handleExpression(
|
|
|
7
6
|
prefix: string,
|
|
8
7
|
expression: unknown,
|
|
9
8
|
): string {
|
|
10
|
-
if (isNullableOrWhitespace(expression)) {
|
|
11
|
-
return prefix;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
9
|
if (Array.isArray(expression)) {
|
|
15
10
|
const {length} = expression;
|
|
16
11
|
|
|
@@ -23,34 +18,37 @@ function handleExpression(
|
|
|
23
18
|
return `${prefix}${expressions}`;
|
|
24
19
|
}
|
|
25
20
|
|
|
26
|
-
if (
|
|
21
|
+
if (
|
|
22
|
+
typeof expression === 'function' ||
|
|
23
|
+
(typeof expression === 'object' && expression != null)
|
|
24
|
+
) {
|
|
27
25
|
const index = data.values.push(expression) - 1;
|
|
28
26
|
|
|
29
27
|
return `${prefix}<!--abydon.${index}-->`;
|
|
30
28
|
}
|
|
31
29
|
|
|
32
|
-
return `${prefix}${expression}`;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function html(
|
|
36
|
-
strings: TemplateStringsArray,
|
|
37
|
-
...values: unknown[]
|
|
38
|
-
): Fragment {
|
|
39
|
-
return new Fragment(strings, values);
|
|
30
|
+
return isNullableOrWhitespace(expression) ? prefix : `${prefix}${expression}`;
|
|
40
31
|
}
|
|
41
32
|
|
|
42
33
|
export function parse(data: FragmentData): string {
|
|
34
|
+
if (data.template != null) {
|
|
35
|
+
return data.template;
|
|
36
|
+
}
|
|
37
|
+
|
|
43
38
|
const {length} = data.strings;
|
|
44
39
|
|
|
45
|
-
|
|
40
|
+
data.template = '';
|
|
46
41
|
|
|
47
42
|
for (let index = 0; index < length; index += 1) {
|
|
48
|
-
template += handleExpression(
|
|
43
|
+
data.template += handleExpression(
|
|
49
44
|
data,
|
|
50
45
|
data.strings[index],
|
|
51
46
|
data.expressions[index],
|
|
52
47
|
);
|
|
53
48
|
}
|
|
54
49
|
|
|
55
|
-
|
|
50
|
+
data.expressions = [];
|
|
51
|
+
data.strings = [] as never;
|
|
52
|
+
|
|
53
|
+
return data.template;
|
|
56
54
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const ABORT_CONTROLLERS: WeakMap<HTMLOrSVGElement, AbortController>;
|
|
2
|
+
export declare const ATTRIBUTE_CLASS_PREFIX_LENGTH = 6;
|
|
3
|
+
export declare const EXPRESSION_ATTRIBUTE_CLASS: RegExp;
|
|
4
|
+
export declare const EXPRESSION_ATTRIBUTE_STYLE_FULL: RegExp;
|
|
5
|
+
export declare const EXPRESSION_ATTRIBUTE_STYLE_PREFIX: RegExp;
|
|
6
|
+
export declare const EXPRESSION_COMMENT_FULL: RegExp;
|
|
7
|
+
export declare const EXPRESSION_COMMENT_CONTENT: RegExp;
|
|
8
|
+
export declare const EXPRESSION_EVENT_NAME: RegExp;
|
|
9
|
+
export declare const REASON_EVENT_REMOVED = "Event removed as element was removed from document by Abydon";
|
package/types/fragment.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import type { Key } from '@oscarpalmer/atoms/models';
|
|
2
1
|
export declare class Fragment {
|
|
3
|
-
private
|
|
4
|
-
|
|
5
|
-
get identifier(): Key | undefined;
|
|
2
|
+
#private;
|
|
3
|
+
get identifier(): unknown;
|
|
6
4
|
constructor(strings: TemplateStringsArray, expressions: unknown[]);
|
|
7
5
|
/**
|
|
8
6
|
* Appends the fragment to the given element
|
|
@@ -12,7 +10,7 @@ export declare class Fragment {
|
|
|
12
10
|
* Gets a list of the fragment's nodes
|
|
13
11
|
*/
|
|
14
12
|
get(): ChildNode[];
|
|
15
|
-
identify(identifier:
|
|
13
|
+
identify(identifier: unknown): Fragment;
|
|
16
14
|
/**
|
|
17
15
|
* Removes the fragment from the DOM
|
|
18
16
|
*/
|
package/types/helpers/index.d.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
1
|
import type { Fragment } from '../fragment';
|
|
2
|
-
import type { HTMLOrSVGElement } from '../models';
|
|
3
2
|
export declare function compareArrays(first: unknown[], second: unknown[]): 'added' | 'dissimilar' | 'removed';
|
|
4
|
-
export declare function isChildNode(value: unknown): value is ChildNode;
|
|
5
3
|
export declare function isFragment(value: unknown): value is Fragment;
|
|
6
|
-
export declare function isHTMLOrSVGElement(value: unknown): value is HTMLOrSVGElement;
|
package/types/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
import '@oscarpalmer/
|
|
1
|
+
import '@oscarpalmer/mora';
|
|
2
|
+
import { Fragment } from './fragment';
|
|
3
|
+
export declare function html(strings: TemplateStringsArray, ...values: unknown[]): Fragment;
|
|
4
|
+
export * from '@oscarpalmer/mora';
|
|
2
5
|
export type { Fragment } from './fragment';
|
|
3
|
-
export { html } from './html';
|
package/types/models.d.ts
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { Effect, Reactive } from '@oscarpalmer/sentinel';
|
|
1
|
+
import type { Reactive } from '@oscarpalmer/mora';
|
|
3
2
|
import type { Fragment } from './fragment';
|
|
4
3
|
export type FragmentData = {
|
|
5
4
|
expressions: unknown[];
|
|
6
|
-
identifier?:
|
|
5
|
+
identifier?: unknown;
|
|
7
6
|
items: FragmentItem[];
|
|
8
|
-
|
|
7
|
+
mora: MoraData;
|
|
9
8
|
strings: TemplateStringsArray;
|
|
10
9
|
values: unknown[];
|
|
11
10
|
};
|
|
12
|
-
type FragmentDataSentinel = {
|
|
13
|
-
effects: Set<Effect>;
|
|
14
|
-
values: Set<Reactive>;
|
|
15
|
-
};
|
|
16
11
|
export type FragmentItem = {
|
|
17
12
|
fragments?: Fragment[];
|
|
18
13
|
nodes: ChildNode[];
|
|
19
14
|
};
|
|
20
|
-
|
|
15
|
+
type MoraData = {
|
|
16
|
+
subscribers: Set<() => void>;
|
|
17
|
+
values: Set<Reactive<unknown>>;
|
|
18
|
+
};
|
|
21
19
|
export {};
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { HTMLOrSVGElement } from '@oscarpalmer/toretto/models';
|
|
2
|
+
import type { FragmentData } from '../../models';
|
|
2
3
|
export declare function mapAttributes(data: FragmentData, element: HTMLOrSVGElement): void;
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { HTMLOrSVGElement } from '@oscarpalmer/toretto/models';
|
|
2
|
+
import type { FragmentData } from '../../models';
|
|
2
3
|
export declare function setAttribute(data: FragmentData, element: HTMLOrSVGElement, name: string, value: unknown): void;
|
package/types/node/event.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { HTMLOrSVGElement } from '
|
|
1
|
+
import type { HTMLOrSVGElement } from '@oscarpalmer/toretto/models';
|
|
2
2
|
export declare function mapEvent(element: HTMLOrSVGElement, name: string, value: unknown): void;
|
|
3
3
|
export declare function removeEvents(element: HTMLOrSVGElement): void;
|
package/types/node/value.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Reactive } from '@oscarpalmer/mora';
|
|
2
2
|
import type { FragmentData } from '../models';
|
|
3
|
-
export declare function setReactiveValue(data: FragmentData, comment: Comment, reactive: Reactive): void;
|
|
3
|
+
export declare function setReactiveValue(data: FragmentData, comment: Comment, reactive: Reactive<unknown>): void;
|
package/types/parse.d.ts
ADDED
package/dist/fragment.mjs
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
// src/fragment.ts
|
|
2
|
-
import {html as html2} from "@oscarpalmer/toretto/html";
|
|
3
|
-
import {parse} from "./html";
|
|
4
|
-
import {mapNodes} from "./node";
|
|
5
|
-
import {removeNodes} from "./helpers/dom";
|
|
6
|
-
function removeFragment(data) {
|
|
7
|
-
removeSentinels(data);
|
|
8
|
-
const { length } = data.items;
|
|
9
|
-
for (let index = 0;index < length; index += 1) {
|
|
10
|
-
const { fragments, nodes } = data.items[index];
|
|
11
|
-
const { length: length2 } = fragments ?? [];
|
|
12
|
-
for (let index2 = 0;index2 < length2; index2 += 1) {
|
|
13
|
-
fragments?.[index2]?.remove();
|
|
14
|
-
}
|
|
15
|
-
removeNodes(nodes);
|
|
16
|
-
}
|
|
17
|
-
data.items.splice(0, length);
|
|
18
|
-
}
|
|
19
|
-
function removeSentinels(data) {
|
|
20
|
-
const sentinels = [...data.sentinel.effects, ...data.sentinel.values];
|
|
21
|
-
const { length } = sentinels;
|
|
22
|
-
for (let index = 0;index < length; index += 1) {
|
|
23
|
-
sentinels[index].stop();
|
|
24
|
-
}
|
|
25
|
-
data.sentinel.effects.clear();
|
|
26
|
-
data.sentinel.values.clear();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
class Fragment {
|
|
30
|
-
$fragment = true;
|
|
31
|
-
data;
|
|
32
|
-
get identifier() {
|
|
33
|
-
return this.data.identifier;
|
|
34
|
-
}
|
|
35
|
-
constructor(strings, expressions) {
|
|
36
|
-
this.data = {
|
|
37
|
-
expressions,
|
|
38
|
-
strings,
|
|
39
|
-
items: [],
|
|
40
|
-
sentinel: {
|
|
41
|
-
effects: new Set,
|
|
42
|
-
values: new Set
|
|
43
|
-
},
|
|
44
|
-
values: []
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
appendTo(element) {
|
|
48
|
-
element.append(...this.get());
|
|
49
|
-
}
|
|
50
|
-
get() {
|
|
51
|
-
if (this.data.items.length === 0) {
|
|
52
|
-
const parsed = parse(this.data);
|
|
53
|
-
const templated = html2(parsed, {
|
|
54
|
-
sanitiseBooleanAttributes: false
|
|
55
|
-
});
|
|
56
|
-
this.data.items.splice(0, this.data.items.length, ...templated.map((node2) => ({
|
|
57
|
-
nodes: [node2]
|
|
58
|
-
})));
|
|
59
|
-
mapNodes(this.data, this.data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes));
|
|
60
|
-
}
|
|
61
|
-
return [
|
|
62
|
-
...this.data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes)
|
|
63
|
-
];
|
|
64
|
-
}
|
|
65
|
-
identify(identifier) {
|
|
66
|
-
this.data.identifier = identifier;
|
|
67
|
-
return this;
|
|
68
|
-
}
|
|
69
|
-
remove() {
|
|
70
|
-
removeFragment(this.data);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
export {
|
|
74
|
-
Fragment
|
|
75
|
-
};
|
package/dist/helpers/dom.mjs
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
// src/helpers/dom.ts
|
|
2
|
-
import {getString} from "@oscarpalmer/atoms/string";
|
|
3
|
-
import {isChildNode, isFragment, isHTMLOrSVGElement} from "./index";
|
|
4
|
-
import {removeEvents} from "../node/event";
|
|
5
|
-
function createNodes(value) {
|
|
6
|
-
if (isFragment(value)) {
|
|
7
|
-
return value.get();
|
|
8
|
-
}
|
|
9
|
-
if (isChildNode(value)) {
|
|
10
|
-
return [value];
|
|
11
|
-
}
|
|
12
|
-
return [new Text(getString(value))];
|
|
13
|
-
}
|
|
14
|
-
function removeNodes(nodes) {
|
|
15
|
-
sanitiseNodes(nodes);
|
|
16
|
-
const { length } = nodes;
|
|
17
|
-
for (let index = 0;index < length; index += 1) {
|
|
18
|
-
nodes[index].remove();
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
function replaceNodes(from, to) {
|
|
22
|
-
from[0]?.replaceWith(...to);
|
|
23
|
-
const { length } = from;
|
|
24
|
-
for (let index = 1;index < length; index += 1) {
|
|
25
|
-
from[index].remove();
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
function sanitiseNodes(nodes) {
|
|
29
|
-
const { length } = nodes;
|
|
30
|
-
for (let index = 0;index < length; index += 1) {
|
|
31
|
-
const node = nodes[index];
|
|
32
|
-
if (isHTMLOrSVGElement(node)) {
|
|
33
|
-
removeEvents(node);
|
|
34
|
-
}
|
|
35
|
-
if (node.hasChildNodes()) {
|
|
36
|
-
sanitiseNodes([...node.childNodes]);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
export {
|
|
41
|
-
replaceNodes,
|
|
42
|
-
removeNodes,
|
|
43
|
-
createNodes
|
|
44
|
-
};
|