@oscarpalmer/abydon 0.21.0 → 0.23.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/README.md +2 -0
- package/dist/abydon.full.mjs +422 -359
- package/dist/attribute/index.d.mts +7 -0
- package/dist/attribute/index.mjs +47 -0
- package/dist/{node/attribute → attribute}/value.d.mts +2 -2
- package/dist/attribute/value.mjs +53 -0
- package/dist/constants.d.mts +8 -8
- package/dist/constants.mjs +15 -15
- package/dist/fragment.d.mts +30 -13
- package/dist/fragment.mjs +40 -18
- package/dist/fragments.d.mts +3 -7
- package/dist/fragments.mjs +6 -12
- package/dist/helpers/dom.d.mts +2 -3
- package/dist/helpers/dom.mjs +2 -4
- package/dist/helpers/index.d.mts +16 -2
- package/dist/helpers/index.mjs +17 -1
- package/dist/index.d.mts +35 -7
- package/dist/index.mjs +39 -8
- package/dist/models.d.mts +6 -4
- package/dist/node/event.mjs +9 -4
- package/dist/node/index.mjs +26 -32
- package/dist/node/value.mjs +70 -56
- package/dist/parse.mjs +6 -4
- package/package.json +6 -5
- package/src/attribute/index.ts +89 -0
- package/src/attribute/value.ts +107 -0
- package/src/constants.ts +19 -19
- package/src/fragment.ts +43 -21
- package/src/fragments.ts +8 -15
- package/src/helpers/dom.ts +3 -5
- package/src/helpers/index.ts +25 -1
- package/src/index.ts +47 -7
- package/src/models.ts +6 -4
- package/src/node/event.ts +12 -5
- package/src/node/index.ts +36 -56
- package/src/node/value.ts +121 -104
- package/src/parse.ts +15 -5
- package/dist/node/attribute/index.d.mts +0 -6
- package/dist/node/attribute/index.mjs +0 -51
- package/dist/node/attribute/value.mjs +0 -65
- package/src/node/attribute/index.ts +0 -100
- package/src/node/attribute/value.ts +0 -158
package/src/node/value.ts
CHANGED
|
@@ -10,9 +10,30 @@ import type {FragmentData, FragmentItem} from '../models';
|
|
|
10
10
|
|
|
11
11
|
//
|
|
12
12
|
|
|
13
|
+
type ArrayData = {
|
|
14
|
+
next: ArrayDataIdentifiers;
|
|
15
|
+
previous: ArrayDataIdentifiers;
|
|
16
|
+
template: ArrayDataTemplate;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type ArrayDataIdentifiers = {
|
|
20
|
+
array: unknown[];
|
|
21
|
+
set: Set<unknown>;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type ArrayDataTemplate = {
|
|
25
|
+
empty: boolean;
|
|
26
|
+
items: Fragment[];
|
|
27
|
+
};
|
|
28
|
+
|
|
13
29
|
type Identifiers = {
|
|
14
|
-
next:
|
|
15
|
-
previous:
|
|
30
|
+
next: IdentifiersValues;
|
|
31
|
+
previous: IdentifiersValues;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
type IdentifiersValues = {
|
|
35
|
+
array: unknown[];
|
|
36
|
+
set: Set<unknown>;
|
|
16
37
|
};
|
|
17
38
|
|
|
18
39
|
type BaseItems = {
|
|
@@ -34,7 +55,7 @@ function addToArray(
|
|
|
34
55
|
): void {
|
|
35
56
|
let position = nodes[0];
|
|
36
57
|
|
|
37
|
-
const before = added && !identifiers.previous.has(items.templates[0].identifier);
|
|
58
|
+
const before = added && !identifiers.previous.set.has(items.templates[0].identifier);
|
|
38
59
|
|
|
39
60
|
const next = items.next.flatMap(fragment =>
|
|
40
61
|
fragment.get().flatMap(node => ({
|
|
@@ -48,7 +69,7 @@ function addToArray(
|
|
|
48
69
|
for (let index = 0; index < length; index += 1) {
|
|
49
70
|
const node = next[index];
|
|
50
71
|
|
|
51
|
-
if (!(added && identifiers.previous.has(node.identifier))) {
|
|
72
|
+
if (!(added && identifiers.previous.set.has(node.identifier))) {
|
|
52
73
|
if (index === 0 && before) {
|
|
53
74
|
position.before(node.value);
|
|
54
75
|
} else {
|
|
@@ -60,6 +81,46 @@ function addToArray(
|
|
|
60
81
|
}
|
|
61
82
|
}
|
|
62
83
|
|
|
84
|
+
function getArrayData(item: FragmentItem, values: unknown[]): ArrayData {
|
|
85
|
+
const {length} = values;
|
|
86
|
+
|
|
87
|
+
const next: unknown[] = [];
|
|
88
|
+
|
|
89
|
+
let templates: Fragment[] = [];
|
|
90
|
+
|
|
91
|
+
for (let index = 0; index < length; index += 1) {
|
|
92
|
+
const value = values[index];
|
|
93
|
+
|
|
94
|
+
if (isFragment(value) && value.identifier != null) {
|
|
95
|
+
next.push(value.identifier);
|
|
96
|
+
templates.push(value);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const previous = item.fragments?.map(fragment => fragment.identifier) ?? [];
|
|
101
|
+
|
|
102
|
+
const nextSet = new Set(next);
|
|
103
|
+
|
|
104
|
+
if (nextSet.size !== templates.length) {
|
|
105
|
+
templates = [];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
next: {
|
|
110
|
+
array: next,
|
|
111
|
+
set: nextSet,
|
|
112
|
+
},
|
|
113
|
+
previous: {
|
|
114
|
+
array: previous,
|
|
115
|
+
set: new Set(previous),
|
|
116
|
+
},
|
|
117
|
+
template: {
|
|
118
|
+
empty: templates.length === 0,
|
|
119
|
+
items: templates,
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
63
124
|
function handleArray(
|
|
64
125
|
identifiers: Identifiers,
|
|
65
126
|
items: BaseItems,
|
|
@@ -67,17 +128,18 @@ function handleArray(
|
|
|
67
128
|
): Partial<FragmentItem> {
|
|
68
129
|
const next = items.templates.map(
|
|
69
130
|
template =>
|
|
70
|
-
items.fragments
|
|
131
|
+
items.fragments.find(fragment => fragment.identifier === template.identifier) ?? template,
|
|
71
132
|
);
|
|
72
133
|
|
|
73
|
-
const comparison = compareArrays(
|
|
134
|
+
const comparison = compareArrays(identifiers.previous.array, identifiers.next.array);
|
|
74
135
|
|
|
75
136
|
if (comparison !== ARRAY_COMPARISON_REMOVED) {
|
|
76
137
|
addToArray(identifiers, {...items, next}, nodes, comparison === ARRAY_COMPARISON_ADDED);
|
|
77
138
|
}
|
|
78
139
|
|
|
79
|
-
const toRemove =
|
|
80
|
-
|
|
140
|
+
const toRemove = items.fragments.filter(
|
|
141
|
+
fragment => !identifiers.next.set.has(fragment.identifier),
|
|
142
|
+
);
|
|
81
143
|
|
|
82
144
|
const {length} = toRemove;
|
|
83
145
|
|
|
@@ -91,90 +153,70 @@ function handleArray(
|
|
|
91
153
|
};
|
|
92
154
|
}
|
|
93
155
|
|
|
94
|
-
function
|
|
95
|
-
|
|
96
|
-
const {length} = fragments;
|
|
156
|
+
function removeArray(item: FragmentItem, comment: Comment): Partial<FragmentItem> {
|
|
157
|
+
const fragments = (item.fragments ?? []).slice();
|
|
97
158
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
159
|
+
const result = {
|
|
160
|
+
nodes: setText(item, comment),
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
removeFragmentsItems(fragments);
|
|
164
|
+
|
|
165
|
+
return result;
|
|
102
166
|
}
|
|
103
167
|
|
|
104
|
-
function
|
|
105
|
-
|
|
168
|
+
function removeFragmentsItems(fragments: Fragment[]): void {
|
|
169
|
+
const {length} = fragments;
|
|
106
170
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
} else {
|
|
110
|
-
to = item.text == null ? [] : [item.text];
|
|
171
|
+
for (let index = 0; index < length; index += 1) {
|
|
172
|
+
fragments[index].remove();
|
|
111
173
|
}
|
|
112
|
-
|
|
113
|
-
replaceNodes(item.nodes ?? [], to);
|
|
114
174
|
}
|
|
115
175
|
|
|
116
|
-
function setArray(
|
|
117
|
-
item: FragmentItem,
|
|
118
|
-
comment: Comment,
|
|
119
|
-
value: unknown[],
|
|
120
|
-
): Partial<FragmentItem> | boolean {
|
|
176
|
+
function setArray(item: FragmentItem, comment: Comment, value: unknown[]): Partial<FragmentItem> {
|
|
121
177
|
if (value.length === 0) {
|
|
122
|
-
return
|
|
123
|
-
nodes: setText(item, comment, value),
|
|
124
|
-
};
|
|
178
|
+
return removeArray(item, comment);
|
|
125
179
|
}
|
|
126
180
|
|
|
127
|
-
|
|
181
|
+
const {next, previous, template} = getArrayData(item, value);
|
|
128
182
|
|
|
129
|
-
|
|
130
|
-
|
|
183
|
+
if (
|
|
184
|
+
template.empty ||
|
|
185
|
+
item.nodes == null ||
|
|
186
|
+
previous.array.some(identifier => identifier == null)
|
|
187
|
+
) {
|
|
188
|
+
const fragments = (item.fragments ?? []).slice();
|
|
131
189
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (noTemplates || item.nodes == null || previous.some(identifier => identifier == null)) {
|
|
139
|
-
return {
|
|
140
|
-
fragments: noTemplates ? undefined : templates,
|
|
141
|
-
nodes: setNodes(
|
|
142
|
-
item,
|
|
143
|
-
comment,
|
|
144
|
-
noTemplates
|
|
190
|
+
const result = {
|
|
191
|
+
fragments: template.empty ? undefined : template.items,
|
|
192
|
+
nodes: replaceNodes(
|
|
193
|
+
item.nodes ?? [comment],
|
|
194
|
+
template.empty
|
|
145
195
|
? value.flatMap(item => createNodes(item))
|
|
146
|
-
:
|
|
196
|
+
: template.items.flatMap(template => template.get()),
|
|
147
197
|
),
|
|
148
198
|
};
|
|
199
|
+
|
|
200
|
+
removeFragmentsItems(fragments);
|
|
201
|
+
|
|
202
|
+
return result;
|
|
149
203
|
}
|
|
150
204
|
|
|
151
205
|
return handleArray(
|
|
152
206
|
{
|
|
153
|
-
next
|
|
154
|
-
previous
|
|
207
|
+
next,
|
|
208
|
+
previous,
|
|
155
209
|
},
|
|
156
210
|
{
|
|
157
|
-
templates,
|
|
158
211
|
fragments: item.fragments ?? [],
|
|
212
|
+
templates: template.items,
|
|
159
213
|
},
|
|
160
214
|
item.nodes,
|
|
161
215
|
);
|
|
162
216
|
}
|
|
163
217
|
|
|
164
218
|
function setNodes(item: FragmentItem, comment: Comment, next: ChildNode[]): ChildNode[] {
|
|
165
|
-
|
|
166
|
-
if (comment.parentNode != null) {
|
|
167
|
-
replaceNodes([comment], next);
|
|
168
|
-
} else if (item.text?.parentNode != null) {
|
|
169
|
-
replaceNodes([item.text], next);
|
|
170
|
-
}
|
|
171
|
-
} else {
|
|
172
|
-
replaceNodes(item.nodes, next);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
removeFragments(item.fragments);
|
|
176
|
-
|
|
177
|
-
return next;
|
|
219
|
+
return replaceNodes(item.nodes ?? [comment], next);
|
|
178
220
|
}
|
|
179
221
|
|
|
180
222
|
export function setReactiveValue(
|
|
@@ -186,8 +228,6 @@ export function setReactiveValue(
|
|
|
186
228
|
|
|
187
229
|
item ??= {};
|
|
188
230
|
|
|
189
|
-
item.text = new Text();
|
|
190
|
-
|
|
191
231
|
data.mora.subscribers.add(
|
|
192
232
|
reactive.subscribe(value => {
|
|
193
233
|
if (Array.isArray(value)) {
|
|
@@ -195,66 +235,43 @@ export function setReactiveValue(
|
|
|
195
235
|
} else {
|
|
196
236
|
setReactiveValueForSingle(item, comment, value);
|
|
197
237
|
}
|
|
198
|
-
|
|
199
|
-
item.nodes = [...(item.nodes ?? [comment])];
|
|
200
238
|
}),
|
|
201
239
|
);
|
|
202
240
|
}
|
|
203
241
|
|
|
204
242
|
function setReactiveValueForArray(item: FragmentItem, comment: Comment, value: unknown[]): void {
|
|
205
|
-
const
|
|
243
|
+
const {fragments, nodes} = setArray(item, comment, value);
|
|
206
244
|
|
|
207
|
-
item.fragments =
|
|
208
|
-
|
|
209
|
-
if (typeof result === 'boolean') {
|
|
210
|
-
if (result) {
|
|
211
|
-
item.nodes = item.text == null ? [] : [item.text];
|
|
212
|
-
} else {
|
|
213
|
-
item.nodes = undefined;
|
|
214
|
-
}
|
|
215
|
-
} else {
|
|
216
|
-
item.nodes = result?.nodes;
|
|
217
|
-
}
|
|
245
|
+
item.fragments = fragments;
|
|
246
|
+
item.nodes = nodes;
|
|
218
247
|
}
|
|
219
248
|
|
|
220
249
|
function setReactiveValueForSingle(item: FragmentItem, comment: Comment, value: unknown): void {
|
|
221
|
-
const
|
|
250
|
+
const fragments = (item.fragments ?? []).slice();
|
|
222
251
|
|
|
223
|
-
|
|
252
|
+
const valueIsFragment = isFragment(value);
|
|
224
253
|
|
|
225
254
|
if (valueIsFragment || isChildNode(value)) {
|
|
226
255
|
item.nodes = setNodes(item, comment, createNodes(value));
|
|
227
256
|
} else {
|
|
228
257
|
item.nodes = setText(item, comment, value);
|
|
229
258
|
}
|
|
230
|
-
}
|
|
231
259
|
|
|
232
|
-
|
|
233
|
-
const isNullable = isNullableOrWhitespace(value);
|
|
260
|
+
item.fragments = valueIsFragment ? [value] : undefined;
|
|
234
261
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
262
|
+
removeFragmentsItems(fragments);
|
|
263
|
+
}
|
|
238
264
|
|
|
239
|
-
|
|
265
|
+
function setText(item: FragmentItem, comment: Comment, value?: unknown): ChildNode[] {
|
|
266
|
+
const valueIsNullable = isNullableOrWhitespace(value);
|
|
240
267
|
|
|
241
|
-
|
|
242
|
-
replaceText(item, comment, isNullable);
|
|
268
|
+
item.text ??= new Text();
|
|
243
269
|
|
|
244
|
-
|
|
245
|
-
} else if (isNullable && comment.parentNode == null) {
|
|
246
|
-
item.text?.replaceWith(comment);
|
|
247
|
-
} else if (!isNullable && item?.text?.parentNode == null) {
|
|
248
|
-
if (item.text != null) {
|
|
249
|
-
comment.replaceWith(item.text);
|
|
250
|
-
}
|
|
270
|
+
item.text.textContent = valueIsNullable ? '' : getString(value);
|
|
251
271
|
|
|
252
|
-
|
|
253
|
-
}
|
|
272
|
+
const result = valueIsNullable ? [comment] : [item.text];
|
|
254
273
|
|
|
255
|
-
|
|
274
|
+
replaceNodes(item.nodes ?? [comment], result);
|
|
256
275
|
|
|
257
|
-
|
|
258
|
-
return item.text == null ? [] : [item.text];
|
|
259
|
-
}
|
|
276
|
+
return result;
|
|
260
277
|
}
|
package/src/parse.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {getString} from '@oscarpalmer/atoms/string';
|
|
2
|
+
import {
|
|
3
|
+
EXPRESSION_ABYDON_ATTRIBUTE_FULL,
|
|
4
|
+
EXPRESSION_EVENT_ATTRIBUTE,
|
|
5
|
+
WHITESPACE,
|
|
6
|
+
} from './constants';
|
|
3
7
|
import type {FragmentData} from './models';
|
|
4
8
|
|
|
5
9
|
function handleExpression(data: FragmentData, prefix: string, expression: unknown): string {
|
|
6
10
|
if (Array.isArray(expression)) {
|
|
11
|
+
if (EXPRESSION_EVENT_ATTRIBUTE.test(prefix.split(WHITESPACE).at(-1)!)) {
|
|
12
|
+
return transformExpression(prefix, data.values.push(expression) - 1);
|
|
13
|
+
}
|
|
14
|
+
|
|
7
15
|
const {length} = expression;
|
|
8
16
|
|
|
9
17
|
let expressions = '';
|
|
@@ -19,7 +27,9 @@ function handleExpression(data: FragmentData, prefix: string, expression: unknow
|
|
|
19
27
|
return transformExpression(prefix, data.values.push(expression) - 1);
|
|
20
28
|
}
|
|
21
29
|
|
|
22
|
-
|
|
30
|
+
const asString = getString(expression);
|
|
31
|
+
|
|
32
|
+
return asString.trim().length === 0 ? prefix : `${prefix}${asString}`;
|
|
23
33
|
}
|
|
24
34
|
|
|
25
35
|
export function parse(data: FragmentData): string {
|
|
@@ -38,13 +48,13 @@ export function parse(data: FragmentData): string {
|
|
|
38
48
|
data.template = data.template.replaceAll(EXPRESSION_ABYDON_ATTRIBUTE_FULL, transformAttribute);
|
|
39
49
|
|
|
40
50
|
data.expressions = [];
|
|
41
|
-
data.strings = []
|
|
51
|
+
data.strings = [];
|
|
42
52
|
|
|
43
53
|
return data.template;
|
|
44
54
|
}
|
|
45
55
|
|
|
46
56
|
function transformAttribute(_: string, name: string, index: string): string {
|
|
47
|
-
return `
|
|
57
|
+
return `abydon-${name}="abydon.${index}"`;
|
|
48
58
|
}
|
|
49
59
|
|
|
50
60
|
function transformExpression(prefix: string, index: number): string {
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { EXPRESSION_ABYDON_ATTRIBUTE_PREFIX, EXPRESSION_ABYDON_CONTENT, EXPRESSION_EVENT_PREFIX, EXPRESSION_PERIOD, PROPERTY_CHECKED, PROPERTY_VALUE } from "../../constants.mjs";
|
|
2
|
-
import { isInputElement } from "../../helpers/dom.mjs";
|
|
3
|
-
import { mapEvent } from "../event.mjs";
|
|
4
|
-
import { setAttribute } from "./value.mjs";
|
|
5
|
-
import { parse } from "@oscarpalmer/atoms/string";
|
|
6
|
-
import { computed, isReactive, isSignal } from "@oscarpalmer/mora";
|
|
7
|
-
//#region src/node/attribute/index.ts
|
|
8
|
-
function getValue(data, original) {
|
|
9
|
-
const matches = EXPRESSION_ABYDON_CONTENT.exec(original ?? "");
|
|
10
|
-
return matches == null ? original : data.values[+matches[1]];
|
|
11
|
-
}
|
|
12
|
-
function mapAttributes(data, element) {
|
|
13
|
-
const attributes = [...element.attributes];
|
|
14
|
-
const { length } = attributes;
|
|
15
|
-
for (let index = 0; index < length; index += 1) {
|
|
16
|
-
const { name, value } = attributes[index];
|
|
17
|
-
const actualName = name.replace(EXPRESSION_ABYDON_ATTRIBUTE_PREFIX, "");
|
|
18
|
-
const actualValue = getValue(data, value);
|
|
19
|
-
if (actualName !== name) element.removeAttribute(name);
|
|
20
|
-
switch (true) {
|
|
21
|
-
case EXPRESSION_EVENT_PREFIX.test(actualName):
|
|
22
|
-
mapEvent(element, actualName, actualValue);
|
|
23
|
-
break;
|
|
24
|
-
case EXPRESSION_PERIOD.test(actualName):
|
|
25
|
-
case typeof actualValue === "function":
|
|
26
|
-
case isReactive(actualValue):
|
|
27
|
-
mapValue(data, element, actualName, actualValue);
|
|
28
|
-
break;
|
|
29
|
-
default: break;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function mapValue(data, element, name, value) {
|
|
34
|
-
if (typeof value === "function") setComputedAttribute(data, element, name, value);
|
|
35
|
-
else setAttribute(data, element, name, value);
|
|
36
|
-
if (!isInputElement(element) || !isSignal(value)) return;
|
|
37
|
-
let property;
|
|
38
|
-
if (name === "checked" && element.type === "checkbox") property = PROPERTY_CHECKED;
|
|
39
|
-
else if (name === "value") property = PROPERTY_VALUE;
|
|
40
|
-
if (property != null) mapEvent(element, "@on", () => {
|
|
41
|
-
const next = element[property];
|
|
42
|
-
value.set(parse(String(next)) ?? next);
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
function setComputedAttribute(data, element, name, callback) {
|
|
46
|
-
const value = computed(callback);
|
|
47
|
-
data.mora.values.add(value);
|
|
48
|
-
setAttribute(data, element, name, value);
|
|
49
|
-
}
|
|
50
|
-
//#endregion
|
|
51
|
-
export { mapAttributes };
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { EVENT_CHANGE, EVENT_INPUT, EXPRESSION_ATTRIBUTE_CLASS, EXPRESSION_ATTRIBUTE_STYLE_FULL, EXPRESSION_ATTRIBUTE_STYLE_PREFIX, PROPERTY_CHECKED, PROPERTY_VALUE } from "../../constants.mjs";
|
|
2
|
-
import { isReactive } from "@oscarpalmer/mora";
|
|
3
|
-
import { isBooleanAttribute, setAttribute as setAttribute$1 } from "@oscarpalmer/toretto/attribute";
|
|
4
|
-
//#region src/node/attribute/value.ts
|
|
5
|
-
function getCallback(element, name) {
|
|
6
|
-
if (isBooleanAttribute(name) && name in element) return name === "checked" ? updateChecked : updateProperty;
|
|
7
|
-
return name === "value" ? updateValue : setAttribute$1;
|
|
8
|
-
}
|
|
9
|
-
function setAttribute(data, element, name, value) {
|
|
10
|
-
switch (true) {
|
|
11
|
-
case EXPRESSION_ATTRIBUTE_CLASS.test(name):
|
|
12
|
-
setClasses(data, element, name, value);
|
|
13
|
-
return;
|
|
14
|
-
case EXPRESSION_ATTRIBUTE_STYLE_PREFIX.test(name):
|
|
15
|
-
setStyle(data, element, name, value);
|
|
16
|
-
return;
|
|
17
|
-
default:
|
|
18
|
-
setValue(data, element, name, value);
|
|
19
|
-
break;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
function setClasses(data, element, name, value) {
|
|
23
|
-
function update(value) {
|
|
24
|
-
if (value === true) element.classList.add(...classes);
|
|
25
|
-
else element.classList.remove(...classes);
|
|
26
|
-
}
|
|
27
|
-
const classes = name.slice(6).split(".");
|
|
28
|
-
if (isReactive(value)) data.mora.subscribers.add(value.subscribe(update));
|
|
29
|
-
else update(value);
|
|
30
|
-
}
|
|
31
|
-
function setStyle(data, element, name, value) {
|
|
32
|
-
const [, property, unit] = EXPRESSION_ATTRIBUTE_STYLE_FULL.exec(name) ?? [];
|
|
33
|
-
if (property == null) return;
|
|
34
|
-
function update(value) {
|
|
35
|
-
if (value == null || value === false || value === true && unit == null) element.style.removeProperty(property);
|
|
36
|
-
else element.style.setProperty(property, value === true ? unit : String(value));
|
|
37
|
-
}
|
|
38
|
-
if (isReactive(value)) data.mora.subscribers.add(value.subscribe(update));
|
|
39
|
-
else update(value);
|
|
40
|
-
}
|
|
41
|
-
function setValue(data, element, name, value) {
|
|
42
|
-
const callback = getCallback(element, name);
|
|
43
|
-
if (isReactive(value)) data.mora.subscribers.add(value.subscribe((next) => {
|
|
44
|
-
callback(element, name, next);
|
|
45
|
-
}));
|
|
46
|
-
else callback(element, name, value);
|
|
47
|
-
}
|
|
48
|
-
function updateChecked(element, name, value) {
|
|
49
|
-
updateElement(EVENT_CHANGE, PROPERTY_CHECKED, element, name, value, value === true);
|
|
50
|
-
}
|
|
51
|
-
function updateElement(event, property, element, name, value, next) {
|
|
52
|
-
if (!(property in element) || element[property] === next) return;
|
|
53
|
-
setAttribute$1(element, name, value);
|
|
54
|
-
if (element[property] === next) return;
|
|
55
|
-
element[property] = next;
|
|
56
|
-
element.dispatchEvent(new Event(event, { bubbles: true }));
|
|
57
|
-
}
|
|
58
|
-
function updateProperty(element, name, value) {
|
|
59
|
-
setAttribute$1(element, name, value === true);
|
|
60
|
-
}
|
|
61
|
-
function updateValue(element, name, value) {
|
|
62
|
-
updateElement(element instanceof HTMLSelectElement ? EVENT_CHANGE : EVENT_INPUT, PROPERTY_VALUE, element, name, value, String(value));
|
|
63
|
-
}
|
|
64
|
-
//#endregion
|
|
65
|
-
export { setAttribute };
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import type {GenericCallback} from '@oscarpalmer/atoms/models';
|
|
2
|
-
import {parse} from '@oscarpalmer/atoms/string';
|
|
3
|
-
import {computed, isReactive, isSignal} from '@oscarpalmer/mora';
|
|
4
|
-
import {
|
|
5
|
-
EVENT_ON_PREFIXED,
|
|
6
|
-
EXPRESSION_ABYDON_ATTRIBUTE_PREFIX,
|
|
7
|
-
EXPRESSION_ABYDON_CONTENT,
|
|
8
|
-
EXPRESSION_EVENT_PREFIX,
|
|
9
|
-
EXPRESSION_PERIOD,
|
|
10
|
-
INPUT_TYPE_CHECKBOX,
|
|
11
|
-
PROPERTY_CHECKED,
|
|
12
|
-
PROPERTY_VALUE,
|
|
13
|
-
} from '../../constants';
|
|
14
|
-
import {isInputElement} from '../../helpers/dom';
|
|
15
|
-
import type {FragmentData} from '../../models';
|
|
16
|
-
import {mapEvent} from '../event';
|
|
17
|
-
import {setAttribute} from './value';
|
|
18
|
-
|
|
19
|
-
function getValue(data: FragmentData, original: string): unknown {
|
|
20
|
-
const matches = EXPRESSION_ABYDON_CONTENT.exec(original ?? '');
|
|
21
|
-
|
|
22
|
-
return matches == null ? original : data.values[+matches[1]];
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function mapAttributes(data: FragmentData, element: HTMLElement | SVGElement): void {
|
|
26
|
-
const attributes = [...element.attributes];
|
|
27
|
-
const {length} = attributes;
|
|
28
|
-
|
|
29
|
-
for (let index = 0; index < length; index += 1) {
|
|
30
|
-
const {name, value} = attributes[index];
|
|
31
|
-
|
|
32
|
-
const actualName = name.replace(EXPRESSION_ABYDON_ATTRIBUTE_PREFIX, '');
|
|
33
|
-
const actualValue = getValue(data, value) as never;
|
|
34
|
-
|
|
35
|
-
if (actualName !== name) {
|
|
36
|
-
element.removeAttribute(name);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
switch (true) {
|
|
40
|
-
case EXPRESSION_EVENT_PREFIX.test(actualName):
|
|
41
|
-
mapEvent(element, actualName, actualValue);
|
|
42
|
-
break;
|
|
43
|
-
|
|
44
|
-
case EXPRESSION_PERIOD.test(actualName):
|
|
45
|
-
case typeof actualValue === 'function':
|
|
46
|
-
case isReactive(actualValue):
|
|
47
|
-
mapValue(data, element, actualName, actualValue);
|
|
48
|
-
break;
|
|
49
|
-
|
|
50
|
-
default:
|
|
51
|
-
break;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function mapValue(
|
|
57
|
-
data: FragmentData,
|
|
58
|
-
element: HTMLElement | SVGElement,
|
|
59
|
-
name: string,
|
|
60
|
-
value: unknown,
|
|
61
|
-
): void {
|
|
62
|
-
if (typeof value === 'function') {
|
|
63
|
-
setComputedAttribute(data, element, name, value as GenericCallback);
|
|
64
|
-
} else {
|
|
65
|
-
setAttribute(data, element, name, value);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (!isInputElement(element) || !isSignal(value)) {
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
let property: string | undefined;
|
|
73
|
-
|
|
74
|
-
if (name === PROPERTY_CHECKED && element.type === INPUT_TYPE_CHECKBOX) {
|
|
75
|
-
property = PROPERTY_CHECKED;
|
|
76
|
-
} else if (name === PROPERTY_VALUE) {
|
|
77
|
-
property = PROPERTY_VALUE;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (property != null) {
|
|
81
|
-
mapEvent(element, EVENT_ON_PREFIXED, () => {
|
|
82
|
-
const next = element[property as keyof typeof element];
|
|
83
|
-
|
|
84
|
-
value.set(parse(String(next)) ?? next);
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function setComputedAttribute(
|
|
90
|
-
data: FragmentData,
|
|
91
|
-
element: HTMLElement | SVGElement,
|
|
92
|
-
name: string,
|
|
93
|
-
callback: GenericCallback,
|
|
94
|
-
): void {
|
|
95
|
-
const value = computed(callback);
|
|
96
|
-
|
|
97
|
-
data.mora.values.add(value);
|
|
98
|
-
|
|
99
|
-
setAttribute(data, element, name, value);
|
|
100
|
-
}
|