@basthon/gui-base 0.62.20 → 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.
Files changed (2) hide show
  1. package/lib/main.js +29 -40
  2. 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 = (_a = options === null || options === void 0 ? void 0 : options.kernelOptions) === null || _a === void 0 ? void 0 : _a.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,19 @@ 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 = (_b = (_a = error) === null || _a === void 0 ? void 0 : _a.reason) === null || _b === void 0 ? void 0 : _b.message;
89
+ message = error?.reason?.message;
92
90
  if (message == null)
93
91
  message = error.toString();
94
- message = message.split("\n").join("<br>");
92
+ // avoid html/js injection on errors
93
+ const encodeHTMLEntities = (text) => {
94
+ var textArea = document.createElement("textarea");
95
+ textArea.innerText = text;
96
+ return textArea.innerHTML;
97
+ };
98
+ message = encodeHTMLEntities(message).split("\n").join("<br>");
95
99
  this.error("Erreur", `Erreur : ${message}`);
96
100
  // In case of error, force loader hiding.
97
101
  try {
@@ -125,7 +129,6 @@ export class GUIBase {
125
129
  * Loading the content from query string (ipynb=/script= or from=).
126
130
  */
127
131
  async loadFromQS(key) {
128
- var _a;
129
132
  const url = new URL(window.location.href);
130
133
  const from_key = "from";
131
134
  let content = null;
@@ -156,7 +159,7 @@ export class GUIBase {
156
159
  content = await response.text();
157
160
  }
158
161
  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()}`);
162
+ throw new Error(`Le chargement de ${fileURL} a échoué : ${error?.message ?? error.toString()}`);
160
163
  }
161
164
  }
162
165
  }
@@ -169,10 +172,9 @@ export class GUIBase {
169
172
  * (call submited callback).
170
173
  */
171
174
  async _loadExtensions() {
172
- var _a, _b;
173
175
  /* get requested extensions from URL */
174
176
  const url = new URL(window.location.href);
175
- const extensions = (_b = (_a = url.searchParams.get("extensions")) === null || _a === void 0 ? void 0 : _a.split(",")) !== null && _b !== void 0 ? _b : [];
177
+ const extensions = url.searchParams.get("extensions")?.split(",") ?? [];
176
178
  // call callbacks for requested extensions
177
179
  const promises = [];
178
180
  for (const ext of extensions) {
@@ -212,8 +214,7 @@ export class GUIBase {
212
214
  * Get state from strorage.
213
215
  */
214
216
  async getState(state, def) {
215
- var _a;
216
- return (_a = (await this._stateStorage.get(state))) !== null && _a !== void 0 ? _a : def;
217
+ return (await this._stateStorage.get(state)) ?? def;
217
218
  }
218
219
  /**
219
220
  * Set state in storage.
@@ -235,14 +236,13 @@ export class GUIBase {
235
236
  * Load content from local forage.
236
237
  */
237
238
  async loadFromStorage(setContent = true) {
238
- var _a;
239
239
  const approved = await this.lastBackupValid();
240
240
  let content = null;
241
241
  if (approved == null) {
242
242
  content = null;
243
243
  }
244
244
  else if (approved) {
245
- content = (await ((_a = this._checkpoints) === null || _a === void 0 ? void 0 : _a.getLast()));
245
+ content = (await this._checkpoints?.getLast());
246
246
  }
247
247
  else {
248
248
  const promise = new PromiseDelegate();
@@ -261,28 +261,24 @@ export class GUIBase {
261
261
  * Tag last backup as "approved".
262
262
  */
263
263
  async validateBackup() {
264
- var _a;
265
- await ((_a = this._checkpoints) === null || _a === void 0 ? void 0 : _a.tagLast("approved"));
264
+ await this._checkpoints?.tagLast("approved");
266
265
  }
267
266
  /**
268
267
  * Is last backup tagged as "approved"?
269
268
  */
270
269
  async lastBackupValid() {
271
- var _a;
272
- return await ((_a = this._checkpoints) === null || _a === void 0 ? void 0 : _a.lastHasTag("approved"));
270
+ return await this._checkpoints?.lastHasTag("approved");
273
271
  }
274
272
  /**
275
273
  * Select a checkpoint to load in the script.
276
274
  */
277
275
  async selectCheckpoint() {
278
- var _a;
279
- const times = await ((_a = this._checkpoints) === null || _a === void 0 ? void 0 : _a.times());
276
+ const times = await this._checkpoints?.times();
280
277
  const promise = new PromiseDelegate();
281
- const choices = times === null || times === void 0 ? void 0 : times.map((t, i) => ({
278
+ const choices = times?.map((t, i) => ({
282
279
  text: CheckpointsManager.toHumanDate(parseInt(t, 10)),
283
280
  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);
281
+ promise.resolve((await this._checkpoints?.getIndex(i)) ?? null);
286
282
  },
287
283
  }));
288
284
  if (choices == null)
@@ -302,25 +298,23 @@ export class GUIBase {
302
298
  * Backup to checkpoints.
303
299
  */
304
300
  async backup(approved = true) {
305
- var _a;
306
- 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"] : []);
307
302
  }
308
303
  /**
309
304
  * Internal GUI init.
310
305
  * It calls setupUI then loadInitialContent.
311
306
  */
312
307
  async _init(options = null) {
313
- var _a;
314
308
  /* all errors redirected to notification system */
315
309
  const onerror = this.notifyError.bind(this);
316
310
  window.addEventListener("error", onerror);
317
311
  window.addEventListener("unhandledrejection", onerror);
318
312
  console.error = (message) => onerror(new Error(message));
319
313
  await this._loadExtensions();
320
- await ((_a = this._checkpoints) === null || _a === void 0 ? void 0 : _a.ready());
314
+ await this._checkpoints?.ready();
321
315
  await this.setupUI(options);
322
316
  await this.loadInitialContent(options);
323
- await this.kernelLoader.kernelLoaded();
317
+ await this.kernelLoader.kernelStarted();
324
318
  const init = this.initCaller.bind(this);
325
319
  // loading aux files from URL
326
320
  await init(this.loadURLAux.bind(this), "Chargement des fichiers auxiliaires...", true);
@@ -355,10 +349,8 @@ export class GUIBase {
355
349
  * Restart the kernel.
356
350
  */
357
351
  kernelRestart() {
358
- var _a, _b;
359
- if ((_a = this.kernelSafe) === null || _a === void 0 ? void 0 : _a.pendingInput())
360
- throw new Error("pending input");
361
- (_b = this.kernelSafe) === null || _b === void 0 ? void 0 : _b.restart();
352
+ this.kernelSafe?.resolvePendingInput();
353
+ this.kernelSafe?.restart();
362
354
  }
363
355
  /**
364
356
  * Load ressources from URL (common part to files and modules).
@@ -370,7 +362,6 @@ export class GUIBase {
370
362
  fileURL = decodeURIComponent(fileURL);
371
363
  const filename = fileURL.split("/").pop() || "";
372
364
  promises.push((async () => {
373
- var _a;
374
365
  let data;
375
366
  try {
376
367
  const response = await fetch(fileURL);
@@ -380,7 +371,7 @@ export class GUIBase {
380
371
  await put(filename, data);
381
372
  }
382
373
  catch (error) {
383
- throw new Error(`Impossible de charger le fichier ${filename} : ${(_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error.toString()}`);
374
+ throw new Error(`Impossible de charger le fichier ${filename} : ${error?.message ?? error.toString()}`);
384
375
  }
385
376
  })());
386
377
  }
@@ -394,9 +385,8 @@ export class GUIBase {
394
385
  const reader = new FileReader();
395
386
  reader.readAsArrayBuffer(file);
396
387
  reader.onload = async (event) => {
397
- var _a, _b, _c;
398
- await ((_a = this.kernelSafe) === null || _a === void 0 ? void 0 : _a.putRessource(file.name, reader.result));
399
- 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()}`);
400
390
  resolve();
401
391
  };
402
392
  reader.onerror = reject;
@@ -440,7 +430,7 @@ export class GUIBase {
440
430
  return;
441
431
  for (let file of input.files) {
442
432
  const ext = file.name.split(".").pop();
443
- const callback = callbacks[ext !== null && ext !== void 0 ? ext : ""];
433
+ const callback = callbacks[ext ?? ""];
444
434
  if (callback != null) {
445
435
  await callback(file);
446
436
  }
@@ -510,8 +500,7 @@ Un lien permanant vers le contenu actuel a été créé.
510
500
  const reader = new FileReader();
511
501
  reader.readAsText(file);
512
502
  reader.onload = (event) => {
513
- var _a;
514
- 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);
515
504
  resolve();
516
505
  };
517
506
  reader.onerror = reject;
@@ -524,7 +513,7 @@ Un lien permanant vers le contenu actuel a été créé.
524
513
  this.backup();
525
514
  const content = this.content().replace(/\r\n|\r|\n/g, "\r\n"); // To retain the Line breaks.
526
515
  let blob = new Blob([content], { type: "text/plain" });
527
- GUIBase.openURL(window.URL.createObjectURL(blob), filename !== null && filename !== void 0 ? filename : this._contentFilename);
516
+ GUIBase.openURL(window.URL.createObjectURL(blob), filename ?? this._contentFilename);
528
517
  }
529
518
  /**
530
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.20",
3
+ "version": "0.62.22",
4
4
  "description": "Basthon - Base GUI",
5
5
  "homepage": "https://basthon.fr",
6
6
  "bugs": {
7
- "url": "https://framagit.org/basthon/basthon-kernel/issues"
7
+ "url": "https://forge.apps.education.fr/basthon/basthon-kernel/issues"
8
8
  },
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "https://framagit.org/basthon/basthon-kernel.git"
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": "gulp all",
24
+ "build": "tsc",
25
25
  "clean": "rm -rf lib/"
26
26
  },
27
27
  "dependencies": {
28
- "@basthon/checkpoints": "0.62.20",
29
- "@basthon/kernel-base": "0.62.20",
30
- "@basthon/kernel-loader": "0.62.20",
31
- "js-base64": "^3.7.2",
32
- "pako": "^2.0.4",
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": "^1.0.2",
37
- "gulp": "^4.0.2",
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": "fdaa2ed08c687a4b4e44f07ff28de1ad4cffeb38"
42
+ "gitHead": "1dd6225a7caf14cbee203687cac611495f5b18d4"
45
43
  }