create-prisma-php-app 1.13.3 → 1.13.500
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/bootstrap.php +56 -0
- package/dist/index.js +1 -1
- package/dist/prisma-php.js +0 -1
- package/dist/settings/public-functions.php +2 -7
- package/dist/settings/request-methods.php +0 -1
- package/dist/src/Lib/FormHandler.php +1 -6
- package/dist/src/Lib/StateManager.php +39 -26
- package/dist/src/Lib/Validator.php +10 -44
- package/dist/src/app/js/index.js +233 -429
- package/dist/src/app/layout.php +2 -2
- package/dist/tsconfig.json +1 -1
- package/package.json +1 -1
- package/tsconfig.json +1 -1
- package/dist/src/app/js/htmx.min.js +0 -1
package/dist/src/app/js/index.js
CHANGED
|
@@ -29,163 +29,6 @@ function debounce(func, wait = 300, immediate = false) {
|
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
/**
|
|
33
|
-
* Represents a HTTP request.
|
|
34
|
-
*/
|
|
35
|
-
class RequestApi {
|
|
36
|
-
static instance = null;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* The constructor is now private. To ensure it's not accessible from outside,
|
|
40
|
-
* you can throw an error if someone tries to instantiate it directly
|
|
41
|
-
* (though JavaScript does not have true private constructors).
|
|
42
|
-
*/
|
|
43
|
-
constructor(baseURL = window.location.origin) {
|
|
44
|
-
this.baseURL = baseURL;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Static method to get instance of RequestApi.
|
|
49
|
-
*
|
|
50
|
-
* @param {string} [baseURL=window.location.origin] - The base URL for the request.
|
|
51
|
-
* @returns {RequestApi} The singleton instance of the RequestApi.
|
|
52
|
-
*/
|
|
53
|
-
static getInstance(baseURL = window.location.origin) {
|
|
54
|
-
if (!RequestApi.instance) {
|
|
55
|
-
RequestApi.instance = new RequestApi(baseURL);
|
|
56
|
-
}
|
|
57
|
-
return RequestApi.instance;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Sends a HTTP request.
|
|
62
|
-
*
|
|
63
|
-
* @async
|
|
64
|
-
* @param {string} method - The HTTP method.
|
|
65
|
-
* @param {string} url - The URL to send the request to.
|
|
66
|
-
* @param {*} [data=null] - The data to send with the request.
|
|
67
|
-
* @param {Object} [headers={}] - The headers to include in the request.
|
|
68
|
-
* @returns {Promise<unknown>} - A promise that resolves to the response data.
|
|
69
|
-
*/
|
|
70
|
-
async request(method, url, data = null, headers = {}) {
|
|
71
|
-
let fullUrl = `${this.baseURL}${url}`;
|
|
72
|
-
const options = {
|
|
73
|
-
method,
|
|
74
|
-
headers: {
|
|
75
|
-
"Content-Type": "application/json",
|
|
76
|
-
"X-Requested-With": "XMLHttpRequest",
|
|
77
|
-
...headers,
|
|
78
|
-
},
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
if (data) {
|
|
82
|
-
if (method === "GET") {
|
|
83
|
-
const params = new URLSearchParams(data).toString();
|
|
84
|
-
fullUrl += `?${params}`;
|
|
85
|
-
} else if (method !== "HEAD" && method !== "OPTIONS") {
|
|
86
|
-
options.body = JSON.stringify(data);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
const response = await fetch(fullUrl, options);
|
|
92
|
-
if (method === "HEAD") {
|
|
93
|
-
return response.headers;
|
|
94
|
-
}
|
|
95
|
-
const contentType = response.headers.get("content-type");
|
|
96
|
-
if (contentType && contentType.includes("application/json")) {
|
|
97
|
-
return await response.json();
|
|
98
|
-
} else {
|
|
99
|
-
return await response.text();
|
|
100
|
-
}
|
|
101
|
-
} catch (error) {
|
|
102
|
-
throw error;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Sends a GET request.
|
|
108
|
-
*
|
|
109
|
-
* @param {string} url - The URL to send the request to.
|
|
110
|
-
* @param {*} [params] - The parameters to include in the request.
|
|
111
|
-
* @param {Object} [headers={}] - The headers to include in the request.
|
|
112
|
-
* @returns {Promise<unknown>} - A promise that resolves to the response data.
|
|
113
|
-
*/
|
|
114
|
-
get(url, params, headers) {
|
|
115
|
-
return this.request("GET", url, params, headers);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Sends a POST request.
|
|
120
|
-
*
|
|
121
|
-
* @param {string} url - The URL to send the request to.
|
|
122
|
-
* @param {*} data - The data to send with the request.
|
|
123
|
-
* @param {Object} [headers={}] - The headers to include in the request.
|
|
124
|
-
* @returns {Promise<unknown>} - A promise that resolves to the response data.
|
|
125
|
-
*/
|
|
126
|
-
post(url, data, headers) {
|
|
127
|
-
return this.request("POST", url, data, headers);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Sends a PUT request.
|
|
132
|
-
*
|
|
133
|
-
* @param {string} url - The URL to send the request to.
|
|
134
|
-
* @param {*} data - The data to send with the request.
|
|
135
|
-
* @param {Object} [headers={}] - The headers to include in the request.
|
|
136
|
-
* @returns {Promise<unknown>} - A promise that resolves to the response data.
|
|
137
|
-
*/
|
|
138
|
-
put(url, data, headers) {
|
|
139
|
-
return this.request("PUT", url, data, headers);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Sends a DELETE request.
|
|
144
|
-
*
|
|
145
|
-
* @param {string} url - The URL to send the request to.
|
|
146
|
-
* @param {*} data - The data to send with the request.
|
|
147
|
-
* @param {Object} [headers={}] - The headers to include in the request.
|
|
148
|
-
* @returns {Promise<unknown>} - A promise that resolves to the response data.
|
|
149
|
-
*/
|
|
150
|
-
delete(url, data, headers) {
|
|
151
|
-
return this.request("DELETE", url, data, headers);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Sends a PATCH request.
|
|
156
|
-
*
|
|
157
|
-
* @param {string} url - The URL to send the request to.
|
|
158
|
-
* @param {*} data - The data to send with the request.
|
|
159
|
-
* @param {Object} [headers={}] - The headers to include in the request.
|
|
160
|
-
* @returns {Promise<unknown>} - A promise that resolves to the response data.
|
|
161
|
-
*/
|
|
162
|
-
patch(url, data, headers) {
|
|
163
|
-
return this.request("PATCH", url, data, headers);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Sends a HEAD request.
|
|
168
|
-
*
|
|
169
|
-
* @param {string} url - The URL to send the request to.
|
|
170
|
-
* @param {Object} [headers={}] - The headers to include in the request.
|
|
171
|
-
* @returns {Promise<unknown>} - A promise that resolves to the response headers.
|
|
172
|
-
*/
|
|
173
|
-
head(url, headers) {
|
|
174
|
-
return this.request("HEAD", url, null, headers);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Sends an OPTIONS request.
|
|
179
|
-
*
|
|
180
|
-
* @param {string} url - The URL to send the request to.
|
|
181
|
-
* @param {Object} [headers={}] - The headers to include in the request.
|
|
182
|
-
* @returns {Promise<unknown>} - A promise that resolves to the options available.
|
|
183
|
-
*/
|
|
184
|
-
options(url, headers) {
|
|
185
|
-
return this.request("OPTIONS", url, null, headers);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
32
|
/**
|
|
190
33
|
* Copies text to the clipboard.
|
|
191
34
|
*
|
|
@@ -230,310 +73,271 @@ function copyCode(btnElement) {
|
|
|
230
73
|
copyToClipboard(textToCopy, btnElement);
|
|
231
74
|
}
|
|
232
75
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* Creates a new StateManager instance.
|
|
241
|
-
*
|
|
242
|
-
* @param {{}} [initialState={}] - The initial state.
|
|
243
|
-
*/
|
|
244
|
-
constructor(initialState = {}) {
|
|
245
|
-
this.state = initialState;
|
|
246
|
-
this.listeners = [];
|
|
247
|
-
}
|
|
248
|
-
|
|
76
|
+
if (
|
|
77
|
+
typeof RequestApi === "undefined" &&
|
|
78
|
+
typeof StateManager === "undefined" &&
|
|
79
|
+
typeof HXConnector === "undefined"
|
|
80
|
+
) {
|
|
249
81
|
/**
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
* @static
|
|
253
|
-
* @param {{}} [initialState={}] - The initial state.
|
|
254
|
-
* @returns {StateManager} - The StateManager instance.
|
|
82
|
+
* Represents a HTTP request.
|
|
255
83
|
*/
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
84
|
+
class RequestApi {
|
|
85
|
+
static instance = null;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The constructor is now private. To ensure it's not accessible from outside,
|
|
89
|
+
* you can throw an error if someone tries to instantiate it directly
|
|
90
|
+
* (though JavaScript does not have true private constructors).
|
|
91
|
+
*/
|
|
92
|
+
constructor(baseURL = window.location.origin) {
|
|
93
|
+
this.baseURL = baseURL;
|
|
260
94
|
}
|
|
261
|
-
return StateManager.instance;
|
|
262
|
-
}
|
|
263
95
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Static method to get instance of RequestApi.
|
|
98
|
+
*
|
|
99
|
+
* @param {string} [baseURL=window.location.origin] - The base URL for the request.
|
|
100
|
+
* @returns {RequestApi} The singleton instance of the RequestApi.
|
|
101
|
+
*/
|
|
102
|
+
static getInstance(baseURL = window.location.origin) {
|
|
103
|
+
if (!RequestApi.instance) {
|
|
104
|
+
RequestApi.instance = new RequestApi(baseURL);
|
|
105
|
+
}
|
|
106
|
+
return RequestApi.instance;
|
|
275
107
|
}
|
|
276
|
-
}
|
|
277
108
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Sends a HTTP request.
|
|
111
|
+
*
|
|
112
|
+
* @async
|
|
113
|
+
* @param {string} method - The HTTP method.
|
|
114
|
+
* @param {string} url - The URL to send the request to.
|
|
115
|
+
* @param {*} [data=null] - The data to send with the request.
|
|
116
|
+
* @param {Object} [headers={}] - The headers to include in the request.
|
|
117
|
+
* @returns {Promise<unknown>} - A promise that resolves to the response data.
|
|
118
|
+
*/
|
|
119
|
+
async request(method, url, data = null, headers = {}) {
|
|
120
|
+
let fullUrl = `${this.baseURL}${url}`;
|
|
121
|
+
const options = {
|
|
122
|
+
method,
|
|
123
|
+
headers: {
|
|
124
|
+
"Content-Type": "application/json",
|
|
125
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
126
|
+
...headers,
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
if (data) {
|
|
131
|
+
if (method === "GET") {
|
|
132
|
+
const params = new URLSearchParams(data).toString();
|
|
133
|
+
fullUrl += `?${params}`;
|
|
134
|
+
} else if (method !== "HEAD" && method !== "OPTIONS") {
|
|
135
|
+
options.body = JSON.stringify(data);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
297
138
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
139
|
+
try {
|
|
140
|
+
const response = await fetch(fullUrl, options);
|
|
141
|
+
if (method === "HEAD") {
|
|
142
|
+
return response.headers;
|
|
143
|
+
}
|
|
144
|
+
const contentType = response.headers.get("content-type");
|
|
145
|
+
if (contentType && contentType.includes("application/json")) {
|
|
146
|
+
return await response.json();
|
|
147
|
+
} else {
|
|
148
|
+
return await response.text();
|
|
149
|
+
}
|
|
150
|
+
} catch (error) {
|
|
151
|
+
throw error;
|
|
152
|
+
}
|
|
306
153
|
}
|
|
307
|
-
}
|
|
308
154
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
155
|
+
/**
|
|
156
|
+
* Sends a GET request.
|
|
157
|
+
*
|
|
158
|
+
* @param {string} url - The URL to send the request to.
|
|
159
|
+
* @param {*} [params] - The parameters to include in the request.
|
|
160
|
+
* @param {Object} [headers={}] - The headers to include in the request.
|
|
161
|
+
* @returns {Promise<unknown>} - A promise that resolves to the response data.
|
|
162
|
+
*/
|
|
163
|
+
get(url, params, headers) {
|
|
164
|
+
return this.request("GET", url, params, headers);
|
|
319
165
|
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
class HXConnector {
|
|
324
|
-
// Static property to hold the single instance
|
|
325
|
-
static instance = null;
|
|
326
166
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
167
|
+
/**
|
|
168
|
+
* Sends a POST request.
|
|
169
|
+
*
|
|
170
|
+
* @param {string} url - The URL to send the request to.
|
|
171
|
+
* @param {*} data - The data to send with the request.
|
|
172
|
+
* @param {Object} [headers={}] - The headers to include in the request.
|
|
173
|
+
* @returns {Promise<unknown>} - A promise that resolves to the response data.
|
|
174
|
+
*/
|
|
175
|
+
post(url, data, headers) {
|
|
176
|
+
return this.request("POST", url, data, headers);
|
|
331
177
|
}
|
|
332
178
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
179
|
+
/**
|
|
180
|
+
* Sends a PUT request.
|
|
181
|
+
*
|
|
182
|
+
* @param {string} url - The URL to send the request to.
|
|
183
|
+
* @param {*} data - The data to send with the request.
|
|
184
|
+
* @param {Object} [headers={}] - The headers to include in the request.
|
|
185
|
+
* @returns {Promise<unknown>} - A promise that resolves to the response data.
|
|
186
|
+
*/
|
|
187
|
+
put(url, data, headers) {
|
|
188
|
+
return this.request("PUT", url, data, headers);
|
|
341
189
|
}
|
|
342
|
-
return HXConnector.instance;
|
|
343
|
-
}
|
|
344
190
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
this.handleFormEvents(event.detail.target.querySelectorAll("[hx-form]"));
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// Connects attributes of the provided elements based on the values specified
|
|
361
|
-
// in their `hx-vals` attributes and attaches event listeners based on `hx-trigger`.
|
|
362
|
-
connectAttributes(elements) {
|
|
363
|
-
elements.forEach((element) => {
|
|
364
|
-
const event = element.getAttribute("hx-trigger");
|
|
365
|
-
element.addEventListener(event, (el) => {
|
|
366
|
-
const targetElement = el.target.closest("[hx-trigger]");
|
|
367
|
-
if (targetElement) {
|
|
368
|
-
const values = JSON.parse(targetElement.getAttribute("hx-vals"));
|
|
191
|
+
/**
|
|
192
|
+
* Sends a DELETE request.
|
|
193
|
+
*
|
|
194
|
+
* @param {string} url - The URL to send the request to.
|
|
195
|
+
* @param {*} data - The data to send with the request.
|
|
196
|
+
* @param {Object} [headers={}] - The headers to include in the request.
|
|
197
|
+
* @returns {Promise<unknown>} - A promise that resolves to the response data.
|
|
198
|
+
*/
|
|
199
|
+
delete(url, data, headers) {
|
|
200
|
+
return this.request("DELETE", url, data, headers);
|
|
201
|
+
}
|
|
369
202
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
203
|
+
/**
|
|
204
|
+
* Sends a PATCH request.
|
|
205
|
+
*
|
|
206
|
+
* @param {string} url - The URL to send the request to.
|
|
207
|
+
* @param {*} data - The data to send with the request.
|
|
208
|
+
* @param {Object} [headers={}] - The headers to include in the request.
|
|
209
|
+
* @returns {Promise<unknown>} - A promise that resolves to the response data.
|
|
210
|
+
*/
|
|
211
|
+
patch(url, data, headers) {
|
|
212
|
+
return this.request("PATCH", url, data, headers);
|
|
213
|
+
}
|
|
379
214
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
break;
|
|
391
|
-
case "add":
|
|
392
|
-
element.setAttribute(value, "");
|
|
393
|
-
break;
|
|
394
|
-
case "remove":
|
|
395
|
-
element.removeAttribute(value);
|
|
396
|
-
break;
|
|
397
|
-
default:
|
|
398
|
-
element.setAttribute(attr, value);
|
|
399
|
-
}
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
});
|
|
403
|
-
}
|
|
215
|
+
/**
|
|
216
|
+
* Sends a HEAD request.
|
|
217
|
+
*
|
|
218
|
+
* @param {string} url - The URL to send the request to.
|
|
219
|
+
* @param {Object} [headers={}] - The headers to include in the request.
|
|
220
|
+
* @returns {Promise<unknown>} - A promise that resolves to the response headers.
|
|
221
|
+
*/
|
|
222
|
+
head(url, headers) {
|
|
223
|
+
return this.request("HEAD", url, null, headers);
|
|
224
|
+
}
|
|
404
225
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
switch (attr) {
|
|
416
|
-
case "class":
|
|
417
|
-
this.updateClassAttribute(element, value);
|
|
418
|
-
break;
|
|
419
|
-
case "add":
|
|
420
|
-
element.setAttribute(value, "");
|
|
421
|
-
break;
|
|
422
|
-
case "remove":
|
|
423
|
-
element.removeAttribute(value);
|
|
424
|
-
break;
|
|
425
|
-
default:
|
|
426
|
-
element.setAttribute(attr, value);
|
|
427
|
-
}
|
|
428
|
-
});
|
|
429
|
-
}
|
|
430
|
-
});
|
|
431
|
-
},
|
|
432
|
-
{
|
|
433
|
-
once: true,
|
|
434
|
-
}
|
|
435
|
-
);
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
});
|
|
439
|
-
});
|
|
226
|
+
/**
|
|
227
|
+
* Sends an OPTIONS request.
|
|
228
|
+
*
|
|
229
|
+
* @param {string} url - The URL to send the request to.
|
|
230
|
+
* @param {Object} [headers={}] - The headers to include in the request.
|
|
231
|
+
* @returns {Promise<unknown>} - A promise that resolves to the options available.
|
|
232
|
+
*/
|
|
233
|
+
options(url, headers) {
|
|
234
|
+
return this.request("OPTIONS", url, null, headers);
|
|
235
|
+
}
|
|
440
236
|
}
|
|
441
237
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
238
|
+
/**
|
|
239
|
+
* Manages the application state.
|
|
240
|
+
*/
|
|
241
|
+
class StateManager {
|
|
242
|
+
static instance = null;
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Creates a new StateManager instance.
|
|
246
|
+
*
|
|
247
|
+
* @param {{}} [initialState={}] - The initial state.
|
|
248
|
+
*/
|
|
249
|
+
constructor(initialState = {}) {
|
|
250
|
+
this.state = initialState;
|
|
251
|
+
this.listeners = [];
|
|
252
|
+
}
|
|
456
253
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
254
|
+
/**
|
|
255
|
+
* Gets the singleton instance of StateManager.
|
|
256
|
+
*
|
|
257
|
+
* @static
|
|
258
|
+
* @param {{}} [initialState={}] - The initial state.
|
|
259
|
+
* @returns {StateManager} - The StateManager instance.
|
|
260
|
+
*/
|
|
261
|
+
static getInstance(initialState = {}) {
|
|
262
|
+
if (!StateManager.instance) {
|
|
263
|
+
StateManager.instance = new StateManager(initialState);
|
|
264
|
+
StateManager.instance.loadState(); // Load state immediately after instance creation
|
|
265
|
+
}
|
|
266
|
+
return StateManager.instance;
|
|
267
|
+
}
|
|
462
268
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
269
|
+
/**
|
|
270
|
+
* Sets the state.
|
|
271
|
+
*
|
|
272
|
+
* @param {*} update - The state update.
|
|
273
|
+
* @param {boolean} [saveToStorage=false] - Whether to save the state to localStorage.
|
|
274
|
+
*/
|
|
275
|
+
setState(update, saveToStorage = false) {
|
|
276
|
+
this.state = { ...this.state, ...update };
|
|
277
|
+
this.listeners.forEach((listener) => listener(this.state));
|
|
278
|
+
if (saveToStorage) {
|
|
279
|
+
this.saveState();
|
|
280
|
+
}
|
|
281
|
+
}
|
|
466
282
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
283
|
+
/**
|
|
284
|
+
* Subscribes to state changes.
|
|
285
|
+
*
|
|
286
|
+
* @param {*} listener - The listener function.
|
|
287
|
+
* @returns {Function} - A function to unsubscribe the listener.
|
|
288
|
+
*/
|
|
289
|
+
subscribe(listener) {
|
|
290
|
+
this.listeners.push(listener);
|
|
291
|
+
listener(this.state); // Immediately invoke the listener with the current state
|
|
292
|
+
return () =>
|
|
293
|
+
(this.listeners = this.listeners.filter((l) => l !== listener));
|
|
294
|
+
}
|
|
470
295
|
|
|
471
|
-
|
|
296
|
+
/**
|
|
297
|
+
* Saves the state to localStorage.
|
|
298
|
+
*/
|
|
299
|
+
saveState() {
|
|
300
|
+
localStorage.setItem("appState", JSON.stringify(this.state));
|
|
301
|
+
}
|
|
472
302
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
303
|
+
/**
|
|
304
|
+
* Loads the state from localStorage.
|
|
305
|
+
*/
|
|
306
|
+
loadState() {
|
|
307
|
+
const state = localStorage.getItem("appState");
|
|
308
|
+
if (state) {
|
|
309
|
+
this.state = JSON.parse(state);
|
|
310
|
+
this.listeners.forEach((listener) => listener(this.state));
|
|
478
311
|
}
|
|
479
|
-
}
|
|
480
|
-
}
|
|
312
|
+
}
|
|
481
313
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
}
|
|
489
|
-
|
|
314
|
+
/**
|
|
315
|
+
* Resets the state to its initial value.
|
|
316
|
+
*
|
|
317
|
+
* @param {boolean} [clearFromStorage=false] - Whether to clear the state from localStorage.
|
|
318
|
+
*/
|
|
319
|
+
resetState(clearFromStorage = false) {
|
|
320
|
+
this.state = {}; // Reset the state to an empty object or a default state if you prefer
|
|
321
|
+
this.listeners.forEach((listener) => listener(this.state));
|
|
322
|
+
if (clearFromStorage) {
|
|
323
|
+
localStorage.removeItem("appState"); // Clear the state from localStorage
|
|
490
324
|
}
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
// Toggles the disabled state of the specified form's inputs.
|
|
495
|
-
toggleForm(form, state) {
|
|
496
|
-
const inputs = form.querySelectorAll("input, textarea, select, button");
|
|
497
|
-
inputs.forEach((input) => {
|
|
498
|
-
input.disabled = state;
|
|
499
|
-
});
|
|
325
|
+
}
|
|
500
326
|
}
|
|
501
327
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
const tagName = element.tagName;
|
|
505
|
-
const inputType = element.type;
|
|
328
|
+
let store = null;
|
|
329
|
+
let api = null;
|
|
506
330
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
element.value = value;
|
|
512
|
-
}
|
|
513
|
-
} else {
|
|
514
|
-
element.textContent = value;
|
|
515
|
-
}
|
|
331
|
+
// Function to initialize instances
|
|
332
|
+
function initializeInstances() {
|
|
333
|
+
store = StateManager.getInstance();
|
|
334
|
+
api = RequestApi.getInstance();
|
|
516
335
|
}
|
|
517
336
|
|
|
518
|
-
//
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
classNames.forEach((name) => {
|
|
523
|
-
if (name.startsWith("-")) {
|
|
524
|
-
element.classList.remove(name.substring(1));
|
|
525
|
-
} else {
|
|
526
|
-
element.classList.add(name);
|
|
527
|
-
}
|
|
528
|
-
});
|
|
529
|
-
}
|
|
337
|
+
// Initialize instances on initial page load
|
|
338
|
+
document.addEventListener("DOMContentLoaded", function () {
|
|
339
|
+
initializeInstances();
|
|
340
|
+
});
|
|
530
341
|
}
|
|
531
342
|
|
|
532
|
-
let
|
|
533
|
-
let api = null;
|
|
534
|
-
let hxConnector = null;
|
|
535
|
-
document.addEventListener("DOMContentLoaded", function () {
|
|
536
|
-
store = StateManager.getInstance();
|
|
537
|
-
api = RequestApi.getInstance();
|
|
538
|
-
hxConnector = HXConnector.getInstance();
|
|
539
|
-
});
|
|
343
|
+
"use strict";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"];function attachWireFunctionEvents(){document.querySelectorAll("button, input, select, textarea, a, form, label, div, span").forEach((t=>{t instanceof HTMLAnchorElement&&t.addEventListener("click",handleAnchorTag),eventAttributes.forEach((e=>{const n=t.getAttribute(e),o=e.slice(2);n&&(t.removeAttribute(e),t.addEventListener(o,(e=>{e.preventDefault();const{funcName:o,data:r}=parseCallback(t,n);if(o){const t=window[o];if("function"==typeof t)try{t(...r)}catch(t){}else handleUndefinedFunction(o,r)}})))}))}))}async function handleAnchorTag(t){t.preventDefault();const e=t.currentTarget.getAttribute("href");if(e)try{history.pushState(null,"",e),window.dispatchEvent(new PopStateEvent("popstate",{state:null}))}catch(t){}}function updateDocumentContent(t){t.includes("<!DOCTYPE html>")?document.documentElement.innerHTML=t:document.body.innerHTML=t,attachWireFunctionEvents()}function parseCallback(t,e){let n={};if(t instanceof HTMLFormElement){const e=new FormData(t);n=Object.fromEntries(e.entries())}else t instanceof HTMLInputElement&&(t.name?"checkbox"===t.type||"radio"===t.type?n[t.name]=t.checked:n[t.name]=t.value:"checkbox"===t.type||"radio"===t.type?n.value=t.checked:n.value=t.value);const o=e.match(/(\w+)\(([^)]*)\)/);if(o){const t=o[1];let e=[];return o[2]&&(e=o[2].split(/,(?=(?:[^'"]*['"][^'"]*['"])*[^'"]*$)/).map((t=>t.trim())),e=e.map((t=>{try{const e=t.replace(/'/g,'"');return JSON.parse(e)}catch{return t}}))),e.forEach((t=>{n="object"==typeof t&&null!==t?{...n,...t}:{...n,args:e}})),{funcName:t,data:n}}return{funcName:e,data:n}}function handleUndefinedFunction(t,e){const n={callback:t,...e},o={method:"POST",headers:{"Content-Type":"application/json","X-Requested-With":"XMLHttpRequest",HTTP_PPHP_WIRE_REQUEST:"true"},body:JSON.stringify(n)},r={method:"POST",headers:{"Content-Type":"application/json","X-Requested-With":"XMLHttpRequest",HTTP_PPHP_WIRE_REQUEST:"true"}},c=async t=>{const e=await fetch(window.location.pathname,t);return await e.text()};let a="";c(o).then((t=>(""===a&&(a=t),c(r)))).then((t=>{updateDocumentContent(mergeAndReplaceDuplicates(a,t))})).catch((t=>{}))}function mergeAndReplaceDuplicates(t,e){const{html:n,scripts:o}=extractScripts(t),{html:r,scripts:c}=extractScripts(e),a=new DOMParser,i=a.parseFromString(n,"text/html"),s=a.parseFromString(r,"text/html");mergeElements(i.body,s.body);const l=i.body.innerHTML;return mergeScripts(o,c)+l}function mergeElements(t,e){e.getAttributeNames().forEach((n=>{t.setAttribute(n,e.getAttribute(n))})),e.textContent&&!e.children.length?t.textContent=e.textContent:e.children.length||(t.textContent=""),!e.children.length&&t.children.length&&(t.innerHTML="");const n=Array.from(t.children),o=Array.from(e.children);for(let e=0;e<o.length;e++){const r=n[e],c=o[e];r&&c?mergeElements(r,c):c&&t.appendChild(c.cloneNode(!0))}if(n.length>o.length)for(let e=o.length;e<n.length;e++)t.removeChild(n[e])}function extractScripts(t){const e=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi;let n,o="",r=t;for(;null!==(n=e.exec(t));)o+=n[0],r=r.replace(n[0],"");return{html:r,scripts:o}}function mergeScripts(t,e){const n=new Set;return[...t.match(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi)||[],...e.match(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi)||[]].forEach((t=>n.add(t))),Array.from(n).join("\n")}document.addEventListener("DOMContentLoaded",(()=>{attachWireFunctionEvents()})),window.addEventListener("popstate",(async()=>{try{const t=await fetch(window.location.href,{headers:{"X-Requested-With":"XMLHttpRequest"}});updateDocumentContent(await t.text())}catch(t){}}));
|