@basthon/gui-base 0.62.21 → 0.62.22
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.js +23 -40
- package/package.json +12 -14
package/lib/main.js
CHANGED
|
@@ -6,7 +6,6 @@ import { KernelLoader } from "@basthon/kernel-loader";
|
|
|
6
6
|
*/
|
|
7
7
|
export class GUIBase {
|
|
8
8
|
constructor(options) {
|
|
9
|
-
var _a;
|
|
10
9
|
this._loaded = new PromiseDelegate();
|
|
11
10
|
this._maxCheckpoints = 10;
|
|
12
11
|
this._contentFilename = "content.txt";
|
|
@@ -14,7 +13,7 @@ export class GUIBase {
|
|
|
14
13
|
this._extensions = new Map();
|
|
15
14
|
/* console errors redirected to notification system */
|
|
16
15
|
this._console_error = console.error;
|
|
17
|
-
this._language =
|
|
16
|
+
this._language = options?.kernelOptions?.language;
|
|
18
17
|
this._loader = new KernelLoader(options.kernelOptions);
|
|
19
18
|
// loading Basthon (errors are fatal)
|
|
20
19
|
this._loader.showLoader("Chargement de Basthon...", false, false);
|
|
@@ -84,14 +83,13 @@ export class GUIBase {
|
|
|
84
83
|
* The error notification system.
|
|
85
84
|
*/
|
|
86
85
|
notifyError(error) {
|
|
87
|
-
var _a, _b;
|
|
88
86
|
this._console_error(error);
|
|
89
87
|
let message = error.message;
|
|
90
88
|
if (message == null)
|
|
91
|
-
message =
|
|
89
|
+
message = error?.reason?.message;
|
|
92
90
|
if (message == null)
|
|
93
91
|
message = error.toString();
|
|
94
|
-
// avoid html injection on errors
|
|
92
|
+
// avoid html/js injection on errors
|
|
95
93
|
const encodeHTMLEntities = (text) => {
|
|
96
94
|
var textArea = document.createElement("textarea");
|
|
97
95
|
textArea.innerText = text;
|
|
@@ -131,7 +129,6 @@ export class GUIBase {
|
|
|
131
129
|
* Loading the content from query string (ipynb=/script= or from=).
|
|
132
130
|
*/
|
|
133
131
|
async loadFromQS(key) {
|
|
134
|
-
var _a;
|
|
135
132
|
const url = new URL(window.location.href);
|
|
136
133
|
const from_key = "from";
|
|
137
134
|
let content = null;
|
|
@@ -162,7 +159,7 @@ export class GUIBase {
|
|
|
162
159
|
content = await response.text();
|
|
163
160
|
}
|
|
164
161
|
catch (error) {
|
|
165
|
-
throw new Error(`Le chargement de ${fileURL} a échoué : ${
|
|
162
|
+
throw new Error(`Le chargement de ${fileURL} a échoué : ${error?.message ?? error.toString()}`);
|
|
166
163
|
}
|
|
167
164
|
}
|
|
168
165
|
}
|
|
@@ -175,10 +172,9 @@ export class GUIBase {
|
|
|
175
172
|
* (call submited callback).
|
|
176
173
|
*/
|
|
177
174
|
async _loadExtensions() {
|
|
178
|
-
var _a, _b;
|
|
179
175
|
/* get requested extensions from URL */
|
|
180
176
|
const url = new URL(window.location.href);
|
|
181
|
-
const extensions =
|
|
177
|
+
const extensions = url.searchParams.get("extensions")?.split(",") ?? [];
|
|
182
178
|
// call callbacks for requested extensions
|
|
183
179
|
const promises = [];
|
|
184
180
|
for (const ext of extensions) {
|
|
@@ -218,8 +214,7 @@ export class GUIBase {
|
|
|
218
214
|
* Get state from strorage.
|
|
219
215
|
*/
|
|
220
216
|
async getState(state, def) {
|
|
221
|
-
|
|
222
|
-
return (_a = (await this._stateStorage.get(state))) !== null && _a !== void 0 ? _a : def;
|
|
217
|
+
return (await this._stateStorage.get(state)) ?? def;
|
|
223
218
|
}
|
|
224
219
|
/**
|
|
225
220
|
* Set state in storage.
|
|
@@ -241,14 +236,13 @@ export class GUIBase {
|
|
|
241
236
|
* Load content from local forage.
|
|
242
237
|
*/
|
|
243
238
|
async loadFromStorage(setContent = true) {
|
|
244
|
-
var _a;
|
|
245
239
|
const approved = await this.lastBackupValid();
|
|
246
240
|
let content = null;
|
|
247
241
|
if (approved == null) {
|
|
248
242
|
content = null;
|
|
249
243
|
}
|
|
250
244
|
else if (approved) {
|
|
251
|
-
content = (await
|
|
245
|
+
content = (await this._checkpoints?.getLast());
|
|
252
246
|
}
|
|
253
247
|
else {
|
|
254
248
|
const promise = new PromiseDelegate();
|
|
@@ -267,28 +261,24 @@ export class GUIBase {
|
|
|
267
261
|
* Tag last backup as "approved".
|
|
268
262
|
*/
|
|
269
263
|
async validateBackup() {
|
|
270
|
-
|
|
271
|
-
await ((_a = this._checkpoints) === null || _a === void 0 ? void 0 : _a.tagLast("approved"));
|
|
264
|
+
await this._checkpoints?.tagLast("approved");
|
|
272
265
|
}
|
|
273
266
|
/**
|
|
274
267
|
* Is last backup tagged as "approved"?
|
|
275
268
|
*/
|
|
276
269
|
async lastBackupValid() {
|
|
277
|
-
|
|
278
|
-
return await ((_a = this._checkpoints) === null || _a === void 0 ? void 0 : _a.lastHasTag("approved"));
|
|
270
|
+
return await this._checkpoints?.lastHasTag("approved");
|
|
279
271
|
}
|
|
280
272
|
/**
|
|
281
273
|
* Select a checkpoint to load in the script.
|
|
282
274
|
*/
|
|
283
275
|
async selectCheckpoint() {
|
|
284
|
-
|
|
285
|
-
const times = await ((_a = this._checkpoints) === null || _a === void 0 ? void 0 : _a.times());
|
|
276
|
+
const times = await this._checkpoints?.times();
|
|
286
277
|
const promise = new PromiseDelegate();
|
|
287
|
-
const choices = times
|
|
278
|
+
const choices = times?.map((t, i) => ({
|
|
288
279
|
text: CheckpointsManager.toHumanDate(parseInt(t, 10)),
|
|
289
280
|
handler: async () => {
|
|
290
|
-
|
|
291
|
-
promise.resolve((_b = (await ((_a = this._checkpoints) === null || _a === void 0 ? void 0 : _a.getIndex(i)))) !== null && _b !== void 0 ? _b : null);
|
|
281
|
+
promise.resolve((await this._checkpoints?.getIndex(i)) ?? null);
|
|
292
282
|
},
|
|
293
283
|
}));
|
|
294
284
|
if (choices == null)
|
|
@@ -308,25 +298,23 @@ export class GUIBase {
|
|
|
308
298
|
* Backup to checkpoints.
|
|
309
299
|
*/
|
|
310
300
|
async backup(approved = true) {
|
|
311
|
-
|
|
312
|
-
return await ((_a = this._checkpoints) === null || _a === void 0 ? void 0 : _a.push(this.content(), approved ? ["approved"] : []));
|
|
301
|
+
return await this._checkpoints?.push(this.content(), approved ? ["approved"] : []);
|
|
313
302
|
}
|
|
314
303
|
/**
|
|
315
304
|
* Internal GUI init.
|
|
316
305
|
* It calls setupUI then loadInitialContent.
|
|
317
306
|
*/
|
|
318
307
|
async _init(options = null) {
|
|
319
|
-
var _a;
|
|
320
308
|
/* all errors redirected to notification system */
|
|
321
309
|
const onerror = this.notifyError.bind(this);
|
|
322
310
|
window.addEventListener("error", onerror);
|
|
323
311
|
window.addEventListener("unhandledrejection", onerror);
|
|
324
312
|
console.error = (message) => onerror(new Error(message));
|
|
325
313
|
await this._loadExtensions();
|
|
326
|
-
await
|
|
314
|
+
await this._checkpoints?.ready();
|
|
327
315
|
await this.setupUI(options);
|
|
328
316
|
await this.loadInitialContent(options);
|
|
329
|
-
await this.kernelLoader.
|
|
317
|
+
await this.kernelLoader.kernelStarted();
|
|
330
318
|
const init = this.initCaller.bind(this);
|
|
331
319
|
// loading aux files from URL
|
|
332
320
|
await init(this.loadURLAux.bind(this), "Chargement des fichiers auxiliaires...", true);
|
|
@@ -361,10 +349,8 @@ export class GUIBase {
|
|
|
361
349
|
* Restart the kernel.
|
|
362
350
|
*/
|
|
363
351
|
kernelRestart() {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
throw new Error("pending input");
|
|
367
|
-
(_b = this.kernelSafe) === null || _b === void 0 ? void 0 : _b.restart();
|
|
352
|
+
this.kernelSafe?.resolvePendingInput();
|
|
353
|
+
this.kernelSafe?.restart();
|
|
368
354
|
}
|
|
369
355
|
/**
|
|
370
356
|
* Load ressources from URL (common part to files and modules).
|
|
@@ -376,7 +362,6 @@ export class GUIBase {
|
|
|
376
362
|
fileURL = decodeURIComponent(fileURL);
|
|
377
363
|
const filename = fileURL.split("/").pop() || "";
|
|
378
364
|
promises.push((async () => {
|
|
379
|
-
var _a;
|
|
380
365
|
let data;
|
|
381
366
|
try {
|
|
382
367
|
const response = await fetch(fileURL);
|
|
@@ -386,7 +371,7 @@ export class GUIBase {
|
|
|
386
371
|
await put(filename, data);
|
|
387
372
|
}
|
|
388
373
|
catch (error) {
|
|
389
|
-
throw new Error(`Impossible de charger le fichier ${filename} : ${
|
|
374
|
+
throw new Error(`Impossible de charger le fichier ${filename} : ${error?.message ?? error.toString()}`);
|
|
390
375
|
}
|
|
391
376
|
})());
|
|
392
377
|
}
|
|
@@ -400,9 +385,8 @@ export class GUIBase {
|
|
|
400
385
|
const reader = new FileReader();
|
|
401
386
|
reader.readAsArrayBuffer(file);
|
|
402
387
|
reader.onload = async (event) => {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
this.info(`Fichier utilisable depuis ${(_b = this.kernel) === null || _b === void 0 ? void 0 : _b.languageName()}`, `${file.name} est maintenant utilisable depuis ${(_c = this.kernel) === null || _c === void 0 ? void 0 : _c.languageName()}`);
|
|
388
|
+
await this.kernelSafe?.putRessource(file.name, reader.result);
|
|
389
|
+
this.info(`Fichier utilisable depuis ${this.kernel?.languageName()}`, `${file.name} est maintenant utilisable depuis ${this.kernel?.languageName()}`);
|
|
406
390
|
resolve();
|
|
407
391
|
};
|
|
408
392
|
reader.onerror = reject;
|
|
@@ -446,7 +430,7 @@ export class GUIBase {
|
|
|
446
430
|
return;
|
|
447
431
|
for (let file of input.files) {
|
|
448
432
|
const ext = file.name.split(".").pop();
|
|
449
|
-
const callback = callbacks[ext
|
|
433
|
+
const callback = callbacks[ext ?? ""];
|
|
450
434
|
if (callback != null) {
|
|
451
435
|
await callback(file);
|
|
452
436
|
}
|
|
@@ -516,8 +500,7 @@ Un lien permanant vers le contenu actuel a été créé.
|
|
|
516
500
|
const reader = new FileReader();
|
|
517
501
|
reader.readAsText(file);
|
|
518
502
|
reader.onload = (event) => {
|
|
519
|
-
|
|
520
|
-
this.setContent((_a = event === null || event === void 0 ? void 0 : event.target) === null || _a === void 0 ? void 0 : _a.result);
|
|
503
|
+
this.setContent(event?.target?.result);
|
|
521
504
|
resolve();
|
|
522
505
|
};
|
|
523
506
|
reader.onerror = reject;
|
|
@@ -530,7 +513,7 @@ Un lien permanant vers le contenu actuel a été créé.
|
|
|
530
513
|
this.backup();
|
|
531
514
|
const content = this.content().replace(/\r\n|\r|\n/g, "\r\n"); // To retain the Line breaks.
|
|
532
515
|
let blob = new Blob([content], { type: "text/plain" });
|
|
533
|
-
GUIBase.openURL(window.URL.createObjectURL(blob), filename
|
|
516
|
+
GUIBase.openURL(window.URL.createObjectURL(blob), filename ?? this._contentFilename);
|
|
534
517
|
}
|
|
535
518
|
/**
|
|
536
519
|
* Compress a string to another string (URL safe).
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@basthon/gui-base",
|
|
3
|
-
"version": "0.62.
|
|
3
|
+
"version": "0.62.22",
|
|
4
4
|
"description": "Basthon - Base GUI",
|
|
5
5
|
"homepage": "https://basthon.fr",
|
|
6
6
|
"bugs": {
|
|
7
|
-
"url": "https://
|
|
7
|
+
"url": "https://forge.apps.education.fr/basthon/basthon-kernel/issues"
|
|
8
8
|
},
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
11
|
-
"url": "https://
|
|
11
|
+
"url": "https://forge.apps.education.fr/basthon/basthon-kernel.git"
|
|
12
12
|
},
|
|
13
13
|
"license": "GPL-3.0-or-later",
|
|
14
14
|
"author": "Romain Casati",
|
|
@@ -21,25 +21,23 @@
|
|
|
21
21
|
"lib"
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
|
-
"build": "
|
|
24
|
+
"build": "tsc",
|
|
25
25
|
"clean": "rm -rf lib/"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@basthon/checkpoints": "0.62.
|
|
29
|
-
"@basthon/kernel-base": "0.62.
|
|
30
|
-
"@basthon/kernel-loader": "0.62.
|
|
31
|
-
"js-base64": "^3.7.
|
|
32
|
-
"pako": "^2.0
|
|
28
|
+
"@basthon/checkpoints": "0.62.22",
|
|
29
|
+
"@basthon/kernel-base": "0.62.22",
|
|
30
|
+
"@basthon/kernel-loader": "0.62.22",
|
|
31
|
+
"js-base64": "^3.7.7",
|
|
32
|
+
"pako": "^2.1.0",
|
|
33
33
|
"promise-delegate": "^1.0.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@types/pako": "^
|
|
37
|
-
"
|
|
38
|
-
"gulp-typescript": "^6.0.0-alpha.1",
|
|
39
|
-
"typescript": "~4.4.4"
|
|
36
|
+
"@types/pako": "^2.0.3",
|
|
37
|
+
"typescript": "~5.4.5"
|
|
40
38
|
},
|
|
41
39
|
"publishConfig": {
|
|
42
40
|
"access": "public"
|
|
43
41
|
},
|
|
44
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "1dd6225a7caf14cbee203687cac611495f5b18d4"
|
|
45
43
|
}
|