@basthon/gui-base 0.50.16 → 0.50.18
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/lib/main.d.ts +4 -4
- package/lib/main.js +77 -45
- package/package.json +5 -5
package/lib/main.d.ts
CHANGED
|
@@ -63,14 +63,14 @@ export declare class GUIBase {
|
|
|
63
63
|
/**
|
|
64
64
|
* Ask the user to confirm or cancel.
|
|
65
65
|
*/
|
|
66
|
-
confirm(title: string, message: string, text: string, callback: (
|
|
66
|
+
confirm(title: string, message: string, text: string, callback: () => void, textCancel: string, callbackCancel: () => void): void;
|
|
67
67
|
/**
|
|
68
68
|
* Ask the user to select a choice.
|
|
69
69
|
*/
|
|
70
70
|
select(title: string, message: string, choices: {
|
|
71
71
|
text: string;
|
|
72
72
|
handler: () => void;
|
|
73
|
-
}[], textCancel: string, callbackCancel: (
|
|
73
|
+
}[], textCancel: string, callbackCancel: () => void): void;
|
|
74
74
|
/**
|
|
75
75
|
* The error notification system.
|
|
76
76
|
*/
|
|
@@ -170,7 +170,7 @@ export declare class GUIBase {
|
|
|
170
170
|
/**
|
|
171
171
|
* Register an extension and its callback.
|
|
172
172
|
*/
|
|
173
|
-
registerExtension(name: string, callback: (
|
|
173
|
+
registerExtension(name: string, callback: () => Promise<void>): void;
|
|
174
174
|
/**
|
|
175
175
|
* Opening file: If it has ext as extension, loading it in
|
|
176
176
|
* the editor or put on (emulated) local filesystem
|
|
@@ -178,7 +178,7 @@ export declare class GUIBase {
|
|
|
178
178
|
* filesystem.
|
|
179
179
|
*/
|
|
180
180
|
protected _openFile(callbacks: {
|
|
181
|
-
[key: string]: (
|
|
181
|
+
[key: string]: (_: File) => Promise<void>;
|
|
182
182
|
}): Promise<void>;
|
|
183
183
|
/**
|
|
184
184
|
* Open an URL in a new tab or download a file.
|
package/lib/main.js
CHANGED
|
@@ -27,24 +27,36 @@ export class GUIBase {
|
|
|
27
27
|
/**
|
|
28
28
|
* Language getter.
|
|
29
29
|
*/
|
|
30
|
-
get language() {
|
|
30
|
+
get language() {
|
|
31
|
+
return this._language;
|
|
32
|
+
}
|
|
31
33
|
/**
|
|
32
34
|
* Kernel getter.
|
|
33
35
|
*/
|
|
34
|
-
get kernel() {
|
|
35
|
-
|
|
36
|
+
get kernel() {
|
|
37
|
+
return this._loader.kernel;
|
|
38
|
+
}
|
|
39
|
+
get kernelSafe() {
|
|
40
|
+
return this._loader.kernelSafe;
|
|
41
|
+
}
|
|
36
42
|
/**
|
|
37
43
|
* KernelLoader getter.
|
|
38
44
|
*/
|
|
39
|
-
get kernelLoader() {
|
|
45
|
+
get kernelLoader() {
|
|
46
|
+
return this._loader;
|
|
47
|
+
}
|
|
40
48
|
/**
|
|
41
49
|
* Check if GUI is loaded.
|
|
42
50
|
*/
|
|
43
|
-
async loaded() {
|
|
51
|
+
async loaded() {
|
|
52
|
+
await this._loaded.promise;
|
|
53
|
+
}
|
|
44
54
|
/**
|
|
45
55
|
* Wait for par load (document.body available).
|
|
46
56
|
*/
|
|
47
|
-
async pageLoad() {
|
|
57
|
+
async pageLoad() {
|
|
58
|
+
await this._loader.pageLoad();
|
|
59
|
+
}
|
|
48
60
|
/**
|
|
49
61
|
* Set the checkpoints manager
|
|
50
62
|
* (typically use with GUIOptions.noCheckpointsInit set to true).
|
|
@@ -79,7 +91,7 @@ export class GUIBase {
|
|
|
79
91
|
message = (_b = (_a = error) === null || _a === void 0 ? void 0 : _a.reason) === null || _b === void 0 ? void 0 : _b.message;
|
|
80
92
|
if (message == null)
|
|
81
93
|
message = error.toString();
|
|
82
|
-
message = message.split(
|
|
94
|
+
message = message.split("\n").join("<br>");
|
|
83
95
|
this.error("Erreur", `Erreur : ${message}`);
|
|
84
96
|
// In case of error, force loader hiding.
|
|
85
97
|
try {
|
|
@@ -102,7 +114,9 @@ export class GUIBase {
|
|
|
102
114
|
/**
|
|
103
115
|
* Get the content (script or notebook content).
|
|
104
116
|
*/
|
|
105
|
-
content() {
|
|
117
|
+
content() {
|
|
118
|
+
return "";
|
|
119
|
+
}
|
|
106
120
|
/**
|
|
107
121
|
* Set the content (script or notebook content).
|
|
108
122
|
*/
|
|
@@ -113,7 +127,7 @@ export class GUIBase {
|
|
|
113
127
|
async loadFromQS(key) {
|
|
114
128
|
var _a;
|
|
115
129
|
const url = new URL(window.location.href);
|
|
116
|
-
const from_key =
|
|
130
|
+
const from_key = "from";
|
|
117
131
|
let content = null;
|
|
118
132
|
if (url.searchParams.has(key)) {
|
|
119
133
|
content = url.searchParams.get(key) || "";
|
|
@@ -130,14 +144,20 @@ export class GUIBase {
|
|
|
130
144
|
let fileURL = url.searchParams.get(from_key);
|
|
131
145
|
if (fileURL != null)
|
|
132
146
|
fileURL = decodeURIComponent(fileURL);
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
throw new Error(response.statusText);
|
|
137
|
-
content = await response.text();
|
|
147
|
+
// empty from param gives empty content
|
|
148
|
+
if (fileURL === "") {
|
|
149
|
+
content = "";
|
|
138
150
|
}
|
|
139
|
-
|
|
140
|
-
|
|
151
|
+
else {
|
|
152
|
+
try {
|
|
153
|
+
const response = await fetch(fileURL);
|
|
154
|
+
if (!response.ok)
|
|
155
|
+
throw new Error(response.statusText);
|
|
156
|
+
content = await response.text();
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
throw new Error(`Le chargement de ${fileURL} a échoué : ${(_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error.toString()}`);
|
|
160
|
+
}
|
|
141
161
|
}
|
|
142
162
|
}
|
|
143
163
|
if (content != null)
|
|
@@ -152,7 +172,7 @@ export class GUIBase {
|
|
|
152
172
|
var _a, _b;
|
|
153
173
|
/* get requested extensions from URL */
|
|
154
174
|
const url = new URL(window.location.href);
|
|
155
|
-
const extensions = (_b = (_a = url.searchParams.get("extensions")) === null || _a === void 0 ? void 0 : _a.split(
|
|
175
|
+
const extensions = (_b = (_a = url.searchParams.get("extensions")) === null || _a === void 0 ? void 0 : _a.split(",")) !== null && _b !== void 0 ? _b : [];
|
|
156
176
|
// call callbacks for requested extensions
|
|
157
177
|
const promises = [];
|
|
158
178
|
for (const ext of extensions) {
|
|
@@ -193,7 +213,7 @@ export class GUIBase {
|
|
|
193
213
|
*/
|
|
194
214
|
async getState(state, def) {
|
|
195
215
|
var _a;
|
|
196
|
-
return (_a = await this._stateStorage.get(state)) !== null && _a !== void 0 ? _a : def;
|
|
216
|
+
return (_a = (await this._stateStorage.get(state))) !== null && _a !== void 0 ? _a : def;
|
|
197
217
|
}
|
|
198
218
|
/**
|
|
199
219
|
* Set state in storage.
|
|
@@ -207,7 +227,7 @@ export class GUIBase {
|
|
|
207
227
|
async loadInitialContent(options) {
|
|
208
228
|
if (window._basthonEmptyContent)
|
|
209
229
|
return;
|
|
210
|
-
if (await this.loadFromQS(this._urlKey) != null)
|
|
230
|
+
if ((await this.loadFromQS(this._urlKey)) != null)
|
|
211
231
|
return;
|
|
212
232
|
this.loadFromStorage();
|
|
213
233
|
}
|
|
@@ -222,13 +242,15 @@ export class GUIBase {
|
|
|
222
242
|
content = null;
|
|
223
243
|
}
|
|
224
244
|
else if (approved) {
|
|
225
|
-
content = await ((_a = this._checkpoints) === null || _a === void 0 ? void 0 : _a.getLast());
|
|
245
|
+
content = (await ((_a = this._checkpoints) === null || _a === void 0 ? void 0 : _a.getLast()));
|
|
226
246
|
}
|
|
227
247
|
else {
|
|
228
248
|
const promise = new PromiseDelegate();
|
|
229
249
|
this.confirm("Récupération", "Il semble que Basthon ait rencontré un problème à sa dernière utilisation. Que voulez-vous faire ?", "Choisir une sauvegarde", async () => {
|
|
230
250
|
promise.resolve(await this.selectCheckpoint());
|
|
231
|
-
}, "Annuler", () => {
|
|
251
|
+
}, "Annuler", () => {
|
|
252
|
+
promise.resolve(null);
|
|
253
|
+
});
|
|
232
254
|
content = await promise.promise;
|
|
233
255
|
}
|
|
234
256
|
if (setContent && content != null)
|
|
@@ -258,7 +280,10 @@ export class GUIBase {
|
|
|
258
280
|
const promise = new PromiseDelegate();
|
|
259
281
|
const choices = times === null || times === void 0 ? void 0 : times.map((t, i) => ({
|
|
260
282
|
text: CheckpointsManager.toHumanDate(parseInt(t, 10)),
|
|
261
|
-
handler: async () => {
|
|
283
|
+
handler: async () => {
|
|
284
|
+
var _a, _b;
|
|
285
|
+
promise.resolve((_b = (await ((_a = this._checkpoints) === null || _a === void 0 ? void 0 : _a.getIndex(i)))) !== null && _b !== void 0 ? _b : null);
|
|
286
|
+
},
|
|
262
287
|
}));
|
|
263
288
|
if (choices == null)
|
|
264
289
|
return null;
|
|
@@ -267,7 +292,9 @@ export class GUIBase {
|
|
|
267
292
|
promise.resolve(null);
|
|
268
293
|
}
|
|
269
294
|
else {
|
|
270
|
-
this.select("Choisissez une sauvegarde", "De quelle sauvegarde souhaitez-vous reprendre ?", choices, "Annuler", () => {
|
|
295
|
+
this.select("Choisissez une sauvegarde", "De quelle sauvegarde souhaitez-vous reprendre ?", choices, "Annuler", () => {
|
|
296
|
+
promise.resolve(null);
|
|
297
|
+
});
|
|
271
298
|
}
|
|
272
299
|
return await promise.promise;
|
|
273
300
|
}
|
|
@@ -286,7 +313,7 @@ export class GUIBase {
|
|
|
286
313
|
var _a;
|
|
287
314
|
/* all errors redirected to notification system */
|
|
288
315
|
const onerror = this.notifyError.bind(this);
|
|
289
|
-
window.addEventListener(
|
|
316
|
+
window.addEventListener("error", onerror);
|
|
290
317
|
window.addEventListener("unhandledrejection", onerror);
|
|
291
318
|
console.error = (message) => onerror(new Error(message));
|
|
292
319
|
await this._loadExtensions();
|
|
@@ -321,7 +348,9 @@ export class GUIBase {
|
|
|
321
348
|
/**
|
|
322
349
|
* Get mode as a string (dark/light).
|
|
323
350
|
*/
|
|
324
|
-
async theme() {
|
|
351
|
+
async theme() {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
325
354
|
/**
|
|
326
355
|
* Restart the kernel.
|
|
327
356
|
*/
|
|
@@ -339,7 +368,7 @@ export class GUIBase {
|
|
|
339
368
|
let promises = [];
|
|
340
369
|
for (let fileURL of url.searchParams.getAll(key)) {
|
|
341
370
|
fileURL = decodeURIComponent(fileURL);
|
|
342
|
-
const filename = fileURL.split(
|
|
371
|
+
const filename = fileURL.split("/").pop() || "";
|
|
343
372
|
promises.push((async () => {
|
|
344
373
|
var _a;
|
|
345
374
|
let data;
|
|
@@ -379,7 +408,7 @@ export class GUIBase {
|
|
|
379
408
|
async loadURLAux() {
|
|
380
409
|
if (this.kernelSafe == null)
|
|
381
410
|
return;
|
|
382
|
-
await this._loadFromURL(
|
|
411
|
+
await this._loadFromURL("aux", this.kernelSafe.putFile.bind(this.kernelSafe));
|
|
383
412
|
}
|
|
384
413
|
/**
|
|
385
414
|
* Load modules submited via URL (module= parameter) (async).
|
|
@@ -387,7 +416,7 @@ export class GUIBase {
|
|
|
387
416
|
async loadURLModules() {
|
|
388
417
|
if (this.kernelSafe == null)
|
|
389
418
|
return;
|
|
390
|
-
await this._loadFromURL(
|
|
419
|
+
await this._loadFromURL("module", this.kernelSafe.putModule.bind(this.kernelSafe));
|
|
391
420
|
}
|
|
392
421
|
/**
|
|
393
422
|
* Register an extension and its callback.
|
|
@@ -403,14 +432,14 @@ export class GUIBase {
|
|
|
403
432
|
*/
|
|
404
433
|
_openFile(callbacks) {
|
|
405
434
|
return new Promise((resolve, reject) => {
|
|
406
|
-
let input = document.createElement(
|
|
407
|
-
input.type =
|
|
435
|
+
let input = document.createElement("input");
|
|
436
|
+
input.type = "file";
|
|
408
437
|
input.style.display = "none";
|
|
409
438
|
input.onchange = async () => {
|
|
410
439
|
if (input.files == null)
|
|
411
440
|
return;
|
|
412
441
|
for (let file of input.files) {
|
|
413
|
-
const ext = file.name.split(
|
|
442
|
+
const ext = file.name.split(".").pop();
|
|
414
443
|
const callback = callbacks[ext !== null && ext !== void 0 ? ext : ""];
|
|
415
444
|
if (callback != null) {
|
|
416
445
|
await callback(file);
|
|
@@ -453,8 +482,11 @@ export class GUIBase {
|
|
|
453
482
|
try {
|
|
454
483
|
content = await this.deflate(content);
|
|
455
484
|
}
|
|
456
|
-
catch (e) {
|
|
457
|
-
|
|
485
|
+
catch (e) {
|
|
486
|
+
// fallback
|
|
487
|
+
content = encodeURIComponent(content)
|
|
488
|
+
.replace(/\(/g, "%28")
|
|
489
|
+
.replace(/\)/g, "%29");
|
|
458
490
|
}
|
|
459
491
|
url.searchParams.set(key, content);
|
|
460
492
|
return url.href;
|
|
@@ -510,7 +542,7 @@ Un lien permanant vers le contenu actuel a été créé.
|
|
|
510
542
|
// dynamic import for webpack
|
|
511
543
|
const pako = await import("pako");
|
|
512
544
|
const { Base64 } = await import("js-base64");
|
|
513
|
-
return pako.inflate(Base64.toUint8Array(content), { to:
|
|
545
|
+
return pako.inflate(Base64.toUint8Array(content), { to: "string" });
|
|
514
546
|
}
|
|
515
547
|
}
|
|
516
548
|
/**
|
|
@@ -524,32 +556,32 @@ GUIBase.copyToClipboard = function (text) {
|
|
|
524
556
|
let textArea = document.createElement("textarea");
|
|
525
557
|
// Precautions from https://stackoverflow.com/questions/400212/how-do-i-copy-to-the-clipboard-in-javascript
|
|
526
558
|
// Place in top-left corner of screen regardless of scroll position.
|
|
527
|
-
textArea.style.position =
|
|
559
|
+
textArea.style.position = "fixed";
|
|
528
560
|
textArea.style.top = "0px";
|
|
529
561
|
textArea.style.left = "0px";
|
|
530
562
|
// Ensure it has a small width and height. Setting to 1px / 1em
|
|
531
563
|
// doesn't work as this gives a negative w/h on some browsers.
|
|
532
|
-
textArea.style.width =
|
|
533
|
-
textArea.style.height =
|
|
564
|
+
textArea.style.width = "2em";
|
|
565
|
+
textArea.style.height = "2em";
|
|
534
566
|
// We don't need padding, reducing the size if it does flash render.
|
|
535
567
|
textArea.style.padding = "0px";
|
|
536
568
|
// Clean up any borders.
|
|
537
|
-
textArea.style.border =
|
|
538
|
-
textArea.style.outline =
|
|
539
|
-
textArea.style.boxShadow =
|
|
569
|
+
textArea.style.border = "none";
|
|
570
|
+
textArea.style.outline = "none";
|
|
571
|
+
textArea.style.boxShadow = "none";
|
|
540
572
|
// Avoid flash of white box if rendered for any reason.
|
|
541
|
-
textArea.style.background =
|
|
573
|
+
textArea.style.background = "transparent";
|
|
542
574
|
textArea.value = text;
|
|
543
575
|
document.body.appendChild(textArea);
|
|
544
576
|
textArea.focus();
|
|
545
577
|
textArea.select();
|
|
546
578
|
try {
|
|
547
|
-
let successful = document.execCommand(
|
|
548
|
-
let msg = successful ?
|
|
549
|
-
console.log(
|
|
579
|
+
let successful = document.execCommand("copy");
|
|
580
|
+
let msg = successful ? "successful" : "unsuccessful";
|
|
581
|
+
console.log("Copying text command was " + msg);
|
|
550
582
|
}
|
|
551
583
|
catch (err) {
|
|
552
|
-
console.log(
|
|
584
|
+
console.log("Oops, unable to copy");
|
|
553
585
|
}
|
|
554
586
|
document.body.removeChild(textArea);
|
|
555
587
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@basthon/gui-base",
|
|
3
|
-
"version": "0.50.
|
|
3
|
+
"version": "0.50.18",
|
|
4
4
|
"description": "Basthon - Base GUI",
|
|
5
5
|
"homepage": "https://basthon.fr",
|
|
6
6
|
"bugs": {
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"clean": "rm -rf lib/"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@basthon/checkpoints": "0.50.
|
|
29
|
-
"@basthon/kernel-base": "0.50.
|
|
30
|
-
"@basthon/kernel-loader": "0.50.
|
|
28
|
+
"@basthon/checkpoints": "0.50.18",
|
|
29
|
+
"@basthon/kernel-base": "0.50.18",
|
|
30
|
+
"@basthon/kernel-loader": "0.50.18",
|
|
31
31
|
"js-base64": "^3.7.2",
|
|
32
32
|
"pako": "^2.0.4",
|
|
33
33
|
"promise-delegate": "^1.0.1"
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"publishConfig": {
|
|
42
42
|
"access": "public"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "2d12d64597825a66606b5251ca09101b865d6f05"
|
|
45
45
|
}
|