@oscarpalmer/abydon 0.15.0 → 0.17.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.mjs +1443 -0
- package/dist/constants.d.mts +20 -0
- package/dist/constants.mjs +27 -0
- package/dist/fragment-9qTBAvtR.d.mts +82 -0
- package/dist/fragment.d.mts +2 -0
- package/dist/{fragment.js → fragment.mjs} +41 -14
- package/dist/fragments.d.mts +16 -0
- package/dist/{fragments.js → fragments.mjs} +10 -4
- package/dist/helpers/dom.d.mts +6 -0
- package/dist/helpers/{dom.js → dom.mjs} +4 -12
- package/dist/helpers/index.d.mts +9 -0
- package/dist/helpers/index.mjs +23 -0
- package/dist/index.d.mts +21 -0
- package/dist/index.mjs +24 -0
- package/dist/models.d.mts +2 -0
- package/dist/models.mjs +1 -0
- package/dist/node/attribute/index.d.mts +6 -0
- package/dist/node/attribute/index.mjs +41 -0
- package/dist/node/attribute/value.d.mts +6 -0
- package/dist/node/attribute/value.mjs +65 -0
- package/dist/node/event.d.mts +4 -0
- package/dist/node/event.mjs +25 -0
- package/dist/node/index.d.mts +6 -0
- package/dist/node/{index.js → index.mjs} +10 -8
- package/dist/node/value.d.mts +7 -0
- package/dist/node/{value.js → value.mjs} +12 -10
- package/dist/parse.d.mts +6 -0
- package/dist/{parse.js → parse.mjs} +11 -1
- package/package.json +42 -42
- package/src/constants.ts +30 -10
- package/src/fragment.ts +12 -24
- package/src/fragments.ts +3 -5
- package/src/helpers/dom.ts +1 -20
- package/src/helpers/index.ts +18 -15
- package/src/index.ts +14 -10
- package/src/models.ts +10 -1
- package/src/node/attribute/index.ts +22 -21
- package/src/node/attribute/value.ts +47 -37
- package/src/node/event.ts +26 -33
- package/src/node/index.ts +6 -18
- package/src/node/value.ts +15 -46
- package/src/parse.ts +15 -17
- package/dist/abydon.full.js +0 -1274
- package/dist/constants.js +0 -10
- package/dist/helpers/index.js +0 -14
- package/dist/index.js +0 -11
- package/dist/models.js +0 -0
- package/dist/node/attribute/index.js +0 -39
- package/dist/node/attribute/value.js +0 -56
- package/dist/node/event.js +0 -30
- package/types/constants.d.ts +0 -9
- package/types/fragment.d.ts +0 -38
- package/types/fragments.d.ts +0 -13
- package/types/helpers/dom.d.ts +0 -3
- package/types/helpers/index.d.ts +0 -5
- package/types/index.d.ts +0 -9
- package/types/models.d.ts +0 -32
- package/types/node/attribute/index.d.ts +0 -3
- package/types/node/attribute/value.d.ts +0 -3
- package/types/node/event.d.ts +0 -3
- package/types/node/index.d.ts +0 -2
- package/types/node/value.d.ts +0 -3
- package/types/parse.d.ts +0 -2
package/dist/abydon.full.js
DELETED
|
@@ -1,1274 +0,0 @@
|
|
|
1
|
-
const ACTIVE = {};
|
|
2
|
-
const BATCH = {
|
|
3
|
-
depth: 0,
|
|
4
|
-
handlers: /* @__PURE__ */ new Set()
|
|
5
|
-
};
|
|
6
|
-
const METHODS_AFFECTING_LENGTH = new Set([
|
|
7
|
-
"pop",
|
|
8
|
-
"push",
|
|
9
|
-
"shift",
|
|
10
|
-
"unshift"
|
|
11
|
-
]);
|
|
12
|
-
const METHODS_UPDATE = new Set([
|
|
13
|
-
...METHODS_AFFECTING_LENGTH,
|
|
14
|
-
"copyWithin",
|
|
15
|
-
"fill",
|
|
16
|
-
"reverse",
|
|
17
|
-
"sort",
|
|
18
|
-
"splice"
|
|
19
|
-
]);
|
|
20
|
-
const NAME_ARRAY = "array";
|
|
21
|
-
const NAME_COMPUTED = "computed";
|
|
22
|
-
const NAME_EFFECT = "effect";
|
|
23
|
-
const NAME_SIGNAL = "signal";
|
|
24
|
-
const NAME_STORE = "store";
|
|
25
|
-
const NAMES = new Set([
|
|
26
|
-
NAME_ARRAY,
|
|
27
|
-
NAME_COMPUTED,
|
|
28
|
-
NAME_SIGNAL,
|
|
29
|
-
NAME_STORE
|
|
30
|
-
]);
|
|
31
|
-
|
|
32
|
-
var Effect = class {
|
|
33
|
-
constructor(callback) {
|
|
34
|
-
Object.defineProperty(this, "$mora", { value: NAME_EFFECT });
|
|
35
|
-
this.state = { callback };
|
|
36
|
-
runEffect(this);
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
function runEffect(effect$1) {
|
|
40
|
-
const previousEffect = ACTIVE.effect;
|
|
41
|
-
ACTIVE.effect = effect$1;
|
|
42
|
-
try {
|
|
43
|
-
effect$1.state.callback();
|
|
44
|
-
} finally {
|
|
45
|
-
ACTIVE.effect = previousEffect;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
function effect(callback) {
|
|
49
|
-
return typeof callback === "function" ? new Effect(callback) : void 0;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function isArray(value) {
|
|
53
|
-
return isMora(value, NAME_ARRAY);
|
|
54
|
-
}
|
|
55
|
-
function isComputed(value) {
|
|
56
|
-
return isMora(value, NAME_COMPUTED);
|
|
57
|
-
}
|
|
58
|
-
function isEffect(value) {
|
|
59
|
-
return isMora(value, NAME_EFFECT);
|
|
60
|
-
}
|
|
61
|
-
function isMora(value, name) {
|
|
62
|
-
return typeof value === "object" && value != null && "$mora" in value && (typeof name === "string" ? value.$mora === name : name.has(value.$mora));
|
|
63
|
-
}
|
|
64
|
-
function isReactive(value) {
|
|
65
|
-
return isMora(value, NAMES);
|
|
66
|
-
}
|
|
67
|
-
function isSignal(value) {
|
|
68
|
-
return isMora(value, NAME_SIGNAL);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function flushHandlers() {
|
|
72
|
-
while (BATCH.depth === 0 && BATCH.handlers.size > 0) {
|
|
73
|
-
const handlers = [...BATCH.handlers];
|
|
74
|
-
BATCH.handlers.clear();
|
|
75
|
-
for (const handler of handlers) if (isEffect(handler)) runEffect(handler);
|
|
76
|
-
else handler.callback(handler.state.value);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
function startBatch() {
|
|
80
|
-
BATCH.depth += 1;
|
|
81
|
-
}
|
|
82
|
-
function stopBatch() {
|
|
83
|
-
if (BATCH.depth > 0) BATCH.depth -= 1;
|
|
84
|
-
flushHandlers();
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
var Subscription = class {
|
|
88
|
-
callback;
|
|
89
|
-
state;
|
|
90
|
-
constructor(state, callback) {
|
|
91
|
-
this.state = state;
|
|
92
|
-
this.callback = callback;
|
|
93
|
-
callback(state.value);
|
|
94
|
-
}
|
|
95
|
-
destroy() {
|
|
96
|
-
this.callback = noop;
|
|
97
|
-
this.state = void 0;
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
function noop() {}
|
|
101
|
-
function subscribe(state, callback) {
|
|
102
|
-
if (typeof callback !== "function" || state.subscriptions.has(callback)) return noop;
|
|
103
|
-
state.subscriptions.set(callback, new Subscription(state, callback));
|
|
104
|
-
return () => {
|
|
105
|
-
unsubscribe(state, callback);
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
function unsubscribe(state, callback) {
|
|
109
|
-
state.subscriptions.get(callback)?.destroy();
|
|
110
|
-
state.subscriptions.delete(callback);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
var Reactive = class {
|
|
114
|
-
state = {
|
|
115
|
-
computeds: /* @__PURE__ */ new Set(),
|
|
116
|
-
effects: /* @__PURE__ */ new Set(),
|
|
117
|
-
equal: Object.is,
|
|
118
|
-
subscriptions: /* @__PURE__ */ new Map(),
|
|
119
|
-
value: void 0
|
|
120
|
-
};
|
|
121
|
-
constructor(name, value, options) {
|
|
122
|
-
this.state.value = value;
|
|
123
|
-
if (typeof options === "object" && typeof options.equal === "function") this.state.equal = options.equal;
|
|
124
|
-
Object.defineProperty(this, "$mora", { value: name });
|
|
125
|
-
}
|
|
126
|
-
peek() {
|
|
127
|
-
return this.state.value;
|
|
128
|
-
}
|
|
129
|
-
subscribe(callback) {
|
|
130
|
-
return subscribe(this.state, callback);
|
|
131
|
-
}
|
|
132
|
-
toJSON() {
|
|
133
|
-
return this.get();
|
|
134
|
-
}
|
|
135
|
-
toString() {
|
|
136
|
-
return String(this.get());
|
|
137
|
-
}
|
|
138
|
-
unsubscribe(callback) {
|
|
139
|
-
unsubscribe(this.state, callback);
|
|
140
|
-
}
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
var Computed = class extends Reactive {
|
|
144
|
-
effect = {
|
|
145
|
-
dirty: true,
|
|
146
|
-
instance: void 0
|
|
147
|
-
};
|
|
148
|
-
constructor(callback, options) {
|
|
149
|
-
super(NAME_COMPUTED, void 0, options);
|
|
150
|
-
this.effect.instance = effect(() => {
|
|
151
|
-
if (!this.effect.dirty) return;
|
|
152
|
-
const previousComputed = ACTIVE.computed;
|
|
153
|
-
ACTIVE.computed = this;
|
|
154
|
-
const value = callback();
|
|
155
|
-
ACTIVE.computed = previousComputed;
|
|
156
|
-
if (!this.state.equal(this.state.value, value)) {
|
|
157
|
-
this.state.value = value;
|
|
158
|
-
for (const computed$1 of this.state.computeds) computed$1.effect.dirty = true;
|
|
159
|
-
for (const effect$1 of this.state.effects) BATCH.handlers.add(effect$1);
|
|
160
|
-
for (const [, subscription] of this.state.subscriptions) subscription.callback(value);
|
|
161
|
-
}
|
|
162
|
-
this.effect.dirty = false;
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
get() {
|
|
166
|
-
if (ACTIVE.computed != null && this !== ACTIVE.computed) this.state.computeds.add(ACTIVE.computed);
|
|
167
|
-
if (ACTIVE.effect != null && ACTIVE.effect !== this.effect.instance) this.state.effects.add(ACTIVE.effect);
|
|
168
|
-
if (this.effect.dirty && BATCH.depth === 0) runEffect(this.effect.instance);
|
|
169
|
-
return this.state.value;
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
function computed(callback, options) {
|
|
173
|
-
return new Computed(callback, options);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
function emitValue(state) {
|
|
177
|
-
for (const computed of state.computeds) computed.effect.dirty = true;
|
|
178
|
-
for (const effect of state.effects) BATCH.handlers.add(effect);
|
|
179
|
-
for (const [, subscription] of state.subscriptions) BATCH.handlers.add(subscription);
|
|
180
|
-
if (BATCH.depth === 0) flushHandlers();
|
|
181
|
-
}
|
|
182
|
-
function equalArrays(state, first, second) {
|
|
183
|
-
let { length } = first;
|
|
184
|
-
if (length !== second.length) return false;
|
|
185
|
-
let offset = 0;
|
|
186
|
-
if (length >= 100) {
|
|
187
|
-
offset = Math.round(length / 10);
|
|
188
|
-
offset = offset > 25 ? 25 : offset;
|
|
189
|
-
for (let index = 0; index < offset; index += 1) if (!state.equal(first[index], second[index])) return false;
|
|
190
|
-
}
|
|
191
|
-
length -= offset;
|
|
192
|
-
for (let index = offset; index < length; index += 1) if (!state.equal(first[index], second[index])) return false;
|
|
193
|
-
return true;
|
|
194
|
-
}
|
|
195
|
-
function getValue$1(state) {
|
|
196
|
-
if (ACTIVE.computed != null) state.computeds.add(ACTIVE.computed);
|
|
197
|
-
if (ACTIVE.effect != null) state.effects.add(ACTIVE.effect);
|
|
198
|
-
return state.value;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
var Signal = class extends Reactive {
|
|
202
|
-
constructor(value, options) {
|
|
203
|
-
super(NAME_SIGNAL, value, options);
|
|
204
|
-
}
|
|
205
|
-
get() {
|
|
206
|
-
return getValue$1(this.state);
|
|
207
|
-
}
|
|
208
|
-
set(value) {
|
|
209
|
-
if (!this.state.equal(this.state.value, value)) {
|
|
210
|
-
this.state.value = value;
|
|
211
|
-
emitValue(this.state);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
update(callback) {
|
|
215
|
-
this.set(callback(this.state.value));
|
|
216
|
-
}
|
|
217
|
-
};
|
|
218
|
-
function signal(value, options) {
|
|
219
|
-
return new Signal(value, options);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
function getReactiveValueInProxy(reactive, mapped, key, isArray) {
|
|
223
|
-
let item = mapped.get(key);
|
|
224
|
-
if (item == null) {
|
|
225
|
-
item = computed(() => {
|
|
226
|
-
const value = reactive.get();
|
|
227
|
-
return isArray ? value.at(key) : value[key];
|
|
228
|
-
});
|
|
229
|
-
mapped.set(key, item);
|
|
230
|
-
}
|
|
231
|
-
return item;
|
|
232
|
-
}
|
|
233
|
-
function setProxyValue(proxy, value) {
|
|
234
|
-
startBatch();
|
|
235
|
-
const proxyKeys = Object.keys(proxy);
|
|
236
|
-
const valueKeys = Object.keys(value);
|
|
237
|
-
let { length } = proxyKeys;
|
|
238
|
-
for (let index = 0; index < length; index += 1) {
|
|
239
|
-
const key = proxyKeys[index];
|
|
240
|
-
proxy[key] = valueKeys.includes(key) ? value[key] : void 0;
|
|
241
|
-
}
|
|
242
|
-
length = valueKeys.length;
|
|
243
|
-
for (let index = 0; index < length; index += 1) {
|
|
244
|
-
const key = valueKeys[index];
|
|
245
|
-
if (!proxyKeys.includes(key)) proxy[key] = value[key];
|
|
246
|
-
}
|
|
247
|
-
stopBatch();
|
|
248
|
-
}
|
|
249
|
-
function setValueInProxy(parameters) {
|
|
250
|
-
const { isArray, length, property, state, target, value } = parameters;
|
|
251
|
-
if (isArray) {
|
|
252
|
-
if (!(!Number.isNaN(Number(property)) || property === "length")) return Reflect.set(target, property, value);
|
|
253
|
-
}
|
|
254
|
-
const previous = Reflect.get(target, property);
|
|
255
|
-
if (!state.equal(previous, value)) {
|
|
256
|
-
Reflect.set(target, property, value);
|
|
257
|
-
emitValue(state);
|
|
258
|
-
if (isArray) length?.set(target.length);
|
|
259
|
-
}
|
|
260
|
-
return true;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
var ReactiveArray = class extends Reactive {
|
|
264
|
-
#indiced = /* @__PURE__ */ new Map();
|
|
265
|
-
#size = signal(0);
|
|
266
|
-
get length() {
|
|
267
|
-
return this.#size.get();
|
|
268
|
-
}
|
|
269
|
-
set length(value) {
|
|
270
|
-
if (typeof value === "number" && value >= 0 && value !== this.state.value.length) this.get().length = value;
|
|
271
|
-
}
|
|
272
|
-
constructor(value, options) {
|
|
273
|
-
super(NAME_ARRAY, new Proxy(value, {
|
|
274
|
-
get: (target, property) => METHODS_UPDATE.has(property) ? updateArray(property, target, this.state, this.#size) : Reflect.get(target, property),
|
|
275
|
-
set: (target, property, value$1) => setValueInProxy({
|
|
276
|
-
property,
|
|
277
|
-
target,
|
|
278
|
-
value: value$1,
|
|
279
|
-
isArray: true,
|
|
280
|
-
state: this.state,
|
|
281
|
-
length: this.#size
|
|
282
|
-
})
|
|
283
|
-
}), options);
|
|
284
|
-
this.#size.set(value.length);
|
|
285
|
-
}
|
|
286
|
-
clear() {
|
|
287
|
-
this.length = 0;
|
|
288
|
-
}
|
|
289
|
-
filter(callback) {
|
|
290
|
-
return computed(() => this.get().filter(callback));
|
|
291
|
-
}
|
|
292
|
-
get(first) {
|
|
293
|
-
if (typeof first === "number") return getReactiveValueInProxy(this, this.#indiced, first, true).get();
|
|
294
|
-
if (first === "length") return this.length;
|
|
295
|
-
return getValue$1(this.state);
|
|
296
|
-
}
|
|
297
|
-
map(callback) {
|
|
298
|
-
return computed(() => this.get().map(callback));
|
|
299
|
-
}
|
|
300
|
-
notify() {
|
|
301
|
-
emitValue(this.state);
|
|
302
|
-
}
|
|
303
|
-
peek(value) {
|
|
304
|
-
if (value === "length") return this.#size.peek();
|
|
305
|
-
if (typeof value === "number") return this.state.value.at(value);
|
|
306
|
-
return [...this.state.value];
|
|
307
|
-
}
|
|
308
|
-
pop() {
|
|
309
|
-
return this.state.value.pop();
|
|
310
|
-
}
|
|
311
|
-
push(...items) {
|
|
312
|
-
return this.state.value.push(...items);
|
|
313
|
-
}
|
|
314
|
-
set(first, second) {
|
|
315
|
-
if (first == null || Array.isArray(first)) this.state.value.splice(0, this.state.value.length, ...first ?? []);
|
|
316
|
-
else if (first === "length") this.length = second;
|
|
317
|
-
else if (typeof first === "number" && !Number.isNaN(first)) setAtIndex(this.state.value, first, second);
|
|
318
|
-
}
|
|
319
|
-
shift() {
|
|
320
|
-
return this.state.value.shift();
|
|
321
|
-
}
|
|
322
|
-
splice(from, to, ...items) {
|
|
323
|
-
return this.state.value.splice(from, to ?? this.state.value.length, ...items);
|
|
324
|
-
}
|
|
325
|
-
subscribe(first, second) {
|
|
326
|
-
if (typeof first === "number" && typeof second === "function") return getReactiveValueInProxy(this, this.#indiced, first, true).subscribe(second);
|
|
327
|
-
return typeof first === "function" ? subscribe(this.state, first) : noop;
|
|
328
|
-
}
|
|
329
|
-
unshift(...items) {
|
|
330
|
-
return this.state.value.unshift(...items);
|
|
331
|
-
}
|
|
332
|
-
update(callback) {
|
|
333
|
-
const updated = callback(this.state.value);
|
|
334
|
-
if (updated == null || Array.isArray(updated)) this.set(updated);
|
|
335
|
-
}
|
|
336
|
-
};
|
|
337
|
-
function array(value, options) {
|
|
338
|
-
return new ReactiveArray(Array.isArray(value) ? value : [], options);
|
|
339
|
-
}
|
|
340
|
-
function updateArray(type, array$1, state, length) {
|
|
341
|
-
const affectsLength = METHODS_AFFECTING_LENGTH.has(type);
|
|
342
|
-
const previousArray = affectsLength ? [] : [...array$1];
|
|
343
|
-
const previousLength = array$1.length;
|
|
344
|
-
return (...args) => {
|
|
345
|
-
const result = array$1[type](...args);
|
|
346
|
-
if (affectsLength ? array$1.length !== previousLength : !equalArrays(state, previousArray, array$1)) {
|
|
347
|
-
emitValue(state);
|
|
348
|
-
length.set(array$1.length);
|
|
349
|
-
}
|
|
350
|
-
return result;
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
function setAtIndex(array$1, index, value) {
|
|
354
|
-
const actual = index < 0 ? array$1.length + index : index;
|
|
355
|
-
if (actual > -1) array$1[actual] = value;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
function isKey(value) {
|
|
359
|
-
return typeof value === "number" || typeof value === "string";
|
|
360
|
-
}
|
|
361
|
-
function isPlainObject(value) {
|
|
362
|
-
if (value === null || typeof value !== "object") return false;
|
|
363
|
-
if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
|
|
364
|
-
const prototype = Object.getPrototypeOf(value);
|
|
365
|
-
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
function getString(value) {
|
|
369
|
-
if (typeof value === "string") return value;
|
|
370
|
-
if (value == null) return "";
|
|
371
|
-
if (typeof value !== "object") return String(value);
|
|
372
|
-
const asString = String(value.valueOf?.() ?? value);
|
|
373
|
-
return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
function isNullableOrWhitespace(value) {
|
|
377
|
-
return value == null || EXPRESSION_WHITESPACE.test(getString(value));
|
|
378
|
-
}
|
|
379
|
-
var EXPRESSION_WHITESPACE = /^\s*$/;
|
|
380
|
-
|
|
381
|
-
var Store = class extends Reactive {
|
|
382
|
-
#keyed = /* @__PURE__ */ new Map();
|
|
383
|
-
constructor(value, options) {
|
|
384
|
-
super(NAME_STORE, new Proxy(value, { set: (target, property, value$1) => setValueInProxy({
|
|
385
|
-
target,
|
|
386
|
-
property,
|
|
387
|
-
value: value$1,
|
|
388
|
-
isArray: false,
|
|
389
|
-
state: this.state
|
|
390
|
-
}) }), options);
|
|
391
|
-
}
|
|
392
|
-
get(key) {
|
|
393
|
-
return isKey(key) ? getReactiveValueInProxy(this, this.#keyed, key, false).get() : getValue$1(this.state);
|
|
394
|
-
}
|
|
395
|
-
peek(key) {
|
|
396
|
-
return isKey(key) ? this.state.value[key] : { ...this.state.value };
|
|
397
|
-
}
|
|
398
|
-
set(first, second) {
|
|
399
|
-
if (isKey(first)) this.state.value[first] = second;
|
|
400
|
-
else if (first == null || isPlainObject(first)) setProxyValue(this.state.value, first ?? {});
|
|
401
|
-
}
|
|
402
|
-
subscribe(first, second) {
|
|
403
|
-
if (isKey(first) && typeof second === "function") return getReactiveValueInProxy(this, this.#keyed, first, false).subscribe(second);
|
|
404
|
-
return typeof first === "function" ? subscribe(this.state, first) : noop;
|
|
405
|
-
}
|
|
406
|
-
update(callback) {
|
|
407
|
-
const updated = callback({ ...this.state.value });
|
|
408
|
-
if (updated == null || isPlainObject(updated)) setProxyValue(this.state.value, updated ?? {});
|
|
409
|
-
}
|
|
410
|
-
};
|
|
411
|
-
function store(value, options) {
|
|
412
|
-
return new Store(isPlainObject(value) ? value : {}, options);
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
function isChildNode(value) {
|
|
416
|
-
return value instanceof Node && CHILD_NODE_TYPES.has(value.nodeType);
|
|
417
|
-
}
|
|
418
|
-
function isHTMLOrSVGElement(value) {
|
|
419
|
-
return value instanceof HTMLElement || value instanceof SVGElement;
|
|
420
|
-
}
|
|
421
|
-
var CHILD_NODE_TYPES = new Set([
|
|
422
|
-
Node.ELEMENT_NODE,
|
|
423
|
-
Node.TEXT_NODE,
|
|
424
|
-
Node.PROCESSING_INSTRUCTION_NODE,
|
|
425
|
-
Node.COMMENT_NODE,
|
|
426
|
-
Node.DOCUMENT_TYPE_NODE
|
|
427
|
-
]);
|
|
428
|
-
|
|
429
|
-
function isAttribute(value) {
|
|
430
|
-
return value instanceof Attr || isPlainObject(value) && typeof value.name === "string" && typeof value.value === "string";
|
|
431
|
-
}
|
|
432
|
-
function isBadAttribute(first, second) {
|
|
433
|
-
return validateAttribute((attribute) => attribute == null || EXPRESSION_ON_PREFIX.test(attribute.name) || EXPRESSION_SOURCE_PREFIX.test(attribute.name) && EXPRESSION_VALUE_PREFIX.test(String(attribute.value)), first, second);
|
|
434
|
-
}
|
|
435
|
-
function isBooleanAttribute(value) {
|
|
436
|
-
return validateAttribute((attribute) => attribute != null && booleanAttributes.includes(attribute.name.toLowerCase()), value, "");
|
|
437
|
-
}
|
|
438
|
-
function isEmptyNonBooleanAttribute(first, second) {
|
|
439
|
-
return validateAttribute((attribute) => attribute != null && !booleanAttributes.includes(attribute.name) && String(attribute.value).trim().length === 0, first, second);
|
|
440
|
-
}
|
|
441
|
-
function isInvalidBooleanAttribute(first, second) {
|
|
442
|
-
return validateAttribute((attribute) => {
|
|
443
|
-
if (attribute == null) return true;
|
|
444
|
-
if (!booleanAttributes.includes(attribute.name)) return false;
|
|
445
|
-
const normalized = String(attribute.value).toLowerCase().trim();
|
|
446
|
-
return !(normalized.length === 0 || normalized === attribute.name);
|
|
447
|
-
}, first, second);
|
|
448
|
-
}
|
|
449
|
-
function isProperty(value) {
|
|
450
|
-
return isPlainObject(value) && typeof value.name === "string";
|
|
451
|
-
}
|
|
452
|
-
function setAttribute$1(element, first, second) {
|
|
453
|
-
updateValue(element, first, second, updateAttribute);
|
|
454
|
-
}
|
|
455
|
-
function setProperty(element, first, second) {
|
|
456
|
-
updateValue(element, first, second, updateProperty$1);
|
|
457
|
-
}
|
|
458
|
-
function updateAttribute(element, name, value) {
|
|
459
|
-
if (booleanAttributes.includes(name.toLowerCase())) updateProperty$1(element, name, value, false);
|
|
460
|
-
else if (value == null) element.removeAttribute(name);
|
|
461
|
-
else element.setAttribute(name, typeof value === "string" ? value : getString(value));
|
|
462
|
-
}
|
|
463
|
-
function updateProperty$1(element, name, value, validate) {
|
|
464
|
-
const actual = validate ?? true ? name.toLowerCase() : name;
|
|
465
|
-
if (actual === "hidden") element.hidden = value === "" || value === true;
|
|
466
|
-
else element[actual] = value === "" || typeof value === "string" && value.toLowerCase() === actual || value === true;
|
|
467
|
-
}
|
|
468
|
-
function updateValue(element, first, second, callback) {
|
|
469
|
-
if (!isHTMLOrSVGElement(element)) return;
|
|
470
|
-
if (isProperty(first)) callback(element, first.name, first.value);
|
|
471
|
-
else if (typeof first === "string") callback(element, first, second);
|
|
472
|
-
}
|
|
473
|
-
function validateAttribute(callback, first, second) {
|
|
474
|
-
let attribute;
|
|
475
|
-
if (isAttribute(first)) attribute = first;
|
|
476
|
-
else if (typeof first === "string" && typeof second === "string") attribute = {
|
|
477
|
-
name: first,
|
|
478
|
-
value: second
|
|
479
|
-
};
|
|
480
|
-
return callback(attribute);
|
|
481
|
-
}
|
|
482
|
-
var EXPRESSION_ON_PREFIX = /^on/i;
|
|
483
|
-
var EXPRESSION_SOURCE_PREFIX = /^(href|src|xlink:href)$/i;
|
|
484
|
-
var EXPRESSION_VALUE_PREFIX = /(data:text\/html|javascript:)/i;
|
|
485
|
-
const booleanAttributes = Object.freeze([
|
|
486
|
-
"async",
|
|
487
|
-
"autofocus",
|
|
488
|
-
"autoplay",
|
|
489
|
-
"checked",
|
|
490
|
-
"controls",
|
|
491
|
-
"default",
|
|
492
|
-
"defer",
|
|
493
|
-
"disabled",
|
|
494
|
-
"formnovalidate",
|
|
495
|
-
"hidden",
|
|
496
|
-
"inert",
|
|
497
|
-
"ismap",
|
|
498
|
-
"itemscope",
|
|
499
|
-
"loop",
|
|
500
|
-
"multiple",
|
|
501
|
-
"muted",
|
|
502
|
-
"nomodule",
|
|
503
|
-
"novalidate",
|
|
504
|
-
"open",
|
|
505
|
-
"playsinline",
|
|
506
|
-
"readonly",
|
|
507
|
-
"required",
|
|
508
|
-
"reversed",
|
|
509
|
-
"selected"
|
|
510
|
-
]);
|
|
511
|
-
|
|
512
|
-
function sanitizeAttributes(element, attributes, options) {
|
|
513
|
-
const { length } = attributes;
|
|
514
|
-
for (let index = 0; index < length; index += 1) {
|
|
515
|
-
const attribute = attributes[index];
|
|
516
|
-
if (isBadAttribute(attribute) || isEmptyNonBooleanAttribute(attribute)) element.removeAttribute(attribute.name);
|
|
517
|
-
else if (options.sanitizeBooleanAttributes && isInvalidBooleanAttribute(attribute)) element.setAttribute(attribute.name, "");
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
function sanitizeNodes$1(nodes, options) {
|
|
521
|
-
const actual = nodes.filter((node) => node instanceof Node);
|
|
522
|
-
const { length } = nodes;
|
|
523
|
-
for (let index = 0; index < length; index += 1) {
|
|
524
|
-
const node = actual[index];
|
|
525
|
-
if (node instanceof Element) {
|
|
526
|
-
const scripts = node.querySelectorAll("script");
|
|
527
|
-
for (const script of scripts) script.remove();
|
|
528
|
-
sanitizeAttributes(node, [...node.attributes], options);
|
|
529
|
-
}
|
|
530
|
-
if (node.hasChildNodes()) sanitizeNodes$1([...node.childNodes], options);
|
|
531
|
-
}
|
|
532
|
-
return nodes;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
function createTemplate(html$1, ignore) {
|
|
536
|
-
const template = document.createElement("template");
|
|
537
|
-
template.innerHTML = html$1;
|
|
538
|
-
if (!ignore) templates[html$1] = template;
|
|
539
|
-
return template;
|
|
540
|
-
}
|
|
541
|
-
function getHtml(value, options) {
|
|
542
|
-
if (typeof value !== "string" && !(value instanceof HTMLTemplateElement)) return [];
|
|
543
|
-
const template = value instanceof HTMLTemplateElement ? value : getTemplate(value, options.ignoreCache);
|
|
544
|
-
if (template == null) return [];
|
|
545
|
-
const cloned = template.content.cloneNode(true);
|
|
546
|
-
const scripts = cloned.querySelectorAll("script");
|
|
547
|
-
for (const script of scripts) script.remove();
|
|
548
|
-
cloned.normalize();
|
|
549
|
-
return sanitizeNodes$1([...cloned.childNodes], options);
|
|
550
|
-
}
|
|
551
|
-
function getOptions$1(input) {
|
|
552
|
-
const options = isPlainObject(input) ? input : {};
|
|
553
|
-
options.ignoreCache = typeof options.ignoreCache === "boolean" ? options.ignoreCache : false;
|
|
554
|
-
options.sanitizeBooleanAttributes = typeof options.sanitizeBooleanAttributes === "boolean" ? options.sanitizeBooleanAttributes : true;
|
|
555
|
-
return options;
|
|
556
|
-
}
|
|
557
|
-
function getTemplate(value, ignore) {
|
|
558
|
-
if (typeof value !== "string" || value.trim().length === 0) return;
|
|
559
|
-
let template = templates[value];
|
|
560
|
-
if (template != null) return template;
|
|
561
|
-
const element = EXPRESSION_ID.test(value) ? document.querySelector(`#${value}`) : null;
|
|
562
|
-
template = element instanceof HTMLTemplateElement ? element : createTemplate(value, ignore);
|
|
563
|
-
return template;
|
|
564
|
-
}
|
|
565
|
-
var html$1 = ((value, options) => {
|
|
566
|
-
return getHtml(value, getOptions$1(options));
|
|
567
|
-
});
|
|
568
|
-
html$1.clear = () => {
|
|
569
|
-
templates = {};
|
|
570
|
-
};
|
|
571
|
-
html$1.remove = (template) => {
|
|
572
|
-
if (typeof template !== "string" || templates[template] == null) return;
|
|
573
|
-
const keys = Object.keys(templates);
|
|
574
|
-
const { length } = keys;
|
|
575
|
-
const updated = {};
|
|
576
|
-
for (let index = 0; index < length; index += 1) {
|
|
577
|
-
const key = keys[index];
|
|
578
|
-
if (key !== template) updated[key] = templates[key];
|
|
579
|
-
}
|
|
580
|
-
templates = updated;
|
|
581
|
-
};
|
|
582
|
-
var EXPRESSION_ID = /^[a-z][\w-]*$/i;
|
|
583
|
-
var templates = {};
|
|
584
|
-
|
|
585
|
-
function compareArrays(first, second) {
|
|
586
|
-
const firstIsLarger = first.length > second.length;
|
|
587
|
-
const from = firstIsLarger ? first : second;
|
|
588
|
-
const to = firstIsLarger ? second : first;
|
|
589
|
-
if (!from
|
|
590
|
-
.filter(key => to.includes(key))
|
|
591
|
-
.every((key, index) => to[index] === key)) {
|
|
592
|
-
return 'dissimilar';
|
|
593
|
-
}
|
|
594
|
-
return firstIsLarger ? 'removed' : 'added';
|
|
595
|
-
}
|
|
596
|
-
function isFragment(value) {
|
|
597
|
-
return (typeof value === 'object' &&
|
|
598
|
-
value != null &&
|
|
599
|
-
'$fragment' in value &&
|
|
600
|
-
value.$fragment === true);
|
|
601
|
-
}
|
|
602
|
-
function isFragments(value) {
|
|
603
|
-
return (typeof value === 'object' &&
|
|
604
|
-
value != null &&
|
|
605
|
-
'$fragments' in value &&
|
|
606
|
-
value.$fragments === true);
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
class Fragments {
|
|
610
|
-
#state;
|
|
611
|
-
/**
|
|
612
|
-
* Fragment items
|
|
613
|
-
*/
|
|
614
|
-
get items() {
|
|
615
|
-
return this.#state.mapped;
|
|
616
|
-
}
|
|
617
|
-
constructor(items, identify, fragment) {
|
|
618
|
-
Object.defineProperty(this, '$fragments', {
|
|
619
|
-
value: true,
|
|
620
|
-
});
|
|
621
|
-
this.#state = {
|
|
622
|
-
fragment,
|
|
623
|
-
identify,
|
|
624
|
-
array: items,
|
|
625
|
-
instances: {},
|
|
626
|
-
mapped: array([]),
|
|
627
|
-
subscriber: undefined,
|
|
628
|
-
};
|
|
629
|
-
states.set(this, this.#state);
|
|
630
|
-
initializeFragments(this.#state);
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
function handleFragments(item, remove) {
|
|
634
|
-
const state = isFragments(item) ? states.get(item) : item;
|
|
635
|
-
if (state != null) {
|
|
636
|
-
(remove ? removeFragments$1 : initializeFragments)(state);
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
function handleItems(state, items) {
|
|
640
|
-
const keys = new Set();
|
|
641
|
-
const mapped = [];
|
|
642
|
-
const { length } = items;
|
|
643
|
-
for (let index = 0; index < length; index += 1) {
|
|
644
|
-
const item = items[index];
|
|
645
|
-
const identifier = state.identify(item);
|
|
646
|
-
if (identifier == null) {
|
|
647
|
-
throw new Error('Identifier cannot be null or undefined');
|
|
648
|
-
}
|
|
649
|
-
const key = getString(identifier);
|
|
650
|
-
if (keys.has(key)) {
|
|
651
|
-
throw new Error(`Duplicate identifier found: "${key}"`);
|
|
652
|
-
}
|
|
653
|
-
let instance = state.instances[key];
|
|
654
|
-
if (instance == null) {
|
|
655
|
-
instance = state.fragment(item);
|
|
656
|
-
if (!isFragment(instance)) {
|
|
657
|
-
throw new Error('Fragment function must return a Fragment instance');
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
instance.identify(key);
|
|
661
|
-
state.instances[key] = instance;
|
|
662
|
-
keys.add(key);
|
|
663
|
-
mapped.push(instance);
|
|
664
|
-
}
|
|
665
|
-
state.mapped.set(mapped);
|
|
666
|
-
updateFragments(state, keys);
|
|
667
|
-
}
|
|
668
|
-
function initializeFragments(state) {
|
|
669
|
-
state.subscriber ??= state.array.subscribe(items => {
|
|
670
|
-
handleItems(state, items);
|
|
671
|
-
});
|
|
672
|
-
}
|
|
673
|
-
function removeFragments$1(state) {
|
|
674
|
-
state.subscriber?.();
|
|
675
|
-
updateFragments(state);
|
|
676
|
-
state.subscriber = undefined;
|
|
677
|
-
}
|
|
678
|
-
function updateFragments(state, active) {
|
|
679
|
-
const next = {};
|
|
680
|
-
const previous = { ...state.instances };
|
|
681
|
-
const keys = Object.keys(previous);
|
|
682
|
-
const { length } = keys;
|
|
683
|
-
for (let index = 0; index < length; index += 1) {
|
|
684
|
-
const key = keys[index];
|
|
685
|
-
if (active?.has(key)) {
|
|
686
|
-
next[key] = previous[key];
|
|
687
|
-
}
|
|
688
|
-
else {
|
|
689
|
-
previous[key].remove();
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
state.instances = next;
|
|
693
|
-
active?.clear();
|
|
694
|
-
}
|
|
695
|
-
//
|
|
696
|
-
const states = new WeakMap();
|
|
697
|
-
|
|
698
|
-
const ABORT_CONTROLLERS = new WeakMap();
|
|
699
|
-
const ATTRIBUTE_CLASS_PREFIX_LENGTH = 6;
|
|
700
|
-
const EXPRESSION_ATTRIBUTE_CLASS = /^class\./;
|
|
701
|
-
const EXPRESSION_ATTRIBUTE_STYLE_FULL = /^style\.([\w-]+)(?:\.([\w-]+))?$/;
|
|
702
|
-
const EXPRESSION_ATTRIBUTE_STYLE_PREFIX = /^style\./;
|
|
703
|
-
const EXPRESSION_COMMENT_FULL = /^<!--abydon\.(\d+)-->$/;
|
|
704
|
-
const EXPRESSION_COMMENT_CONTENT = /^abydon\.(\d+)$/;
|
|
705
|
-
const EXPRESSION_EVENT_NAME = /^@([\w-]+)(?::([a-z:]+))?$/i;
|
|
706
|
-
const REASON_EVENT_REMOVED = 'Event removed as element was removed from document by Abydon';
|
|
707
|
-
|
|
708
|
-
function getController(element) {
|
|
709
|
-
let controller = ABORT_CONTROLLERS.get(element);
|
|
710
|
-
if (controller == null) {
|
|
711
|
-
controller = new AbortController();
|
|
712
|
-
ABORT_CONTROLLERS.set(element, controller);
|
|
713
|
-
}
|
|
714
|
-
return controller;
|
|
715
|
-
}
|
|
716
|
-
function getOptions(options) {
|
|
717
|
-
const parts = options.split(':');
|
|
718
|
-
return {
|
|
719
|
-
capture: parts.includes('c') || parts.includes('capture'),
|
|
720
|
-
once: parts.includes('o') || parts.includes('once'),
|
|
721
|
-
passive: !(parts.includes('a') || parts.includes('active')),
|
|
722
|
-
};
|
|
723
|
-
}
|
|
724
|
-
function mapEvent(element, name, value) {
|
|
725
|
-
element.removeAttribute(name);
|
|
726
|
-
const [, type, options] = EXPRESSION_EVENT_NAME.exec(name) ?? [];
|
|
727
|
-
if (typeof value === 'function' && type != null) {
|
|
728
|
-
element.addEventListener(type, value, {
|
|
729
|
-
...getOptions(options ?? ''),
|
|
730
|
-
signal: getController(element).signal,
|
|
731
|
-
});
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
function removeEvents(element) {
|
|
735
|
-
ABORT_CONTROLLERS.get(element)?.abort(REASON_EVENT_REMOVED);
|
|
736
|
-
ABORT_CONTROLLERS.delete(element);
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
function createNodes(value) {
|
|
740
|
-
if (isFragment(value)) {
|
|
741
|
-
return value.get();
|
|
742
|
-
}
|
|
743
|
-
if (isChildNode(value)) {
|
|
744
|
-
return [value];
|
|
745
|
-
}
|
|
746
|
-
return [new Text(getString(value))];
|
|
747
|
-
}
|
|
748
|
-
function removeNodes(nodes) {
|
|
749
|
-
sanitizeNodes(nodes);
|
|
750
|
-
const { length } = nodes;
|
|
751
|
-
for (let index = 0; index < length; index += 1) {
|
|
752
|
-
nodes[index].remove();
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
function replaceNodes(from, to) {
|
|
756
|
-
from[0]?.replaceWith(...to);
|
|
757
|
-
const { length } = from;
|
|
758
|
-
for (let index = 1; index < length; index += 1) {
|
|
759
|
-
from[index].remove();
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
function sanitizeNodes(nodes) {
|
|
763
|
-
const { length } = nodes;
|
|
764
|
-
for (let index = 0; index < length; index += 1) {
|
|
765
|
-
const node = nodes[index];
|
|
766
|
-
if (isHTMLOrSVGElement(node)) {
|
|
767
|
-
removeEvents(node);
|
|
768
|
-
}
|
|
769
|
-
if (node.hasChildNodes()) {
|
|
770
|
-
sanitizeNodes([...node.childNodes]);
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
function setAttribute(data, element, name, value) {
|
|
776
|
-
element.removeAttribute(name);
|
|
777
|
-
switch (true) {
|
|
778
|
-
case EXPRESSION_ATTRIBUTE_CLASS.test(name):
|
|
779
|
-
setClasses(data, element, name, value);
|
|
780
|
-
return;
|
|
781
|
-
case EXPRESSION_ATTRIBUTE_STYLE_PREFIX.test(name):
|
|
782
|
-
setStyle(data, element, name, value);
|
|
783
|
-
return;
|
|
784
|
-
default:
|
|
785
|
-
setValue(data, element, name, value);
|
|
786
|
-
break;
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
function setClasses(data, element, name, value) {
|
|
790
|
-
function update(value) {
|
|
791
|
-
if (value === true) {
|
|
792
|
-
element.classList.add(...classes);
|
|
793
|
-
}
|
|
794
|
-
else {
|
|
795
|
-
element.classList.remove(...classes);
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
const classes = name.slice(ATTRIBUTE_CLASS_PREFIX_LENGTH).split('.');
|
|
799
|
-
if (isReactive(value)) {
|
|
800
|
-
data.mora.subscribers.add(value.subscribe(update));
|
|
801
|
-
}
|
|
802
|
-
else {
|
|
803
|
-
update(value);
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
function setStyle(data, element, name, value) {
|
|
807
|
-
const [, property, unit] = EXPRESSION_ATTRIBUTE_STYLE_FULL.exec(name) ?? [];
|
|
808
|
-
if (property == null) {
|
|
809
|
-
return;
|
|
810
|
-
}
|
|
811
|
-
function update(value) {
|
|
812
|
-
if (value == null || value === false || (value === true && unit == null)) {
|
|
813
|
-
element.style.removeProperty(property);
|
|
814
|
-
}
|
|
815
|
-
else {
|
|
816
|
-
element.style.setProperty(property, value === true ? unit : getString(value));
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
if (isReactive(value)) {
|
|
820
|
-
data.mora.subscribers.add(value.subscribe(update));
|
|
821
|
-
}
|
|
822
|
-
else {
|
|
823
|
-
update(value);
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
function setValue(data, element, name, value) {
|
|
827
|
-
let callback;
|
|
828
|
-
if (isBooleanAttribute(name) && name in element) {
|
|
829
|
-
callback = name === 'selected' ? updateSelected : updateProperty;
|
|
830
|
-
}
|
|
831
|
-
else {
|
|
832
|
-
callback = setAttribute$1;
|
|
833
|
-
}
|
|
834
|
-
if (isReactive(value)) {
|
|
835
|
-
data.mora.subscribers.add(value.subscribe(next => {
|
|
836
|
-
callback(element, name, next);
|
|
837
|
-
}));
|
|
838
|
-
}
|
|
839
|
-
else {
|
|
840
|
-
callback(element, name, value);
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
|
-
function updateProperty(element, name, value) {
|
|
844
|
-
element[name] = value === true;
|
|
845
|
-
}
|
|
846
|
-
function updateSelected(element, name, value) {
|
|
847
|
-
const select = element.closest('select');
|
|
848
|
-
const options = [...(select?.options ?? [])];
|
|
849
|
-
if (select != null && options.includes(element)) {
|
|
850
|
-
select.dispatchEvent(new Event('change', { bubbles: true }));
|
|
851
|
-
}
|
|
852
|
-
updateProperty(element, name, value);
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
function getValue(data, original) {
|
|
856
|
-
const matches = EXPRESSION_COMMENT_FULL.exec(original ?? '');
|
|
857
|
-
return matches == null ? original : data.values[+matches[1]];
|
|
858
|
-
}
|
|
859
|
-
function mapAttributes(data, element) {
|
|
860
|
-
const attributes = [...element.attributes];
|
|
861
|
-
const { length } = attributes;
|
|
862
|
-
for (let index = 0; index < length; index += 1) {
|
|
863
|
-
const { name, value } = attributes[index];
|
|
864
|
-
const actual = getValue(data, value);
|
|
865
|
-
switch (true) {
|
|
866
|
-
case name.startsWith('@'):
|
|
867
|
-
mapEvent(element, name, actual);
|
|
868
|
-
break;
|
|
869
|
-
case name.includes('.') ||
|
|
870
|
-
typeof actual === 'function' ||
|
|
871
|
-
isReactive(actual):
|
|
872
|
-
mapValue$1(data, element, name, actual);
|
|
873
|
-
break;
|
|
874
|
-
case isBooleanAttribute(name):
|
|
875
|
-
setProperty(element, name, value);
|
|
876
|
-
break;
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
function mapValue$1(data, element, name, value) {
|
|
881
|
-
if (typeof value === 'function') {
|
|
882
|
-
setComputedAttribute(data, element, name, value);
|
|
883
|
-
}
|
|
884
|
-
else {
|
|
885
|
-
setAttribute(data, element, name, value);
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
function setComputedAttribute(data, element, name, callback) {
|
|
889
|
-
const value = computed(callback);
|
|
890
|
-
data.mora.values.add(value);
|
|
891
|
-
setAttribute(data, element, name, value);
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
//
|
|
895
|
-
function addToArray(identifiers, items, nodes, added) {
|
|
896
|
-
let position = nodes[0];
|
|
897
|
-
const before = added && !identifiers.previous.includes(items.templates[0].identifier);
|
|
898
|
-
const next = items.next.flatMap(fragment => fragment.get().flatMap(node => ({
|
|
899
|
-
identifier: fragment.identifier,
|
|
900
|
-
value: node,
|
|
901
|
-
})));
|
|
902
|
-
const { length } = next;
|
|
903
|
-
for (let index = 0; index < length; index += 1) {
|
|
904
|
-
const node = next[index];
|
|
905
|
-
if (!(added && identifiers.previous.includes(node.identifier))) {
|
|
906
|
-
if (index === 0 && before) {
|
|
907
|
-
position.before(node.value);
|
|
908
|
-
}
|
|
909
|
-
else {
|
|
910
|
-
position.after(node.value);
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
position = node.value;
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
function handleArray(identifiers, items, nodes) {
|
|
917
|
-
const next = items.templates.map(template => items.fragments?.find(fragment => fragment.identifier === template.identifier) ?? template);
|
|
918
|
-
const comparison = compareArrays(items.fragments ?? [], items.templates);
|
|
919
|
-
if (comparison !== 'removed') {
|
|
920
|
-
addToArray(identifiers, { ...items, next }, nodes, comparison === 'added');
|
|
921
|
-
}
|
|
922
|
-
const toRemove = items.fragments?.filter(fragment => !identifiers.next.includes(fragment.identifier)) ?? [];
|
|
923
|
-
const { length } = toRemove;
|
|
924
|
-
for (let index = 0; index < length; index += 1) {
|
|
925
|
-
toRemove[index].remove();
|
|
926
|
-
}
|
|
927
|
-
return {
|
|
928
|
-
fragments: next,
|
|
929
|
-
nodes: next.flatMap(fragment => fragment.get()),
|
|
930
|
-
};
|
|
931
|
-
}
|
|
932
|
-
function removeFragments(fragments) {
|
|
933
|
-
if (fragments != null) {
|
|
934
|
-
const { length } = fragments;
|
|
935
|
-
for (let index = 0; index < length; index += 1) {
|
|
936
|
-
fragments[index].remove();
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
function replaceText(item, comment, isNullable) {
|
|
941
|
-
let to;
|
|
942
|
-
if (isNullable) {
|
|
943
|
-
to = [comment];
|
|
944
|
-
}
|
|
945
|
-
else {
|
|
946
|
-
to = item.text == null ? [] : [item.text];
|
|
947
|
-
}
|
|
948
|
-
replaceNodes(item.nodes ?? [], to);
|
|
949
|
-
}
|
|
950
|
-
function setArray(item, comment, value) {
|
|
951
|
-
if (value.length === 0) {
|
|
952
|
-
return {
|
|
953
|
-
nodes: setText(item, comment, value),
|
|
954
|
-
};
|
|
955
|
-
}
|
|
956
|
-
let templates = value.filter(item => isFragment(item) && item.identifier != null);
|
|
957
|
-
const next = templates.map(fragment => fragment.identifier);
|
|
958
|
-
const previous = item.fragments?.map(fragment => fragment.identifier) ?? [];
|
|
959
|
-
if (new Set(next).size !== templates.length) {
|
|
960
|
-
templates = [];
|
|
961
|
-
}
|
|
962
|
-
const noTemplates = templates.length === 0;
|
|
963
|
-
if (noTemplates ||
|
|
964
|
-
item.nodes == null ||
|
|
965
|
-
previous.some(identifier => identifier == null)) {
|
|
966
|
-
return {
|
|
967
|
-
fragments: noTemplates ? undefined : templates,
|
|
968
|
-
nodes: setNodes(item, comment, noTemplates
|
|
969
|
-
? value.flatMap(item => createNodes(item))
|
|
970
|
-
: templates.flatMap(template => template.get())),
|
|
971
|
-
};
|
|
972
|
-
}
|
|
973
|
-
return handleArray({
|
|
974
|
-
next,
|
|
975
|
-
previous,
|
|
976
|
-
}, {
|
|
977
|
-
templates,
|
|
978
|
-
fragments: item.fragments ?? [],
|
|
979
|
-
}, item.nodes);
|
|
980
|
-
}
|
|
981
|
-
function setNodes(item, comment, next) {
|
|
982
|
-
if (item.nodes == null) {
|
|
983
|
-
if (comment.parentNode != null) {
|
|
984
|
-
replaceNodes([comment], next);
|
|
985
|
-
}
|
|
986
|
-
else if (item.text?.parentNode != null) {
|
|
987
|
-
replaceNodes([item.text], next);
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
else {
|
|
991
|
-
replaceNodes(item.nodes, next);
|
|
992
|
-
}
|
|
993
|
-
removeFragments(item.fragments);
|
|
994
|
-
return next;
|
|
995
|
-
}
|
|
996
|
-
function setReactiveValue(data, comment, reactive) {
|
|
997
|
-
let item = data.items.find(item => item.nodes?.includes(comment));
|
|
998
|
-
item ??= {};
|
|
999
|
-
item.text = new Text();
|
|
1000
|
-
data.mora.subscribers.add(reactive.subscribe(value => {
|
|
1001
|
-
if (Array.isArray(value)) {
|
|
1002
|
-
setReactiveValueForArray(item, comment, value);
|
|
1003
|
-
}
|
|
1004
|
-
else {
|
|
1005
|
-
setReactiveValueForSingle(item, comment, value);
|
|
1006
|
-
}
|
|
1007
|
-
item.nodes = [...(item.nodes ?? [comment])];
|
|
1008
|
-
}));
|
|
1009
|
-
}
|
|
1010
|
-
function setReactiveValueForArray(item, comment, value) {
|
|
1011
|
-
const result = setArray(item, comment, value);
|
|
1012
|
-
item.fragments = typeof result === 'boolean' ? undefined : result?.fragments;
|
|
1013
|
-
if (typeof result === 'boolean') {
|
|
1014
|
-
if (result) {
|
|
1015
|
-
item.nodes = item.text == null ? [] : [item.text];
|
|
1016
|
-
}
|
|
1017
|
-
else {
|
|
1018
|
-
item.nodes = undefined;
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
else {
|
|
1022
|
-
item.nodes = result?.nodes;
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
function setReactiveValueForSingle(item, comment, value) {
|
|
1026
|
-
const valueIsFragment = isFragment(value);
|
|
1027
|
-
item.fragments = valueIsFragment ? [value] : undefined;
|
|
1028
|
-
if (valueIsFragment || isChildNode(value)) {
|
|
1029
|
-
item.nodes = setNodes(item, comment, createNodes(value));
|
|
1030
|
-
}
|
|
1031
|
-
else {
|
|
1032
|
-
item.nodes = setText(item, comment, value);
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
function setText(item, comment, value) {
|
|
1036
|
-
const isNullable = isNullableOrWhitespace(value);
|
|
1037
|
-
if (item.text != null) {
|
|
1038
|
-
item.text.textContent = isNullable ? '' : getString(value);
|
|
1039
|
-
}
|
|
1040
|
-
let result = false;
|
|
1041
|
-
if (item.nodes != null) {
|
|
1042
|
-
replaceText(item, comment, isNullable);
|
|
1043
|
-
result = !isNullable;
|
|
1044
|
-
}
|
|
1045
|
-
else if (isNullable && comment.parentNode == null) {
|
|
1046
|
-
item.text?.replaceWith(comment);
|
|
1047
|
-
}
|
|
1048
|
-
else if (!isNullable && item?.text?.parentNode == null) {
|
|
1049
|
-
if (item.text != null) {
|
|
1050
|
-
comment.replaceWith(item.text);
|
|
1051
|
-
}
|
|
1052
|
-
result = true;
|
|
1053
|
-
}
|
|
1054
|
-
removeFragments(item.fragments);
|
|
1055
|
-
if (result) {
|
|
1056
|
-
return item.text == null ? [] : [item.text];
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
function mapNode(data, comment) {
|
|
1061
|
-
const matches = EXPRESSION_COMMENT_CONTENT.exec(comment.textContent ?? '');
|
|
1062
|
-
const value = matches == null ? null : data.values[+matches[1]];
|
|
1063
|
-
if (value != null) {
|
|
1064
|
-
mapValue(data, comment, value);
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
function mapNodes(data, nodes) {
|
|
1068
|
-
const { length } = nodes;
|
|
1069
|
-
for (let index = 0; index < length; index += 1) {
|
|
1070
|
-
const node = nodes[index];
|
|
1071
|
-
if (node instanceof Comment) {
|
|
1072
|
-
mapNode(data, node);
|
|
1073
|
-
continue;
|
|
1074
|
-
}
|
|
1075
|
-
if (isHTMLOrSVGElement(node)) {
|
|
1076
|
-
mapAttributes(data, node);
|
|
1077
|
-
}
|
|
1078
|
-
if (node.hasChildNodes()) {
|
|
1079
|
-
mapNodes(data, [...node.childNodes]);
|
|
1080
|
-
}
|
|
1081
|
-
}
|
|
1082
|
-
}
|
|
1083
|
-
function mapValue(data, comment, value) {
|
|
1084
|
-
switch (true) {
|
|
1085
|
-
case typeof value === 'function':
|
|
1086
|
-
setComputedValue(data, comment, value);
|
|
1087
|
-
break;
|
|
1088
|
-
case isFragments(value):
|
|
1089
|
-
handleFragments(value, false);
|
|
1090
|
-
setReactiveValue(data, comment, value.items);
|
|
1091
|
-
break;
|
|
1092
|
-
case isReactive(value):
|
|
1093
|
-
setReactiveValue(data, comment, value);
|
|
1094
|
-
break;
|
|
1095
|
-
default:
|
|
1096
|
-
replaceComment(data, comment, value);
|
|
1097
|
-
break;
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
function replaceComment(data, comment, value) {
|
|
1101
|
-
const item = data.items.find(item => item.nodes?.includes(comment));
|
|
1102
|
-
const nodes = createNodes(value);
|
|
1103
|
-
if (item != null) {
|
|
1104
|
-
item.fragments = isFragment(value) ? [value] : undefined;
|
|
1105
|
-
item.nodes = nodes;
|
|
1106
|
-
}
|
|
1107
|
-
comment.replaceWith(...nodes);
|
|
1108
|
-
}
|
|
1109
|
-
function setComputedValue(data, comment, callback) {
|
|
1110
|
-
const value = computed(callback);
|
|
1111
|
-
data.mora.values.add(value);
|
|
1112
|
-
setReactiveValue(data, comment, value);
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
|
-
function handleExpression(data, prefix, expression) {
|
|
1116
|
-
if (Array.isArray(expression)) {
|
|
1117
|
-
const { length } = expression;
|
|
1118
|
-
let expressions = '';
|
|
1119
|
-
for (let index = 0; index < length; index += 1) {
|
|
1120
|
-
expressions += handleExpression(data, '', expression[index]);
|
|
1121
|
-
}
|
|
1122
|
-
return `${prefix}${expressions}`;
|
|
1123
|
-
}
|
|
1124
|
-
if (typeof expression === 'function' ||
|
|
1125
|
-
(typeof expression === 'object' && expression != null)) {
|
|
1126
|
-
const index = data.values.push(expression) - 1;
|
|
1127
|
-
return `${prefix}<!--abydon.${index}-->`;
|
|
1128
|
-
}
|
|
1129
|
-
return isNullableOrWhitespace(expression) ? prefix : `${prefix}${expression}`;
|
|
1130
|
-
}
|
|
1131
|
-
function parse(data) {
|
|
1132
|
-
if (data.template != null) {
|
|
1133
|
-
return data.template;
|
|
1134
|
-
}
|
|
1135
|
-
const { length } = data.strings;
|
|
1136
|
-
data.template = '';
|
|
1137
|
-
for (let index = 0; index < length; index += 1) {
|
|
1138
|
-
data.template += handleExpression(data, data.strings[index], data.expressions[index]);
|
|
1139
|
-
}
|
|
1140
|
-
data.expressions = [];
|
|
1141
|
-
data.strings = [];
|
|
1142
|
-
return data.template;
|
|
1143
|
-
}
|
|
1144
|
-
|
|
1145
|
-
class Fragment {
|
|
1146
|
-
#data;
|
|
1147
|
-
#configuration = {
|
|
1148
|
-
identifier: undefined,
|
|
1149
|
-
ignoreCache: false,
|
|
1150
|
-
};
|
|
1151
|
-
/**
|
|
1152
|
-
* Fragment identifier
|
|
1153
|
-
*/
|
|
1154
|
-
get identifier() {
|
|
1155
|
-
return this.#configuration.identifier;
|
|
1156
|
-
}
|
|
1157
|
-
constructor(strings, expressions) {
|
|
1158
|
-
Object.defineProperty(this, '$fragment', {
|
|
1159
|
-
value: true,
|
|
1160
|
-
});
|
|
1161
|
-
this.#data = {
|
|
1162
|
-
expressions,
|
|
1163
|
-
strings,
|
|
1164
|
-
items: [],
|
|
1165
|
-
mora: {
|
|
1166
|
-
subscribers: new Set(),
|
|
1167
|
-
values: new Set(),
|
|
1168
|
-
},
|
|
1169
|
-
values: [],
|
|
1170
|
-
};
|
|
1171
|
-
}
|
|
1172
|
-
/**
|
|
1173
|
-
* Append the fragment to the given element
|
|
1174
|
-
* @param element Element to append to
|
|
1175
|
-
*/
|
|
1176
|
-
appendTo(element) {
|
|
1177
|
-
element.append(...this.get());
|
|
1178
|
-
}
|
|
1179
|
-
/**
|
|
1180
|
-
* Configure the fragment
|
|
1181
|
-
* @param configuration Configuration options
|
|
1182
|
-
* @returns Fragment
|
|
1183
|
-
*/
|
|
1184
|
-
configure(configuration) {
|
|
1185
|
-
const actual = isPlainObject(configuration) ? configuration : {};
|
|
1186
|
-
if (actual.identifier !== undefined) {
|
|
1187
|
-
this.#configuration.identifier = actual.identifier;
|
|
1188
|
-
}
|
|
1189
|
-
if (typeof actual.ignoreCache === 'boolean') {
|
|
1190
|
-
this.#configuration.ignoreCache = actual.ignoreCache;
|
|
1191
|
-
}
|
|
1192
|
-
return this;
|
|
1193
|
-
}
|
|
1194
|
-
/**
|
|
1195
|
-
* Get a list of the fragment's nodes
|
|
1196
|
-
* @returns List of nodes
|
|
1197
|
-
*/
|
|
1198
|
-
get() {
|
|
1199
|
-
const data = this.#data;
|
|
1200
|
-
if (data.items.length === 0) {
|
|
1201
|
-
const parsed = parse(data);
|
|
1202
|
-
const templated = html$1(parsed, {
|
|
1203
|
-
ignoreCache: this.#configuration.ignoreCache,
|
|
1204
|
-
sanitizeBooleanAttributes: false,
|
|
1205
|
-
});
|
|
1206
|
-
data.items.splice(0, data.items.length, ...templated.map(node => ({
|
|
1207
|
-
nodes: [node],
|
|
1208
|
-
})));
|
|
1209
|
-
mapNodes(data, data.items.flatMap(item => item.fragments?.flatMap(fragment => fragment.get()) ??
|
|
1210
|
-
item.nodes ??
|
|
1211
|
-
[]));
|
|
1212
|
-
}
|
|
1213
|
-
return [
|
|
1214
|
-
...data.items.flatMap(item => item.fragments?.flatMap(fragment => fragment.get()) ??
|
|
1215
|
-
item.nodes ??
|
|
1216
|
-
[]),
|
|
1217
|
-
];
|
|
1218
|
-
}
|
|
1219
|
-
/**
|
|
1220
|
-
* Set an identifier for the fragment
|
|
1221
|
-
*
|
|
1222
|
-
* _An identifier can be used to uniquely identify a fragment,
|
|
1223
|
-
* which helps prevent re-rendering in certain scenarios._
|
|
1224
|
-
* @param identifier Identifier
|
|
1225
|
-
* @returns Fragment
|
|
1226
|
-
*/
|
|
1227
|
-
identify(identifier) {
|
|
1228
|
-
this.#configuration.identifier = identifier;
|
|
1229
|
-
return this;
|
|
1230
|
-
}
|
|
1231
|
-
/**
|
|
1232
|
-
* Remove the fragment from the DOM
|
|
1233
|
-
*/
|
|
1234
|
-
remove() {
|
|
1235
|
-
removeFragment(this.#data);
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
|
-
function removeFragment(data) {
|
|
1239
|
-
removeMora(data);
|
|
1240
|
-
let { length } = data.items;
|
|
1241
|
-
for (let index = 0; index < length; index += 1) {
|
|
1242
|
-
const { fragments, nodes } = data.items[index];
|
|
1243
|
-
const fragmentsLength = fragments?.length ?? 0;
|
|
1244
|
-
for (let fragmentIndex = 0; fragmentIndex < fragmentsLength; fragmentIndex += 1) {
|
|
1245
|
-
fragments?.[fragmentIndex]?.remove();
|
|
1246
|
-
}
|
|
1247
|
-
removeNodes(nodes ?? []);
|
|
1248
|
-
}
|
|
1249
|
-
data.items.length = 0;
|
|
1250
|
-
length = data.values.length;
|
|
1251
|
-
for (let index = 0; index < length; index += 1) {
|
|
1252
|
-
const value = data.values[index];
|
|
1253
|
-
if (isFragments(value)) {
|
|
1254
|
-
handleFragments(value, true);
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
}
|
|
1258
|
-
function removeMora(data) {
|
|
1259
|
-
const unsubscribers = [...data.mora.subscribers];
|
|
1260
|
-
data.mora.subscribers.clear();
|
|
1261
|
-
data.mora.values.clear();
|
|
1262
|
-
for (const unsubscribe of unsubscribers) {
|
|
1263
|
-
unsubscribe();
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1267
|
-
function fragments(array, identify, fragment) {
|
|
1268
|
-
return new Fragments(array, identify, fragment);
|
|
1269
|
-
}
|
|
1270
|
-
function html(strings, ...values) {
|
|
1271
|
-
return new Fragment(strings, values);
|
|
1272
|
-
}
|
|
1273
|
-
|
|
1274
|
-
export { array, computed, effect, fragments, html, isArray, isComputed, isEffect, isReactive, isSignal, signal, startBatch, stopBatch, store };
|