defuss 3.1.0 → 3.2.1
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/dom-B58Ij3VD.cjs +2907 -0
- package/dist/dom-B5zbx-3T.mjs +2810 -0
- package/dist/dom-BMSWQp9d.cjs +2899 -0
- package/dist/dom-BNE0x2_-.mjs +2823 -0
- package/dist/dom-BiGAr6m-.mjs +2827 -0
- package/dist/dom-BjFpmoeW.mjs +2818 -0
- package/dist/dom-BzXkdUr2.cjs +2916 -0
- package/dist/dom-CUHgK6d1.mjs +2807 -0
- package/dist/dom-Dc6i7wMh.cjs +2912 -0
- package/dist/index-DKd9l_sC.d.ts +1367 -0
- package/dist/index-DnUO13Ql.d.ts +1365 -0
- package/dist/index.cjs +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +3 -3
- package/dist/mount-7zkpjGb9.cjs +29 -0
- package/dist/mount-B241SuNi.mjs +26 -0
- package/dist/mount-BcH7K_c6.mjs +26 -0
- package/dist/mount-DKbhuW_5.cjs +29 -0
- package/dist/mount-DqMUI3Li.cjs +29 -0
- package/dist/mount-OwEsrEgH.mjs +26 -0
- package/dist/mount-TA9rAjfX.mjs +26 -0
- package/dist/mount-WayWo_Wo.cjs +29 -0
- package/dist/mount-cbdw4Rn8.mjs +26 -0
- package/dist/render/client.cjs +2 -2
- package/dist/render/client.d.ts +2 -2
- package/dist/render/client.mjs +3 -3
- package/dist/render/dev/index.cjs +1 -1
- package/dist/render/dev/index.d.ts +1 -1
- package/dist/render/dev/index.mjs +1 -1
- package/dist/render/index.cjs +2 -2
- package/dist/render/index.d.ts +2 -2
- package/dist/render/index.mjs +2 -2
- package/dist/render/server.cjs +2 -2
- package/dist/render/server.d.ts +2 -2
- package/dist/render/server.mjs +3 -3
- package/package.json +6 -6
|
@@ -0,0 +1,2907 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var defussRuntime = require('defuss-runtime');
|
|
4
|
+
|
|
5
|
+
const CAPTURE_ONLY_EVENTS = /* @__PURE__ */ new Set([
|
|
6
|
+
"focus",
|
|
7
|
+
"blur",
|
|
8
|
+
"scroll",
|
|
9
|
+
"mouseenter",
|
|
10
|
+
"mouseleave"
|
|
11
|
+
// Note: focusin/focusout DO bubble, so they're not included here
|
|
12
|
+
]);
|
|
13
|
+
const elementHandlerMap = /* @__PURE__ */ new WeakMap();
|
|
14
|
+
const parseEventPropName = (propName) => {
|
|
15
|
+
if (!propName.startsWith("on")) return null;
|
|
16
|
+
const raw = propName.slice(2);
|
|
17
|
+
if (!raw) return null;
|
|
18
|
+
const lower = raw.toLowerCase();
|
|
19
|
+
const isCapture = lower.endsWith("capture");
|
|
20
|
+
const eventType = isCapture ? lower.slice(0, -"capture".length) : lower;
|
|
21
|
+
if (!eventType) return null;
|
|
22
|
+
return { eventType, capture: isCapture };
|
|
23
|
+
};
|
|
24
|
+
const getOrCreateElementHandlers = (el) => {
|
|
25
|
+
const existing = elementHandlerMap.get(el);
|
|
26
|
+
if (existing) return existing;
|
|
27
|
+
const created = /* @__PURE__ */ new Map();
|
|
28
|
+
elementHandlerMap.set(el, created);
|
|
29
|
+
return created;
|
|
30
|
+
};
|
|
31
|
+
const getEventPath = (event) => {
|
|
32
|
+
const composedPath = event.composedPath?.();
|
|
33
|
+
if (composedPath && composedPath.length > 0) return composedPath;
|
|
34
|
+
const path = [];
|
|
35
|
+
let node = event.target;
|
|
36
|
+
while (node) {
|
|
37
|
+
path.push(node);
|
|
38
|
+
const maybeNode = node;
|
|
39
|
+
if (typeof maybeNode === "object" && maybeNode && "parentNode" in maybeNode) {
|
|
40
|
+
node = maybeNode.parentNode;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
const doc = event.target?.ownerDocument;
|
|
46
|
+
if (doc && path[path.length - 1] !== doc) path.push(doc);
|
|
47
|
+
const win = doc?.defaultView;
|
|
48
|
+
if (win && path[path.length - 1] !== win) path.push(win);
|
|
49
|
+
return path;
|
|
50
|
+
};
|
|
51
|
+
const createPhaseHandler = (eventType, phase) => {
|
|
52
|
+
return (event) => {
|
|
53
|
+
const path = getEventPath(event).filter(
|
|
54
|
+
(t) => typeof t === "object" && t !== null && t.nodeType === 1
|
|
55
|
+
);
|
|
56
|
+
const ordered = phase === "capture" ? [...path].reverse() : path;
|
|
57
|
+
for (const target of ordered) {
|
|
58
|
+
const handlersByEvent = elementHandlerMap.get(target);
|
|
59
|
+
if (!handlersByEvent) continue;
|
|
60
|
+
const entry = handlersByEvent.get(eventType);
|
|
61
|
+
if (!entry) continue;
|
|
62
|
+
if (phase === "capture") {
|
|
63
|
+
if (entry.capture) {
|
|
64
|
+
entry.capture.call(target, event);
|
|
65
|
+
if (event.cancelBubble) return;
|
|
66
|
+
}
|
|
67
|
+
if (entry.captureSet) {
|
|
68
|
+
for (const handler of entry.captureSet) {
|
|
69
|
+
handler.call(target, event);
|
|
70
|
+
if (event.cancelBubble) return;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
if (entry.bubble) {
|
|
75
|
+
entry.bubble.call(target, event);
|
|
76
|
+
if (event.cancelBubble) return;
|
|
77
|
+
}
|
|
78
|
+
if (entry.bubbleSet) {
|
|
79
|
+
for (const handler of entry.bubbleSet) {
|
|
80
|
+
handler.call(target, event);
|
|
81
|
+
if (event.cancelBubble) return;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
const installedRootListeners = /* @__PURE__ */ new WeakMap();
|
|
89
|
+
const ensureRootListener = (root, eventType) => {
|
|
90
|
+
const installed = installedRootListeners.get(root) ?? /* @__PURE__ */ new Set();
|
|
91
|
+
installedRootListeners.set(root, installed);
|
|
92
|
+
const captureKey = `${eventType}:capture`;
|
|
93
|
+
if (!installed.has(captureKey)) {
|
|
94
|
+
root.addEventListener(eventType, createPhaseHandler(eventType, "capture"), true);
|
|
95
|
+
installed.add(captureKey);
|
|
96
|
+
}
|
|
97
|
+
const bubbleKey = `${eventType}:bubble`;
|
|
98
|
+
if (!installed.has(bubbleKey)) {
|
|
99
|
+
root.addEventListener(eventType, createPhaseHandler(eventType, "bubble"), false);
|
|
100
|
+
installed.add(bubbleKey);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
const getEventRoot = (element) => {
|
|
104
|
+
const root = element.getRootNode();
|
|
105
|
+
if (root && root.nodeType === 9) {
|
|
106
|
+
return root;
|
|
107
|
+
}
|
|
108
|
+
if (root && root.nodeType === 11 && "host" in root) {
|
|
109
|
+
return root;
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
};
|
|
113
|
+
const registerDelegatedEvent = (element, eventType, handler, options = {}) => {
|
|
114
|
+
const root = getEventRoot(element);
|
|
115
|
+
const capture = options.capture || CAPTURE_ONLY_EVENTS.has(eventType);
|
|
116
|
+
if (root) {
|
|
117
|
+
ensureRootListener(root, eventType);
|
|
118
|
+
} else if (element.ownerDocument) {
|
|
119
|
+
ensureRootListener(element.ownerDocument, eventType);
|
|
120
|
+
} else {
|
|
121
|
+
element.addEventListener(eventType, handler, capture);
|
|
122
|
+
}
|
|
123
|
+
const byEvent = getOrCreateElementHandlers(element);
|
|
124
|
+
const entry = byEvent.get(eventType) ?? {};
|
|
125
|
+
byEvent.set(eventType, entry);
|
|
126
|
+
if (options.multi) {
|
|
127
|
+
if (capture) {
|
|
128
|
+
if (!entry.captureSet) entry.captureSet = /* @__PURE__ */ new Set();
|
|
129
|
+
entry.captureSet.add(handler);
|
|
130
|
+
} else {
|
|
131
|
+
if (!entry.bubbleSet) entry.bubbleSet = /* @__PURE__ */ new Set();
|
|
132
|
+
entry.bubbleSet.add(handler);
|
|
133
|
+
}
|
|
134
|
+
} else {
|
|
135
|
+
if (capture) {
|
|
136
|
+
entry.capture = handler;
|
|
137
|
+
} else {
|
|
138
|
+
entry.bubble = handler;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
const removeDelegatedEvent = (target, eventType, handler, options = {}) => {
|
|
143
|
+
options.capture || CAPTURE_ONLY_EVENTS.has(eventType);
|
|
144
|
+
const byEvent = elementHandlerMap.get(target);
|
|
145
|
+
if (!byEvent) return;
|
|
146
|
+
const entry = byEvent.get(eventType);
|
|
147
|
+
if (!entry) return;
|
|
148
|
+
if (handler) {
|
|
149
|
+
if (entry.captureSet) {
|
|
150
|
+
entry.captureSet.delete(handler);
|
|
151
|
+
}
|
|
152
|
+
if (entry.bubbleSet) {
|
|
153
|
+
entry.bubbleSet.delete(handler);
|
|
154
|
+
}
|
|
155
|
+
if (entry.capture === handler) {
|
|
156
|
+
entry.capture = void 0;
|
|
157
|
+
}
|
|
158
|
+
if (entry.bubble === handler) {
|
|
159
|
+
entry.bubble = void 0;
|
|
160
|
+
}
|
|
161
|
+
target.removeEventListener(eventType, handler, true);
|
|
162
|
+
target.removeEventListener(eventType, handler, false);
|
|
163
|
+
} else {
|
|
164
|
+
entry.capture = void 0;
|
|
165
|
+
entry.bubble = void 0;
|
|
166
|
+
entry.captureSet = void 0;
|
|
167
|
+
entry.bubbleSet = void 0;
|
|
168
|
+
}
|
|
169
|
+
const isEmpty = !entry.capture && !entry.bubble && (!entry.captureSet || entry.captureSet.size === 0) && (!entry.bubbleSet || entry.bubbleSet.size === 0);
|
|
170
|
+
if (isEmpty) {
|
|
171
|
+
byEvent.delete(eventType);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
const clearDelegatedEvents = (target) => {
|
|
175
|
+
const byEvent = elementHandlerMap.get(target);
|
|
176
|
+
if (!byEvent) return;
|
|
177
|
+
byEvent.clear();
|
|
178
|
+
};
|
|
179
|
+
const clearDelegatedEventsDeep = (root) => {
|
|
180
|
+
clearDelegatedEvents(root);
|
|
181
|
+
const doc = root.ownerDocument;
|
|
182
|
+
if (!doc) return;
|
|
183
|
+
const walker = doc.createTreeWalker(
|
|
184
|
+
root,
|
|
185
|
+
1
|
|
186
|
+
/* NodeFilter.SHOW_ELEMENT */
|
|
187
|
+
);
|
|
188
|
+
let node = walker.nextNode();
|
|
189
|
+
while (node) {
|
|
190
|
+
clearDelegatedEvents(node);
|
|
191
|
+
node = walker.nextNode();
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
const getRegisteredEventTypes = (element) => {
|
|
195
|
+
const byEvent = elementHandlerMap.get(element);
|
|
196
|
+
if (!byEvent) return /* @__PURE__ */ new Set();
|
|
197
|
+
return new Set(byEvent.keys());
|
|
198
|
+
};
|
|
199
|
+
const getRegisteredEventKeys = (element) => {
|
|
200
|
+
const byEvent = elementHandlerMap.get(element);
|
|
201
|
+
if (!byEvent) return /* @__PURE__ */ new Set();
|
|
202
|
+
const keys = /* @__PURE__ */ new Set();
|
|
203
|
+
for (const [eventType, entry] of byEvent) {
|
|
204
|
+
if (entry.bubble || entry.bubbleSet?.size) keys.add(`${eventType}:bubble`);
|
|
205
|
+
if (entry.capture || entry.captureSet?.size) keys.add(`${eventType}:capture`);
|
|
206
|
+
}
|
|
207
|
+
return keys;
|
|
208
|
+
};
|
|
209
|
+
const removeDelegatedEventByKey = (element, eventType, phase) => {
|
|
210
|
+
const byEvent = elementHandlerMap.get(element);
|
|
211
|
+
if (!byEvent) return;
|
|
212
|
+
const entry = byEvent.get(eventType);
|
|
213
|
+
if (!entry) return;
|
|
214
|
+
if (phase === "capture") {
|
|
215
|
+
entry.capture = void 0;
|
|
216
|
+
entry.captureSet = void 0;
|
|
217
|
+
} else {
|
|
218
|
+
entry.bubble = void 0;
|
|
219
|
+
entry.bubbleSet = void 0;
|
|
220
|
+
}
|
|
221
|
+
const isEmpty = !entry.capture && !entry.bubble && (!entry.captureSet || entry.captureSet.size === 0) && (!entry.bubbleSet || entry.bubbleSet.size === 0);
|
|
222
|
+
if (isEmpty) byEvent.delete(eventType);
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
const componentRegistry = /* @__PURE__ */ new WeakMap();
|
|
226
|
+
function isComponentRoot(el) {
|
|
227
|
+
return componentRegistry.has(el);
|
|
228
|
+
}
|
|
229
|
+
function getComponentInstance(el) {
|
|
230
|
+
return componentRegistry.get(el);
|
|
231
|
+
}
|
|
232
|
+
function registerComponent(el, renderFn, props) {
|
|
233
|
+
componentRegistry.set(el, { renderFn, props });
|
|
234
|
+
}
|
|
235
|
+
function unregisterComponent(el) {
|
|
236
|
+
componentRegistry.delete(el);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
class Call {
|
|
240
|
+
name;
|
|
241
|
+
fn;
|
|
242
|
+
args;
|
|
243
|
+
constructor(name, fn, ...args) {
|
|
244
|
+
this.name = name;
|
|
245
|
+
this.fn = fn;
|
|
246
|
+
this.args = args;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
const globalRegistry = globalThis;
|
|
250
|
+
if (!globalRegistry.__defuss_nonChainedReturnCallNames) {
|
|
251
|
+
globalRegistry.__defuss_nonChainedReturnCallNames = [
|
|
252
|
+
"getFirstElement",
|
|
253
|
+
"toArray",
|
|
254
|
+
"map",
|
|
255
|
+
"isHidden",
|
|
256
|
+
"isVisible",
|
|
257
|
+
"hasClass",
|
|
258
|
+
"dimension",
|
|
259
|
+
"position",
|
|
260
|
+
"offset",
|
|
261
|
+
"prop",
|
|
262
|
+
"val",
|
|
263
|
+
"form",
|
|
264
|
+
"attr",
|
|
265
|
+
"data",
|
|
266
|
+
"css",
|
|
267
|
+
"html",
|
|
268
|
+
"serialize"
|
|
269
|
+
];
|
|
270
|
+
}
|
|
271
|
+
function addNonChainedReturnCallNames(callNames) {
|
|
272
|
+
const global = globalRegistry.__defuss_nonChainedReturnCallNames;
|
|
273
|
+
callNames.forEach((name) => {
|
|
274
|
+
if (!global.includes(name)) {
|
|
275
|
+
global.push(name);
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
function getNonChainedReturnCallNames() {
|
|
280
|
+
return [...globalRegistry.__defuss_nonChainedReturnCallNames];
|
|
281
|
+
}
|
|
282
|
+
function isNonChainedReturnCall(callName) {
|
|
283
|
+
return globalRegistry.__defuss_nonChainedReturnCallNames.includes(callName);
|
|
284
|
+
}
|
|
285
|
+
const emptyImpl = (nodes) => {
|
|
286
|
+
nodes.forEach((el) => {
|
|
287
|
+
const element = el;
|
|
288
|
+
const target = element.shadowRoot ?? element;
|
|
289
|
+
while (target.firstChild) {
|
|
290
|
+
const node = target.firstChild;
|
|
291
|
+
if (node instanceof HTMLElement) {
|
|
292
|
+
clearDelegatedEventsDeep(node);
|
|
293
|
+
}
|
|
294
|
+
node.remove();
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
return nodes;
|
|
298
|
+
};
|
|
299
|
+
class CallChainImpl {
|
|
300
|
+
isResolved;
|
|
301
|
+
options;
|
|
302
|
+
elementCreationOptions;
|
|
303
|
+
callStack;
|
|
304
|
+
resultStack;
|
|
305
|
+
stackPointer;
|
|
306
|
+
lastResolvedStackPointer;
|
|
307
|
+
stoppedWithError;
|
|
308
|
+
lastResult;
|
|
309
|
+
length;
|
|
310
|
+
chainStartTime;
|
|
311
|
+
chainAsyncStartTime;
|
|
312
|
+
chainAsyncFinishTime;
|
|
313
|
+
// SSR-ability
|
|
314
|
+
document;
|
|
315
|
+
window;
|
|
316
|
+
performance;
|
|
317
|
+
Parser;
|
|
318
|
+
constructor(options = {}) {
|
|
319
|
+
this.options = {
|
|
320
|
+
...getDefaultDequeryOptions(),
|
|
321
|
+
...options
|
|
322
|
+
};
|
|
323
|
+
const optionsKeys = Object.keys(getDefaultDequeryOptions());
|
|
324
|
+
this.options = defussRuntime.pick(this.options, optionsKeys);
|
|
325
|
+
this.window = this.options.globals.window;
|
|
326
|
+
this.document = this.options.globals.window.document;
|
|
327
|
+
this.performance = this.options.globals.performance;
|
|
328
|
+
this.Parser = this.options.globals.window.DOMParser;
|
|
329
|
+
const elementCreationOptions = defussRuntime.omit(
|
|
330
|
+
options,
|
|
331
|
+
optionsKeys
|
|
332
|
+
);
|
|
333
|
+
this.elementCreationOptions = elementCreationOptions;
|
|
334
|
+
this.callStack = [];
|
|
335
|
+
this.resultStack = options.resultStack ? [options.resultStack] : [];
|
|
336
|
+
this.stackPointer = 0;
|
|
337
|
+
this.lastResolvedStackPointer = 0;
|
|
338
|
+
this.stoppedWithError = null;
|
|
339
|
+
this.lastResult = [];
|
|
340
|
+
this.length = 0;
|
|
341
|
+
this.isResolved = false;
|
|
342
|
+
this.chainStartTime = this.performance.now() ?? 0;
|
|
343
|
+
this.chainAsyncStartTime = 0;
|
|
344
|
+
this.chainAsyncFinishTime = 0;
|
|
345
|
+
}
|
|
346
|
+
get globals() {
|
|
347
|
+
return this.options.globals;
|
|
348
|
+
}
|
|
349
|
+
// sync methods
|
|
350
|
+
// currently selected nodes
|
|
351
|
+
get nodes() {
|
|
352
|
+
return this.resultStack.length > 0 ? this.resultStack[this.resultStack.length - 1] : [];
|
|
353
|
+
}
|
|
354
|
+
// allow for for .. of loop
|
|
355
|
+
[Symbol.iterator]() {
|
|
356
|
+
return this.nodes[Symbol.iterator]();
|
|
357
|
+
}
|
|
358
|
+
// async, direct result method
|
|
359
|
+
getFirstElement() {
|
|
360
|
+
return createCall(
|
|
361
|
+
this,
|
|
362
|
+
"getFirstElement",
|
|
363
|
+
async () => this[0]
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
// async, wrapped/chainable API methods
|
|
367
|
+
debug(cb) {
|
|
368
|
+
return createCall(this, "debug", async () => {
|
|
369
|
+
cb(this);
|
|
370
|
+
return this.nodes;
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
ref(ref) {
|
|
374
|
+
return createCall(this, "ref", async () => {
|
|
375
|
+
if (ref.current) {
|
|
376
|
+
return [ref.current];
|
|
377
|
+
}
|
|
378
|
+
await defussRuntime.waitForRef(ref, this.options.timeout);
|
|
379
|
+
if (ref.current) {
|
|
380
|
+
return [ref.current];
|
|
381
|
+
} else {
|
|
382
|
+
console.log("\u274C ref() - ref is still null after timeout");
|
|
383
|
+
throw new Error("Ref is null or undefined after timeout");
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
query(selector) {
|
|
388
|
+
return createCall(
|
|
389
|
+
this,
|
|
390
|
+
"query",
|
|
391
|
+
async () => {
|
|
392
|
+
return Array.from(
|
|
393
|
+
await waitForDOM(
|
|
394
|
+
() => Array.from(this.document.querySelectorAll(selector)),
|
|
395
|
+
this.options.timeout,
|
|
396
|
+
this.document
|
|
397
|
+
)
|
|
398
|
+
);
|
|
399
|
+
},
|
|
400
|
+
selector
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
next() {
|
|
404
|
+
return traverse(this, "next", (el) => el.nextElementSibling);
|
|
405
|
+
}
|
|
406
|
+
prev() {
|
|
407
|
+
return traverse(this, "prev", (el) => el.previousElementSibling);
|
|
408
|
+
}
|
|
409
|
+
find(selector) {
|
|
410
|
+
return createCall(
|
|
411
|
+
this,
|
|
412
|
+
"find",
|
|
413
|
+
async () => {
|
|
414
|
+
const results = await Promise.all(
|
|
415
|
+
this.nodes.map(async (el) => {
|
|
416
|
+
return await waitForDOM(
|
|
417
|
+
() => Array.from(el.querySelectorAll(selector)),
|
|
418
|
+
this.options.timeout,
|
|
419
|
+
this.document
|
|
420
|
+
);
|
|
421
|
+
})
|
|
422
|
+
);
|
|
423
|
+
return results.flat();
|
|
424
|
+
},
|
|
425
|
+
selector
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
parent() {
|
|
429
|
+
return traverse(this, "parent", (el) => el.parentElement);
|
|
430
|
+
}
|
|
431
|
+
children() {
|
|
432
|
+
return traverse(this, "children", (el) => Array.from(el.children));
|
|
433
|
+
}
|
|
434
|
+
closest(selector) {
|
|
435
|
+
return traverse(this, "closest", (el) => el.closest(selector));
|
|
436
|
+
}
|
|
437
|
+
first() {
|
|
438
|
+
return createCall(this, "first", async () => {
|
|
439
|
+
return this.nodes.slice(0, 1);
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
last() {
|
|
443
|
+
return createCall(this, "last", async () => {
|
|
444
|
+
return this.nodes.slice(-1);
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
attr(name, value) {
|
|
448
|
+
return createGetterSetterCall(
|
|
449
|
+
this,
|
|
450
|
+
"attr",
|
|
451
|
+
value,
|
|
452
|
+
// Getter function
|
|
453
|
+
() => {
|
|
454
|
+
if (this.nodes.length === 0) return null;
|
|
455
|
+
return this.nodes[0].getAttribute(name);
|
|
456
|
+
},
|
|
457
|
+
// Setter function
|
|
458
|
+
(val) => {
|
|
459
|
+
this.nodes.forEach((el) => el.setAttribute(name, val));
|
|
460
|
+
}
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
prop(name, value) {
|
|
464
|
+
return createGetterSetterCall(
|
|
465
|
+
this,
|
|
466
|
+
"prop",
|
|
467
|
+
value,
|
|
468
|
+
// Getter function
|
|
469
|
+
() => {
|
|
470
|
+
if (this.nodes.length === 0) return void 0;
|
|
471
|
+
return this.nodes[0][name];
|
|
472
|
+
},
|
|
473
|
+
// Setter function
|
|
474
|
+
(val) => {
|
|
475
|
+
this.nodes.forEach((el) => {
|
|
476
|
+
el[name] = val;
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
// --- CSS & Class Methods ---
|
|
482
|
+
static resultCache = /* @__PURE__ */ new WeakMap();
|
|
483
|
+
css(prop, value) {
|
|
484
|
+
if (typeof prop === "object") {
|
|
485
|
+
return createCall(this, "css", async () => {
|
|
486
|
+
const elements = this.nodes;
|
|
487
|
+
elements.forEach((el) => {
|
|
488
|
+
const htmlEl = el;
|
|
489
|
+
Object.entries(prop).forEach(([key, val]) => {
|
|
490
|
+
htmlEl.style.setProperty(
|
|
491
|
+
key.replace(/([A-Z])/g, "-$1").toLowerCase(),
|
|
492
|
+
String(val)
|
|
493
|
+
);
|
|
494
|
+
});
|
|
495
|
+
});
|
|
496
|
+
return this.nodes;
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
return createGetterSetterCall(
|
|
500
|
+
this,
|
|
501
|
+
"css",
|
|
502
|
+
value,
|
|
503
|
+
// Getter with caching - returns computed style (jQuery behavior)
|
|
504
|
+
() => {
|
|
505
|
+
if (this.nodes.length === 0) return "";
|
|
506
|
+
const el = this.nodes[0];
|
|
507
|
+
const cache = CallChainImpl.resultCache.get(el) || /* @__PURE__ */ new Map();
|
|
508
|
+
const cacheKey = `css:${prop}`;
|
|
509
|
+
if (cache.has(cacheKey)) {
|
|
510
|
+
return cache.get(cacheKey);
|
|
511
|
+
}
|
|
512
|
+
const computed = this.window.getComputedStyle(el);
|
|
513
|
+
const result = computed.getPropertyValue(prop);
|
|
514
|
+
cache.set(cacheKey, result);
|
|
515
|
+
CallChainImpl.resultCache.set(el, cache);
|
|
516
|
+
return result;
|
|
517
|
+
},
|
|
518
|
+
// Setter with cache invalidation
|
|
519
|
+
(val) => {
|
|
520
|
+
this.nodes.forEach((el) => {
|
|
521
|
+
el.style.setProperty(prop, String(val));
|
|
522
|
+
const cache = CallChainImpl.resultCache.get(el);
|
|
523
|
+
if (cache) {
|
|
524
|
+
cache.delete(`css:${prop}`);
|
|
525
|
+
}
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
addClass(name) {
|
|
531
|
+
return createSyncCall(this, "addClass", () => {
|
|
532
|
+
const list = Array.isArray(name) ? name : [name];
|
|
533
|
+
this.nodes.forEach((el) => el.classList.add(...list));
|
|
534
|
+
return this.nodes;
|
|
535
|
+
}, name);
|
|
536
|
+
}
|
|
537
|
+
removeClass(name) {
|
|
538
|
+
return createSyncCall(this, "removeClass", () => {
|
|
539
|
+
const list = Array.isArray(name) ? name : [name];
|
|
540
|
+
this.nodes.forEach((el) => el.classList.remove(...list));
|
|
541
|
+
return this.nodes;
|
|
542
|
+
}, name);
|
|
543
|
+
}
|
|
544
|
+
hasClass(name) {
|
|
545
|
+
return createCall(
|
|
546
|
+
this,
|
|
547
|
+
"hasClass",
|
|
548
|
+
async () => this.nodes.every(
|
|
549
|
+
(el) => el.classList.contains(name)
|
|
550
|
+
)
|
|
551
|
+
);
|
|
552
|
+
}
|
|
553
|
+
toggleClass(name) {
|
|
554
|
+
return createSyncCall(this, "toggleClass", () => {
|
|
555
|
+
this.nodes.forEach((el) => el.classList.toggle(name));
|
|
556
|
+
return this.nodes;
|
|
557
|
+
}, name);
|
|
558
|
+
}
|
|
559
|
+
animateClass(name, duration) {
|
|
560
|
+
return createSyncCall(this, "animateClass", () => {
|
|
561
|
+
this.nodes.forEach((el) => {
|
|
562
|
+
const e = el;
|
|
563
|
+
e.classList.add(name);
|
|
564
|
+
setTimeout(() => e.classList.remove(name), duration);
|
|
565
|
+
});
|
|
566
|
+
return this.nodes;
|
|
567
|
+
}, name, duration);
|
|
568
|
+
}
|
|
569
|
+
// --- Content Manipulation Methods ---
|
|
570
|
+
empty() {
|
|
571
|
+
return createCall(
|
|
572
|
+
this,
|
|
573
|
+
"empty",
|
|
574
|
+
async () => emptyImpl(this.nodes)
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
html(html) {
|
|
578
|
+
return createGetterSetterCall(
|
|
579
|
+
this,
|
|
580
|
+
"html",
|
|
581
|
+
html,
|
|
582
|
+
() => {
|
|
583
|
+
if (this.nodes.length === 0) return "";
|
|
584
|
+
return this.nodes[0].innerHTML;
|
|
585
|
+
},
|
|
586
|
+
(val) => {
|
|
587
|
+
this.nodes.forEach((el) => {
|
|
588
|
+
el.innerHTML = val;
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
);
|
|
592
|
+
}
|
|
593
|
+
jsx(vdom) {
|
|
594
|
+
if (!isJSX(vdom)) {
|
|
595
|
+
throw new Error("Invalid JSX input");
|
|
596
|
+
}
|
|
597
|
+
return createCall(this, "jsx", async () => {
|
|
598
|
+
this.nodes.forEach(
|
|
599
|
+
(el) => updateDomWithVdom(el, vdom, this.globals)
|
|
600
|
+
);
|
|
601
|
+
return this.nodes;
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* Alias for .jsx() - renders new JSX into the selected element(s).
|
|
606
|
+
* Explicitly named to make clear that JSX is being rendered.
|
|
607
|
+
*/
|
|
608
|
+
render(vdom) {
|
|
609
|
+
return this.jsx(vdom);
|
|
610
|
+
}
|
|
611
|
+
text(text) {
|
|
612
|
+
return createGetterSetterCall(
|
|
613
|
+
this,
|
|
614
|
+
"text",
|
|
615
|
+
text,
|
|
616
|
+
// Getter function
|
|
617
|
+
() => {
|
|
618
|
+
if (this.nodes.length === 0) return "";
|
|
619
|
+
return this.nodes[0].textContent || "";
|
|
620
|
+
},
|
|
621
|
+
// Setter function
|
|
622
|
+
(val) => {
|
|
623
|
+
this.nodes.forEach((el) => {
|
|
624
|
+
el.textContent = val;
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
remove() {
|
|
630
|
+
return createCall(this, "remove", async () => {
|
|
631
|
+
const removedElements = [...this.nodes];
|
|
632
|
+
this.nodes.forEach((el) => el.remove());
|
|
633
|
+
return removedElements;
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
replaceWith(content) {
|
|
637
|
+
return createCall(this, "replaceWith", async () => {
|
|
638
|
+
const newElements = [];
|
|
639
|
+
const newElement = await renderNode(content, this);
|
|
640
|
+
for (let i = 0; i < this.nodes.length; i++) {
|
|
641
|
+
const originalEl = this.nodes[i];
|
|
642
|
+
if (!originalEl?.parentNode) continue;
|
|
643
|
+
if (!newElement) continue;
|
|
644
|
+
const nodeToUse = i === 0 ? newElement : newElement.cloneNode(true);
|
|
645
|
+
originalEl.parentNode.replaceChild(nodeToUse, originalEl);
|
|
646
|
+
newElements.push(nodeToUse);
|
|
647
|
+
}
|
|
648
|
+
this.resultStack[this.resultStack.length - 1] = newElements;
|
|
649
|
+
mapArrayIndexAccess(this, this);
|
|
650
|
+
return newElements;
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
append(content) {
|
|
654
|
+
return createCall(this, "append", async () => {
|
|
655
|
+
if (content == null) {
|
|
656
|
+
return this.nodes;
|
|
657
|
+
}
|
|
658
|
+
if (content instanceof Node) {
|
|
659
|
+
this.nodes.forEach((el, index) => {
|
|
660
|
+
if (el && content && !el.isEqualNode(content) && el.parentNode !== content) {
|
|
661
|
+
const nodeToAppend = index === 0 ? content : content.cloneNode(true);
|
|
662
|
+
el.appendChild(nodeToAppend);
|
|
663
|
+
}
|
|
664
|
+
});
|
|
665
|
+
return this.nodes;
|
|
666
|
+
}
|
|
667
|
+
const element = await renderNode(content, this);
|
|
668
|
+
if (!element) return this.nodes;
|
|
669
|
+
if (isDequery(content)) {
|
|
670
|
+
const children = content.nodes;
|
|
671
|
+
this.nodes.forEach((parent, parentIndex) => {
|
|
672
|
+
children.forEach((child) => {
|
|
673
|
+
if (!child?.nodeType || !parent?.nodeType) return;
|
|
674
|
+
if (child.isEqualNode(parent) || parent?.parentNode === child) return;
|
|
675
|
+
const nodeToInsert = parentIndex === 0 ? child : child.cloneNode(true);
|
|
676
|
+
parent.appendChild(nodeToInsert);
|
|
677
|
+
});
|
|
678
|
+
});
|
|
679
|
+
} else if (typeof content === "string" && isMarkup(content, this.Parser)) {
|
|
680
|
+
const elements = renderMarkup(content, this.Parser);
|
|
681
|
+
this.nodes.forEach((el, parentIndex) => {
|
|
682
|
+
elements.forEach((childEl) => {
|
|
683
|
+
const node = parentIndex === 0 ? childEl : childEl.cloneNode(true);
|
|
684
|
+
el.appendChild(node);
|
|
685
|
+
});
|
|
686
|
+
});
|
|
687
|
+
} else {
|
|
688
|
+
this.nodes.forEach((el, index) => {
|
|
689
|
+
if (!element) return;
|
|
690
|
+
const nodeToAppend = index === 0 ? element : element.cloneNode(true);
|
|
691
|
+
el.appendChild(nodeToAppend);
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
return this.nodes;
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
appendTo(target) {
|
|
698
|
+
return createCall(this, "appendTo", async () => {
|
|
699
|
+
const nodes = await resolveNodes(
|
|
700
|
+
target,
|
|
701
|
+
this.options.timeout,
|
|
702
|
+
this.document
|
|
703
|
+
);
|
|
704
|
+
if (nodes.length === 0) {
|
|
705
|
+
return this.nodes;
|
|
706
|
+
}
|
|
707
|
+
nodes.forEach((node) => {
|
|
708
|
+
this.nodes.forEach((el) => {
|
|
709
|
+
if (!node || !el) return;
|
|
710
|
+
node.appendChild(el.cloneNode(true));
|
|
711
|
+
});
|
|
712
|
+
});
|
|
713
|
+
return this.nodes;
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* @deprecated Use .jsx() or .render() for rendering JSX content. This method will be removed in v4.
|
|
718
|
+
* Note: .update() with props object for component re-rendering is still supported.
|
|
719
|
+
*/
|
|
720
|
+
update(input, transitionConfig) {
|
|
721
|
+
return createCall(this, "update", async () => {
|
|
722
|
+
if (input && typeof input === "object" && !(input instanceof Node) && !isJSX(input) && !isRef(input) && !isDequery(input)) {
|
|
723
|
+
let didImplicitUpdate = false;
|
|
724
|
+
for (const node of this.nodes) {
|
|
725
|
+
if (!(node instanceof Element)) continue;
|
|
726
|
+
const instance = getComponentInstance(node);
|
|
727
|
+
if (!instance) continue;
|
|
728
|
+
Object.assign(instance.props, input);
|
|
729
|
+
const newVNode = instance.renderFn(instance.props);
|
|
730
|
+
updateDomWithVdom(node, newVNode, this.globals);
|
|
731
|
+
instance.prevVNode = newVNode;
|
|
732
|
+
didImplicitUpdate = true;
|
|
733
|
+
}
|
|
734
|
+
if (didImplicitUpdate) {
|
|
735
|
+
return this.nodes;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
return await updateDom(
|
|
739
|
+
input,
|
|
740
|
+
this.nodes,
|
|
741
|
+
this.options.timeout,
|
|
742
|
+
this.Parser,
|
|
743
|
+
transitionConfig
|
|
744
|
+
);
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
on(event, handler) {
|
|
748
|
+
return createSyncCall(
|
|
749
|
+
this,
|
|
750
|
+
"on",
|
|
751
|
+
() => {
|
|
752
|
+
this.nodes.forEach((el) => {
|
|
753
|
+
if (el && typeof el.addEventListener === "function") {
|
|
754
|
+
addElementEvent(el, event, handler);
|
|
755
|
+
}
|
|
756
|
+
});
|
|
757
|
+
return this.nodes;
|
|
758
|
+
},
|
|
759
|
+
event,
|
|
760
|
+
handler
|
|
761
|
+
);
|
|
762
|
+
}
|
|
763
|
+
off(event, handler) {
|
|
764
|
+
return createSyncCall(
|
|
765
|
+
this,
|
|
766
|
+
"off",
|
|
767
|
+
() => {
|
|
768
|
+
this.nodes.forEach((el) => {
|
|
769
|
+
removeElementEvent(el, event, handler);
|
|
770
|
+
});
|
|
771
|
+
return this.nodes;
|
|
772
|
+
},
|
|
773
|
+
event,
|
|
774
|
+
handler
|
|
775
|
+
);
|
|
776
|
+
}
|
|
777
|
+
clearEvents() {
|
|
778
|
+
return createSyncCall(this, "clearEvents", () => {
|
|
779
|
+
this.nodes.forEach((el) => {
|
|
780
|
+
clearElementEvents(el);
|
|
781
|
+
});
|
|
782
|
+
return this.nodes;
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
trigger(eventType) {
|
|
786
|
+
return createSyncCall(
|
|
787
|
+
this,
|
|
788
|
+
"trigger",
|
|
789
|
+
() => {
|
|
790
|
+
this.nodes.forEach(
|
|
791
|
+
(el) => el.dispatchEvent(
|
|
792
|
+
new Event(eventType, { bubbles: true, cancelable: true })
|
|
793
|
+
)
|
|
794
|
+
);
|
|
795
|
+
return this.nodes;
|
|
796
|
+
},
|
|
797
|
+
eventType
|
|
798
|
+
);
|
|
799
|
+
}
|
|
800
|
+
// --- Position Methods ---
|
|
801
|
+
position() {
|
|
802
|
+
return createCall(
|
|
803
|
+
this,
|
|
804
|
+
"position",
|
|
805
|
+
async () => ({
|
|
806
|
+
top: this.nodes[0].offsetTop,
|
|
807
|
+
left: this.nodes[0].offsetLeft
|
|
808
|
+
})
|
|
809
|
+
);
|
|
810
|
+
}
|
|
811
|
+
offset() {
|
|
812
|
+
return createCall(this, "offset", async () => {
|
|
813
|
+
const el = this.nodes[0];
|
|
814
|
+
const rect = el.getBoundingClientRect();
|
|
815
|
+
return {
|
|
816
|
+
top: rect.top + window.scrollY,
|
|
817
|
+
left: rect.left + window.scrollX
|
|
818
|
+
};
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
// --- Data Methods ---
|
|
822
|
+
data(name, value) {
|
|
823
|
+
return createGetterSetterCall(
|
|
824
|
+
this,
|
|
825
|
+
"data",
|
|
826
|
+
value,
|
|
827
|
+
// Getter function
|
|
828
|
+
() => {
|
|
829
|
+
if (this.nodes.length === 0) return void 0;
|
|
830
|
+
return this.nodes[0].dataset[name];
|
|
831
|
+
},
|
|
832
|
+
// Setter function
|
|
833
|
+
(val) => {
|
|
834
|
+
this.nodes.forEach((el) => {
|
|
835
|
+
el.dataset[name] = val;
|
|
836
|
+
});
|
|
837
|
+
}
|
|
838
|
+
);
|
|
839
|
+
}
|
|
840
|
+
val(val) {
|
|
841
|
+
return createGetterSetterCall(
|
|
842
|
+
this,
|
|
843
|
+
"val",
|
|
844
|
+
val,
|
|
845
|
+
// Getter function
|
|
846
|
+
() => {
|
|
847
|
+
if (this.nodes.length === 0) return "";
|
|
848
|
+
const el = this.nodes[0];
|
|
849
|
+
if (el.type === "checkbox") {
|
|
850
|
+
return el.checked;
|
|
851
|
+
}
|
|
852
|
+
return el.value;
|
|
853
|
+
},
|
|
854
|
+
// Setter function
|
|
855
|
+
(value) => {
|
|
856
|
+
this.nodes.forEach((el) => {
|
|
857
|
+
const input = el;
|
|
858
|
+
if (input.type === "checkbox" && typeof value === "boolean") {
|
|
859
|
+
input.checked = value;
|
|
860
|
+
} else {
|
|
861
|
+
input.value = String(value);
|
|
862
|
+
}
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
);
|
|
866
|
+
}
|
|
867
|
+
serialize(format = "querystring") {
|
|
868
|
+
const mapValue = (value) => typeof value === "boolean" ? value ? "on" : "off" : value;
|
|
869
|
+
return createCall(this, "serialize", async () => {
|
|
870
|
+
const formData = getAllFormValues(this);
|
|
871
|
+
if (format === "json") {
|
|
872
|
+
return JSON.stringify(formData);
|
|
873
|
+
} else {
|
|
874
|
+
const urlSearchParams = new URLSearchParams();
|
|
875
|
+
const keys = Object.keys(formData);
|
|
876
|
+
keys.forEach((key) => {
|
|
877
|
+
const value = formData[key];
|
|
878
|
+
if (typeof value === "string") {
|
|
879
|
+
urlSearchParams.append(key, value);
|
|
880
|
+
} else if (typeof value === "boolean") {
|
|
881
|
+
urlSearchParams.append(key, mapValue(value));
|
|
882
|
+
} else if (Array.isArray(value)) {
|
|
883
|
+
value.forEach(
|
|
884
|
+
(value2) => urlSearchParams.append(key, mapValue(value2))
|
|
885
|
+
);
|
|
886
|
+
}
|
|
887
|
+
});
|
|
888
|
+
return urlSearchParams.toString();
|
|
889
|
+
}
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
form(formData) {
|
|
893
|
+
return createGetterSetterCall(
|
|
894
|
+
this,
|
|
895
|
+
"form",
|
|
896
|
+
formData,
|
|
897
|
+
// Getter function
|
|
898
|
+
() => getAllFormValues(this),
|
|
899
|
+
// Setter function
|
|
900
|
+
(values) => {
|
|
901
|
+
this.nodes.forEach((el) => {
|
|
902
|
+
processAllFormElements(el, (input, key) => {
|
|
903
|
+
if (values[key] !== void 0) {
|
|
904
|
+
if (input.type === "checkbox") {
|
|
905
|
+
input.checked = Boolean(values[key]);
|
|
906
|
+
} else {
|
|
907
|
+
input.value = String(values[key]);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
});
|
|
911
|
+
});
|
|
912
|
+
}
|
|
913
|
+
);
|
|
914
|
+
}
|
|
915
|
+
// --- Dimension Methods ---
|
|
916
|
+
dimension(includeMarginOrPadding, includePaddingIfMarginTrue) {
|
|
917
|
+
return createCall(this, "dimension", async () => {
|
|
918
|
+
if (this.nodes.length === 0) {
|
|
919
|
+
return { width: 0, height: 0 };
|
|
920
|
+
}
|
|
921
|
+
const el = this.nodes[0];
|
|
922
|
+
const style = this.window.getComputedStyle(el);
|
|
923
|
+
if (!style) return { width: 0, height: 0 };
|
|
924
|
+
const rect = el.getBoundingClientRect();
|
|
925
|
+
let width = rect.width;
|
|
926
|
+
let height = rect.height;
|
|
927
|
+
let includeMargin = false;
|
|
928
|
+
let includePadding = true;
|
|
929
|
+
if (includePaddingIfMarginTrue !== void 0) {
|
|
930
|
+
includeMargin = !!includeMarginOrPadding;
|
|
931
|
+
includePadding = !!includePaddingIfMarginTrue;
|
|
932
|
+
} else if (includeMarginOrPadding !== void 0) {
|
|
933
|
+
includePadding = !!includeMarginOrPadding;
|
|
934
|
+
}
|
|
935
|
+
if (!includePadding) {
|
|
936
|
+
const paddingLeft = Number.parseFloat(style.paddingLeft) || 0;
|
|
937
|
+
const paddingRight = Number.parseFloat(style.paddingRight) || 0;
|
|
938
|
+
const paddingTop = Number.parseFloat(style.paddingTop) || 0;
|
|
939
|
+
const paddingBottom = Number.parseFloat(style.paddingBottom) || 0;
|
|
940
|
+
const borderLeft = Number.parseFloat(style.borderLeftWidth) || 0;
|
|
941
|
+
const borderRight = Number.parseFloat(style.borderRightWidth) || 0;
|
|
942
|
+
const borderTop = Number.parseFloat(style.borderTopWidth) || 0;
|
|
943
|
+
const borderBottom = Number.parseFloat(style.borderBottomWidth) || 0;
|
|
944
|
+
width -= paddingLeft + paddingRight + borderLeft + borderRight;
|
|
945
|
+
height -= paddingTop + paddingBottom + borderTop + borderBottom;
|
|
946
|
+
}
|
|
947
|
+
if (includeMargin) {
|
|
948
|
+
const marginLeft = Number.parseFloat(style.marginLeft) || 0;
|
|
949
|
+
const marginRight = Number.parseFloat(style.marginRight) || 0;
|
|
950
|
+
const marginTop = Number.parseFloat(style.marginTop) || 0;
|
|
951
|
+
const marginBottom = Number.parseFloat(style.marginBottom) || 0;
|
|
952
|
+
const baseWidthForOuter = includePadding ? rect.width : width;
|
|
953
|
+
const baseHeightForOuter = includePadding ? rect.height : height;
|
|
954
|
+
const outerWidth = baseWidthForOuter + marginLeft + marginRight;
|
|
955
|
+
const outerHeight = baseHeightForOuter + marginTop + marginBottom;
|
|
956
|
+
return {
|
|
957
|
+
width,
|
|
958
|
+
height,
|
|
959
|
+
outerWidth,
|
|
960
|
+
outerHeight
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
return {
|
|
964
|
+
width,
|
|
965
|
+
height
|
|
966
|
+
};
|
|
967
|
+
});
|
|
968
|
+
}
|
|
969
|
+
// --- Visibility Methods ---
|
|
970
|
+
isVisible() {
|
|
971
|
+
return createCall(this, "isVisible", async () => {
|
|
972
|
+
if (this.nodes.length === 0) return false;
|
|
973
|
+
const el = this.nodes[0];
|
|
974
|
+
return checkElementVisibility(el, this.window, this.document);
|
|
975
|
+
});
|
|
976
|
+
}
|
|
977
|
+
isHidden() {
|
|
978
|
+
return createCall(this, "isHidden", async () => {
|
|
979
|
+
if (this.nodes.length === 0) return true;
|
|
980
|
+
const el = this.nodes[0];
|
|
981
|
+
return !checkElementVisibility(el, this.window, this.document);
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
// --- Scrolling Methods ---
|
|
985
|
+
scrollTo(xOrOptions, y) {
|
|
986
|
+
return createCall(this, "scrollTo", async () => {
|
|
987
|
+
return scrollHelper("scrollTo", this.nodes, xOrOptions, y);
|
|
988
|
+
});
|
|
989
|
+
}
|
|
990
|
+
scrollBy(xOrOptions, y) {
|
|
991
|
+
return createCall(this, "scrollBy", async () => {
|
|
992
|
+
return scrollHelper("scrollBy", this.nodes, xOrOptions, y);
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
scrollIntoView(options) {
|
|
996
|
+
return createCall(this, "scrollIntoView", async () => {
|
|
997
|
+
if (this.nodes.length === 0) return this.nodes;
|
|
998
|
+
this.nodes[0].scrollIntoView(options);
|
|
999
|
+
return this.nodes;
|
|
1000
|
+
});
|
|
1001
|
+
}
|
|
1002
|
+
// --- Transformation Methods ---
|
|
1003
|
+
map(cb) {
|
|
1004
|
+
return createCall(this, "map", async () => {
|
|
1005
|
+
const elements = this.nodes;
|
|
1006
|
+
const results = new Array(elements.length);
|
|
1007
|
+
for (let i = 0; i < elements.length; i++) {
|
|
1008
|
+
results[i] = cb(elements[i], i);
|
|
1009
|
+
}
|
|
1010
|
+
return results;
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
toArray() {
|
|
1014
|
+
return createCall(
|
|
1015
|
+
this,
|
|
1016
|
+
"toArray",
|
|
1017
|
+
async () => [...this.nodes]
|
|
1018
|
+
);
|
|
1019
|
+
}
|
|
1020
|
+
filter(selector) {
|
|
1021
|
+
return createCall(
|
|
1022
|
+
this,
|
|
1023
|
+
"filter",
|
|
1024
|
+
async () => this.nodes.filter(
|
|
1025
|
+
(el) => el instanceof Element && el.matches(selector)
|
|
1026
|
+
)
|
|
1027
|
+
);
|
|
1028
|
+
}
|
|
1029
|
+
// --- Cleanup Methods ---
|
|
1030
|
+
/** memory cleanup (chain becomes useless after calling this method) */
|
|
1031
|
+
dispose() {
|
|
1032
|
+
return createCall(this, "dispose", async () => {
|
|
1033
|
+
this.nodes.forEach((el) => {
|
|
1034
|
+
CallChainImpl.resultCache.delete(el);
|
|
1035
|
+
});
|
|
1036
|
+
this.callStack.length = 0;
|
|
1037
|
+
this.resultStack.length = 0;
|
|
1038
|
+
this.stackPointer = 0;
|
|
1039
|
+
this.lastResolvedStackPointer = 0;
|
|
1040
|
+
return void 0;
|
|
1041
|
+
});
|
|
1042
|
+
}
|
|
1043
|
+
ready(callback) {
|
|
1044
|
+
return createCall(this, "ready", async () => {
|
|
1045
|
+
if (this.document.readyState === "complete" || this.document.readyState === "interactive") {
|
|
1046
|
+
if (callback) {
|
|
1047
|
+
callback();
|
|
1048
|
+
}
|
|
1049
|
+
return this.nodes;
|
|
1050
|
+
}
|
|
1051
|
+
const nodes = this.nodes;
|
|
1052
|
+
const document = this.document;
|
|
1053
|
+
return new Promise((resolve) => {
|
|
1054
|
+
const handleDOMContentLoaded = () => {
|
|
1055
|
+
document.removeEventListener(
|
|
1056
|
+
"DOMContentLoaded",
|
|
1057
|
+
handleDOMContentLoaded
|
|
1058
|
+
);
|
|
1059
|
+
if (callback) {
|
|
1060
|
+
callback();
|
|
1061
|
+
}
|
|
1062
|
+
resolve(nodes);
|
|
1063
|
+
};
|
|
1064
|
+
document.addEventListener("DOMContentLoaded", handleDOMContentLoaded);
|
|
1065
|
+
});
|
|
1066
|
+
});
|
|
1067
|
+
}
|
|
1068
|
+
// TODO:
|
|
1069
|
+
// - deserialize (from URL string, JSON, etc.)
|
|
1070
|
+
}
|
|
1071
|
+
class CallChainImplThenable extends CallChainImpl {
|
|
1072
|
+
constructor(options = {}, isResolved = false) {
|
|
1073
|
+
super(options);
|
|
1074
|
+
this.isResolved = isResolved;
|
|
1075
|
+
}
|
|
1076
|
+
// biome-ignore lint/suspicious/noThenProperty: <explanation>
|
|
1077
|
+
then(onfulfilled, onrejected) {
|
|
1078
|
+
this.chainAsyncStartTime = this.performance.now() ?? 0;
|
|
1079
|
+
if (this.stoppedWithError) {
|
|
1080
|
+
return Promise.reject(this.stoppedWithError).then(
|
|
1081
|
+
onfulfilled,
|
|
1082
|
+
onrejected
|
|
1083
|
+
);
|
|
1084
|
+
}
|
|
1085
|
+
if (this.isResolved && this.stackPointer >= this.callStack.length) {
|
|
1086
|
+
this.lastResolvedStackPointer = this.stackPointer;
|
|
1087
|
+
const lastCallName = this.callStack[this.callStack.length - 1]?.name;
|
|
1088
|
+
let result;
|
|
1089
|
+
if (isNonChainedReturnCall(lastCallName)) {
|
|
1090
|
+
result = this.lastResult;
|
|
1091
|
+
} else {
|
|
1092
|
+
result = createSubChain(this, CallChainImpl, true);
|
|
1093
|
+
}
|
|
1094
|
+
this.chainAsyncFinishTime = (this.performance.now() ?? 0) - this.chainAsyncStartTime;
|
|
1095
|
+
return Promise.resolve(result).then(onfulfilled, onrejected);
|
|
1096
|
+
}
|
|
1097
|
+
return runWithTimeGuard(
|
|
1098
|
+
this.options.timeout,
|
|
1099
|
+
async () => {
|
|
1100
|
+
let call;
|
|
1101
|
+
while (this.stackPointer < this.callStack.length) {
|
|
1102
|
+
call = this.callStack[this.stackPointer];
|
|
1103
|
+
try {
|
|
1104
|
+
const callReturnValue = await call.fn.apply(this);
|
|
1105
|
+
this.lastResult = callReturnValue;
|
|
1106
|
+
if (!isNonChainedReturnCall(call.name)) {
|
|
1107
|
+
if (!Array.isArray(callReturnValue)) {
|
|
1108
|
+
throw new Error(`Call "${call.name}" must return an array for chaining.`);
|
|
1109
|
+
}
|
|
1110
|
+
this.resultStack.push(callReturnValue);
|
|
1111
|
+
}
|
|
1112
|
+
if (Array.isArray(this.lastResult)) {
|
|
1113
|
+
mapArrayIndexAccess(this, this);
|
|
1114
|
+
}
|
|
1115
|
+
this.stackPointer++;
|
|
1116
|
+
} catch (err) {
|
|
1117
|
+
this.stoppedWithError = err;
|
|
1118
|
+
throw err;
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
this.isResolved = true;
|
|
1122
|
+
this.chainAsyncFinishTime = (this.performance.now() ?? 0) - this.chainAsyncStartTime;
|
|
1123
|
+
return this;
|
|
1124
|
+
},
|
|
1125
|
+
[this],
|
|
1126
|
+
// ← Pass the chain context as args[0]
|
|
1127
|
+
// Timeout error handler - called by runWithTimeGuard when timeout is exceeded
|
|
1128
|
+
(ms, call) => {
|
|
1129
|
+
this.stoppedWithError = new Error(
|
|
1130
|
+
`Chain execution timeout after ${ms}ms`
|
|
1131
|
+
);
|
|
1132
|
+
}
|
|
1133
|
+
).then((result) => {
|
|
1134
|
+
onfulfilled(result);
|
|
1135
|
+
return result;
|
|
1136
|
+
}).catch(onrejected);
|
|
1137
|
+
}
|
|
1138
|
+
catch(onrejected) {
|
|
1139
|
+
return this.then(void 0, onrejected);
|
|
1140
|
+
}
|
|
1141
|
+
finally(onfinally) {
|
|
1142
|
+
return this.then(
|
|
1143
|
+
(value) => {
|
|
1144
|
+
onfinally?.();
|
|
1145
|
+
return value;
|
|
1146
|
+
},
|
|
1147
|
+
(reason) => {
|
|
1148
|
+
onfinally?.();
|
|
1149
|
+
throw reason;
|
|
1150
|
+
}
|
|
1151
|
+
);
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
function scrollHelper(methodName, elements, xOrOptions, y) {
|
|
1155
|
+
elements.forEach((el) => {
|
|
1156
|
+
const element = el;
|
|
1157
|
+
if (typeof xOrOptions === "object") {
|
|
1158
|
+
element[methodName](xOrOptions);
|
|
1159
|
+
} else if (y !== void 0) {
|
|
1160
|
+
element[methodName](xOrOptions, y);
|
|
1161
|
+
} else {
|
|
1162
|
+
element[methodName](xOrOptions, 0);
|
|
1163
|
+
}
|
|
1164
|
+
});
|
|
1165
|
+
return elements;
|
|
1166
|
+
}
|
|
1167
|
+
function getAllFormValues(chain) {
|
|
1168
|
+
const formFields = {};
|
|
1169
|
+
const mapCheckboxValue = (value) => value === "on" ? true : value;
|
|
1170
|
+
chain.nodes.forEach((el) => {
|
|
1171
|
+
processAllFormElements(el, (input, key) => {
|
|
1172
|
+
if (!key) return;
|
|
1173
|
+
if (input instanceof HTMLInputElement) {
|
|
1174
|
+
if (input.type === "checkbox") {
|
|
1175
|
+
if (input.checked) {
|
|
1176
|
+
const value = mapCheckboxValue(input.value);
|
|
1177
|
+
if (typeof formFields[key] !== "undefined") {
|
|
1178
|
+
formFields[key] = [formFields[key], value];
|
|
1179
|
+
} else if (Array.isArray(formFields[key])) {
|
|
1180
|
+
formFields[key].push(value);
|
|
1181
|
+
} else {
|
|
1182
|
+
formFields[key] = value;
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
} else if (input.type === "radio") {
|
|
1186
|
+
if (input.checked) {
|
|
1187
|
+
formFields[key] = input.value === "on" ? true : input.value;
|
|
1188
|
+
}
|
|
1189
|
+
} else if (input.type === "file") {
|
|
1190
|
+
if (input.files?.length) {
|
|
1191
|
+
const fileNames = Array.from(input.files).map((file) => file.name);
|
|
1192
|
+
formFields[key] = fileNames.length === 1 ? fileNames[0] : fileNames;
|
|
1193
|
+
}
|
|
1194
|
+
} else {
|
|
1195
|
+
formFields[key] = input.value;
|
|
1196
|
+
}
|
|
1197
|
+
} else if (input instanceof HTMLSelectElement) {
|
|
1198
|
+
if (input.multiple) {
|
|
1199
|
+
const values = Array.from(input.selectedOptions).map(
|
|
1200
|
+
(option) => option.value
|
|
1201
|
+
);
|
|
1202
|
+
formFields[key] = values.length === 1 ? values[0] : values;
|
|
1203
|
+
} else {
|
|
1204
|
+
formFields[key] = input.value;
|
|
1205
|
+
}
|
|
1206
|
+
} else if (input instanceof HTMLTextAreaElement) {
|
|
1207
|
+
formFields[key] = input.value;
|
|
1208
|
+
}
|
|
1209
|
+
});
|
|
1210
|
+
});
|
|
1211
|
+
return formFields;
|
|
1212
|
+
}
|
|
1213
|
+
function delayedAutoStart(chain) {
|
|
1214
|
+
if (chain.options.autoStart) {
|
|
1215
|
+
setTimeout(async () => {
|
|
1216
|
+
if (chain.chainAsyncStartTime === 0) {
|
|
1217
|
+
chain = await chain;
|
|
1218
|
+
}
|
|
1219
|
+
}, chain.options.autoStartDelay);
|
|
1220
|
+
}
|
|
1221
|
+
return chain;
|
|
1222
|
+
}
|
|
1223
|
+
function dequery(selectorRefOrEl, options = getDefaultDequeryOptions()) {
|
|
1224
|
+
if (typeof selectorRefOrEl === "function") {
|
|
1225
|
+
const syncChain = dequery("body", options);
|
|
1226
|
+
queueMicrotask(async () => {
|
|
1227
|
+
const result = await selectorRefOrEl();
|
|
1228
|
+
if (!syncChain.isResolved) {
|
|
1229
|
+
if (typeof result !== "undefined") {
|
|
1230
|
+
const newChain = dequery(result, options);
|
|
1231
|
+
syncChain.resultStack = newChain.resultStack;
|
|
1232
|
+
syncChain.lastResult = newChain.lastResult;
|
|
1233
|
+
mapArrayIndexAccess(newChain, syncChain);
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
});
|
|
1237
|
+
return delayedAutoStart(syncChain);
|
|
1238
|
+
}
|
|
1239
|
+
const chain = new CallChainImplThenable({
|
|
1240
|
+
...options,
|
|
1241
|
+
resultStack: []
|
|
1242
|
+
});
|
|
1243
|
+
if (!selectorRefOrEl)
|
|
1244
|
+
throw new Error("dequery: selector/ref/element required");
|
|
1245
|
+
if (typeof selectorRefOrEl === "string") {
|
|
1246
|
+
if (selectorRefOrEl.indexOf("<") === 0) {
|
|
1247
|
+
const elements = renderMarkup(selectorRefOrEl, chain.Parser);
|
|
1248
|
+
const renderRootEl = elements[0];
|
|
1249
|
+
const { text, html, ...attributes } = chain.elementCreationOptions;
|
|
1250
|
+
if (renderRootEl instanceof Element) {
|
|
1251
|
+
Object.entries(attributes).forEach(([key, value]) => {
|
|
1252
|
+
renderRootEl.setAttribute(key, String(value));
|
|
1253
|
+
});
|
|
1254
|
+
if (html) {
|
|
1255
|
+
renderRootEl.innerHTML = html;
|
|
1256
|
+
} else if (text) {
|
|
1257
|
+
renderRootEl.textContent = text;
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
chain.resultStack = [elements];
|
|
1261
|
+
return delayedAutoStart(chain);
|
|
1262
|
+
} else {
|
|
1263
|
+
return delayedAutoStart(
|
|
1264
|
+
chain.query(selectorRefOrEl)
|
|
1265
|
+
);
|
|
1266
|
+
}
|
|
1267
|
+
} else if (isRef(selectorRefOrEl)) {
|
|
1268
|
+
return delayedAutoStart(
|
|
1269
|
+
chain.ref(selectorRefOrEl)
|
|
1270
|
+
);
|
|
1271
|
+
} else if (selectorRefOrEl.nodeType) {
|
|
1272
|
+
chain.resultStack = [[selectorRefOrEl]];
|
|
1273
|
+
return delayedAutoStart(chain);
|
|
1274
|
+
} else if (isJSX(selectorRefOrEl)) {
|
|
1275
|
+
const renderResult = renderIsomorphicSync(
|
|
1276
|
+
selectorRefOrEl,
|
|
1277
|
+
chain.document.body,
|
|
1278
|
+
chain.globals
|
|
1279
|
+
);
|
|
1280
|
+
const elements = typeof renderResult !== "undefined" ? Array.isArray(renderResult) ? renderResult : [renderResult] : [];
|
|
1281
|
+
chain.resultStack = [elements];
|
|
1282
|
+
return delayedAutoStart(chain);
|
|
1283
|
+
}
|
|
1284
|
+
throw new Error("Unsupported selectorOrEl type");
|
|
1285
|
+
}
|
|
1286
|
+
dequery.extend = (ExtensionClass, nonChainedReturnCalls = []) => {
|
|
1287
|
+
const extensionPrototype = ExtensionClass.prototype;
|
|
1288
|
+
const basePrototype = CallChainImpl.prototype;
|
|
1289
|
+
const extensionMethods = Object.getOwnPropertyNames(extensionPrototype);
|
|
1290
|
+
const baseMethods = Object.getOwnPropertyNames(basePrototype);
|
|
1291
|
+
extensionMethods.forEach((methodName) => {
|
|
1292
|
+
if (methodName !== "constructor" && !baseMethods.includes(methodName) && typeof extensionPrototype[methodName] === "function") {
|
|
1293
|
+
CallChainImpl.prototype[methodName] = extensionPrototype[methodName];
|
|
1294
|
+
CallChainImplThenable.prototype[methodName] = extensionPrototype[methodName];
|
|
1295
|
+
}
|
|
1296
|
+
});
|
|
1297
|
+
if (nonChainedReturnCalls.length > 0) {
|
|
1298
|
+
addNonChainedReturnCallNames(nonChainedReturnCalls);
|
|
1299
|
+
}
|
|
1300
|
+
return (selectorRefOrEl, options) => {
|
|
1301
|
+
return dequery(
|
|
1302
|
+
selectorRefOrEl,
|
|
1303
|
+
options
|
|
1304
|
+
);
|
|
1305
|
+
};
|
|
1306
|
+
};
|
|
1307
|
+
const $ = dequery;
|
|
1308
|
+
function isDequery(obj) {
|
|
1309
|
+
return typeof obj === "object" && obj !== null && "isResolved" in obj && "lastResult" in obj && "resultStack" in obj && "callStack" in obj && "stackPointer" in obj;
|
|
1310
|
+
}
|
|
1311
|
+
function isDequeryOptionsObject(o) {
|
|
1312
|
+
return o && typeof o === "object" && o.timeout !== void 0 && o.globals !== void 0;
|
|
1313
|
+
}
|
|
1314
|
+
let defaultOptions = null;
|
|
1315
|
+
function getDefaultDequeryOptions() {
|
|
1316
|
+
if (!defaultOptions) {
|
|
1317
|
+
defaultOptions = {
|
|
1318
|
+
timeout: 5e3,
|
|
1319
|
+
// even long sync chains would execute in < .1ms
|
|
1320
|
+
// so after 1ms, we can assume the "await" in front is
|
|
1321
|
+
// missing (intentionally non-blocking in sync code)
|
|
1322
|
+
autoStartDelay: 1,
|
|
1323
|
+
autoStart: true,
|
|
1324
|
+
resultStack: [],
|
|
1325
|
+
globals: {
|
|
1326
|
+
document: globalThis.document,
|
|
1327
|
+
window: globalThis.window,
|
|
1328
|
+
performance: globalThis.performance
|
|
1329
|
+
}
|
|
1330
|
+
};
|
|
1331
|
+
}
|
|
1332
|
+
return { ...defaultOptions };
|
|
1333
|
+
}
|
|
1334
|
+
function mapArrayIndexAccess(source, target) {
|
|
1335
|
+
const elements = source.nodes;
|
|
1336
|
+
for (let i = 0; i < elements.length; i++) {
|
|
1337
|
+
target[i] = elements[i];
|
|
1338
|
+
}
|
|
1339
|
+
target.length = elements.length;
|
|
1340
|
+
}
|
|
1341
|
+
function createCall(chain, methodName, handler, ...callArgs) {
|
|
1342
|
+
chain.callStack.push(new Call(methodName, handler, ...callArgs));
|
|
1343
|
+
return subChainForNextAwait(chain);
|
|
1344
|
+
}
|
|
1345
|
+
function createSyncCall(chain, methodName, handler, ...callArgs) {
|
|
1346
|
+
const canRunNow = chain.callStack.length === 0;
|
|
1347
|
+
if (canRunNow) {
|
|
1348
|
+
const result = handler();
|
|
1349
|
+
if (Array.isArray(result)) {
|
|
1350
|
+
chain.resultStack.push(result);
|
|
1351
|
+
chain.lastResult = result;
|
|
1352
|
+
} else {
|
|
1353
|
+
chain.lastResult = [result];
|
|
1354
|
+
}
|
|
1355
|
+
return subChainForNextAwait(chain);
|
|
1356
|
+
}
|
|
1357
|
+
chain.callStack.push(
|
|
1358
|
+
new Call(
|
|
1359
|
+
methodName,
|
|
1360
|
+
async () => handler(),
|
|
1361
|
+
...callArgs
|
|
1362
|
+
)
|
|
1363
|
+
);
|
|
1364
|
+
return subChainForNextAwait(chain);
|
|
1365
|
+
}
|
|
1366
|
+
function createGetterSetterCall(chain, methodName, value, getter, setter) {
|
|
1367
|
+
if (value !== void 0) {
|
|
1368
|
+
return createCall(chain, methodName, async () => {
|
|
1369
|
+
setter(value);
|
|
1370
|
+
return chain.nodes;
|
|
1371
|
+
});
|
|
1372
|
+
} else {
|
|
1373
|
+
return createCall(chain, methodName, async () => {
|
|
1374
|
+
return getter();
|
|
1375
|
+
});
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
function createSubChain(source, Constructor = CallChainImpl, isResolved = false) {
|
|
1379
|
+
const subChain = new Constructor(source.options);
|
|
1380
|
+
subChain.callStack = source.callStack;
|
|
1381
|
+
subChain.resultStack = source.resultStack;
|
|
1382
|
+
subChain.stackPointer = source.stackPointer;
|
|
1383
|
+
subChain.stoppedWithError = source.stoppedWithError;
|
|
1384
|
+
subChain.lastResult = source.lastResult;
|
|
1385
|
+
subChain.isResolved = typeof isResolved !== "undefined" ? isResolved : source.isResolved;
|
|
1386
|
+
subChain.lastResolvedStackPointer = source.lastResolvedStackPointer;
|
|
1387
|
+
if (Array.isArray(subChain.lastResult)) {
|
|
1388
|
+
mapArrayIndexAccess(source, subChain);
|
|
1389
|
+
}
|
|
1390
|
+
return delayedAutoStart(subChain);
|
|
1391
|
+
}
|
|
1392
|
+
function subChainForNextAwait(source) {
|
|
1393
|
+
if (source.lastResolvedStackPointer) {
|
|
1394
|
+
source.callStack = source.callStack.slice(source.lastResolvedStackPointer);
|
|
1395
|
+
source.stackPointer = source.stackPointer - source.lastResolvedStackPointer;
|
|
1396
|
+
source.resultStack = source.resultStack.slice(
|
|
1397
|
+
source.lastResolvedStackPointer
|
|
1398
|
+
);
|
|
1399
|
+
source.lastResult = source.resultStack[source.resultStack.length - 1] || [];
|
|
1400
|
+
source.lastResolvedStackPointer = 0;
|
|
1401
|
+
source.stoppedWithError = null;
|
|
1402
|
+
}
|
|
1403
|
+
return source instanceof CallChainImplThenable ? source : createSubChain(source, CallChainImplThenable);
|
|
1404
|
+
}
|
|
1405
|
+
function runWithTimeGuard(timeout, fn, args, onError) {
|
|
1406
|
+
const operationId = Math.random().toString(36).substr(2, 9);
|
|
1407
|
+
return defussRuntime.createTimeoutPromise(
|
|
1408
|
+
timeout,
|
|
1409
|
+
async () => {
|
|
1410
|
+
const chainContext = args[0];
|
|
1411
|
+
if (chainContext?.callStack && chainContext.stackPointer !== void 0) {
|
|
1412
|
+
chainContext.callStack.slice(chainContext.stackPointer).map((call) => call.name).join(" -> ");
|
|
1413
|
+
}
|
|
1414
|
+
const result = await fn(...args);
|
|
1415
|
+
return result;
|
|
1416
|
+
},
|
|
1417
|
+
(ms) => {
|
|
1418
|
+
console.log(`\u{1F534} TIMEOUT [${operationId}] after ${ms}ms`);
|
|
1419
|
+
const chainContext = args[0];
|
|
1420
|
+
if (chainContext?.callStack && chainContext.stackPointer !== void 0) {
|
|
1421
|
+
const currentCall = chainContext.callStack[chainContext.stackPointer];
|
|
1422
|
+
const remainingCalls = chainContext.callStack.slice(chainContext.stackPointer).map((call) => `${call.name}(${call.args.join(", ")})`).join(" -> ");
|
|
1423
|
+
console.log(
|
|
1424
|
+
`\u{1F534} TIMEOUT occurred during call: ${currentCall?.name || "unknown"}`
|
|
1425
|
+
);
|
|
1426
|
+
console.log(`\u{1F534} Remaining calls were: ${remainingCalls}`);
|
|
1427
|
+
} else {
|
|
1428
|
+
console.log("\u{1F534} Call stack at timeout: unknown");
|
|
1429
|
+
}
|
|
1430
|
+
const fakeCall = new Call("timeout", async () => []);
|
|
1431
|
+
onError(ms, fakeCall);
|
|
1432
|
+
}
|
|
1433
|
+
);
|
|
1434
|
+
}
|
|
1435
|
+
async function renderNode(input, chain) {
|
|
1436
|
+
if (input == null) {
|
|
1437
|
+
return null;
|
|
1438
|
+
}
|
|
1439
|
+
if (typeof input === "string") {
|
|
1440
|
+
if (isMarkup(input, chain.Parser)) {
|
|
1441
|
+
return renderMarkup(input, chain.Parser)[0];
|
|
1442
|
+
} else {
|
|
1443
|
+
return chain.document.createTextNode(input);
|
|
1444
|
+
}
|
|
1445
|
+
} else if (isJSX(input)) {
|
|
1446
|
+
return renderIsomorphicSync(
|
|
1447
|
+
input,
|
|
1448
|
+
chain.document.body,
|
|
1449
|
+
chain.options.globals
|
|
1450
|
+
);
|
|
1451
|
+
} else if (isRef(input)) {
|
|
1452
|
+
await defussRuntime.waitForRef(input, chain.options.timeout);
|
|
1453
|
+
return input.current ?? null;
|
|
1454
|
+
} else if (input && typeof input === "object" && "nodeType" in input) {
|
|
1455
|
+
return input;
|
|
1456
|
+
} else if (isDequery(input)) {
|
|
1457
|
+
return await input.getFirstElement();
|
|
1458
|
+
}
|
|
1459
|
+
console.warn("resolveContent: unsupported content type", input);
|
|
1460
|
+
return null;
|
|
1461
|
+
}
|
|
1462
|
+
async function resolveNodes(input, timeout, document) {
|
|
1463
|
+
let nodes = [];
|
|
1464
|
+
if (isRef(input)) {
|
|
1465
|
+
await defussRuntime.waitForRef(input, timeout);
|
|
1466
|
+
nodes = [input.current];
|
|
1467
|
+
} else if (typeof input === "string" && document) {
|
|
1468
|
+
const result = await waitForDOM(
|
|
1469
|
+
() => {
|
|
1470
|
+
const el2 = document.querySelector(input);
|
|
1471
|
+
if (el2) {
|
|
1472
|
+
return [el2];
|
|
1473
|
+
} else {
|
|
1474
|
+
return [];
|
|
1475
|
+
}
|
|
1476
|
+
},
|
|
1477
|
+
timeout,
|
|
1478
|
+
document
|
|
1479
|
+
);
|
|
1480
|
+
const el = result[0];
|
|
1481
|
+
if (el) nodes = [el];
|
|
1482
|
+
} else if (input && typeof input === "object" && "nodeType" in input) {
|
|
1483
|
+
nodes = [input];
|
|
1484
|
+
} else if (isDequery(input)) {
|
|
1485
|
+
const elements = input.nodes;
|
|
1486
|
+
nodes = elements.filter((el) => el.nodeType !== void 0).map((el) => el);
|
|
1487
|
+
} else {
|
|
1488
|
+
console.warn("resolveTargets: expected selector, ref or node, got", input);
|
|
1489
|
+
}
|
|
1490
|
+
return nodes;
|
|
1491
|
+
}
|
|
1492
|
+
function traverse(chain, methodName, selector) {
|
|
1493
|
+
return createCall(chain, methodName, async () => {
|
|
1494
|
+
return chain.nodes.flatMap((el) => {
|
|
1495
|
+
if (el instanceof Element) {
|
|
1496
|
+
try {
|
|
1497
|
+
const result = selector(el);
|
|
1498
|
+
if (Array.isArray(result)) {
|
|
1499
|
+
return result.filter(
|
|
1500
|
+
(item) => item instanceof Element
|
|
1501
|
+
);
|
|
1502
|
+
} else if (result instanceof Element) {
|
|
1503
|
+
return [result];
|
|
1504
|
+
}
|
|
1505
|
+
} catch (err) {
|
|
1506
|
+
console.warn("Error in traverse selector function:", err);
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
return [];
|
|
1510
|
+
});
|
|
1511
|
+
});
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
const newInMemoryGenericStorageBackend = () => {
|
|
1515
|
+
const cache = /* @__PURE__ */ new Map();
|
|
1516
|
+
return {
|
|
1517
|
+
clear: () => {
|
|
1518
|
+
cache.clear();
|
|
1519
|
+
},
|
|
1520
|
+
getItem: (key) => {
|
|
1521
|
+
return cache.get(String(key)) ?? null;
|
|
1522
|
+
},
|
|
1523
|
+
removeItem: (key) => {
|
|
1524
|
+
cache.delete(String(key));
|
|
1525
|
+
},
|
|
1526
|
+
setItem: (key, value) => {
|
|
1527
|
+
cache.set(String(key), value);
|
|
1528
|
+
}
|
|
1529
|
+
};
|
|
1530
|
+
};
|
|
1531
|
+
const memory = newInMemoryGenericStorageBackend();
|
|
1532
|
+
class WebStorageProvider {
|
|
1533
|
+
storage;
|
|
1534
|
+
constructor(storage) {
|
|
1535
|
+
this.storage = storage || memory;
|
|
1536
|
+
}
|
|
1537
|
+
get(key, defaultValue, middlewareFn) {
|
|
1538
|
+
const rawValue = this.storage.getItem(key);
|
|
1539
|
+
if (rawValue === null) return defaultValue;
|
|
1540
|
+
let value;
|
|
1541
|
+
try {
|
|
1542
|
+
value = JSON.parse(rawValue);
|
|
1543
|
+
} catch {
|
|
1544
|
+
return defaultValue;
|
|
1545
|
+
}
|
|
1546
|
+
if (middlewareFn) {
|
|
1547
|
+
value = middlewareFn(key, value);
|
|
1548
|
+
}
|
|
1549
|
+
return value;
|
|
1550
|
+
}
|
|
1551
|
+
set(key, value, middlewareFn) {
|
|
1552
|
+
if (middlewareFn) {
|
|
1553
|
+
value = middlewareFn(key, value);
|
|
1554
|
+
}
|
|
1555
|
+
this.storage.setItem(key, JSON.stringify(value));
|
|
1556
|
+
}
|
|
1557
|
+
remove(key) {
|
|
1558
|
+
this.storage.removeItem(key);
|
|
1559
|
+
}
|
|
1560
|
+
removeAll() {
|
|
1561
|
+
this.storage.clear();
|
|
1562
|
+
}
|
|
1563
|
+
get backendApi() {
|
|
1564
|
+
return this.storage;
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
const getPersistenceProvider$1 = (provider, _options) => {
|
|
1569
|
+
switch (provider) {
|
|
1570
|
+
case "session":
|
|
1571
|
+
return new WebStorageProvider(window.sessionStorage);
|
|
1572
|
+
case "local":
|
|
1573
|
+
return new WebStorageProvider(window.localStorage);
|
|
1574
|
+
}
|
|
1575
|
+
return new WebStorageProvider();
|
|
1576
|
+
};
|
|
1577
|
+
|
|
1578
|
+
const getPersistenceProvider = (_provider, _options) => {
|
|
1579
|
+
return new WebStorageProvider();
|
|
1580
|
+
};
|
|
1581
|
+
|
|
1582
|
+
const isServer = () => typeof window === "undefined" || typeof window.document === "undefined";
|
|
1583
|
+
|
|
1584
|
+
const webstorage = (provider = "local", options) => {
|
|
1585
|
+
if (isServer()) {
|
|
1586
|
+
return getPersistenceProvider();
|
|
1587
|
+
} else {
|
|
1588
|
+
return getPersistenceProvider$1(provider);
|
|
1589
|
+
}
|
|
1590
|
+
};
|
|
1591
|
+
|
|
1592
|
+
const shallowEquals = (a, b) => Object.is(a, b);
|
|
1593
|
+
const deepEquals = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
1594
|
+
const createStore = (initialValue, options = {}) => {
|
|
1595
|
+
const equals = options.equals ?? shallowEquals;
|
|
1596
|
+
let value = initialValue;
|
|
1597
|
+
const listeners = [];
|
|
1598
|
+
const notify = (oldValue, changedKey) => {
|
|
1599
|
+
listeners.forEach((listener) => listener(value, oldValue, changedKey));
|
|
1600
|
+
};
|
|
1601
|
+
let storage = null;
|
|
1602
|
+
let storageKey = null;
|
|
1603
|
+
let storageProvider;
|
|
1604
|
+
const initStorage = (provider) => {
|
|
1605
|
+
if (!storage || storageProvider !== provider) {
|
|
1606
|
+
storage = webstorage(provider);
|
|
1607
|
+
storageProvider = provider;
|
|
1608
|
+
}
|
|
1609
|
+
return storage;
|
|
1610
|
+
};
|
|
1611
|
+
const persistToStorage = () => {
|
|
1612
|
+
if (storage && storageKey) {
|
|
1613
|
+
storage.set(storageKey, value);
|
|
1614
|
+
}
|
|
1615
|
+
};
|
|
1616
|
+
return {
|
|
1617
|
+
// allow reading value but prevent external mutation
|
|
1618
|
+
get value() {
|
|
1619
|
+
return value;
|
|
1620
|
+
},
|
|
1621
|
+
persist(key, provider = "local") {
|
|
1622
|
+
storage = initStorage(provider);
|
|
1623
|
+
storageKey = key;
|
|
1624
|
+
persistToStorage();
|
|
1625
|
+
},
|
|
1626
|
+
restore(key, provider = "local") {
|
|
1627
|
+
storage = initStorage(provider);
|
|
1628
|
+
storageKey = key;
|
|
1629
|
+
const storedValue = storage.get(key, value);
|
|
1630
|
+
const oldValue = value;
|
|
1631
|
+
if (!equals(oldValue, storedValue)) {
|
|
1632
|
+
value = storedValue;
|
|
1633
|
+
notify(oldValue);
|
|
1634
|
+
}
|
|
1635
|
+
},
|
|
1636
|
+
get(path) {
|
|
1637
|
+
return path ? defussRuntime.getByPath(value, path) : value;
|
|
1638
|
+
},
|
|
1639
|
+
/** Get entire store value (clearer API) */
|
|
1640
|
+
getRaw() {
|
|
1641
|
+
return value;
|
|
1642
|
+
},
|
|
1643
|
+
/** Replace entire store value (clearer API) */
|
|
1644
|
+
setRaw(newValue) {
|
|
1645
|
+
const oldValue = value;
|
|
1646
|
+
if (!equals(value, newValue)) {
|
|
1647
|
+
value = newValue;
|
|
1648
|
+
notify(oldValue);
|
|
1649
|
+
persistToStorage();
|
|
1650
|
+
}
|
|
1651
|
+
},
|
|
1652
|
+
/** Reset to initial or provided value */
|
|
1653
|
+
reset(resetValue) {
|
|
1654
|
+
const oldValue = value;
|
|
1655
|
+
const newValue = resetValue ?? initialValue;
|
|
1656
|
+
if (!equals(value, newValue)) {
|
|
1657
|
+
value = newValue;
|
|
1658
|
+
notify(oldValue);
|
|
1659
|
+
persistToStorage();
|
|
1660
|
+
}
|
|
1661
|
+
},
|
|
1662
|
+
set(pathOrValue, newValue) {
|
|
1663
|
+
const oldValue = value;
|
|
1664
|
+
if (newValue === void 0) {
|
|
1665
|
+
if (!equals(value, pathOrValue)) {
|
|
1666
|
+
value = pathOrValue;
|
|
1667
|
+
notify(oldValue);
|
|
1668
|
+
persistToStorage();
|
|
1669
|
+
}
|
|
1670
|
+
} else {
|
|
1671
|
+
const updatedValue = defussRuntime.setByPath(value, pathOrValue, newValue);
|
|
1672
|
+
if (!equals(value, updatedValue)) {
|
|
1673
|
+
value = updatedValue;
|
|
1674
|
+
notify(oldValue, pathOrValue);
|
|
1675
|
+
persistToStorage();
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
},
|
|
1679
|
+
subscribe(listener) {
|
|
1680
|
+
listeners.push(listener);
|
|
1681
|
+
return () => {
|
|
1682
|
+
const index = listeners.indexOf(listener);
|
|
1683
|
+
if (index >= 0) listeners.splice(index, 1);
|
|
1684
|
+
};
|
|
1685
|
+
}
|
|
1686
|
+
};
|
|
1687
|
+
};
|
|
1688
|
+
|
|
1689
|
+
const isRef = (obj) => Boolean(obj && typeof obj === "object" && "current" in obj);
|
|
1690
|
+
function createRef(refUpdateFn, defaultState) {
|
|
1691
|
+
const stateStore = createStore(defaultState);
|
|
1692
|
+
const render = async (input, ref2) => await $(ref2.current).update(input);
|
|
1693
|
+
const ref = {
|
|
1694
|
+
current: null,
|
|
1695
|
+
store: stateStore,
|
|
1696
|
+
get state() {
|
|
1697
|
+
return stateStore.value;
|
|
1698
|
+
},
|
|
1699
|
+
set state(value) {
|
|
1700
|
+
stateStore.set(value);
|
|
1701
|
+
},
|
|
1702
|
+
persist: (key, provider = "local") => {
|
|
1703
|
+
stateStore.persist(key, provider);
|
|
1704
|
+
},
|
|
1705
|
+
restore: (key, provider = "local") => {
|
|
1706
|
+
stateStore.restore(key, provider);
|
|
1707
|
+
},
|
|
1708
|
+
updateState: (state) => {
|
|
1709
|
+
stateStore.set(state);
|
|
1710
|
+
},
|
|
1711
|
+
render: async (input) => render(input, ref),
|
|
1712
|
+
update: async (input) => render(input, ref),
|
|
1713
|
+
subscribe: (refUpdateFn2) => stateStore.subscribe(refUpdateFn2)
|
|
1714
|
+
};
|
|
1715
|
+
if (typeof refUpdateFn === "function") {
|
|
1716
|
+
ref.subscribe(refUpdateFn);
|
|
1717
|
+
}
|
|
1718
|
+
return ref;
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
const injectShakeKeyframes = () => {
|
|
1722
|
+
if (!document.getElementById("defuss-shake")) {
|
|
1723
|
+
const style = document.createElement("style");
|
|
1724
|
+
style.id = "defuss-shake";
|
|
1725
|
+
style.textContent = "@keyframes shake{0%,100%{transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{transform:translate3d(-10px,0,0)}20%,40%,60%,80%{transform:translate3d(10px,0,0)}}";
|
|
1726
|
+
document.head.appendChild(style);
|
|
1727
|
+
}
|
|
1728
|
+
};
|
|
1729
|
+
const getTransitionStyles = (type, duration, easing = "ease-in-out") => {
|
|
1730
|
+
const t = `transform ${duration}ms ${easing}, opacity ${duration}ms ${easing}`;
|
|
1731
|
+
const styles = {
|
|
1732
|
+
fade: {
|
|
1733
|
+
enter: { opacity: "0", transition: t, transform: "translate3d(0,0,0)" },
|
|
1734
|
+
enterActive: { opacity: "1" },
|
|
1735
|
+
exit: { opacity: "1", transition: t, transform: "translate3d(0,0,0)" },
|
|
1736
|
+
exitActive: { opacity: "0" }
|
|
1737
|
+
},
|
|
1738
|
+
"slide-left": {
|
|
1739
|
+
enter: {
|
|
1740
|
+
transform: "translate3d(100%,0,0)",
|
|
1741
|
+
opacity: "0.5",
|
|
1742
|
+
transition: t
|
|
1743
|
+
},
|
|
1744
|
+
enterActive: { transform: "translate3d(0,0,0)", opacity: "1" },
|
|
1745
|
+
exit: { transform: "translate3d(0,0,0)", opacity: "1", transition: t },
|
|
1746
|
+
exitActive: { transform: "translate3d(-100%,0,0)", opacity: "0.5" }
|
|
1747
|
+
},
|
|
1748
|
+
"slide-right": {
|
|
1749
|
+
enter: {
|
|
1750
|
+
transform: "translate3d(-100%,0,0)",
|
|
1751
|
+
opacity: "0.5",
|
|
1752
|
+
transition: t
|
|
1753
|
+
},
|
|
1754
|
+
enterActive: { transform: "translate3d(0,0,0)", opacity: "1" },
|
|
1755
|
+
exit: { transform: "translate3d(0,0,0)", opacity: "1", transition: t },
|
|
1756
|
+
exitActive: { transform: "translate3d(100%,0,0)", opacity: "0.5" }
|
|
1757
|
+
},
|
|
1758
|
+
shake: (() => {
|
|
1759
|
+
injectShakeKeyframes();
|
|
1760
|
+
return {
|
|
1761
|
+
enter: {
|
|
1762
|
+
transform: "translate3d(0,0,0)",
|
|
1763
|
+
opacity: "1",
|
|
1764
|
+
transition: "none"
|
|
1765
|
+
},
|
|
1766
|
+
enterActive: {
|
|
1767
|
+
transform: "translate3d(0,0,0)",
|
|
1768
|
+
opacity: "1",
|
|
1769
|
+
animation: `shake ${duration}ms cubic-bezier(0.36,0.07,0.19,0.97)`
|
|
1770
|
+
},
|
|
1771
|
+
exit: {
|
|
1772
|
+
transform: "translate3d(0,0,0)",
|
|
1773
|
+
opacity: "1",
|
|
1774
|
+
transition: "none"
|
|
1775
|
+
},
|
|
1776
|
+
exitActive: {
|
|
1777
|
+
transform: "translate3d(0,0,0)",
|
|
1778
|
+
opacity: "1",
|
|
1779
|
+
animation: `shake ${duration}ms cubic-bezier(0.36,0.07,0.19,0.97)`
|
|
1780
|
+
}
|
|
1781
|
+
};
|
|
1782
|
+
})()
|
|
1783
|
+
};
|
|
1784
|
+
return styles[type] || { enter: {}, enterActive: {}, exit: {}, exitActive: {} };
|
|
1785
|
+
};
|
|
1786
|
+
const applyStyles = (el, styles) => Object.entries(styles).forEach(
|
|
1787
|
+
([k, v]) => el.style.setProperty(k, String(v))
|
|
1788
|
+
);
|
|
1789
|
+
const DEFAULT_TRANSITION_CONFIG = {
|
|
1790
|
+
type: "fade",
|
|
1791
|
+
duration: 300,
|
|
1792
|
+
easing: "ease-in-out",
|
|
1793
|
+
delay: 0,
|
|
1794
|
+
target: "parent"
|
|
1795
|
+
};
|
|
1796
|
+
const wait = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
1797
|
+
const performCrossfade = async (element, updateCallback, duration, easing) => {
|
|
1798
|
+
const originalStyle = element.style.cssText;
|
|
1799
|
+
const snapshot = element.cloneNode(true);
|
|
1800
|
+
try {
|
|
1801
|
+
const container = element.parentElement || element;
|
|
1802
|
+
const rect = element.getBoundingClientRect();
|
|
1803
|
+
snapshot.style.cssText = `position:absolute;top:${rect.top}px;left:${rect.left}px;width:${rect.width}px;height:${rect.height}px;opacity:1;transition:opacity ${duration}ms ${easing};z-index:1000;`;
|
|
1804
|
+
element.style.opacity = "0";
|
|
1805
|
+
element.style.transition = `opacity ${duration}ms ${easing}`;
|
|
1806
|
+
document.body.appendChild(snapshot);
|
|
1807
|
+
await updateCallback();
|
|
1808
|
+
void element.offsetHeight;
|
|
1809
|
+
snapshot.style.opacity = "0";
|
|
1810
|
+
element.style.opacity = "1";
|
|
1811
|
+
await wait(duration);
|
|
1812
|
+
document.body.removeChild(snapshot);
|
|
1813
|
+
} catch (error) {
|
|
1814
|
+
if (snapshot.parentElement) document.body.removeChild(snapshot);
|
|
1815
|
+
throw error;
|
|
1816
|
+
} finally {
|
|
1817
|
+
element.style.cssText = originalStyle;
|
|
1818
|
+
}
|
|
1819
|
+
};
|
|
1820
|
+
const performTransition = async (element, updateCallback, config = {}) => {
|
|
1821
|
+
const {
|
|
1822
|
+
type = "fade",
|
|
1823
|
+
duration = 300,
|
|
1824
|
+
easing = "ease-in-out",
|
|
1825
|
+
delay = 0
|
|
1826
|
+
} = { ...DEFAULT_TRANSITION_CONFIG, ...config };
|
|
1827
|
+
if (type === "none") {
|
|
1828
|
+
await updateCallback();
|
|
1829
|
+
return;
|
|
1830
|
+
}
|
|
1831
|
+
if (delay > 0) await wait(delay);
|
|
1832
|
+
if (type === "fade") {
|
|
1833
|
+
await performCrossfade(element, updateCallback, duration, easing);
|
|
1834
|
+
return;
|
|
1835
|
+
}
|
|
1836
|
+
const styles = config.styles || getTransitionStyles(type, duration, easing);
|
|
1837
|
+
const originalTransition = element.style.transition;
|
|
1838
|
+
const originalAnimation = element.style.animation;
|
|
1839
|
+
try {
|
|
1840
|
+
if (type === "shake") {
|
|
1841
|
+
element.style.animation = "none";
|
|
1842
|
+
void element.offsetHeight;
|
|
1843
|
+
}
|
|
1844
|
+
applyStyles(element, styles.exit);
|
|
1845
|
+
void element.offsetHeight;
|
|
1846
|
+
applyStyles(element, styles.exitActive);
|
|
1847
|
+
await wait(duration);
|
|
1848
|
+
await updateCallback();
|
|
1849
|
+
applyStyles(element, styles.enter);
|
|
1850
|
+
void element.offsetHeight;
|
|
1851
|
+
applyStyles(element, styles.enterActive);
|
|
1852
|
+
await wait(duration);
|
|
1853
|
+
element.style.transition = originalTransition;
|
|
1854
|
+
element.style.animation = originalAnimation;
|
|
1855
|
+
} catch (error) {
|
|
1856
|
+
element.style.transition = originalTransition;
|
|
1857
|
+
element.style.animation = originalAnimation;
|
|
1858
|
+
throw error;
|
|
1859
|
+
}
|
|
1860
|
+
};
|
|
1861
|
+
|
|
1862
|
+
const queueCallback = (cb) => (...args) => queueMicrotask(() => cb(...args));
|
|
1863
|
+
|
|
1864
|
+
const CLASS_ATTRIBUTE_NAME = "class";
|
|
1865
|
+
const XLINK_ATTRIBUTE_NAME = "xlink";
|
|
1866
|
+
const XMLNS_ATTRIBUTE_NAME = "xmlns";
|
|
1867
|
+
const REF_ATTRIBUTE_NAME = "ref";
|
|
1868
|
+
const DANGEROUSLY_SET_INNER_HTML_ATTRIBUTE = "dangerouslySetInnerHTML";
|
|
1869
|
+
const nsMap = {
|
|
1870
|
+
[XMLNS_ATTRIBUTE_NAME]: "http://www.w3.org/2000/xmlns/",
|
|
1871
|
+
[XLINK_ATTRIBUTE_NAME]: "http://www.w3.org/1999/xlink",
|
|
1872
|
+
svg: "http://www.w3.org/2000/svg"
|
|
1873
|
+
};
|
|
1874
|
+
const isJSXComment = (node) => (
|
|
1875
|
+
/* v8 ignore next */
|
|
1876
|
+
node && typeof node === "object" && !node.attributes && !node.type && !node.children
|
|
1877
|
+
);
|
|
1878
|
+
const filterComments = (children) => children.filter((child) => !isJSXComment(child));
|
|
1879
|
+
const createInPlaceErrorMessageVNode = (error) => ({
|
|
1880
|
+
type: "p",
|
|
1881
|
+
attributes: {},
|
|
1882
|
+
children: [`FATAL ERROR: ${error?.message || error}`]
|
|
1883
|
+
});
|
|
1884
|
+
const jsx = (type, attributes, key, sourceInfo) => {
|
|
1885
|
+
attributes = { ...attributes };
|
|
1886
|
+
if (typeof key !== "undefined") {
|
|
1887
|
+
attributes.key = key;
|
|
1888
|
+
}
|
|
1889
|
+
let children = (attributes?.children ? [].concat(attributes.children) : []).filter((c) => c !== null && c !== void 0 && typeof c !== "boolean");
|
|
1890
|
+
delete attributes?.children;
|
|
1891
|
+
children = filterComments(
|
|
1892
|
+
// Implementation to flatten virtual node children structures like:
|
|
1893
|
+
// [<p>1</p>, [<p>2</p>,<p>3</p>]] to: [<p>1</p>,<p>2</p>,<p>3</p>]
|
|
1894
|
+
[].concat.apply(
|
|
1895
|
+
[],
|
|
1896
|
+
children
|
|
1897
|
+
)
|
|
1898
|
+
);
|
|
1899
|
+
if (type === "fragment") {
|
|
1900
|
+
return filterComments(children);
|
|
1901
|
+
}
|
|
1902
|
+
if (typeof type === "function" && type.constructor.name === "AsyncFunction") {
|
|
1903
|
+
const fallback = attributes?.fallback;
|
|
1904
|
+
const propsForAsyncFn = { ...attributes };
|
|
1905
|
+
delete propsForAsyncFn.fallback;
|
|
1906
|
+
const onMount = async (containerEl) => {
|
|
1907
|
+
try {
|
|
1908
|
+
const resolvedVNode = await type({
|
|
1909
|
+
...propsForAsyncFn,
|
|
1910
|
+
children
|
|
1911
|
+
});
|
|
1912
|
+
if (containerEl && resolvedVNode) {
|
|
1913
|
+
const globals = {
|
|
1914
|
+
window: containerEl.ownerDocument?.defaultView ?? globalThis
|
|
1915
|
+
};
|
|
1916
|
+
updateDomWithVdom(containerEl, resolvedVNode, globals);
|
|
1917
|
+
}
|
|
1918
|
+
} catch (error) {
|
|
1919
|
+
console.error("[defuss] Async component error:", error);
|
|
1920
|
+
if (containerEl) {
|
|
1921
|
+
containerEl.textContent = `Error: ${error?.message || error}`;
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
};
|
|
1925
|
+
return {
|
|
1926
|
+
type: "div",
|
|
1927
|
+
attributes: {
|
|
1928
|
+
key,
|
|
1929
|
+
onMount
|
|
1930
|
+
},
|
|
1931
|
+
children: fallback ? [fallback] : [],
|
|
1932
|
+
sourceInfo
|
|
1933
|
+
};
|
|
1934
|
+
}
|
|
1935
|
+
if (typeof type === "function" && type.constructor.name !== "AsyncFunction") {
|
|
1936
|
+
try {
|
|
1937
|
+
const rendered = type({
|
|
1938
|
+
children,
|
|
1939
|
+
...attributes
|
|
1940
|
+
});
|
|
1941
|
+
if (typeof key !== "undefined" && rendered && typeof rendered === "object") {
|
|
1942
|
+
if ("attributes" in rendered) {
|
|
1943
|
+
rendered.attributes = {
|
|
1944
|
+
...rendered.attributes,
|
|
1945
|
+
key
|
|
1946
|
+
};
|
|
1947
|
+
} else if (Array.isArray(rendered) && rendered.length === 1) {
|
|
1948
|
+
const only = rendered[0];
|
|
1949
|
+
if (only && typeof only === "object" && "attributes" in only) {
|
|
1950
|
+
only.attributes = {
|
|
1951
|
+
...only.attributes,
|
|
1952
|
+
key
|
|
1953
|
+
};
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
return rendered;
|
|
1958
|
+
} catch (error) {
|
|
1959
|
+
if (typeof error === "string") {
|
|
1960
|
+
error = `[JsxError] in ${type.name}: ${error}`;
|
|
1961
|
+
} else if (error instanceof Error) {
|
|
1962
|
+
error.message = `[JsxError] in ${type.name}: ${error.message}`;
|
|
1963
|
+
}
|
|
1964
|
+
return createInPlaceErrorMessageVNode(error);
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
return {
|
|
1968
|
+
type,
|
|
1969
|
+
attributes,
|
|
1970
|
+
children,
|
|
1971
|
+
sourceInfo
|
|
1972
|
+
};
|
|
1973
|
+
};
|
|
1974
|
+
const observeUnmount = (domNode, onUnmount) => {
|
|
1975
|
+
if (!domNode || typeof onUnmount !== "function") {
|
|
1976
|
+
throw new Error(
|
|
1977
|
+
"Invalid arguments. Ensure domNode and onUnmount are valid."
|
|
1978
|
+
);
|
|
1979
|
+
}
|
|
1980
|
+
if (typeof MutationObserver === "undefined") {
|
|
1981
|
+
return;
|
|
1982
|
+
}
|
|
1983
|
+
let parentNode = domNode.parentNode;
|
|
1984
|
+
if (!parentNode) {
|
|
1985
|
+
throw new Error("The provided domNode does not have a parentNode.");
|
|
1986
|
+
}
|
|
1987
|
+
const observer = new MutationObserver((mutationsList) => {
|
|
1988
|
+
for (const mutation of mutationsList) {
|
|
1989
|
+
if (mutation.removedNodes.length > 0) {
|
|
1990
|
+
for (const removedNode of mutation.removedNodes) {
|
|
1991
|
+
if (removedNode === domNode) {
|
|
1992
|
+
queueMicrotask(() => {
|
|
1993
|
+
if (!domNode.isConnected) {
|
|
1994
|
+
onUnmount();
|
|
1995
|
+
observer.disconnect();
|
|
1996
|
+
return;
|
|
1997
|
+
}
|
|
1998
|
+
const newParent = domNode.parentNode;
|
|
1999
|
+
if (newParent && newParent !== parentNode) {
|
|
2000
|
+
parentNode = newParent;
|
|
2001
|
+
observer.disconnect();
|
|
2002
|
+
observer.observe(parentNode, { childList: true });
|
|
2003
|
+
}
|
|
2004
|
+
});
|
|
2005
|
+
return;
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
});
|
|
2011
|
+
observer.observe(parentNode, { childList: true });
|
|
2012
|
+
};
|
|
2013
|
+
const handleLifecycleEventsForOnMount = (newEl) => {
|
|
2014
|
+
if (typeof newEl?.$onMount === "function") {
|
|
2015
|
+
newEl.$onMount(newEl);
|
|
2016
|
+
newEl.$onMount = null;
|
|
2017
|
+
}
|
|
2018
|
+
if (typeof newEl?.$onUnmount === "function") {
|
|
2019
|
+
observeUnmount(newEl, newEl.$onUnmount);
|
|
2020
|
+
}
|
|
2021
|
+
};
|
|
2022
|
+
const getRenderer = (document) => {
|
|
2023
|
+
const renderer = {
|
|
2024
|
+
hasElNamespace: (domElement) => domElement.namespaceURI === nsMap.svg,
|
|
2025
|
+
hasSvgNamespace: (parentElement, type) => renderer.hasElNamespace(parentElement) && type !== "STYLE" && type !== "SCRIPT",
|
|
2026
|
+
createElementOrElements: (virtualNode, parentDomElement) => {
|
|
2027
|
+
if (Array.isArray(virtualNode)) {
|
|
2028
|
+
return renderer.createChildElements(virtualNode, parentDomElement);
|
|
2029
|
+
}
|
|
2030
|
+
if (typeof virtualNode !== "undefined") {
|
|
2031
|
+
return renderer.createElement(virtualNode, parentDomElement);
|
|
2032
|
+
}
|
|
2033
|
+
return renderer.createTextNode("", parentDomElement);
|
|
2034
|
+
},
|
|
2035
|
+
createElement: (virtualNode, parentDomElement) => {
|
|
2036
|
+
let newEl = void 0;
|
|
2037
|
+
try {
|
|
2038
|
+
if (typeof virtualNode === "function" && virtualNode.constructor.name === "AsyncFunction") {
|
|
2039
|
+
newEl = document.createElement("div");
|
|
2040
|
+
} else if (typeof virtualNode === "object" && virtualNode !== null && "type" in virtualNode) {
|
|
2041
|
+
const vNode = virtualNode;
|
|
2042
|
+
if (typeof vNode.type === "function") {
|
|
2043
|
+
newEl = document.createElement("div");
|
|
2044
|
+
newEl.innerText = `FATAL ERROR: ${vNode.type._error}`;
|
|
2045
|
+
} else if (
|
|
2046
|
+
// SVG support
|
|
2047
|
+
typeof vNode.type === "string" && vNode.type.toUpperCase() === "SVG" || parentDomElement && renderer.hasSvgNamespace(
|
|
2048
|
+
parentDomElement,
|
|
2049
|
+
typeof vNode.type === "string" ? vNode.type.toUpperCase() : ""
|
|
2050
|
+
)
|
|
2051
|
+
) {
|
|
2052
|
+
newEl = document.createElementNS(
|
|
2053
|
+
nsMap.svg,
|
|
2054
|
+
vNode.type
|
|
2055
|
+
);
|
|
2056
|
+
} else {
|
|
2057
|
+
newEl = document.createElement(vNode.type);
|
|
2058
|
+
}
|
|
2059
|
+
if (vNode.attributes) {
|
|
2060
|
+
renderer.setAttributes(vNode, newEl);
|
|
2061
|
+
if (vNode.attributes.dangerouslySetInnerHTML) {
|
|
2062
|
+
newEl.innerHTML = vNode.attributes.dangerouslySetInnerHTML.__html;
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
if (vNode.children && !vNode.attributes?.dangerouslySetInnerHTML) {
|
|
2066
|
+
renderer.createChildElements(vNode.children, newEl);
|
|
2067
|
+
}
|
|
2068
|
+
} else {
|
|
2069
|
+
if (typeof virtualNode === "string" || typeof virtualNode === "number") {
|
|
2070
|
+
newEl = document.createElement(String(virtualNode));
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
if (newEl && parentDomElement) {
|
|
2074
|
+
parentDomElement.appendChild(newEl);
|
|
2075
|
+
handleLifecycleEventsForOnMount(newEl);
|
|
2076
|
+
}
|
|
2077
|
+
} catch (e) {
|
|
2078
|
+
console.error(
|
|
2079
|
+
"Fatal error! Error happend while rendering the VDOM!",
|
|
2080
|
+
e,
|
|
2081
|
+
virtualNode
|
|
2082
|
+
);
|
|
2083
|
+
throw e;
|
|
2084
|
+
}
|
|
2085
|
+
return newEl;
|
|
2086
|
+
},
|
|
2087
|
+
createTextNode: (text, domElement) => {
|
|
2088
|
+
const node = document.createTextNode(text.toString());
|
|
2089
|
+
if (domElement) {
|
|
2090
|
+
domElement.appendChild(node);
|
|
2091
|
+
}
|
|
2092
|
+
return node;
|
|
2093
|
+
},
|
|
2094
|
+
createChildElements: (virtualChildren, domElement) => {
|
|
2095
|
+
const children = [];
|
|
2096
|
+
for (let i = 0; i < virtualChildren.length; i++) {
|
|
2097
|
+
const virtualChild = virtualChildren[i];
|
|
2098
|
+
if (typeof virtualChild === "boolean") {
|
|
2099
|
+
continue;
|
|
2100
|
+
}
|
|
2101
|
+
if (virtualChild === null || typeof virtualChild !== "object" && typeof virtualChild !== "function") {
|
|
2102
|
+
children.push(
|
|
2103
|
+
renderer.createTextNode(
|
|
2104
|
+
(typeof virtualChild === "undefined" || virtualChild === null ? "" : virtualChild).toString(),
|
|
2105
|
+
domElement
|
|
2106
|
+
)
|
|
2107
|
+
);
|
|
2108
|
+
} else {
|
|
2109
|
+
children.push(
|
|
2110
|
+
renderer.createElement(virtualChild, domElement)
|
|
2111
|
+
);
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
return children;
|
|
2115
|
+
},
|
|
2116
|
+
setAttribute: (name, value, domElement, virtualNode) => {
|
|
2117
|
+
if (typeof value === "undefined") return;
|
|
2118
|
+
if (name === DANGEROUSLY_SET_INNER_HTML_ATTRIBUTE) return;
|
|
2119
|
+
if (name === "key") {
|
|
2120
|
+
domElement._defussKey = String(value);
|
|
2121
|
+
return;
|
|
2122
|
+
}
|
|
2123
|
+
if (name === REF_ATTRIBUTE_NAME && typeof value !== "function") {
|
|
2124
|
+
const ref = value;
|
|
2125
|
+
ref.current = domElement;
|
|
2126
|
+
domElement._defussRef = value;
|
|
2127
|
+
domElement.$onUnmount = queueCallback(() => {
|
|
2128
|
+
});
|
|
2129
|
+
if (domElement.parentNode) {
|
|
2130
|
+
observeUnmount(domElement, domElement.$onUnmount);
|
|
2131
|
+
} else {
|
|
2132
|
+
queueMicrotask(() => {
|
|
2133
|
+
if (domElement.parentNode) {
|
|
2134
|
+
observeUnmount(domElement, domElement.$onUnmount);
|
|
2135
|
+
}
|
|
2136
|
+
});
|
|
2137
|
+
}
|
|
2138
|
+
return;
|
|
2139
|
+
}
|
|
2140
|
+
const parsed = parseEventPropName(name);
|
|
2141
|
+
if (parsed && typeof value === "function") {
|
|
2142
|
+
const { eventType, capture } = parsed;
|
|
2143
|
+
if (eventType === "mount") {
|
|
2144
|
+
domElement.$onMount = queueCallback(value);
|
|
2145
|
+
return;
|
|
2146
|
+
}
|
|
2147
|
+
if (eventType === "unmount") {
|
|
2148
|
+
if (domElement.$onUnmount) {
|
|
2149
|
+
const existingUnmount = domElement.$onUnmount;
|
|
2150
|
+
domElement.$onUnmount = () => {
|
|
2151
|
+
existingUnmount();
|
|
2152
|
+
value();
|
|
2153
|
+
};
|
|
2154
|
+
} else {
|
|
2155
|
+
domElement.$onUnmount = queueCallback(value);
|
|
2156
|
+
}
|
|
2157
|
+
return;
|
|
2158
|
+
}
|
|
2159
|
+
registerDelegatedEvent(domElement, eventType, value, { capture });
|
|
2160
|
+
return;
|
|
2161
|
+
}
|
|
2162
|
+
if (name === "className") {
|
|
2163
|
+
name = CLASS_ATTRIBUTE_NAME;
|
|
2164
|
+
}
|
|
2165
|
+
if (name === CLASS_ATTRIBUTE_NAME && Array.isArray(value)) {
|
|
2166
|
+
value = value.filter((val) => !!val).join(" ");
|
|
2167
|
+
}
|
|
2168
|
+
const nsEndIndex = name.match(/[A-Z]/)?.index;
|
|
2169
|
+
if (renderer.hasElNamespace(domElement) && nsEndIndex) {
|
|
2170
|
+
const ns = name.substring(0, nsEndIndex).toLowerCase();
|
|
2171
|
+
const attrName = name.substring(nsEndIndex, name.length).toLowerCase();
|
|
2172
|
+
const namespace = nsMap[ns] || null;
|
|
2173
|
+
domElement.setAttributeNS(
|
|
2174
|
+
namespace,
|
|
2175
|
+
ns === XLINK_ATTRIBUTE_NAME || ns === XMLNS_ATTRIBUTE_NAME ? `${ns}:${attrName}` : name,
|
|
2176
|
+
String(value)
|
|
2177
|
+
);
|
|
2178
|
+
} else if (name === "style" && typeof value !== "string") {
|
|
2179
|
+
const styleObj = value;
|
|
2180
|
+
for (const prop of Object.keys(styleObj)) {
|
|
2181
|
+
domElement.style[prop] = String(styleObj[prop]);
|
|
2182
|
+
}
|
|
2183
|
+
} else if (typeof value === "boolean") {
|
|
2184
|
+
domElement[name] = value;
|
|
2185
|
+
} else if (
|
|
2186
|
+
// Controlled input props: use property assignment, not setAttribute
|
|
2187
|
+
// setAttribute updates the default value, property updates the live value
|
|
2188
|
+
(name === "value" || name === "checked" || name === "selectedIndex") && (domElement.nodeName === "INPUT" || domElement.nodeName === "TEXTAREA" || domElement.nodeName === "SELECT")
|
|
2189
|
+
) {
|
|
2190
|
+
domElement[name] = value;
|
|
2191
|
+
} else {
|
|
2192
|
+
domElement.setAttribute(name, String(value));
|
|
2193
|
+
}
|
|
2194
|
+
},
|
|
2195
|
+
setAttributes: (virtualNode, domElement) => {
|
|
2196
|
+
const attrNames = Object.keys(virtualNode.attributes);
|
|
2197
|
+
for (let i = 0; i < attrNames.length; i++) {
|
|
2198
|
+
renderer.setAttribute(
|
|
2199
|
+
attrNames[i],
|
|
2200
|
+
virtualNode.attributes[attrNames[i]],
|
|
2201
|
+
domElement,
|
|
2202
|
+
virtualNode
|
|
2203
|
+
);
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
};
|
|
2207
|
+
return renderer;
|
|
2208
|
+
};
|
|
2209
|
+
const renderIsomorphicSync = (virtualNode, parentDomElement, globals) => {
|
|
2210
|
+
if (isDequery(parentDomElement)) {
|
|
2211
|
+
parentDomElement = parentDomElement.getFirstElement() || parentDomElement;
|
|
2212
|
+
}
|
|
2213
|
+
let renderResult;
|
|
2214
|
+
if (typeof virtualNode === "string") {
|
|
2215
|
+
renderResult = getRenderer(globals.window.document).createTextNode(
|
|
2216
|
+
virtualNode,
|
|
2217
|
+
parentDomElement
|
|
2218
|
+
);
|
|
2219
|
+
} else {
|
|
2220
|
+
renderResult = getRenderer(globals.window.document).createElementOrElements(
|
|
2221
|
+
virtualNode,
|
|
2222
|
+
parentDomElement
|
|
2223
|
+
);
|
|
2224
|
+
}
|
|
2225
|
+
return renderResult;
|
|
2226
|
+
};
|
|
2227
|
+
const renderIsomorphicAsync = async (virtualNode, parentDomElement, globals) => {
|
|
2228
|
+
if (parentDomElement instanceof Promise) {
|
|
2229
|
+
parentDomElement = await parentDomElement;
|
|
2230
|
+
}
|
|
2231
|
+
if (isDequery(parentDomElement)) {
|
|
2232
|
+
parentDomElement = (await parentDomElement.toArray())[0];
|
|
2233
|
+
}
|
|
2234
|
+
if (virtualNode instanceof Promise) {
|
|
2235
|
+
virtualNode = await virtualNode;
|
|
2236
|
+
}
|
|
2237
|
+
return renderIsomorphicSync(
|
|
2238
|
+
virtualNode,
|
|
2239
|
+
parentDomElement,
|
|
2240
|
+
globals
|
|
2241
|
+
);
|
|
2242
|
+
};
|
|
2243
|
+
const globalScopeDomApis = (window, document) => {
|
|
2244
|
+
globalThis.__defuss_document = document;
|
|
2245
|
+
globalThis.__defuss_window = window;
|
|
2246
|
+
};
|
|
2247
|
+
const render = (jsx2, container) => {
|
|
2248
|
+
if (!container) {
|
|
2249
|
+
console.warn("render: container is null or undefined");
|
|
2250
|
+
return;
|
|
2251
|
+
}
|
|
2252
|
+
const globals = {
|
|
2253
|
+
window: container.ownerDocument?.defaultView ?? globalThis
|
|
2254
|
+
};
|
|
2255
|
+
updateDomWithVdom(container, jsx2, globals);
|
|
2256
|
+
};
|
|
2257
|
+
const renderInto = render;
|
|
2258
|
+
const isJSX = (o) => {
|
|
2259
|
+
if (o === null || typeof o !== "object") return false;
|
|
2260
|
+
if (Array.isArray(o)) {
|
|
2261
|
+
return o.every(
|
|
2262
|
+
(item) => isJSX(item) || typeof item === "string" || typeof item === "number"
|
|
2263
|
+
);
|
|
2264
|
+
}
|
|
2265
|
+
if (typeof o.type === "string") return true;
|
|
2266
|
+
if (typeof o.type === "function") return true;
|
|
2267
|
+
if (typeof o.attributes === "object" && typeof o.children === "object")
|
|
2268
|
+
return true;
|
|
2269
|
+
return false;
|
|
2270
|
+
};
|
|
2271
|
+
const Fragment = (props) => props.children;
|
|
2272
|
+
const jsxs = jsx;
|
|
2273
|
+
const jsxDEV = (type, attributes, key, allChildrenAreStatic, sourceInfo, selfReference) => {
|
|
2274
|
+
let renderResult;
|
|
2275
|
+
try {
|
|
2276
|
+
if (sourceInfo) {
|
|
2277
|
+
if (typeof type === "function" && type.constructor.name !== "AsyncFunction") {
|
|
2278
|
+
sourceInfo.exportName = type.name || sourceInfo?.exportName;
|
|
2279
|
+
}
|
|
2280
|
+
sourceInfo.allChildrenAreStatic = allChildrenAreStatic;
|
|
2281
|
+
sourceInfo.selfReference = selfReference;
|
|
2282
|
+
}
|
|
2283
|
+
renderResult = jsx(type, attributes, key, sourceInfo);
|
|
2284
|
+
} catch (error) {
|
|
2285
|
+
console.error(
|
|
2286
|
+
"JSX error:",
|
|
2287
|
+
error,
|
|
2288
|
+
"in",
|
|
2289
|
+
sourceInfo,
|
|
2290
|
+
"component",
|
|
2291
|
+
selfReference
|
|
2292
|
+
);
|
|
2293
|
+
}
|
|
2294
|
+
return renderResult;
|
|
2295
|
+
};
|
|
2296
|
+
async function performCoreDomUpdate(input, nodes, timeout, Parser) {
|
|
2297
|
+
let processedInput = input;
|
|
2298
|
+
if (isDequery(processedInput)) {
|
|
2299
|
+
processedInput = processedInput[0];
|
|
2300
|
+
}
|
|
2301
|
+
if (isRef(processedInput)) {
|
|
2302
|
+
await defussRuntime.waitForRef(processedInput, timeout);
|
|
2303
|
+
processedInput = processedInput.current;
|
|
2304
|
+
}
|
|
2305
|
+
const getGlobalsFromElement = (el) => {
|
|
2306
|
+
const win = el.ownerDocument?.defaultView;
|
|
2307
|
+
return win ?? globalThis;
|
|
2308
|
+
};
|
|
2309
|
+
if (typeof processedInput === "object" && processedInput !== null && "nodeType" in processedInput && typeof processedInput.nodeType === "number") {
|
|
2310
|
+
const vnode = domNodeToVNode(processedInput);
|
|
2311
|
+
nodes.forEach((el) => {
|
|
2312
|
+
if (el) {
|
|
2313
|
+
updateDomWithVdom(el, vnode, getGlobalsFromElement(el));
|
|
2314
|
+
}
|
|
2315
|
+
});
|
|
2316
|
+
return;
|
|
2317
|
+
}
|
|
2318
|
+
if (typeof processedInput === "string") {
|
|
2319
|
+
if (isMarkup(processedInput, Parser)) {
|
|
2320
|
+
const vNodes = htmlStringToVNodes(processedInput, Parser);
|
|
2321
|
+
nodes.forEach((el) => {
|
|
2322
|
+
if (el) {
|
|
2323
|
+
updateDomWithVdom(el, vNodes, getGlobalsFromElement(el));
|
|
2324
|
+
}
|
|
2325
|
+
});
|
|
2326
|
+
} else {
|
|
2327
|
+
nodes.forEach((el) => {
|
|
2328
|
+
if (el) {
|
|
2329
|
+
updateDomWithVdom(
|
|
2330
|
+
el,
|
|
2331
|
+
processedInput,
|
|
2332
|
+
getGlobalsFromElement(el)
|
|
2333
|
+
);
|
|
2334
|
+
}
|
|
2335
|
+
});
|
|
2336
|
+
}
|
|
2337
|
+
} else if (isJSX(processedInput)) {
|
|
2338
|
+
nodes.forEach((el) => {
|
|
2339
|
+
if (el) {
|
|
2340
|
+
updateDomWithVdom(
|
|
2341
|
+
el,
|
|
2342
|
+
processedInput,
|
|
2343
|
+
getGlobalsFromElement(el)
|
|
2344
|
+
);
|
|
2345
|
+
}
|
|
2346
|
+
});
|
|
2347
|
+
} else {
|
|
2348
|
+
console.warn("update: unsupported content type", processedInput);
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
async function updateDom(input, nodes, timeout, Parser, transitionConfig) {
|
|
2352
|
+
if (transitionConfig && transitionConfig.type !== "none") {
|
|
2353
|
+
const config = { ...DEFAULT_TRANSITION_CONFIG, ...transitionConfig };
|
|
2354
|
+
const { target = "self" } = config;
|
|
2355
|
+
const transitionPromises = nodes.map(async (node) => {
|
|
2356
|
+
if (!node) return node;
|
|
2357
|
+
const element = node;
|
|
2358
|
+
const transitionTarget = target === "self" ? element : element.parentElement;
|
|
2359
|
+
if (!transitionTarget) {
|
|
2360
|
+
await performCoreDomUpdate(input, [node], timeout, Parser);
|
|
2361
|
+
return node;
|
|
2362
|
+
}
|
|
2363
|
+
await performTransition(
|
|
2364
|
+
transitionTarget,
|
|
2365
|
+
() => performCoreDomUpdate(input, [node], timeout, Parser),
|
|
2366
|
+
config
|
|
2367
|
+
);
|
|
2368
|
+
return node;
|
|
2369
|
+
});
|
|
2370
|
+
await Promise.all(transitionPromises);
|
|
2371
|
+
return nodes;
|
|
2372
|
+
}
|
|
2373
|
+
await performCoreDomUpdate(input, nodes, timeout, Parser);
|
|
2374
|
+
return nodes;
|
|
2375
|
+
}
|
|
2376
|
+
|
|
2377
|
+
const areDomNodesEqual = (oldNode, newNode) => {
|
|
2378
|
+
if (oldNode === newNode) return true;
|
|
2379
|
+
if (oldNode.nodeType !== newNode.nodeType) return false;
|
|
2380
|
+
if (oldNode.nodeType === Node.ELEMENT_NODE) {
|
|
2381
|
+
const oldElement = oldNode;
|
|
2382
|
+
const newElement = newNode;
|
|
2383
|
+
if (oldElement.tagName !== newElement.tagName) return false;
|
|
2384
|
+
const oldAttrs = oldElement.attributes;
|
|
2385
|
+
const newAttrs = newElement.attributes;
|
|
2386
|
+
if (oldAttrs.length !== newAttrs.length) return false;
|
|
2387
|
+
for (let i = 0; i < oldAttrs.length; i++) {
|
|
2388
|
+
const oldAttr = oldAttrs[i];
|
|
2389
|
+
const newAttrValue = newElement.getAttribute(oldAttr.name);
|
|
2390
|
+
if (oldAttr.value !== newAttrValue) return false;
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
if (oldNode.nodeType === Node.TEXT_NODE) {
|
|
2394
|
+
if (oldNode.textContent !== newNode.textContent) return false;
|
|
2395
|
+
}
|
|
2396
|
+
return true;
|
|
2397
|
+
};
|
|
2398
|
+
function isTextLike(value) {
|
|
2399
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
2400
|
+
}
|
|
2401
|
+
function isVNode(value) {
|
|
2402
|
+
return Boolean(value && typeof value === "object" && "type" in value);
|
|
2403
|
+
}
|
|
2404
|
+
function toValidChild(child) {
|
|
2405
|
+
if (child == null) return child;
|
|
2406
|
+
if (isTextLike(child)) return child;
|
|
2407
|
+
if (isVNode(child)) return child;
|
|
2408
|
+
return void 0;
|
|
2409
|
+
}
|
|
2410
|
+
function normalizeChildren(input) {
|
|
2411
|
+
const raw = [];
|
|
2412
|
+
const pushChild = (child) => {
|
|
2413
|
+
if (Array.isArray(child)) {
|
|
2414
|
+
child.forEach(pushChild);
|
|
2415
|
+
return;
|
|
2416
|
+
}
|
|
2417
|
+
const valid = toValidChild(child);
|
|
2418
|
+
if (typeof valid === "undefined") return;
|
|
2419
|
+
if (isVNode(valid) && (valid.type === "fragment" || valid.type === "Fragment")) {
|
|
2420
|
+
const nested = Array.isArray(valid.children) ? valid.children : [];
|
|
2421
|
+
nested.forEach(pushChild);
|
|
2422
|
+
return;
|
|
2423
|
+
}
|
|
2424
|
+
if (valid === null || typeof valid === "undefined" || typeof valid === "boolean") return;
|
|
2425
|
+
raw.push(valid);
|
|
2426
|
+
};
|
|
2427
|
+
pushChild(input);
|
|
2428
|
+
const fused = [];
|
|
2429
|
+
let buffer = null;
|
|
2430
|
+
const flush = () => {
|
|
2431
|
+
if (buffer !== null && buffer.length > 0) fused.push(buffer);
|
|
2432
|
+
buffer = null;
|
|
2433
|
+
};
|
|
2434
|
+
for (const child of raw) {
|
|
2435
|
+
if (typeof child === "string" || typeof child === "number" || typeof child === "boolean") {
|
|
2436
|
+
buffer = (buffer ?? "") + String(child);
|
|
2437
|
+
continue;
|
|
2438
|
+
}
|
|
2439
|
+
flush();
|
|
2440
|
+
fused.push(child);
|
|
2441
|
+
}
|
|
2442
|
+
flush();
|
|
2443
|
+
return fused;
|
|
2444
|
+
}
|
|
2445
|
+
function getVNodeMatchKey(child) {
|
|
2446
|
+
if (!child || typeof child !== "object") return null;
|
|
2447
|
+
const key = child.attributes?.key;
|
|
2448
|
+
if (typeof key === "string" || typeof key === "number") return `k:${String(key)}`;
|
|
2449
|
+
const id = child.attributes?.id;
|
|
2450
|
+
if (typeof id === "string" && id.length > 0) return `id:${id}`;
|
|
2451
|
+
return null;
|
|
2452
|
+
}
|
|
2453
|
+
function getDomMatchKeys(node) {
|
|
2454
|
+
if (node.nodeType !== Node.ELEMENT_NODE) return [];
|
|
2455
|
+
const el = node;
|
|
2456
|
+
const keys = [];
|
|
2457
|
+
const internalKey = el._defussKey;
|
|
2458
|
+
if (internalKey) keys.push(`k:${internalKey}`);
|
|
2459
|
+
const attrKey = el.getAttribute("key");
|
|
2460
|
+
if (attrKey) keys.push(`k:${attrKey}`);
|
|
2461
|
+
const id = el.id;
|
|
2462
|
+
if (id) keys.push(`id:${id}`);
|
|
2463
|
+
return keys;
|
|
2464
|
+
}
|
|
2465
|
+
function areNodeAndChildMatching(domNode, child) {
|
|
2466
|
+
if (typeof child === "string" || typeof child === "number" || typeof child === "boolean") {
|
|
2467
|
+
return domNode.nodeType === Node.TEXT_NODE;
|
|
2468
|
+
}
|
|
2469
|
+
if (child && typeof child === "object") {
|
|
2470
|
+
if (domNode.nodeType !== Node.ELEMENT_NODE) return false;
|
|
2471
|
+
const el = domNode;
|
|
2472
|
+
const oldTag = el.tagName.toLowerCase();
|
|
2473
|
+
const newTag = typeof child.type === "string" ? child.type.toLowerCase() : "";
|
|
2474
|
+
if (!newTag || oldTag !== newTag) return false;
|
|
2475
|
+
return true;
|
|
2476
|
+
}
|
|
2477
|
+
return false;
|
|
2478
|
+
}
|
|
2479
|
+
function createDomFromChild(child, globals) {
|
|
2480
|
+
const renderer = getRenderer(globals.window.document);
|
|
2481
|
+
if (child == null) return void 0;
|
|
2482
|
+
if (typeof child === "string" || typeof child === "number" || typeof child === "boolean") {
|
|
2483
|
+
return [globals.window.document.createTextNode(String(child))];
|
|
2484
|
+
}
|
|
2485
|
+
const created = renderer.createElementOrElements(child);
|
|
2486
|
+
if (!created) return void 0;
|
|
2487
|
+
const nodes = Array.isArray(created) ? created : [created];
|
|
2488
|
+
return nodes.filter(Boolean);
|
|
2489
|
+
}
|
|
2490
|
+
function shouldPreserveFormStateAttribute(el, attrName, vnode) {
|
|
2491
|
+
const tag = el.tagName.toLowerCase();
|
|
2492
|
+
const hasExplicit = Object.prototype.hasOwnProperty.call(vnode.attributes ?? {}, attrName);
|
|
2493
|
+
if (hasExplicit) return false;
|
|
2494
|
+
if (tag === "input") return attrName === "value" || attrName === "checked";
|
|
2495
|
+
if (tag === "textarea") return attrName === "value";
|
|
2496
|
+
if (tag === "select") return attrName === "value";
|
|
2497
|
+
return false;
|
|
2498
|
+
}
|
|
2499
|
+
function patchElementInPlace(el, vnode, globals) {
|
|
2500
|
+
const renderer = getRenderer(globals.window.document);
|
|
2501
|
+
const existingAttrs = Array.from(el.attributes);
|
|
2502
|
+
const nextAttrs = vnode.attributes ?? {};
|
|
2503
|
+
for (const attr of existingAttrs) {
|
|
2504
|
+
const { name } = attr;
|
|
2505
|
+
if (name === "key") continue;
|
|
2506
|
+
if (name.startsWith("on")) continue;
|
|
2507
|
+
if (name === "class" && (Object.prototype.hasOwnProperty.call(nextAttrs, "class") || Object.prototype.hasOwnProperty.call(nextAttrs, "className"))) {
|
|
2508
|
+
continue;
|
|
2509
|
+
}
|
|
2510
|
+
if (!Object.prototype.hasOwnProperty.call(nextAttrs, name)) {
|
|
2511
|
+
if (shouldPreserveFormStateAttribute(el, name, vnode)) continue;
|
|
2512
|
+
el.removeAttribute(name);
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
const registeredKeys = getRegisteredEventKeys(el);
|
|
2516
|
+
const nextEventKeys = /* @__PURE__ */ new Set();
|
|
2517
|
+
for (const propName of Object.keys(nextAttrs)) {
|
|
2518
|
+
const parsed = parseEventPropName(propName);
|
|
2519
|
+
if (parsed) {
|
|
2520
|
+
const phase = parsed.capture ? "capture" : "bubble";
|
|
2521
|
+
nextEventKeys.add(`${parsed.eventType}:${phase}`);
|
|
2522
|
+
}
|
|
2523
|
+
}
|
|
2524
|
+
for (const key of registeredKeys) {
|
|
2525
|
+
if (!nextEventKeys.has(key)) {
|
|
2526
|
+
const [eventType, phase] = key.split(":");
|
|
2527
|
+
removeDelegatedEventByKey(el, eventType, phase);
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
renderer.setAttributes(vnode, el);
|
|
2531
|
+
handleLifecycleEventsForOnMount(el);
|
|
2532
|
+
const d = vnode.attributes?.dangerouslySetInnerHTML;
|
|
2533
|
+
if (d && typeof d === "object" && typeof d.__html === "string") {
|
|
2534
|
+
el.innerHTML = d.__html;
|
|
2535
|
+
return;
|
|
2536
|
+
}
|
|
2537
|
+
const tag = el.tagName.toLowerCase();
|
|
2538
|
+
if (tag === "textarea") {
|
|
2539
|
+
const isControlled = Object.prototype.hasOwnProperty.call(nextAttrs, "value");
|
|
2540
|
+
const isActive = el.ownerDocument?.activeElement === el;
|
|
2541
|
+
if (isActive && !isControlled) return;
|
|
2542
|
+
}
|
|
2543
|
+
updateDomWithVdom(el, vnode.children ?? [], globals);
|
|
2544
|
+
}
|
|
2545
|
+
function morphNode(domNode, child, globals) {
|
|
2546
|
+
if (typeof child === "string" || typeof child === "number" || typeof child === "boolean") {
|
|
2547
|
+
const text = String(child);
|
|
2548
|
+
if (domNode.nodeType === Node.TEXT_NODE) {
|
|
2549
|
+
if (domNode.nodeValue !== text) domNode.nodeValue = text;
|
|
2550
|
+
return domNode;
|
|
2551
|
+
}
|
|
2552
|
+
const next = globals.window.document.createTextNode(text);
|
|
2553
|
+
domNode.parentNode?.replaceChild(next, domNode);
|
|
2554
|
+
return next;
|
|
2555
|
+
}
|
|
2556
|
+
if (child && typeof child === "object") {
|
|
2557
|
+
const newType = typeof child.type === "string" ? child.type : null;
|
|
2558
|
+
if (!newType) return domNode;
|
|
2559
|
+
if (domNode.nodeType !== Node.ELEMENT_NODE) {
|
|
2560
|
+
const created = createDomFromChild(child, globals);
|
|
2561
|
+
const first = Array.isArray(created) ? created[0] : created;
|
|
2562
|
+
if (!first) return null;
|
|
2563
|
+
domNode.parentNode?.replaceChild(first, domNode);
|
|
2564
|
+
handleLifecycleEventsForOnMount(first);
|
|
2565
|
+
return first;
|
|
2566
|
+
}
|
|
2567
|
+
const el = domNode;
|
|
2568
|
+
const oldTag = el.tagName.toLowerCase();
|
|
2569
|
+
const newTag = newType.toLowerCase();
|
|
2570
|
+
if (oldTag !== newTag) {
|
|
2571
|
+
const created = createDomFromChild(child, globals);
|
|
2572
|
+
const first = Array.isArray(created) ? created[0] : created;
|
|
2573
|
+
if (!first) return null;
|
|
2574
|
+
el.parentNode?.replaceChild(first, el);
|
|
2575
|
+
handleLifecycleEventsForOnMount(first);
|
|
2576
|
+
return first;
|
|
2577
|
+
}
|
|
2578
|
+
patchElementInPlace(el, child, globals);
|
|
2579
|
+
return el;
|
|
2580
|
+
}
|
|
2581
|
+
domNode.parentNode?.removeChild(domNode);
|
|
2582
|
+
return null;
|
|
2583
|
+
}
|
|
2584
|
+
function updateDomWithVdom(parentElement, newVDOM, globals) {
|
|
2585
|
+
const el = parentElement;
|
|
2586
|
+
const isCustomElement = el.tagName.includes("-");
|
|
2587
|
+
const targetRoot = el.shadowRoot && !isCustomElement ? el.shadowRoot : parentElement;
|
|
2588
|
+
const nextChildren = normalizeChildren(newVDOM);
|
|
2589
|
+
const existing = Array.from(targetRoot.childNodes);
|
|
2590
|
+
const keyedPool = /* @__PURE__ */ new Map();
|
|
2591
|
+
const nodeKeys = /* @__PURE__ */ new WeakMap();
|
|
2592
|
+
const unkeyedPool = [];
|
|
2593
|
+
for (const node of existing) {
|
|
2594
|
+
const keys = getDomMatchKeys(node);
|
|
2595
|
+
if (keys.length > 0) {
|
|
2596
|
+
nodeKeys.set(node, keys);
|
|
2597
|
+
for (const k of keys) {
|
|
2598
|
+
if (!keyedPool.has(k)) keyedPool.set(k, node);
|
|
2599
|
+
}
|
|
2600
|
+
} else {
|
|
2601
|
+
unkeyedPool.push(node);
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
const consumeKeyedNode = (node) => {
|
|
2605
|
+
const keys = nodeKeys.get(node) ?? [];
|
|
2606
|
+
for (const k of keys) keyedPool.delete(k);
|
|
2607
|
+
};
|
|
2608
|
+
const takeUnkeyedMatch = (child) => {
|
|
2609
|
+
for (let i = 0; i < unkeyedPool.length; i++) {
|
|
2610
|
+
const candidate = unkeyedPool[i];
|
|
2611
|
+
if (areNodeAndChildMatching(candidate, child)) {
|
|
2612
|
+
unkeyedPool.splice(i, 1);
|
|
2613
|
+
return candidate;
|
|
2614
|
+
}
|
|
2615
|
+
}
|
|
2616
|
+
return void 0;
|
|
2617
|
+
};
|
|
2618
|
+
let domIndex = 0;
|
|
2619
|
+
for (const child of nextChildren) {
|
|
2620
|
+
const key = getVNodeMatchKey(child);
|
|
2621
|
+
let match;
|
|
2622
|
+
if (key) {
|
|
2623
|
+
match = keyedPool.get(key);
|
|
2624
|
+
if (match) consumeKeyedNode(match);
|
|
2625
|
+
} else {
|
|
2626
|
+
match = takeUnkeyedMatch(child);
|
|
2627
|
+
}
|
|
2628
|
+
const anchor = targetRoot.childNodes[domIndex] ?? null;
|
|
2629
|
+
if (match) {
|
|
2630
|
+
if (match !== anchor) {
|
|
2631
|
+
targetRoot.insertBefore(match, anchor);
|
|
2632
|
+
}
|
|
2633
|
+
morphNode(match, child, globals);
|
|
2634
|
+
domIndex++;
|
|
2635
|
+
continue;
|
|
2636
|
+
}
|
|
2637
|
+
const created = createDomFromChild(child, globals);
|
|
2638
|
+
if (!created || Array.isArray(created) && created.length === 0) continue;
|
|
2639
|
+
const nodes = Array.isArray(created) ? created : [created];
|
|
2640
|
+
for (const node of nodes) {
|
|
2641
|
+
targetRoot.insertBefore(node, anchor);
|
|
2642
|
+
handleLifecycleEventsForOnMount(node);
|
|
2643
|
+
domIndex++;
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
const remaining = /* @__PURE__ */ new Set();
|
|
2647
|
+
for (const node of unkeyedPool) remaining.add(node);
|
|
2648
|
+
for (const node of keyedPool.values()) remaining.add(node);
|
|
2649
|
+
for (const node of remaining) {
|
|
2650
|
+
if (node.parentNode === targetRoot) {
|
|
2651
|
+
if (node instanceof HTMLElement) {
|
|
2652
|
+
clearDelegatedEventsDeep(node);
|
|
2653
|
+
}
|
|
2654
|
+
targetRoot.removeChild(node);
|
|
2655
|
+
}
|
|
2656
|
+
}
|
|
2657
|
+
}
|
|
2658
|
+
function replaceDomWithVdom(parentElement, newVDOM, globals) {
|
|
2659
|
+
while (parentElement.firstChild) {
|
|
2660
|
+
parentElement.removeChild(parentElement.firstChild);
|
|
2661
|
+
}
|
|
2662
|
+
const renderer = getRenderer(globals.window.document);
|
|
2663
|
+
const newDom = renderer.createElementOrElements(
|
|
2664
|
+
newVDOM
|
|
2665
|
+
);
|
|
2666
|
+
if (Array.isArray(newDom)) {
|
|
2667
|
+
for (const node of newDom) {
|
|
2668
|
+
if (node) {
|
|
2669
|
+
parentElement.appendChild(node);
|
|
2670
|
+
handleLifecycleEventsForOnMount(node);
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
} else if (newDom) {
|
|
2674
|
+
parentElement.appendChild(newDom);
|
|
2675
|
+
handleLifecycleEventsForOnMount(newDom);
|
|
2676
|
+
}
|
|
2677
|
+
}
|
|
2678
|
+
async function waitForDOM(check, timeout, document) {
|
|
2679
|
+
const initialResult = check();
|
|
2680
|
+
if (initialResult.length) return initialResult;
|
|
2681
|
+
return defussRuntime.createTimeoutPromise(timeout, () => {
|
|
2682
|
+
return new Promise((resolve) => {
|
|
2683
|
+
if (!document) {
|
|
2684
|
+
setTimeout(() => resolve(check()), 0);
|
|
2685
|
+
return;
|
|
2686
|
+
}
|
|
2687
|
+
const observer = new MutationObserver(() => {
|
|
2688
|
+
const result = check();
|
|
2689
|
+
if (result.length) {
|
|
2690
|
+
observer.disconnect();
|
|
2691
|
+
resolve(result);
|
|
2692
|
+
}
|
|
2693
|
+
});
|
|
2694
|
+
observer.observe(document.documentElement, {
|
|
2695
|
+
childList: true,
|
|
2696
|
+
subtree: true,
|
|
2697
|
+
attributes: true
|
|
2698
|
+
});
|
|
2699
|
+
return () => observer.disconnect();
|
|
2700
|
+
});
|
|
2701
|
+
});
|
|
2702
|
+
}
|
|
2703
|
+
function parseDOM(input, type, Parser) {
|
|
2704
|
+
return new Parser().parseFromString(input, type);
|
|
2705
|
+
}
|
|
2706
|
+
function isSVG(input, Parser) {
|
|
2707
|
+
const doc = parseDOM(input, "image/svg+xml", Parser);
|
|
2708
|
+
if (!doc.documentElement) return false;
|
|
2709
|
+
return doc.documentElement.nodeName.toLowerCase() === "svg";
|
|
2710
|
+
}
|
|
2711
|
+
function isHTML(input, Parser) {
|
|
2712
|
+
const doc = parseDOM(input, "text/html", Parser);
|
|
2713
|
+
return doc.documentElement.querySelectorAll("*").length > 2;
|
|
2714
|
+
}
|
|
2715
|
+
const isMarkup = (input, Parser) => input.indexOf("<") > -1 && input.indexOf(">") > -1 && (isHTML(input, Parser) || isSVG(input, Parser));
|
|
2716
|
+
function renderMarkup(markup, Parser, doc) {
|
|
2717
|
+
return Array.from(
|
|
2718
|
+
(doc ? doc : parseDOM(markup, getMimeType(markup, Parser), Parser)).body.childNodes
|
|
2719
|
+
);
|
|
2720
|
+
}
|
|
2721
|
+
function getMimeType(input, Parser) {
|
|
2722
|
+
if (isSVG(input, Parser)) {
|
|
2723
|
+
return "image/svg+xml";
|
|
2724
|
+
}
|
|
2725
|
+
return "text/html";
|
|
2726
|
+
}
|
|
2727
|
+
function processAllFormElements(node, callback) {
|
|
2728
|
+
if (node instanceof Element) {
|
|
2729
|
+
if (node instanceof HTMLFormElement) {
|
|
2730
|
+
Array.from(node.elements).forEach((element) => {
|
|
2731
|
+
if (element instanceof HTMLInputElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement) {
|
|
2732
|
+
const key = element.name || element.id;
|
|
2733
|
+
if (key) {
|
|
2734
|
+
callback(element, key);
|
|
2735
|
+
}
|
|
2736
|
+
}
|
|
2737
|
+
});
|
|
2738
|
+
} else {
|
|
2739
|
+
const inputElements = node.querySelectorAll("input, select, textarea");
|
|
2740
|
+
inputElements.forEach((element) => {
|
|
2741
|
+
if (element instanceof HTMLInputElement || element instanceof HTMLSelectElement || element instanceof HTMLTextAreaElement) {
|
|
2742
|
+
const key = element.name || element.id;
|
|
2743
|
+
if (key) {
|
|
2744
|
+
callback(element, key);
|
|
2745
|
+
}
|
|
2746
|
+
}
|
|
2747
|
+
});
|
|
2748
|
+
}
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
function checkElementVisibility(element, window, document) {
|
|
2752
|
+
const style = window.getComputedStyle(element);
|
|
2753
|
+
if (!style) return false;
|
|
2754
|
+
if (element.offsetWidth === 0 || element.offsetHeight === 0) return false;
|
|
2755
|
+
if (style.display === "none" || style.visibility === "hidden" || style.opacity === "0" || Number.parseFloat(style.opacity) === 0)
|
|
2756
|
+
return false;
|
|
2757
|
+
if (!document.body.contains(element)) return false;
|
|
2758
|
+
let parent = element.parentElement;
|
|
2759
|
+
while (parent) {
|
|
2760
|
+
const parentStyle = window.getComputedStyle(parent);
|
|
2761
|
+
if (parentStyle && (parentStyle.display === "none" || parentStyle.visibility === "hidden" || parentStyle.opacity === "0" || Number.parseFloat(parentStyle.opacity) === 0)) {
|
|
2762
|
+
return false;
|
|
2763
|
+
}
|
|
2764
|
+
parent = parent.parentElement;
|
|
2765
|
+
}
|
|
2766
|
+
return true;
|
|
2767
|
+
}
|
|
2768
|
+
function getEventMap(element) {
|
|
2769
|
+
if (!element._dequeryEvents) {
|
|
2770
|
+
element._dequeryEvents = /* @__PURE__ */ new Map();
|
|
2771
|
+
}
|
|
2772
|
+
return element._dequeryEvents;
|
|
2773
|
+
}
|
|
2774
|
+
function addElementEvent(target, eventType, handler) {
|
|
2775
|
+
registerDelegatedEvent(target, eventType, handler, { multi: true });
|
|
2776
|
+
}
|
|
2777
|
+
function removeElementEvent(target, eventType, handler) {
|
|
2778
|
+
removeDelegatedEvent(target, eventType, handler);
|
|
2779
|
+
}
|
|
2780
|
+
function clearElementEvents(target) {
|
|
2781
|
+
clearDelegatedEvents(target);
|
|
2782
|
+
}
|
|
2783
|
+
function domNodeToVNode(node) {
|
|
2784
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
2785
|
+
return node.textContent || "";
|
|
2786
|
+
}
|
|
2787
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
2788
|
+
const element = node;
|
|
2789
|
+
const attributes = {};
|
|
2790
|
+
for (let i = 0; i < element.attributes.length; i++) {
|
|
2791
|
+
const attr = element.attributes[i];
|
|
2792
|
+
attributes[attr.name] = attr.value;
|
|
2793
|
+
}
|
|
2794
|
+
const children = [];
|
|
2795
|
+
for (let i = 0; i < element.childNodes.length; i++) {
|
|
2796
|
+
const childVNode = domNodeToVNode(element.childNodes[i]);
|
|
2797
|
+
children.push(childVNode);
|
|
2798
|
+
}
|
|
2799
|
+
return {
|
|
2800
|
+
type: element.tagName.toLowerCase(),
|
|
2801
|
+
attributes,
|
|
2802
|
+
children
|
|
2803
|
+
};
|
|
2804
|
+
}
|
|
2805
|
+
return "";
|
|
2806
|
+
}
|
|
2807
|
+
function htmlStringToVNodes(html, Parser) {
|
|
2808
|
+
const parser = new Parser();
|
|
2809
|
+
const doc = parser.parseFromString(html, "text/html");
|
|
2810
|
+
const vNodes = [];
|
|
2811
|
+
for (let i = 0; i < doc.body.childNodes.length; i++) {
|
|
2812
|
+
const vnode = domNodeToVNode(doc.body.childNodes[i]);
|
|
2813
|
+
if (vnode !== "") {
|
|
2814
|
+
vNodes.push(vnode);
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
return vNodes;
|
|
2818
|
+
}
|
|
2819
|
+
|
|
2820
|
+
exports.$ = $;
|
|
2821
|
+
exports.CAPTURE_ONLY_EVENTS = CAPTURE_ONLY_EVENTS;
|
|
2822
|
+
exports.CLASS_ATTRIBUTE_NAME = CLASS_ATTRIBUTE_NAME;
|
|
2823
|
+
exports.Call = Call;
|
|
2824
|
+
exports.CallChainImpl = CallChainImpl;
|
|
2825
|
+
exports.CallChainImplThenable = CallChainImplThenable;
|
|
2826
|
+
exports.DANGEROUSLY_SET_INNER_HTML_ATTRIBUTE = DANGEROUSLY_SET_INNER_HTML_ATTRIBUTE;
|
|
2827
|
+
exports.DEFAULT_TRANSITION_CONFIG = DEFAULT_TRANSITION_CONFIG;
|
|
2828
|
+
exports.Fragment = Fragment;
|
|
2829
|
+
exports.REF_ATTRIBUTE_NAME = REF_ATTRIBUTE_NAME;
|
|
2830
|
+
exports.XLINK_ATTRIBUTE_NAME = XLINK_ATTRIBUTE_NAME;
|
|
2831
|
+
exports.XMLNS_ATTRIBUTE_NAME = XMLNS_ATTRIBUTE_NAME;
|
|
2832
|
+
exports.addElementEvent = addElementEvent;
|
|
2833
|
+
exports.addNonChainedReturnCallNames = addNonChainedReturnCallNames;
|
|
2834
|
+
exports.applyStyles = applyStyles;
|
|
2835
|
+
exports.areDomNodesEqual = areDomNodesEqual;
|
|
2836
|
+
exports.checkElementVisibility = checkElementVisibility;
|
|
2837
|
+
exports.clearDelegatedEvents = clearDelegatedEvents;
|
|
2838
|
+
exports.clearDelegatedEventsDeep = clearDelegatedEventsDeep;
|
|
2839
|
+
exports.clearElementEvents = clearElementEvents;
|
|
2840
|
+
exports.createCall = createCall;
|
|
2841
|
+
exports.createGetterSetterCall = createGetterSetterCall;
|
|
2842
|
+
exports.createInPlaceErrorMessageVNode = createInPlaceErrorMessageVNode;
|
|
2843
|
+
exports.createRef = createRef;
|
|
2844
|
+
exports.createStore = createStore;
|
|
2845
|
+
exports.createSubChain = createSubChain;
|
|
2846
|
+
exports.createSyncCall = createSyncCall;
|
|
2847
|
+
exports.deepEquals = deepEquals;
|
|
2848
|
+
exports.delayedAutoStart = delayedAutoStart;
|
|
2849
|
+
exports.dequery = dequery;
|
|
2850
|
+
exports.domNodeToVNode = domNodeToVNode;
|
|
2851
|
+
exports.emptyImpl = emptyImpl;
|
|
2852
|
+
exports.getAllFormValues = getAllFormValues;
|
|
2853
|
+
exports.getComponentInstance = getComponentInstance;
|
|
2854
|
+
exports.getDefaultDequeryOptions = getDefaultDequeryOptions;
|
|
2855
|
+
exports.getEventMap = getEventMap;
|
|
2856
|
+
exports.getMimeType = getMimeType;
|
|
2857
|
+
exports.getNonChainedReturnCallNames = getNonChainedReturnCallNames;
|
|
2858
|
+
exports.getRegisteredEventKeys = getRegisteredEventKeys;
|
|
2859
|
+
exports.getRegisteredEventTypes = getRegisteredEventTypes;
|
|
2860
|
+
exports.getRenderer = getRenderer;
|
|
2861
|
+
exports.getTransitionStyles = getTransitionStyles;
|
|
2862
|
+
exports.globalScopeDomApis = globalScopeDomApis;
|
|
2863
|
+
exports.handleLifecycleEventsForOnMount = handleLifecycleEventsForOnMount;
|
|
2864
|
+
exports.htmlStringToVNodes = htmlStringToVNodes;
|
|
2865
|
+
exports.isComponentRoot = isComponentRoot;
|
|
2866
|
+
exports.isDequery = isDequery;
|
|
2867
|
+
exports.isDequeryOptionsObject = isDequeryOptionsObject;
|
|
2868
|
+
exports.isHTML = isHTML;
|
|
2869
|
+
exports.isJSX = isJSX;
|
|
2870
|
+
exports.isMarkup = isMarkup;
|
|
2871
|
+
exports.isNonChainedReturnCall = isNonChainedReturnCall;
|
|
2872
|
+
exports.isRef = isRef;
|
|
2873
|
+
exports.isSVG = isSVG;
|
|
2874
|
+
exports.jsx = jsx;
|
|
2875
|
+
exports.jsxDEV = jsxDEV;
|
|
2876
|
+
exports.jsxs = jsxs;
|
|
2877
|
+
exports.mapArrayIndexAccess = mapArrayIndexAccess;
|
|
2878
|
+
exports.nsMap = nsMap;
|
|
2879
|
+
exports.observeUnmount = observeUnmount;
|
|
2880
|
+
exports.parseDOM = parseDOM;
|
|
2881
|
+
exports.parseEventPropName = parseEventPropName;
|
|
2882
|
+
exports.performTransition = performTransition;
|
|
2883
|
+
exports.processAllFormElements = processAllFormElements;
|
|
2884
|
+
exports.queueCallback = queueCallback;
|
|
2885
|
+
exports.registerComponent = registerComponent;
|
|
2886
|
+
exports.registerDelegatedEvent = registerDelegatedEvent;
|
|
2887
|
+
exports.removeDelegatedEvent = removeDelegatedEvent;
|
|
2888
|
+
exports.removeDelegatedEventByKey = removeDelegatedEventByKey;
|
|
2889
|
+
exports.removeElementEvent = removeElementEvent;
|
|
2890
|
+
exports.render = render;
|
|
2891
|
+
exports.renderInto = renderInto;
|
|
2892
|
+
exports.renderIsomorphicAsync = renderIsomorphicAsync;
|
|
2893
|
+
exports.renderIsomorphicSync = renderIsomorphicSync;
|
|
2894
|
+
exports.renderMarkup = renderMarkup;
|
|
2895
|
+
exports.renderNode = renderNode;
|
|
2896
|
+
exports.replaceDomWithVdom = replaceDomWithVdom;
|
|
2897
|
+
exports.resolveNodes = resolveNodes;
|
|
2898
|
+
exports.runWithTimeGuard = runWithTimeGuard;
|
|
2899
|
+
exports.scrollHelper = scrollHelper;
|
|
2900
|
+
exports.shallowEquals = shallowEquals;
|
|
2901
|
+
exports.subChainForNextAwait = subChainForNextAwait;
|
|
2902
|
+
exports.traverse = traverse;
|
|
2903
|
+
exports.unregisterComponent = unregisterComponent;
|
|
2904
|
+
exports.updateDom = updateDom;
|
|
2905
|
+
exports.updateDomWithVdom = updateDomWithVdom;
|
|
2906
|
+
exports.waitForDOM = waitForDOM;
|
|
2907
|
+
exports.webstorage = webstorage;
|