@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.
Files changed (42) hide show
  1. package/README.md +2 -0
  2. package/dist/abydon.full.mjs +422 -359
  3. package/dist/attribute/index.d.mts +7 -0
  4. package/dist/attribute/index.mjs +47 -0
  5. package/dist/{node/attribute → attribute}/value.d.mts +2 -2
  6. package/dist/attribute/value.mjs +53 -0
  7. package/dist/constants.d.mts +8 -8
  8. package/dist/constants.mjs +15 -15
  9. package/dist/fragment.d.mts +30 -13
  10. package/dist/fragment.mjs +40 -18
  11. package/dist/fragments.d.mts +3 -7
  12. package/dist/fragments.mjs +6 -12
  13. package/dist/helpers/dom.d.mts +2 -3
  14. package/dist/helpers/dom.mjs +2 -4
  15. package/dist/helpers/index.d.mts +16 -2
  16. package/dist/helpers/index.mjs +17 -1
  17. package/dist/index.d.mts +35 -7
  18. package/dist/index.mjs +39 -8
  19. package/dist/models.d.mts +6 -4
  20. package/dist/node/event.mjs +9 -4
  21. package/dist/node/index.mjs +26 -32
  22. package/dist/node/value.mjs +70 -56
  23. package/dist/parse.mjs +6 -4
  24. package/package.json +6 -5
  25. package/src/attribute/index.ts +89 -0
  26. package/src/attribute/value.ts +107 -0
  27. package/src/constants.ts +19 -19
  28. package/src/fragment.ts +43 -21
  29. package/src/fragments.ts +8 -15
  30. package/src/helpers/dom.ts +3 -5
  31. package/src/helpers/index.ts +25 -1
  32. package/src/index.ts +47 -7
  33. package/src/models.ts +6 -4
  34. package/src/node/event.ts +12 -5
  35. package/src/node/index.ts +36 -56
  36. package/src/node/value.ts +121 -104
  37. package/src/parse.ts +15 -5
  38. package/dist/node/attribute/index.d.mts +0 -6
  39. package/dist/node/attribute/index.mjs +0 -51
  40. package/dist/node/attribute/value.mjs +0 -65
  41. package/src/node/attribute/index.ts +0 -100
  42. 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: Set<unknown>;
15
- previous: Set<unknown>;
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?.find(fragment => fragment.identifier === template.identifier) ?? template,
131
+ items.fragments.find(fragment => fragment.identifier === template.identifier) ?? template,
71
132
  );
72
133
 
73
- const comparison = compareArrays(items.fragments ?? [], items.templates);
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
- items.fragments?.filter(fragment => !identifiers.next.has(fragment.identifier)) ?? [];
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 removeFragments(fragments: Fragment[] | undefined): void {
95
- if (fragments != null) {
96
- const {length} = fragments;
156
+ function removeArray(item: FragmentItem, comment: Comment): Partial<FragmentItem> {
157
+ const fragments = (item.fragments ?? []).slice();
97
158
 
98
- for (let index = 0; index < length; index += 1) {
99
- fragments[index].remove();
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 replaceText(item: FragmentItem, comment: Comment, isNullable: boolean): void {
105
- let to: ChildNode[];
168
+ function removeFragmentsItems(fragments: Fragment[]): void {
169
+ const {length} = fragments;
106
170
 
107
- if (isNullable) {
108
- to = [comment];
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
- let templates = value.filter(item => isFragment(item) && item.identifier != null) as Fragment[];
181
+ const {next, previous, template} = getArrayData(item, value);
128
182
 
129
- const next = templates.map(fragment => fragment.identifier) as unknown[];
130
- const previous = item.fragments?.map(fragment => fragment.identifier) ?? [];
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
- if (new Set(next).size !== templates.length) {
133
- templates = [];
134
- }
135
-
136
- const noTemplates = templates.length === 0;
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
- : templates.flatMap(template => template.get()),
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: new Set(next),
154
- previous: new Set(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
- if (item.nodes == null) {
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 result = setArray(item, comment, value);
243
+ const {fragments, nodes} = setArray(item, comment, value);
206
244
 
207
- item.fragments = typeof result === 'boolean' ? undefined : result?.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 valueIsFragment = isFragment(value);
250
+ const fragments = (item.fragments ?? []).slice();
222
251
 
223
- item.fragments = valueIsFragment ? [value] : undefined;
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
- function setText(item: FragmentItem, comment: Comment, value: unknown): ChildNode[] | undefined {
233
- const isNullable = isNullableOrWhitespace(value);
260
+ item.fragments = valueIsFragment ? [value] : undefined;
234
261
 
235
- if (item.text != null) {
236
- item.text.textContent = isNullable ? '' : getString(value);
237
- }
262
+ removeFragmentsItems(fragments);
263
+ }
238
264
 
239
- let result = false;
265
+ function setText(item: FragmentItem, comment: Comment, value?: unknown): ChildNode[] {
266
+ const valueIsNullable = isNullableOrWhitespace(value);
240
267
 
241
- if (item.nodes != null) {
242
- replaceText(item, comment, isNullable);
268
+ item.text ??= new Text();
243
269
 
244
- result = !isNullable;
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
- result = true;
253
- }
272
+ const result = valueIsNullable ? [comment] : [item.text];
254
273
 
255
- removeFragments(item.fragments);
274
+ replaceNodes(item.nodes ?? [comment], result);
256
275
 
257
- if (result) {
258
- return item.text == null ? [] : [item.text];
259
- }
276
+ return result;
260
277
  }
package/src/parse.ts CHANGED
@@ -1,9 +1,17 @@
1
- import {isNullableOrWhitespace} from '@oscarpalmer/atoms/is';
2
- import {EXPRESSION_ABYDON_ATTRIBUTE_FULL} from './constants';
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
- return isNullableOrWhitespace(expression) ? prefix : `${prefix}${expression}`;
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 = [] as never;
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 `_${name}="@abydon.${index}@"`;
57
+ return `abydon-${name}="abydon.${index}"`;
48
58
  }
49
59
 
50
60
  function transformExpression(prefix: string, index: number): string {
@@ -1,6 +0,0 @@
1
- import { FragmentData } from "../../models.mjs";
2
-
3
- //#region src/node/attribute/index.d.ts
4
- declare function mapAttributes(data: FragmentData, element: HTMLElement | SVGElement): void;
5
- //#endregion
6
- export { mapAttributes };
@@ -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
- }