create-prisma-php-app 1.15.34 → 1.15.36

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.
@@ -1,1097 +1 @@
1
- var eventAttributes = [
2
- "onclick",
3
- "ondblclick",
4
- "onmousedown",
5
- "onmouseup",
6
- "onmouseover",
7
- "onmousemove",
8
- "onmouseout",
9
- "onwheel",
10
- "onkeypress",
11
- "onkeydown",
12
- "onkeyup",
13
- "onfocus",
14
- "onblur",
15
- "onchange",
16
- "oninput",
17
- "onselect",
18
- "onsubmit",
19
- "onreset",
20
- "onresize",
21
- "onscroll",
22
- "onload",
23
- "onunload",
24
- "onabort",
25
- "onerror",
26
- "onbeforeunload",
27
- "oncopy",
28
- "oncut",
29
- "onpaste",
30
- "ondrag",
31
- "ondragstart",
32
- "ondragend",
33
- "ondragover",
34
- "ondragenter",
35
- "ondragleave",
36
- "ondrop",
37
- "oncontextmenu",
38
- "ontouchstart",
39
- "ontouchmove",
40
- "ontouchend",
41
- "ontouchcancel",
42
- "onpointerdown",
43
- "onpointerup",
44
- "onpointermove",
45
- "onpointerover",
46
- "onpointerout",
47
- "onpointerenter",
48
- "onpointerleave",
49
- "onpointercancel",
50
- ];
51
- document.addEventListener("DOMContentLoaded", attachWireFunctionEvents);
52
- var state = {
53
- checkedElements: new Set(),
54
- };
55
- var responseData = null;
56
- var store = null;
57
- var isNavigating = false;
58
- function attachWireFunctionEvents() {
59
- handleHiddenAttribute();
60
- const interactiveElements = document.querySelectorAll(
61
- "button, input, select, textarea, a, form, label, div, span"
62
- );
63
- interactiveElements.forEach((element) => {
64
- handleAnchorTag(element);
65
- eventAttributes.forEach((attr) => {
66
- const originalHandler = element.getAttribute(attr);
67
- const eventType = attr.slice(2); // Get the event type (e.g., "click" from "onclick")
68
- if (originalHandler) {
69
- element.removeAttribute(attr);
70
- handleDebounce(element, eventType, originalHandler);
71
- }
72
- });
73
- // Special handling for form submit
74
- if (element instanceof HTMLFormElement) {
75
- const submitHandler = element.getAttribute("onsubmit");
76
- if (submitHandler) {
77
- element.removeAttribute("onsubmit");
78
- handleDebounce(element, "submit", submitHandler);
79
- }
80
- }
81
- });
82
- }
83
- function handleHiddenAttribute() {
84
- const hiddenElements = document.querySelectorAll("[pp-hidden]");
85
- hiddenElements.forEach((element) => {
86
- let hiddenAttr = element.getAttribute("pp-hidden");
87
- if (!hiddenAttr) return;
88
- // Determine if the attribute is JSON-like or a simple time value
89
- if (isJsonLike(hiddenAttr)) {
90
- try {
91
- // Normalize single quotes to double quotes for JSON parsing
92
- const config = parseJson(hiddenAttr);
93
- handleElementVisibility(element, config);
94
- } catch (error) {
95
- console.error("JSON parsing error:", error);
96
- }
97
- } else {
98
- // Handle non-JSON attribute as simple time value
99
- const timeout = parseTime(hiddenAttr);
100
- if (timeout > 0) {
101
- // Directly schedule hiding after the timeout for non-JSON value
102
- scheduleVisibilityChange(element, timeout, "hidden");
103
- }
104
- }
105
- });
106
- }
107
- // Function to determine if a string is JSON-like
108
- function isJsonLike(str) {
109
- // A simple check to see if the string starts with '{' and ends with '}'
110
- return str.trim().startsWith("{") && str.trim().endsWith("}");
111
- }
112
- // Function to handle visibility changes based on config
113
- function handleElementVisibility(element, config) {
114
- const startTimeout = config.start ? parseTime(config.start) : 0;
115
- const endTimeout = config.end ? parseTime(config.end) : 0;
116
- if (startTimeout > 0) {
117
- // Start hidden and show after startTimeout
118
- element.style.visibility = "hidden";
119
- scheduleVisibilityChange(element, startTimeout, "visible");
120
- // If endTimeout is also specified, hide again after endTimeout relative to startTimeout
121
- if (endTimeout > 0) {
122
- scheduleVisibilityChange(element, startTimeout + endTimeout, "hidden");
123
- }
124
- } else if (endTimeout > 0) {
125
- // If no startTimeout but endTimeout is specified, only hide after endTimeout
126
- scheduleVisibilityChange(element, endTimeout, "hidden");
127
- }
128
- }
129
- // Function to schedule visibility changes using requestAnimationFrame
130
- function scheduleVisibilityChange(element, timeout, visibility) {
131
- setTimeout(() => {
132
- requestAnimationFrame(() => {
133
- element.style.visibility = visibility;
134
- });
135
- }, timeout);
136
- }
137
- // Function to parse time strings into milliseconds
138
- function parseTime(time) {
139
- if (typeof time === "number") {
140
- return time;
141
- }
142
- const match = time.match(/^(\d+)(ms|s|m)?$/);
143
- if (match) {
144
- const value = parseInt(match[1], 10);
145
- const unit = match[2] || "ms"; // Default to milliseconds if no unit specified
146
- switch (unit) {
147
- case "ms":
148
- return value;
149
- case "s":
150
- return value * 1000;
151
- case "m":
152
- return value * 60 * 1000;
153
- default:
154
- return value; // Default to milliseconds
155
- }
156
- }
157
- return 0; // Default to 0 if parsing fails
158
- }
159
- async function handleDebounce(element, eventType, originalHandler) {
160
- const debounceTime = element.getAttribute("pp-debounce") || "";
161
- const executeFirst = element.getAttribute("pp-trigger") || "";
162
- const targetOnlyAttribute = element.getAttribute("pp-target-only") || "";
163
- const combinedHandler = async (event) => {
164
- event.preventDefault();
165
- try {
166
- if (executeFirst || targetOnlyAttribute) {
167
- if (targetOnlyAttribute) {
168
- invokeHandler(element, executeFirst);
169
- } else {
170
- await invokeHandler(element, executeFirst);
171
- }
172
- }
173
- // Execute the original handler
174
- await invokeHandler(element, originalHandler);
175
- } catch (error) {
176
- console.error("Error in debounced handler:", error);
177
- }
178
- };
179
- if (debounceTime) {
180
- const wait = parseTime(debounceTime);
181
- const debouncedHandler = debounce(combinedHandler, wait);
182
- if (element instanceof HTMLFormElement && eventType === "submit") {
183
- element.addEventListener(eventType, (event) => {
184
- event.preventDefault();
185
- debouncedHandler(event);
186
- });
187
- } else {
188
- element.addEventListener(eventType, debouncedHandler);
189
- }
190
- } else {
191
- element.addEventListener(eventType, combinedHandler);
192
- }
193
- }
194
- async function invokeHandler(element, handler) {
195
- try {
196
- // Extract method details from the handler string
197
- const methodMatch = handler.match(/^(\w+(\.\w+)*)\((.*)\)$/);
198
- if (methodMatch) {
199
- const fullMethodName = methodMatch[1];
200
- const argsString = methodMatch[3];
201
- // Resolve context for nested methods
202
- const methodParts = fullMethodName.split(".");
203
- const { context, methodName } = resolveContext(methodParts);
204
- // Check if the resolved method is a function
205
- if (typeof context[methodName] === "function") {
206
- const args = parseArguments(argsString);
207
- await context[methodName](...args);
208
- } else {
209
- await handleParsedCallback(element, handler);
210
- }
211
- } else {
212
- await handleParsedCallback(element, handler);
213
- }
214
- } catch (error) {
215
- console.error(`Error executing handler ${handler}:`, error);
216
- }
217
- }
218
- /**
219
- * Resolve the context and method name for nested methods.
220
- * @param methodParts - Array of method parts split by dots.
221
- * @returns Object containing the resolved context and method name.
222
- */
223
- function resolveContext(methodParts) {
224
- let context = window;
225
- for (let i = 0; i < methodParts.length - 1; i++) {
226
- context = context[methodParts[i]];
227
- if (!context) {
228
- throw new Error(`Cannot find object ${methodParts[i]} in the context.`);
229
- }
230
- }
231
- return { context, methodName: methodParts[methodParts.length - 1] };
232
- }
233
- /**
234
- * Parse arguments string into an array.
235
- * @param argsString - Comma-separated string of arguments.
236
- * @returns Parsed arguments as an array.
237
- */
238
- function parseArguments(argsString) {
239
- return argsString ? JSON.parse(`[${argsString}]`) : [];
240
- }
241
- /**
242
- * Handle parsing and executing the callback from the element's handler.
243
- * @param element - HTML element that initiated the handler.
244
- * @param handler - Handler string to be parsed and executed.
245
- */
246
- async function handleParsedCallback(element, handler) {
247
- const { funcName, data } = parseCallback(element, handler);
248
- if (!funcName) return;
249
- const func = window[funcName];
250
- if (typeof func === "function") {
251
- const args = Array.isArray(data.args) ? data.args : [];
252
- const responseJSON = responseData ? parseJson(responseData) : null;
253
- await func(...args, element, data, responseJSON);
254
- } else {
255
- responseData = await handleUndefinedFunction(element, funcName, data);
256
- }
257
- }
258
- function handleAnchorTag(element) {
259
- if (!(element instanceof HTMLAnchorElement)) return;
260
- element.addEventListener("click", async (event) => {
261
- const anchor = event.currentTarget;
262
- const href = anchor.getAttribute("href");
263
- const target = anchor.getAttribute("target");
264
- // If there's no href, or the target is _blank, or the meta key is pressed, allow default behavior
265
- if (!href || target === "_blank" || event.metaKey || event.ctrlKey) {
266
- return;
267
- }
268
- event.preventDefault(); // Prevent the default navigation
269
- if (isNavigating) return; // Prevent multiple navigations
270
- isNavigating = true;
271
- try {
272
- const isExternal =
273
- /^(https?:)?\/\//i.test(href) &&
274
- !href.startsWith(window.location.origin);
275
- if (isExternal) {
276
- // If the link is external, use the default behavior
277
- window.location.href = href;
278
- } else {
279
- // If the link is internal, use history.pushState
280
- history.pushState(null, "", href);
281
- await handleNavigation();
282
- }
283
- } catch (error) {
284
- console.error("Anchor click error:", error);
285
- } finally {
286
- isNavigating = false;
287
- }
288
- });
289
- }
290
- // Handle browser's back/forward navigation
291
- window.addEventListener("popstate", async () => {
292
- await handleNavigation();
293
- });
294
- async function handleNavigation() {
295
- try {
296
- const data = await pphpFetch(window.location.href);
297
- updateDocumentContent(data);
298
- } catch (error) {
299
- console.error("Navigation error:", error);
300
- }
301
- }
302
- function updateDocumentContent(data) {
303
- if (data.includes("<!DOCTYPE html>")) {
304
- const newDoc = new DOMParser().parseFromString(data, "text/html");
305
- // Function to extract and clone scripts
306
- const extractAndCloneScripts = (container) => {
307
- const scriptElements = container.querySelectorAll("script");
308
- const scripts = [];
309
- scriptElements.forEach((script) => {
310
- const newScript = document.createElement("script");
311
- newScript.type = script.type || "text/javascript";
312
- if (script.src) {
313
- newScript.src = script.src;
314
- } else {
315
- newScript.textContent = script.textContent;
316
- }
317
- scripts.push(newScript);
318
- script.remove();
319
- });
320
- return scripts;
321
- };
322
- // Extract scripts from head and body of the new document
323
- const headScripts = extractAndCloneScripts(newDoc.head);
324
- const bodyScripts = extractAndCloneScripts(newDoc.body);
325
- // Replace the document content
326
- document.replaceChild(
327
- document.adoptNode(newDoc.documentElement),
328
- document.documentElement
329
- );
330
- // Append and execute the extracted head scripts
331
- headScripts.forEach((script) => document.head.appendChild(script));
332
- // Append and execute the extracted body scripts
333
- bodyScripts.forEach((script) => document.body.appendChild(script));
334
- } else {
335
- saveState();
336
- const scrollPositions = saveScrollPositions();
337
- const parser = new DOMParser();
338
- const newDoc = parser.parseFromString(data, "text/html");
339
- const scripts = Array.from(newDoc.body.querySelectorAll("script"));
340
- const styles = Array.from(newDoc.head.querySelectorAll("style"));
341
- const newBody = newDoc.body;
342
- diffAndPatch(document.body, newBody);
343
- restoreState();
344
- restoreScrollPositions(scrollPositions);
345
- // Load styles
346
- styles.forEach((style) => {
347
- const newStyle = document.createElement("style");
348
- newStyle.textContent = style.textContent;
349
- document.head.appendChild(newStyle);
350
- });
351
- // Load scripts
352
- scripts.forEach((script) => {
353
- if (script.src) {
354
- loadScript(script.src);
355
- } else {
356
- const newScript = document.createElement("script");
357
- newScript.textContent = script.textContent;
358
- document.body.appendChild(newScript);
359
- document.body.removeChild(newScript);
360
- }
361
- });
362
- }
363
- attachWireFunctionEvents();
364
- }
365
- function diffAndPatch(oldNode, newNode) {
366
- // If nodes are of different types, replace old with new
367
- if (oldNode.nodeType !== newNode.nodeType) {
368
- oldNode.parentNode?.replaceChild(newNode, oldNode);
369
- return;
370
- }
371
- // Compare text nodes
372
- if (
373
- oldNode.nodeType === Node.TEXT_NODE &&
374
- newNode.nodeType === Node.TEXT_NODE
375
- ) {
376
- if (oldNode.textContent !== newNode.textContent) {
377
- oldNode.textContent = newNode.textContent;
378
- }
379
- return;
380
- }
381
- // Compare element nodes
382
- if (oldNode instanceof HTMLElement && newNode instanceof HTMLElement) {
383
- oldNode.replaceWith(newNode);
384
- }
385
- }
386
- function loadScript(src) {
387
- const script = document.createElement("script");
388
- script.src = src;
389
- document.head.appendChild(script);
390
- }
391
- function saveState() {
392
- const focusElement = document.activeElement;
393
- state.focusId = focusElement?.id || focusElement?.name;
394
- state.focusValue = focusElement?.value;
395
- state.focusChecked = focusElement?.checked;
396
- state.focusType = focusElement?.type;
397
- state.focusSelectionStart = focusElement?.selectionStart;
398
- state.focusSelectionEnd = focusElement?.selectionEnd;
399
- state.isSuspense = focusElement.hasAttribute("pp-suspense");
400
- state.checkedElements.clear();
401
- document.querySelectorAll('input[type="checkbox"]:checked').forEach((el) => {
402
- state.checkedElements.add(el.id || el.name);
403
- });
404
- document.querySelectorAll('input[type="radio"]:checked').forEach((el) => {
405
- state.checkedElements.add(el.id || el.name);
406
- });
407
- }
408
- function restoreState() {
409
- if (state.focusId) {
410
- const newFocusElement =
411
- document.getElementById(state.focusId) ||
412
- document.querySelector(`[name="${state.focusId}"]`);
413
- if (newFocusElement instanceof HTMLInputElement) {
414
- newFocusElement.focus();
415
- const length = newFocusElement.value.length || 0;
416
- if (
417
- state.focusSelectionStart !== undefined &&
418
- state.focusSelectionEnd !== null
419
- ) {
420
- newFocusElement.setSelectionRange(length, length);
421
- }
422
- if (state.focusValue) {
423
- if (
424
- newFocusElement.type === "checkbox" ||
425
- newFocusElement.type === "radio"
426
- ) {
427
- newFocusElement.checked = !!state.focusChecked;
428
- } else {
429
- const isSuspense = newFocusElement.hasAttribute("pp-suspense");
430
- if (!isSuspense && !state.isSuspense)
431
- newFocusElement.value = state.focusValue;
432
- }
433
- }
434
- } else if (newFocusElement instanceof HTMLTextAreaElement) {
435
- newFocusElement.focus();
436
- const length = newFocusElement.value.length || 0;
437
- if (
438
- state.focusSelectionStart !== undefined &&
439
- state.focusSelectionEnd !== null
440
- ) {
441
- newFocusElement.setSelectionRange(length, length);
442
- }
443
- if (state.focusValue) {
444
- newFocusElement.value = state.focusValue;
445
- }
446
- } else if (newFocusElement instanceof HTMLSelectElement) {
447
- newFocusElement.focus();
448
- if (state.focusValue) {
449
- newFocusElement.value = state.focusValue;
450
- }
451
- }
452
- }
453
- state.checkedElements.forEach((id) => {
454
- const checkbox = document.getElementById(id);
455
- if (checkbox) {
456
- checkbox.checked = true;
457
- }
458
- });
459
- }
460
- function saveScrollPositions() {
461
- const scrollPositions = {};
462
- document.querySelectorAll("*").forEach((el) => {
463
- if (el.scrollTop || el.scrollLeft) {
464
- scrollPositions[getElementKey(el)] = {
465
- scrollTop: el.scrollTop,
466
- scrollLeft: el.scrollLeft,
467
- };
468
- }
469
- });
470
- return scrollPositions;
471
- }
472
- function restoreScrollPositions(scrollPositions) {
473
- document.querySelectorAll("*").forEach((el) => {
474
- const key = getElementKey(el);
475
- if (scrollPositions[key]) {
476
- el.scrollTop = scrollPositions[key].scrollTop;
477
- el.scrollLeft = scrollPositions[key].scrollLeft;
478
- }
479
- });
480
- }
481
- function getElementKey(el) {
482
- return el.id || el.className || el.tagName;
483
- }
484
- async function pphpFetch(url, options) {
485
- const data = await fetch(url, {
486
- ...options,
487
- headers: {
488
- ...options?.headers,
489
- "X-Requested-With": "XMLHttpRequest",
490
- },
491
- });
492
- return await data.text();
493
- }
494
- function parseCallback(element, callback) {
495
- let data = {};
496
- // Check if the element is inside a form
497
- const form = element.closest("form");
498
- if (form) {
499
- // Serialize the form data
500
- const formData = new FormData(form);
501
- formData.forEach((value, key) => {
502
- if (data[key]) {
503
- // Handle multiple values
504
- if (Array.isArray(data[key])) {
505
- data[key].push(value);
506
- } else {
507
- data[key] = [data[key], value];
508
- }
509
- } else {
510
- data[key] = value;
511
- }
512
- });
513
- } else {
514
- // Handle single input element
515
- if (element instanceof HTMLInputElement) {
516
- data = handleInputElement(element);
517
- } else if (element instanceof HTMLSelectElement) {
518
- data[element.name] = element.value;
519
- } else if (element instanceof HTMLTextAreaElement) {
520
- data[element.name] = element.value;
521
- }
522
- }
523
- // Parse function name and arguments from the callback string
524
- const match = callback.match(/(\w+)\((.*)\)/);
525
- if (match) {
526
- const funcName = match[1];
527
- let rawArgs = match[2].trim();
528
- if (rawArgs.startsWith("{") && rawArgs.endsWith("}")) {
529
- try {
530
- const parsedArg = parseJson(rawArgs);
531
- if (typeof parsedArg === "object" && parsedArg !== null) {
532
- data = { ...data, ...parsedArg };
533
- }
534
- } catch (e) {
535
- console.error("Error parsing JSON:", e);
536
- }
537
- } else {
538
- const args = rawArgs
539
- .split(/,(?=(?:[^'"]*['"][^'"]*['"])*[^'"]*$)/)
540
- .map((arg) => arg.trim().replace(/^['"]|['"]$/g, ""));
541
- data.args = args;
542
- }
543
- return { funcName, data };
544
- }
545
- return { funcName: callback, data };
546
- }
547
- function handleInputElement(element) {
548
- let data = {};
549
- // Only proceed if the element has a name
550
- if (element.name) {
551
- // Handle checkboxes
552
- if (element.type === "checkbox") {
553
- data[element.name] = {
554
- value: element.value,
555
- checked: element.checked,
556
- };
557
- } else if (element.type === "radio") {
558
- // Handle radio buttons
559
- const checkedRadio = document.querySelector(
560
- `input[name="${element.name}"]:checked`
561
- );
562
- data[element.name] = checkedRadio ? checkedRadio.value : null;
563
- } else {
564
- // Handle other input types
565
- data[element.name] = element.value;
566
- }
567
- } else {
568
- // Handle cases where the element does not have a name
569
- if (element.type === "checkbox" || element.type === "radio") {
570
- data.value = element.checked;
571
- } else {
572
- data.value = element.value;
573
- }
574
- }
575
- return data;
576
- }
577
- function updateElementAttributes(element, data) {
578
- for (const key in data) {
579
- if (!data.hasOwnProperty(key)) continue;
580
- switch (key) {
581
- case "innerHTML":
582
- case "outerHTML":
583
- case "textContent":
584
- case "innerText":
585
- element[key] = decodeHTML(data[key]);
586
- break;
587
- case "insertAdjacentHTML":
588
- element.insertAdjacentHTML(
589
- data.position || "beforeend",
590
- decodeHTML(data[key].html)
591
- );
592
- break;
593
- case "insertAdjacentText":
594
- element.insertAdjacentText(
595
- data.position || "beforeend",
596
- decodeHTML(data[key].text)
597
- );
598
- break;
599
- case "setAttribute":
600
- element.setAttribute(data.attrName, decodeHTML(data[key]));
601
- break;
602
- case "removeAttribute":
603
- element.removeAttribute(data[key]);
604
- break;
605
- case "className":
606
- element.className = decodeHTML(data[key]);
607
- break;
608
- case "classList.add":
609
- element.classList.add(...decodeHTML(data[key]).split(","));
610
- break;
611
- case "classList.remove":
612
- element.classList.remove(...decodeHTML(data[key]).split(","));
613
- break;
614
- case "classList.toggle":
615
- element.classList.toggle(decodeHTML(data[key]));
616
- break;
617
- case "classList.replace":
618
- const [oldClass, newClass] = decodeHTML(data[key]).split(",");
619
- element.classList.replace(oldClass, newClass);
620
- break;
621
- case "dataset":
622
- element.dataset[data.attrName] = decodeHTML(data[key]);
623
- break;
624
- case "style":
625
- Object.assign(element.style, data[key]);
626
- break;
627
- case "value":
628
- element.value = decodeHTML(data[key]);
629
- break;
630
- case "checked":
631
- element.checked = data[key];
632
- break;
633
- default:
634
- element.setAttribute(key, decodeHTML(data[key]));
635
- }
636
- }
637
- }
638
- function decodeHTML(html) {
639
- const txt = document.createElement("textarea");
640
- txt.innerHTML = html;
641
- return txt.value;
642
- }
643
- async function handleSuspenseElement(element) {
644
- let suspenseElement = element.getAttribute("pp-suspense") || "";
645
- const handleFormElement = (form, data) => {
646
- for (const key in data) {
647
- if (!data.hasOwnProperty(key)) continue;
648
- for (const formElement of form.elements) {
649
- if (
650
- formElement instanceof HTMLInputElement ||
651
- formElement instanceof HTMLButtonElement ||
652
- formElement instanceof HTMLTextAreaElement ||
653
- formElement instanceof HTMLSelectElement
654
- ) {
655
- const suspenseElement = formElement.getAttribute("pp-suspense") || "";
656
- if (suspenseElement) {
657
- if (isJsonLike(suspenseElement)) {
658
- const suspenseData = parseJson(suspenseElement);
659
- if (suspenseData.onsubmit !== "disabled")
660
- updateElementAttributes(formElement, suspenseData);
661
- } else {
662
- updateElementTextContent(formElement, suspenseElement);
663
- }
664
- }
665
- }
666
- }
667
- }
668
- };
669
- const updateElementTextContent = (element, data) => {
670
- if (element instanceof HTMLInputElement) {
671
- element.value = data;
672
- } else {
673
- element.textContent = data;
674
- }
675
- };
676
- const handleTargetElement = (element, data) => {
677
- if (element instanceof HTMLFormElement) {
678
- handleFormElement(element, data);
679
- } else {
680
- updateElementAttributes(element, data);
681
- }
682
- };
683
- try {
684
- if (suspenseElement && isJsonLike(suspenseElement)) {
685
- const data = parseJson(suspenseElement);
686
- if (data) {
687
- if (element instanceof HTMLFormElement) {
688
- const formData = new FormData(element);
689
- const formDataToProcess = {};
690
- formData.forEach((value, key) => {
691
- formDataToProcess[key] = value;
692
- });
693
- if (data.disabled) {
694
- toggleFormElements(element, true);
695
- }
696
- const { disabled, ...restData } = data;
697
- updateElementAttributes(element, restData);
698
- handleFormElement(element, formDataToProcess);
699
- } else if (data.targets) {
700
- data.targets.forEach((target) => {
701
- const { id, ...rest } = target;
702
- const targetElement = document.querySelector(id);
703
- if (targetElement) {
704
- handleTargetElement(targetElement, rest);
705
- }
706
- });
707
- const { targets, ...restData } = data;
708
- updateElementAttributes(element, restData);
709
- } else {
710
- if (data.empty === "disabled" && element.value === "") return;
711
- const { empty, ...restData } = data;
712
- updateElementAttributes(element, restData);
713
- }
714
- }
715
- } else if (suspenseElement) {
716
- updateElementTextContent(element, suspenseElement);
717
- } else {
718
- if (element instanceof HTMLFormElement) {
719
- const formData = new FormData(element);
720
- const formDataToProcess = {};
721
- formData.forEach((value, key) => {
722
- formDataToProcess[key] = value;
723
- });
724
- handleFormElement(element, formDataToProcess);
725
- }
726
- }
727
- } catch (error) {
728
- console.error("🚀 ~ handleSuspenseElement ~ JSON parse error:", error);
729
- }
730
- }
731
- function parseJson(jsonString) {
732
- return JSON.parse(jsonString.replace(/'/g, '"'));
733
- }
734
- function toggleFormElements(form, disable) {
735
- Array.from(form.elements).forEach((element) => {
736
- if (
737
- element instanceof HTMLInputElement ||
738
- element instanceof HTMLButtonElement ||
739
- element instanceof HTMLSelectElement ||
740
- element instanceof HTMLTextAreaElement
741
- ) {
742
- element.disabled = disable;
743
- }
744
- });
745
- }
746
- async function handleUndefinedFunction(element, funcName, data) {
747
- const body = {
748
- callback: funcName,
749
- ...data,
750
- };
751
- const firstFetchOptions = {
752
- method: "POST",
753
- headers: {
754
- "Content-Type": "application/json",
755
- HTTP_PPHP_WIRE_REQUEST: "true",
756
- },
757
- body: JSON.stringify(body),
758
- };
759
- const secondFetchOptions = {
760
- method: "POST",
761
- headers: {
762
- "Content-Type": "application/json",
763
- HTTP_PPHP_WIRE_REQUEST: "true",
764
- },
765
- body: JSON.stringify({ secondRequestC69CD: true }),
766
- };
767
- try {
768
- handleSuspenseElement(element);
769
- const targetOnlyAttribute = element.getAttribute("pp-target-only") || "";
770
- if (targetOnlyAttribute) {
771
- handlerTargetOnly(element, targetOnlyAttribute);
772
- }
773
- const url = window.location.pathname;
774
- const firstResponseText = await pphpFetch(url, firstFetchOptions);
775
- if (targetOnlyAttribute) return firstResponseText;
776
- const functionOnlyAttribute =
777
- element.getAttribute("pp-function-only") || "";
778
- handleFunctionOnly(functionOnlyAttribute, firstResponseText);
779
- if (functionOnlyAttribute) return firstResponseText;
780
- const secondResponseText = await pphpFetch(url, secondFetchOptions);
781
- if (firstResponseText.includes("redirect_7F834=")) {
782
- const url = firstResponseText.split("=")[1];
783
- await handleRedirect(url);
784
- } else {
785
- // Create a DOM parser
786
- const parser = new DOMParser();
787
- const doc = parser.parseFromString(secondResponseText, "text/html");
788
- const bodyContent = doc.body.innerHTML;
789
- const combinedHTML = firstResponseText + bodyContent;
790
- updateDocumentContent(combinedHTML);
791
- }
792
- } catch (error) {
793
- console.error("Error:", error);
794
- }
795
- }
796
- function handlerTargetOnly(element, functionOnlyAttribute) {
797
- if (!isJsonLike(functionOnlyAttribute)) return;
798
- const getTargetElement = (selector) => {
799
- if (selector.includes(" + ")) {
800
- const [baseSelector, siblingSelector] = selector.split(" + ");
801
- const baseElement = selectElement(baseSelector);
802
- if (baseElement) {
803
- const sibling = baseElement.nextElementSibling;
804
- if (sibling && sibling.matches(siblingSelector)) {
805
- return sibling;
806
- }
807
- }
808
- return null;
809
- } else {
810
- return selectElement(selector);
811
- }
812
- };
813
- const selectElement = (selector) => {
814
- if (selector.startsWith("#")) {
815
- const id = selector.slice(1);
816
- // Use attribute selector for IDs starting with digits
817
- return document.querySelector(`[id="${id}"]`);
818
- } else {
819
- return document.querySelector(selector);
820
- }
821
- };
822
- const applyActions = (target, actions) => {
823
- actions.forEach((action) => {
824
- const [method, ...subProps] = action.method.split(".");
825
- const value = action.value;
826
- if (subProps.length) {
827
- let propRef = target[method];
828
- for (let i = 0; i < subProps.length - 1; i++) {
829
- propRef = propRef[subProps[i]];
830
- }
831
- propRef[subProps[subProps.length - 1]] = value;
832
- } else {
833
- target[method] = value;
834
- }
835
- });
836
- };
837
- const handleClasses = (target, classes, conditionMet) => {
838
- if (conditionMet) {
839
- if (classes.add) target.classList.add(...classes.add.split(" "));
840
- if (classes.remove) target.classList.remove(...classes.remove.split(" "));
841
- } else {
842
- if (classes.add) target.classList.remove(...classes.add.split(" "));
843
- if (classes.remove) target.classList.add(...classes.remove.split(" "));
844
- }
845
- };
846
- const checkCondition = (element, condition) => {
847
- switch (condition) {
848
- case "checked":
849
- return element.checked;
850
- case "focus":
851
- return element === document.activeElement;
852
- // Add more conditions as needed
853
- default:
854
- return false;
855
- }
856
- };
857
- const targetOnlyData = parseJson(functionOnlyAttribute);
858
- targetOnlyData.targets.forEach((targetData) => {
859
- const targetElement = getTargetElement(targetData.id);
860
- if (targetElement) {
861
- const conditionMet = targetData.this.condition
862
- ? checkCondition(element, targetData.this.condition)
863
- : false;
864
- const classList = targetData.this.classList;
865
- const rest = { ...targetData.this };
866
- if (classList) handleClasses(targetElement, classList, conditionMet);
867
- Object.keys(rest).forEach((key) => {
868
- if (key !== "id" && key !== "condition" && key !== "classList") {
869
- const value = rest[key];
870
- if (typeof targetElement[key] === "function") {
871
- targetElement[key](value);
872
- } else {
873
- targetElement[key] = value;
874
- }
875
- }
876
- });
877
- if (targetOnlyData.actions) {
878
- applyActions(targetElement, targetOnlyData.actions);
879
- }
880
- } else {
881
- console.error(`Invalid selector: ${targetData.id}`);
882
- }
883
- });
884
- }
885
- function handleFunctionOnly(functionOnlyAttribute, firstResponseText) {
886
- if (!isJsonLike(functionOnlyAttribute)) return;
887
- const functionOnlyData = parseJson(functionOnlyAttribute);
888
- const responseData = firstResponseText ? parseJson(firstResponseText) : null;
889
- const targets = functionOnlyData.targets; // Assuming targets is an array of objects
890
- if (Array.isArray(targets)) {
891
- targets.forEach((targetData) => {
892
- const { id, ...restData } = targetData;
893
- const targetToProcess = document.querySelector(id);
894
- let targetAttributes = {};
895
- if (responseData) {
896
- for (const key in restData) {
897
- if (restData.hasOwnProperty(key)) {
898
- switch (key) {
899
- case "innerHTML":
900
- case "outerHTML":
901
- case "textContent":
902
- case "innerText":
903
- if (restData[key] === "response") {
904
- targetAttributes[key] = targetData.responseKey
905
- ? responseData[targetData.responseKey]
906
- : responseData.response;
907
- }
908
- break;
909
- default:
910
- targetAttributes[key] = restData[key];
911
- break;
912
- }
913
- }
914
- }
915
- } else {
916
- targetAttributes = restData;
917
- }
918
- if (targetToProcess) {
919
- updateElementAttributes(targetToProcess, targetAttributes);
920
- }
921
- });
922
- }
923
- }
924
- // Function to handle redirection without a full page reload
925
- async function handleRedirect(url) {
926
- if (!url) return;
927
- // Use history.pushState to change the URL without a full refresh
928
- history.pushState(null, "", url);
929
- window.dispatchEvent(new PopStateEvent("popstate", { state: null }));
930
- // Fetch the new content via AJAX
931
- try {
932
- const response = await fetch(url, {
933
- headers: {
934
- "X-Requested-With": "XMLHttpRequest",
935
- },
936
- });
937
- const data = await response.text();
938
- updateDocumentContent(data);
939
- } catch (error) {
940
- console.error("Redirect error:", error);
941
- }
942
- }
943
- /**
944
- * Debounces a function to limit the rate at which it is called.
945
- *
946
- * The debounced function will postpone its execution until after the specified wait time
947
- * has elapsed since the last time it was invoked. If `immediate` is `true`, the function
948
- * will be called at the beginning of the wait period instead of at the end.
949
- *
950
- * @param {Function} func - The function to debounce.
951
- * @param {number} [wait=300] - The number of milliseconds to wait before invoking the function.
952
- * @param {boolean} [immediate=false] - If `true`, the function is invoked immediately on the leading edge.
953
- * @returns {Function} - Returns the debounced version of the original function.
954
- */
955
- function debounce(func, wait = 300, immediate = false) {
956
- let timeout;
957
- return function (...args) {
958
- const context = this;
959
- if (timeout) clearTimeout(timeout);
960
- timeout = setTimeout(() => {
961
- timeout = null;
962
- if (!immediate) func.apply(context, args);
963
- }, wait);
964
- if (immediate && !timeout) {
965
- func.apply(context, args);
966
- }
967
- };
968
- }
969
- /**
970
- * Copies code to the clipboard and updates the button icon.
971
- *
972
- * @param {HTMLElement} btnElement - The button element that triggered the copy action.
973
- * @param {string} containerClass - The class of the container element that contains the code block.
974
- * @param {string} initialIconClass - The initial class for the icon.
975
- * @param {string} successIconClass - The class for the icon after a successful copy.
976
- * @param {number} [timeout=2000] - The time in milliseconds to revert to the initial icon class.
977
- */
978
- function copyCode(
979
- btnElement,
980
- containerClass,
981
- initialIconClass,
982
- successIconClass,
983
- timeout = 2000
984
- ) {
985
- // Find the closest container with the specified class relative to the button
986
- const codeBlock = btnElement
987
- .closest(`.${containerClass}`)
988
- ?.querySelector("pre code");
989
- const textToCopy = codeBlock?.textContent?.trim() || ""; // Get the text content of the code block and trim whitespace
990
- if (textToCopy) {
991
- navigator.clipboard.writeText(textToCopy).then(
992
- () => {
993
- // Clipboard successfully set
994
- const icon = btnElement.querySelector("i");
995
- if (icon) {
996
- icon.className = successIconClass; // Change to success icon
997
- }
998
- // Set a timeout to change the icon back to initial after the specified timeout
999
- setTimeout(() => {
1000
- if (icon) {
1001
- icon.className = initialIconClass; // Change back to initial icon
1002
- }
1003
- }, timeout); // Timeout delay
1004
- },
1005
- () => {
1006
- // Clipboard write failed
1007
- alert("Failed to copy command to clipboard");
1008
- }
1009
- );
1010
- } else {
1011
- alert("Failed to find the code block to copy");
1012
- }
1013
- }
1014
- if (typeof store === "undefined") {
1015
- class StateManager {
1016
- static instance = null;
1017
- state;
1018
- listeners;
1019
- /**
1020
- * Creates a new StateManager instance.
1021
- *
1022
- * @param {State} [initialState={}] - The initial state.
1023
- */
1024
- constructor(initialState = {}) {
1025
- this.state = initialState;
1026
- this.listeners = [];
1027
- }
1028
- /**
1029
- * Gets the singleton instance of StateManager.
1030
- *
1031
- * @param {State} [initialState={}] - The initial state.
1032
- * @returns {StateManager} - The StateManager instance.
1033
- */
1034
- static getInstance(initialState = {}) {
1035
- if (!StateManager.instance) {
1036
- StateManager.instance = new StateManager(initialState);
1037
- StateManager.instance.loadState(); // Load state immediately after instance creation
1038
- }
1039
- return StateManager.instance;
1040
- }
1041
- /**
1042
- * Sets the state.
1043
- *
1044
- * @param {Partial<State>} update - The state update.
1045
- * @param {boolean} [saveToStorage=false] - Whether to save the state to localStorage.
1046
- */
1047
- setState(update, saveToStorage = false) {
1048
- this.state = { ...this.state, ...update };
1049
- this.listeners.forEach((listener) => listener(this.state));
1050
- if (saveToStorage) {
1051
- this.saveState();
1052
- }
1053
- }
1054
- /**
1055
- * Subscribes to state changes.
1056
- *
1057
- * @param {(state: State) => void} listener - The listener function.
1058
- * @returns {() => void} - A function to unsubscribe the listener.
1059
- */
1060
- subscribe(listener) {
1061
- this.listeners.push(listener);
1062
- listener(this.state); // Immediately invoke the listener with the current state
1063
- return () => {
1064
- this.listeners = this.listeners.filter((l) => l !== listener);
1065
- };
1066
- }
1067
- /**
1068
- * Saves the state to localStorage.
1069
- */
1070
- saveState() {
1071
- localStorage.setItem("appState", JSON.stringify(this.state));
1072
- }
1073
- /**
1074
- * Loads the state from localStorage.
1075
- */
1076
- loadState() {
1077
- const state = localStorage.getItem("appState");
1078
- if (state) {
1079
- this.state = JSON.parse(state);
1080
- this.listeners.forEach((listener) => listener(this.state));
1081
- }
1082
- }
1083
- /**
1084
- * Resets the state to its initial value.
1085
- *
1086
- * @param {boolean} [clearFromStorage=false] - Whether to clear the state from localStorage.
1087
- */
1088
- resetState(clearFromStorage = false) {
1089
- this.state = {}; // Reset the state to an empty object or a default state if you prefer
1090
- this.listeners.forEach((listener) => listener(this.state));
1091
- if (clearFromStorage) {
1092
- localStorage.removeItem("appState"); // Clear the state from localStorage
1093
- }
1094
- }
1095
- }
1096
- store = StateManager.getInstance();
1097
- }
1
+ var eventAttributes=["onclick","ondblclick","onmousedown","onmouseup","onmouseover","onmousemove","onmouseout","onwheel","onkeypress","onkeydown","onkeyup","onfocus","onblur","onchange","oninput","onselect","onsubmit","onreset","onresize","onscroll","onload","onunload","onabort","onerror","onbeforeunload","oncopy","oncut","onpaste","ondrag","ondragstart","ondragend","ondragover","ondragenter","ondragleave","ondrop","oncontextmenu","ontouchstart","ontouchmove","ontouchend","ontouchcancel","onpointerdown","onpointerup","onpointermove","onpointerover","onpointerout","onpointerenter","onpointerleave","onpointercancel"];document.addEventListener("DOMContentLoaded",attachWireFunctionEvents);var state={checkedElements:new Set},responseData=null,store=null,isNavigating=!1;function attachWireFunctionEvents(){handleHiddenAttribute();document.querySelectorAll("button, input, select, textarea, a, form, label, div, span").forEach((e=>{if(handleAnchorTag(e),eventAttributes.forEach((t=>{const n=e.getAttribute(t),s=t.slice(2);n&&(e.removeAttribute(t),handleDebounce(e,s,n))})),e instanceof HTMLFormElement){const t=e.getAttribute("onsubmit");t&&(e.removeAttribute("onsubmit"),handleDebounce(e,"submit",t))}}))}function handleHiddenAttribute(){document.querySelectorAll("[pp-hidden]").forEach((e=>{let t=e.getAttribute("pp-hidden");if(t)if(isJsonLike(t))try{handleElementVisibility(e,parseJson(t))}catch(e){}else{const n=parseTime(t);n>0&&scheduleVisibilityChange(e,n,"hidden")}}))}function isJsonLike(e){return e.trim().startsWith("{")&&e.trim().endsWith("}")}function handleElementVisibility(e,t){const n=t.start?parseTime(t.start):0,s=t.end?parseTime(t.end):0;n>0?(e.style.visibility="hidden",scheduleVisibilityChange(e,n,"visible"),s>0&&scheduleVisibilityChange(e,n+s,"hidden")):s>0&&scheduleVisibilityChange(e,s,"hidden")}function scheduleVisibilityChange(e,t,n){setTimeout((()=>{requestAnimationFrame((()=>{e.style.visibility=n}))}),t)}function parseTime(e){if("number"==typeof e)return e;const t=e.match(/^(\d+)(ms|s|m)?$/);if(t){const e=parseInt(t[1],10);switch(t[2]||"ms"){case"ms":return e;case"s":return 1e3*e;case"m":return 60*e*1e3;default:return e}}return 0}async function handleDebounce(e,t,n){const s=e.getAttribute("pp-debounce")||"",o=e.getAttribute("pp-trigger")||"",a=e.getAttribute("pp-target-only")||"",c=async t=>{t.preventDefault();try{(o||a)&&(a?invokeHandler(e,o):await invokeHandler(e,o)),await invokeHandler(e,n)}catch(e){}};if(s){const n=debounce(c,parseTime(s));e instanceof HTMLFormElement&&"submit"===t?e.addEventListener(t,(e=>{e.preventDefault(),n(e)})):e.addEventListener(t,n)}else e.addEventListener(t,c)}async function invokeHandler(e,t){try{const n=t.match(/^(\w+(\.\w+)*)\((.*)\)$/);if(n){const s=n[1],o=n[3],a=s.split("."),{context:c,methodName:i}=resolveContext(a);if("function"==typeof c[i]){const e=parseArguments(o);await c[i](...e)}else await handleParsedCallback(e,t)}else await handleParsedCallback(e,t)}catch(e){}}function resolveContext(e){let t=window;for(let n=0;n<e.length-1;n++)if(t=t[e[n]],!t)throw new Error(`Cannot find object ${e[n]} in the context.`);return{context:t,methodName:e[e.length-1]}}function parseArguments(e){return e?JSON.parse(`[${e}]`):[]}async function handleParsedCallback(e,t){const{funcName:n,data:s}=parseCallback(e,t);if(!n)return;const o=window[n];if("function"==typeof o){const t=Array.isArray(s.args)?s.args:[],n=responseData?parseJson(responseData):null;await o(...t,e,s,n)}else responseData=await handleUndefinedFunction(e,n,s)}function handleAnchorTag(e){e instanceof HTMLAnchorElement&&e.addEventListener("click",(async e=>{const t=e.currentTarget,n=t.getAttribute("href"),s=t.getAttribute("target");if(n&&"_blank"!==s&&!e.metaKey&&!e.ctrlKey&&(e.preventDefault(),!isNavigating)){isNavigating=!0;try{/^(https?:)?\/\//i.test(n)&&!n.startsWith(window.location.origin)?window.location.href=n:(history.pushState(null,"",n),await handleNavigation())}catch(e){}finally{isNavigating=!1}}}))}async function handleNavigation(){try{updateDocumentContent(await pphpFetch(window.location.href))}catch(e){}}function updateDocumentContent(e){if(e.includes("<!DOCTYPE html>")){const t=(new DOMParser).parseFromString(e,"text/html"),n=e=>{const t=e.querySelectorAll("script"),n=[];return t.forEach((e=>{const t=document.createElement("script");t.type=e.type||"text/javascript",e.src?t.src=e.src:t.textContent=e.textContent,n.push(t),e.remove()})),n},s=n(t.head),o=n(t.body);document.replaceChild(document.adoptNode(t.documentElement),document.documentElement),s.forEach((e=>document.head.appendChild(e))),o.forEach((e=>document.body.appendChild(e)))}else{saveState();const t=saveScrollPositions(),n=(new DOMParser).parseFromString(e,"text/html"),s=Array.from(n.body.querySelectorAll("script")),o=n.body;diffAndPatch(document.body,o),restoreState(),restoreScrollPositions(t),s.forEach((e=>{const t=document.createElement("script");t.textContent=e.textContent,document.body.appendChild(t),document.body.removeChild(t)}))}attachWireFunctionEvents()}function diffAndPatch(e,t){e.nodeType===t.nodeType?e.nodeType!==Node.TEXT_NODE||t.nodeType!==Node.TEXT_NODE?e instanceof HTMLElement&&t instanceof HTMLElement&&e.replaceWith(t):e.textContent!==t.textContent&&(e.textContent=t.textContent):e.parentNode?.replaceChild(t,e)}function saveState(){const e=document.activeElement;state.focusId=e?.id||e?.name,state.focusValue=e?.value,state.focusChecked=e?.checked,state.focusType=e?.type,state.focusSelectionStart=e?.selectionStart,state.focusSelectionEnd=e?.selectionEnd,state.isSuspense=e.hasAttribute("pp-suspense"),state.checkedElements.clear(),document.querySelectorAll('input[type="checkbox"]:checked').forEach((e=>{state.checkedElements.add(e.id||e.name)})),document.querySelectorAll('input[type="radio"]:checked').forEach((e=>{state.checkedElements.add(e.id||e.name)}))}function restoreState(){if(state.focusId){const e=document.getElementById(state.focusId)||document.querySelector(`[name="${state.focusId}"]`);if(e instanceof HTMLInputElement){e.focus();const t=e.value.length||0;if(void 0!==state.focusSelectionStart&&null!==state.focusSelectionEnd&&e.setSelectionRange(t,t),state.focusValue)if("checkbox"===e.type||"radio"===e.type)e.checked=!!state.focusChecked;else{e.hasAttribute("pp-suspense")||state.isSuspense||(e.value=state.focusValue)}}else if(e instanceof HTMLTextAreaElement){e.focus();const t=e.value.length||0;void 0!==state.focusSelectionStart&&null!==state.focusSelectionEnd&&e.setSelectionRange(t,t),state.focusValue&&(e.value=state.focusValue)}else e instanceof HTMLSelectElement&&(e.focus(),state.focusValue&&(e.value=state.focusValue))}state.checkedElements.forEach((e=>{const t=document.getElementById(e);t&&(t.checked=!0)}))}function saveScrollPositions(){const e={};return document.querySelectorAll("*").forEach((t=>{(t.scrollTop||t.scrollLeft)&&(e[getElementKey(t)]={scrollTop:t.scrollTop,scrollLeft:t.scrollLeft})})),e}function restoreScrollPositions(e){document.querySelectorAll("*").forEach((t=>{const n=getElementKey(t);e[n]&&(t.scrollTop=e[n].scrollTop,t.scrollLeft=e[n].scrollLeft)}))}function getElementKey(e){return e.id||e.className||e.tagName}async function pphpFetch(e,t){const n=await fetch(e,{...t,headers:{...t?.headers,"X-Requested-With":"XMLHttpRequest"}});return await n.text()}function parseCallback(e,t){let n={};const s=e.closest("form");if(s){new FormData(s).forEach(((e,t)=>{n[t]?Array.isArray(n[t])?n[t].push(e):n[t]=[n[t],e]:n[t]=e}))}else e instanceof HTMLInputElement?n=handleInputElement(e):(e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)&&(n[e.name]=e.value);const o=t.match(/(\w+)\((.*)\)/);if(o){const e=o[1];let t=o[2].trim();if(t.startsWith("{")&&t.endsWith("}"))try{const e=parseJson(t);"object"==typeof e&&null!==e&&(n={...n,...e})}catch(e){}else{const e=t.split(/,(?=(?:[^'"]*['"][^'"]*['"])*[^'"]*$)/).map((e=>e.trim().replace(/^['"]|['"]$/g,"")));n.args=e}return{funcName:e,data:n}}return{funcName:t,data:n}}function handleInputElement(e){let t={};if(e.name)if("checkbox"===e.type)t[e.name]={value:e.value,checked:e.checked};else if("radio"===e.type){const n=document.querySelector(`input[name="${e.name}"]:checked`);t[e.name]=n?n.value:null}else t[e.name]=e.value;else"checkbox"===e.type||"radio"===e.type?t.value=e.checked:t.value=e.value;return t}function updateElementAttributes(e,t){for(const n in t)if(t.hasOwnProperty(n))switch(n){case"innerHTML":case"outerHTML":case"textContent":case"innerText":e[n]=decodeHTML(t[n]);break;case"insertAdjacentHTML":e.insertAdjacentHTML(t.position||"beforeend",decodeHTML(t[n].html));break;case"insertAdjacentText":e.insertAdjacentText(t.position||"beforeend",decodeHTML(t[n].text));break;case"setAttribute":e.setAttribute(t.attrName,decodeHTML(t[n]));break;case"removeAttribute":e.removeAttribute(t[n]);break;case"className":e.className=decodeHTML(t[n]);break;case"classList.add":e.classList.add(...decodeHTML(t[n]).split(","));break;case"classList.remove":e.classList.remove(...decodeHTML(t[n]).split(","));break;case"classList.toggle":e.classList.toggle(decodeHTML(t[n]));break;case"classList.replace":const[s,o]=decodeHTML(t[n]).split(",");e.classList.replace(s,o);break;case"dataset":e.dataset[t.attrName]=decodeHTML(t[n]);break;case"style":Object.assign(e.style,t[n]);break;case"value":e.value=decodeHTML(t[n]);break;case"checked":e.checked=t[n];break;default:e.setAttribute(n,decodeHTML(t[n]))}}function decodeHTML(e){const t=document.createElement("textarea");return t.innerHTML=e,t.value}async function handleSuspenseElement(e){let t=e.getAttribute("pp-suspense")||"";const n=(e,t)=>{for(const n in t)if(t.hasOwnProperty(n))for(const t of e.elements)if(t instanceof HTMLInputElement||t instanceof HTMLButtonElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement){const e=t.getAttribute("pp-suspense")||"";if(e)if(isJsonLike(e)){const n=parseJson(e);"disabled"!==n.onsubmit&&updateElementAttributes(t,n)}else s(t,e)}},s=(e,t)=>{e instanceof HTMLInputElement?e.value=t:e.textContent=t};try{if(t&&isJsonLike(t)){const s=parseJson(t);if(s)if(e instanceof HTMLFormElement){const t=new FormData(e),o={};t.forEach(((e,t)=>{o[t]=e})),s.disabled&&toggleFormElements(e,!0);const{disabled:a,...c}=s;updateElementAttributes(e,c),n(e,o)}else if(s.targets){s.targets.forEach((e=>{const{id:t,...s}=e,o=document.querySelector(t);o&&((e,t)=>{e instanceof HTMLFormElement?n(e,t):updateElementAttributes(e,t)})(o,s)}));const{targets:t,...o}=s;updateElementAttributes(e,o)}else{if("disabled"===s.empty&&""===e.value)return;const{empty:t,...n}=s;updateElementAttributes(e,n)}}else if(t)s(e,t);else if(e instanceof HTMLFormElement){const t=new FormData(e),s={};t.forEach(((e,t)=>{s[t]=e})),n(e,s)}}catch(e){}}function parseJson(e){return JSON.parse(e.replace(/'/g,'"'))}function toggleFormElements(e,t){Array.from(e.elements).forEach((e=>{(e instanceof HTMLInputElement||e instanceof HTMLButtonElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement)&&(e.disabled=t)}))}async function handleUndefinedFunction(e,t,n){const s={callback:t,...n},o={method:"POST",headers:{"Content-Type":"application/json",HTTP_PPHP_WIRE_REQUEST:"true"},body:JSON.stringify(s)},a={method:"POST",headers:{"Content-Type":"application/json",HTTP_PPHP_WIRE_REQUEST:"true"},body:JSON.stringify({secondRequestC69CD:!0})};try{handleSuspenseElement(e);const t=e.getAttribute("pp-target-only")||"";t&&handlerTargetOnly(e,t);const n=window.location.pathname,s=await pphpFetch(n,o);if(t)return s;const c=e.getAttribute("pp-function-only")||"";if(handleFunctionOnly(c,s),c)return s;const i=await pphpFetch(n,a);if(s.includes("redirect_7F834=")){const e=s.split("=")[1];await handleRedirect(e)}else{const e=new DOMParser,t=e.parseFromString(i,"text/html").body.innerHTML;updateDocumentContent(s+t)}}catch(e){}}function handlerTargetOnly(e,t){if(!isJsonLike(t))return;const n=e=>{if(e.startsWith("#")){const t=e.slice(1);return document.querySelector(`[id="${t}"]`)}return document.querySelector(e)},s=parseJson(t);s.targets.forEach((t=>{const o=(e=>{if(e.includes(" + ")){const[t,s]=e.split(" + "),o=n(t);if(o){const e=o.nextElementSibling;if(e&&e.matches(s))return e}return null}return n(e)})(t.id);if(o){const n=!!t.this.condition&&((e,t)=>{switch(t){case"checked":return e.checked;case"focus":return e===document.activeElement;default:return!1}})(e,t.this.condition),c=t.this.classList,i={...t.this};c&&((e,t,n)=>{n?(t.add&&e.classList.add(...t.add.split(" ")),t.remove&&e.classList.remove(...t.remove.split(" "))):(t.add&&e.classList.remove(...t.add.split(" ")),t.remove&&e.classList.add(...t.remove.split(" ")))})(o,c,n),Object.keys(i).forEach((e=>{if("id"!==e&&"condition"!==e&&"classList"!==e){const t=i[e];"function"==typeof o[e]?o[e](t):o[e]=t}})),s.actions&&(a=o,s.actions.forEach((e=>{const[t,...n]=e.method.split("."),s=e.value;if(n.length){let e=a[t];for(let t=0;t<n.length-1;t++)e=e[n[t]];e[n[n.length-1]]=s}else a[t]=s})))}var a}))}function handleFunctionOnly(e,t){if(!isJsonLike(e))return;const n=parseJson(e),s=t?parseJson(t):null,o=n.targets;Array.isArray(o)&&o.forEach((e=>{const{id:t,...n}=e,o=document.querySelector(t);let a={};if(s){for(const t in n)if(n.hasOwnProperty(t))switch(t){case"innerHTML":case"outerHTML":case"textContent":case"innerText":"response"===n[t]&&(a[t]=e.responseKey?s[e.responseKey]:s.response);break;default:a[t]=n[t];break}}else a=n;o&&updateElementAttributes(o,a)}))}async function handleRedirect(e){if(e){history.pushState(null,"",e),window.dispatchEvent(new PopStateEvent("popstate",{state:null}));try{const t=await fetch(e,{headers:{"X-Requested-With":"XMLHttpRequest"}});updateDocumentContent(await t.text())}catch(e){}}}function debounce(e,t=300,n=!1){let s;return function(...o){const a=this;s&&clearTimeout(s),s=setTimeout((()=>{s=null,n||e.apply(a,o)}),t),n&&!s&&e.apply(a,o)}}function copyCode(e,t,n,s,o=2e3){const a=e.closest(`.${t}`)?.querySelector("pre code"),c=a?.textContent?.trim()||"";c?navigator.clipboard.writeText(c).then((()=>{const t=e.querySelector("i");t&&(t.className=s),setTimeout((()=>{t&&(t.className=n)}),o)}),(()=>{alert("Failed to copy command to clipboard")})):alert("Failed to find the code block to copy")}if(window.addEventListener("popstate",(async()=>{await handleNavigation()})),void 0===store){class e{static instance=null;state;listeners;constructor(e={}){this.state=e,this.listeners=[]}static getInstance(t={}){return e.instance||(e.instance=new e(t),e.instance.loadState()),e.instance}setState(e,t=!1){this.state={...this.state,...e},this.listeners.forEach((e=>e(this.state))),t&&this.saveState()}subscribe(e){return this.listeners.push(e),e(this.state),()=>{this.listeners=this.listeners.filter((t=>t!==e))}}saveState(){localStorage.setItem("appState",JSON.stringify(this.state))}loadState(){const e=localStorage.getItem("appState");e&&(this.state=JSON.parse(e),this.listeners.forEach((e=>e(this.state))))}resetState(e=!1){this.state={},this.listeners.forEach((e=>e(this.state))),e&&localStorage.removeItem("appState")}}store=e.getInstance()}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-prisma-php-app",
3
- "version": "1.15.34",
3
+ "version": "1.15.36",
4
4
  "description": "Prisma-PHP: A Revolutionary Library Bridging PHP with Prisma ORM",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",