@theia/core 1.61.0-next.8 → 1.61.1

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 (102) hide show
  1. package/README.md +7 -7
  2. package/i18n/nls.cs.json +34 -5
  3. package/i18n/nls.de.json +34 -5
  4. package/i18n/nls.es.json +34 -5
  5. package/i18n/nls.fr.json +34 -5
  6. package/i18n/nls.hu.json +34 -5
  7. package/i18n/nls.it.json +34 -5
  8. package/i18n/nls.ja.json +34 -5
  9. package/i18n/nls.json +35 -6
  10. package/i18n/nls.ko.json +34 -5
  11. package/i18n/nls.pl.json +34 -5
  12. package/i18n/nls.pt-br.json +34 -5
  13. package/i18n/nls.ru.json +34 -5
  14. package/i18n/nls.tr.json +34 -5
  15. package/i18n/nls.zh-cn.json +34 -5
  16. package/i18n/nls.zh-tw.json +34 -5
  17. package/lib/browser/catalog.json +322 -45
  18. package/lib/browser/dialogs.d.ts +8 -1
  19. package/lib/browser/dialogs.d.ts.map +1 -1
  20. package/lib/browser/dialogs.js +11 -4
  21. package/lib/browser/dialogs.js.map +1 -1
  22. package/lib/browser/frontend-application-module.js +1 -1
  23. package/lib/browser/frontend-application-module.js.map +1 -1
  24. package/lib/browser/preload/i18n-preload-contribution.js +1 -1
  25. package/lib/browser/preload/i18n-preload-contribution.js.map +1 -1
  26. package/lib/browser/shell/application-shell.d.ts +17 -5
  27. package/lib/browser/shell/application-shell.d.ts.map +1 -1
  28. package/lib/browser/shell/application-shell.js +94 -40
  29. package/lib/browser/shell/application-shell.js.map +1 -1
  30. package/lib/browser/shell/index.d.ts +1 -0
  31. package/lib/browser/shell/index.d.ts.map +1 -1
  32. package/lib/browser/shell/index.js +1 -0
  33. package/lib/browser/shell/index.js.map +1 -1
  34. package/lib/browser/shell/tab-bars.d.ts.map +1 -1
  35. package/lib/browser/shell/tab-bars.js +3 -2
  36. package/lib/browser/shell/tab-bars.js.map +1 -1
  37. package/lib/browser/shell/theia-dock-panel.d.ts +4 -10
  38. package/lib/browser/shell/theia-dock-panel.d.ts.map +1 -1
  39. package/lib/browser/shell/theia-dock-panel.js +7 -84
  40. package/lib/browser/shell/theia-dock-panel.js.map +1 -1
  41. package/lib/browser/shell/theia-split-panel.d.ts +6 -0
  42. package/lib/browser/shell/theia-split-panel.d.ts.map +1 -0
  43. package/lib/browser/shell/theia-split-panel.js +56 -0
  44. package/lib/browser/shell/theia-split-panel.js.map +1 -0
  45. package/lib/browser/tree/tree-widget.d.ts +1 -0
  46. package/lib/browser/tree/tree-widget.d.ts.map +1 -1
  47. package/lib/browser/tree/tree-widget.js +6 -0
  48. package/lib/browser/tree/tree-widget.js.map +1 -1
  49. package/lib/browser/view-container.d.ts.map +1 -1
  50. package/lib/browser/view-container.js +2 -1
  51. package/lib/browser/view-container.js.map +1 -1
  52. package/lib/browser/widgets/widget.d.ts.map +1 -1
  53. package/lib/browser/widgets/widget.js.map +1 -1
  54. package/lib/common/content-replacer.d.ts.map +1 -1
  55. package/lib/common/content-replacer.js +2 -1
  56. package/lib/common/content-replacer.js.map +1 -1
  57. package/lib/common/content-replacer.spec.js +2 -2
  58. package/lib/common/content-replacer.spec.js.map +1 -1
  59. package/lib/electron-browser/menu/electron-main-menu-factory.d.ts +1 -1
  60. package/lib/electron-browser/menu/electron-main-menu-factory.d.ts.map +1 -1
  61. package/lib/electron-browser/menu/electron-main-menu-factory.js +15 -13
  62. package/lib/electron-browser/menu/electron-main-menu-factory.js.map +1 -1
  63. package/lib/electron-browser/menu/electron-menu-contribution.d.ts.map +1 -1
  64. package/lib/electron-browser/menu/electron-menu-contribution.js +1 -4
  65. package/lib/electron-browser/menu/electron-menu-contribution.js.map +1 -1
  66. package/lib/electron-main/electron-main-application.d.ts +1 -1
  67. package/lib/electron-main/electron-main-application.d.ts.map +1 -1
  68. package/lib/electron-main/electron-main-application.js +7 -5
  69. package/lib/electron-main/electron-main-application.js.map +1 -1
  70. package/lib/node/backend-application-module.d.ts.map +1 -1
  71. package/lib/node/backend-application-module.js +3 -0
  72. package/lib/node/backend-application-module.js.map +1 -1
  73. package/lib/node/index.d.ts +1 -0
  74. package/lib/node/index.d.ts.map +1 -1
  75. package/lib/node/index.js +1 -0
  76. package/lib/node/index.js.map +1 -1
  77. package/lib/node/setting-service.d.ts +20 -0
  78. package/lib/node/setting-service.d.ts.map +1 -0
  79. package/lib/node/setting-service.js +80 -0
  80. package/lib/node/setting-service.js.map +1 -0
  81. package/package.json +7 -9
  82. package/src/browser/dialogs.ts +11 -4
  83. package/src/browser/frontend-application-module.ts +1 -1
  84. package/src/browser/preload/i18n-preload-contribution.ts +1 -1
  85. package/src/browser/shell/application-shell.ts +96 -34
  86. package/src/browser/shell/index.ts +1 -0
  87. package/src/browser/shell/tab-bars.ts +3 -2
  88. package/src/browser/shell/theia-dock-panel.ts +10 -91
  89. package/src/browser/shell/theia-split-panel.ts +56 -0
  90. package/src/browser/style/index.css +3 -11
  91. package/src/browser/style/sidepanel.css +2 -4
  92. package/src/browser/tree/tree-widget.tsx +7 -0
  93. package/src/browser/view-container.ts +2 -1
  94. package/src/browser/widgets/widget.ts +1 -0
  95. package/src/common/content-replacer.spec.ts +2 -2
  96. package/src/common/content-replacer.ts +2 -1
  97. package/src/electron-browser/menu/electron-main-menu-factory.ts +15 -14
  98. package/src/electron-browser/menu/electron-menu-contribution.ts +1 -4
  99. package/src/electron-main/electron-main-application.ts +8 -5
  100. package/src/node/backend-application-module.ts +4 -0
  101. package/src/node/index.ts +1 -0
  102. package/src/node/setting-service.ts +78 -0
@@ -3,5 +3,6 @@ export * from './debug';
3
3
  export * from '../common/file-uri';
4
4
  export * from './messaging';
5
5
  export * from './cli';
6
+ export * from './setting-service';
6
7
  export { FileSystemLocking } from './filesystem-locking';
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAgBA,cAAc,uBAAuB,CAAC;AACtC,cAAc,SAAS,CAAC;AACxB,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,OAAO,CAAC;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAgBA,cAAc,uBAAuB,CAAC;AACtC,cAAc,SAAS,CAAC;AACxB,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,OAAO,CAAC;AACtB,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC"}
package/lib/node/index.js CHANGED
@@ -22,6 +22,7 @@ tslib_1.__exportStar(require("./debug"), exports);
22
22
  tslib_1.__exportStar(require("../common/file-uri"), exports);
23
23
  tslib_1.__exportStar(require("./messaging"), exports);
24
24
  tslib_1.__exportStar(require("./cli"), exports);
25
+ tslib_1.__exportStar(require("./setting-service"), exports);
25
26
  var filesystem_locking_1 = require("./filesystem-locking");
26
27
  Object.defineProperty(exports, "FileSystemLocking", { enumerable: true, get: function () { return filesystem_locking_1.FileSystemLocking; } });
27
28
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;;AAEhF,gEAAsC;AACtC,kDAAwB;AACxB,6DAAmC;AACnC,sDAA4B;AAC5B,gDAAsB;AACtB,2DAAyD;AAAhD,uHAAA,iBAAiB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,yCAAyC;AACzC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;;AAEhF,gEAAsC;AACtC,kDAAwB;AACxB,6DAAmC;AACnC,sDAA4B;AAC5B,gDAAsB;AACtB,4DAAkC;AAClC,2DAAyD;AAAhD,uHAAA,iBAAiB,OAAA"}
@@ -0,0 +1,20 @@
1
+ import { EnvVariablesServer } from '../common/env-variables';
2
+ import { Deferred } from '../common/promise-util';
3
+ export declare const SettingService: unique symbol;
4
+ /**
5
+ * A service providing a simple user-level, persistent key-value store on the back end
6
+ */
7
+ export interface SettingService {
8
+ set(key: string, value: string): Promise<void>;
9
+ get(key: string): Promise<string | undefined>;
10
+ }
11
+ export declare class SettingServiceImpl implements SettingService {
12
+ protected readonly envVarServer: EnvVariablesServer;
13
+ protected readonly ready: Deferred<void>;
14
+ protected values: Record<string, string>;
15
+ protected init(): void;
16
+ set(key: string, value: string): Promise<void>;
17
+ writeFile(): Promise<void>;
18
+ get(key: string): Promise<string | undefined>;
19
+ }
20
+ //# sourceMappingURL=setting-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setting-service.d.ts","sourceRoot":"","sources":["../../src/node/setting-service.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAIlD,eAAO,MAAM,cAAc,eAA2B,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACjD;AAED,qBACa,kBAAmB,YAAW,cAAc;IAGrD,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAC;IAEpD,SAAS,CAAC,QAAQ,CAAC,KAAK,iBAAwB;IAChD,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;IAG9C,SAAS,CAAC,IAAI,IAAI,IAAI;IAkBhB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM9C,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAO1B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;CAItD"}
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2025 STMicroelectronics and others.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.SettingServiceImpl = exports.SettingService = void 0;
19
+ const tslib_1 = require("tslib");
20
+ const inversify_1 = require("inversify");
21
+ const env_variables_1 = require("../common/env-variables");
22
+ const promise_util_1 = require("../common/promise-util");
23
+ const fs_1 = require("fs");
24
+ const common_1 = require("../common");
25
+ exports.SettingService = Symbol('SettingService');
26
+ let SettingServiceImpl = class SettingServiceImpl {
27
+ constructor() {
28
+ this.ready = new promise_util_1.Deferred();
29
+ this.values = {};
30
+ }
31
+ init() {
32
+ const asyncInit = async () => {
33
+ const configDir = new common_1.URI(await this.envVarServer.getConfigDirUri());
34
+ const path = configDir.resolve('backend-settings.json').path.fsPath();
35
+ try {
36
+ const contents = await fs_1.promises.readFile(path, {
37
+ encoding: 'utf-8'
38
+ });
39
+ this.values = JSON.parse(contents);
40
+ }
41
+ catch (e) {
42
+ console.log(e);
43
+ }
44
+ finally {
45
+ this.ready.resolve();
46
+ }
47
+ };
48
+ asyncInit();
49
+ }
50
+ async set(key, value) {
51
+ await this.ready.promise;
52
+ this.values[key] = value;
53
+ await this.writeFile();
54
+ }
55
+ async writeFile() {
56
+ const configDir = new common_1.URI(await this.envVarServer.getConfigDirUri());
57
+ const path = configDir.resolve('backend-settings.json').path.fsPath();
58
+ const values = JSON.stringify(this.values);
59
+ await fs_1.promises.writeFile(path, values);
60
+ }
61
+ async get(key) {
62
+ await this.ready.promise;
63
+ return this.values[key];
64
+ }
65
+ };
66
+ exports.SettingServiceImpl = SettingServiceImpl;
67
+ tslib_1.__decorate([
68
+ (0, inversify_1.inject)(env_variables_1.EnvVariablesServer),
69
+ tslib_1.__metadata("design:type", Object)
70
+ ], SettingServiceImpl.prototype, "envVarServer", void 0);
71
+ tslib_1.__decorate([
72
+ (0, inversify_1.postConstruct)(),
73
+ tslib_1.__metadata("design:type", Function),
74
+ tslib_1.__metadata("design:paramtypes", []),
75
+ tslib_1.__metadata("design:returntype", void 0)
76
+ ], SettingServiceImpl.prototype, "init", null);
77
+ exports.SettingServiceImpl = SettingServiceImpl = tslib_1.__decorate([
78
+ (0, inversify_1.injectable)()
79
+ ], SettingServiceImpl);
80
+ //# sourceMappingURL=setting-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setting-service.js","sourceRoot":"","sources":["../../src/node/setting-service.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,oDAAoD;AACpD,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;;AAEhF,yCAA8D;AAC9D,2DAA6D;AAC7D,yDAAkD;AAClD,2BAAoC;AACpC,sCAAgC;AAEnB,QAAA,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAWhD,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;IAAxB;QAKgB,UAAK,GAAG,IAAI,uBAAQ,EAAQ,CAAC;QACtC,WAAM,GAA2B,EAAE,CAAC;IAsClD,CAAC;IAnCa,IAAI;QACV,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;YACzB,MAAM,SAAS,GAAG,IAAI,YAAG,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,CAAC,CAAC;YACrE,MAAM,IAAI,GAAW,SAAS,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAC9E,IAAI,CAAC;gBACD,MAAM,QAAQ,GAAG,MAAM,aAAE,CAAC,QAAQ,CAAC,IAAI,EAAE;oBACrC,QAAQ,EAAE,OAAO;iBACpB,CAAC,CAAC;gBACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACvC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACT,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACnB,CAAC;oBAAS,CAAC;gBACP,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACzB,CAAC;QACL,CAAC,CAAC;QACF,SAAS,EAAE,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAa;QAChC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACzB,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,SAAS;QACX,MAAM,SAAS,GAAG,IAAI,YAAG,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,CAAC,CAAC;QACrE,MAAM,IAAI,GAAW,SAAS,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAC9E,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,aAAE,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACjB,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;QACzB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;CACJ,CAAA;AA5CY,gDAAkB;AAGR;IADlB,IAAA,kBAAM,EAAC,kCAAkB,CAAC;;wDACyB;AAM1C;IADT,IAAA,yBAAa,GAAE;;;;8CAiBf;6BAzBQ,kBAAkB;IAD9B,IAAA,sBAAU,GAAE;GACA,kBAAkB,CA4C9B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theia/core",
3
- "version": "1.61.0-next.8+436de3c45",
3
+ "version": "1.61.1",
4
4
  "description": "Theia is a cloud & desktop IDE framework implemented in TypeScript.",
5
5
  "main": "lib/common/index.js",
6
6
  "typings": "lib/common/index.d.ts",
@@ -17,11 +17,10 @@
17
17
  "@lumino/virtualdom": "^2.0.2",
18
18
  "@lumino/widgets": "2.5.0",
19
19
  "@parcel/watcher": "^2.5.0",
20
- "@theia/application-package": "1.61.0-next.8+436de3c45",
21
- "@theia/request": "1.61.0-next.8+436de3c45",
20
+ "@theia/application-package": "1.61.1",
21
+ "@theia/request": "1.61.1",
22
22
  "@types/body-parser": "^1.16.4",
23
23
  "@types/cookie": "^0.3.3",
24
- "@types/dompurify": "^2.2.2",
25
24
  "@types/express": "^4.17.21",
26
25
  "@types/fs-extra": "^4.0.2",
27
26
  "@types/lodash.debounce": "4.0.3",
@@ -39,9 +38,8 @@
39
38
  "async-mutex": "^0.4.0",
40
39
  "body-parser": "^1.17.2",
41
40
  "cookie": "^0.4.0",
42
- "dompurify": "^2.2.9",
41
+ "dompurify": "^3.2.4",
43
42
  "drivelist": "^12.0.2",
44
- "es6-promise": "^4.2.4",
45
43
  "express": "^4.21.0",
46
44
  "fast-json-stable-stringify": "^2.1.0",
47
45
  "file-icons-js": "~1.0.3",
@@ -210,13 +208,13 @@
210
208
  "watch": "theiaext watch"
211
209
  },
212
210
  "devDependencies": {
213
- "@theia/ext-scripts": "1.60.0",
214
- "@theia/re-exports": "1.60.0",
211
+ "@theia/ext-scripts": "1.61.1",
212
+ "@theia/re-exports": "1.61.1",
215
213
  "minimist": "^1.2.0",
216
214
  "nodejs-file-downloader": "4.13.0"
217
215
  },
218
216
  "nyc": {
219
217
  "extends": "../../configs/nyc.json"
220
218
  },
221
- "gitHead": "436de3c4571e0000fdcbbf2e94ddfc992f38ccb2"
219
+ "gitHead": "5ea3cf6111aded4ccf1d5ccaf67b04e6588a6dea"
222
220
  }
@@ -241,10 +241,17 @@ export abstract class AbstractDialog<T> extends BaseWidget {
241
241
  this.toDisposeOnDetach.push(DialogOverlayService.get().push(this));
242
242
  }
243
243
 
244
- protected preventTabbingOutsideDialog(): Disposable {
245
- const nonInertSiblings = Array.from(this.node.ownerDocument.body.children).filter(child => child !== this.node && !(child.hasAttribute('inert')));
246
- nonInertSiblings.forEach(child => child.setAttribute('inert', ''));
247
- return Disposable.create(() => nonInertSiblings.forEach(child => child.removeAttribute('inert')));
244
+ /**
245
+ * This prevents tabbing outside the dialog by marking elements as inert, i.e., non-clickable and non-focussable.
246
+ *
247
+ * @param elements the elements for which we disable tabbing. By default all elements within the body element are considered.
248
+ * Please note that this may also include other popups such as the suggestion overlay, the notification center or quick picks.
249
+ * @returns a disposable that will restore the previous tabbing behavior
250
+ */
251
+ protected preventTabbingOutsideDialog(elements = Array.from(this.node.ownerDocument.body.children)): Disposable {
252
+ const nonInertElements = elements.filter(child => child !== this.node && !(child.hasAttribute('inert')));
253
+ nonInertElements.forEach(child => child.setAttribute('inert', ''));
254
+ return Disposable.create(() => nonInertElements.forEach(child => child.removeAttribute('inert')));
248
255
  }
249
256
 
250
257
  protected handleEscape(event: KeyboardEvent): boolean | void {
@@ -209,7 +209,7 @@ export const frontendApplicationModule = new ContainerModule((bind, _unbind, _is
209
209
  return new TabBarRenderer(contextMenuRenderer, tabBarDecoratorService, iconThemeService,
210
210
  selectionService, commandService, corePreferences, hoverService, contextKeyService);
211
211
  });
212
- bind(TheiaDockPanel.Factory).toFactory(({ container }) => (options?: DockPanel.IOptions) => {
212
+ bind(TheiaDockPanel.Factory).toFactory(({ container }) => (options?: DockPanel.IOptions, maximizeCallback?: (area: TheiaDockPanel) => void) => {
213
213
  const corePreferences = container.get<CorePreferences>(CorePreferences);
214
214
  return new TheiaDockPanel(options, corePreferences);
215
215
  });
@@ -39,7 +39,7 @@ export class I18nPreloadContribution implements PreloadContribution {
39
39
  });
40
40
  }
41
41
  let locale = nls.locale ?? nls.defaultLocale;
42
- if (nls.locale && nls.locale !== nls.defaultLocale) {
42
+ if (nls.locale) {
43
43
  const localization = await this.localizationServer.loadLocalization(locale);
44
44
  if (localization.languagePack) {
45
45
  nls.localization = localization;
@@ -34,7 +34,7 @@ import { FrontendApplicationStateService } from '../frontend-application-state';
34
34
  import { TabBarToolbarRegistry, TabBarToolbarFactory } from './tab-bar-toolbar';
35
35
  import { ContextKeyService } from '../context-key-service';
36
36
  import { Emitter } from '../../common/event';
37
- import { waitForRevealed, waitForClosed, PINNED_CLASS } from '../widgets';
37
+ import { waitForRevealed, waitForClosed, PINNED_CLASS, UnsafeWidgetUtilities } from '../widgets';
38
38
  import { CorePreferences } from '../core-preferences';
39
39
  import { BreadcrumbsRendererFactory } from '../breadcrumbs/breadcrumbs-renderer';
40
40
  import { Deferred } from '../../common/promise-util';
@@ -45,17 +45,18 @@ import URI from '../../common/uri';
45
45
  import { OpenerService } from '../opener-service';
46
46
  import { PreviewableWidget } from '../widgets/previewable-widget';
47
47
  import { WindowService } from '../window/window-service';
48
+ import { TheiaSplitPanel } from './theia-split-panel';
48
49
 
49
50
  /** The class name added to ApplicationShell instances. */
50
- const APPLICATION_SHELL_CLASS = 'theia-ApplicationShell';
51
+ export const APPLICATION_SHELL_CLASS = 'theia-ApplicationShell';
51
52
  /** The class name added to the main and bottom area panels. */
52
- const MAIN_BOTTOM_AREA_CLASS = 'theia-app-centers';
53
+ export const MAIN_BOTTOM_AREA_CLASS = 'theia-app-centers';
53
54
  /** Status bar entry identifier for the bottom panel toggle button. */
54
- const BOTTOM_PANEL_TOGGLE_ID = 'bottom-panel-toggle';
55
+ export const BOTTOM_PANEL_TOGGLE_ID = 'bottom-panel-toggle';
55
56
  /** The class name added to the main area panel. */
56
- const MAIN_AREA_CLASS = 'theia-app-main';
57
+ export const MAIN_AREA_CLASS = 'theia-app-main';
57
58
  /** The class name added to the bottom area panel. */
58
- const BOTTOM_AREA_CLASS = 'theia-app-bottom';
59
+ export const BOTTOM_AREA_CLASS = 'theia-app-bottom';
59
60
 
60
61
  export type ApplicationShellLayoutVersion =
61
62
  /** layout versioning is introduced, unversioned layout are not compatible */
@@ -85,10 +86,6 @@ export interface DockPanelRendererFactory {
85
86
  */
86
87
  @injectable()
87
88
  export class DockPanelRenderer implements DockLayout.IRenderer {
88
-
89
- @inject(TheiaDockPanel.Factory)
90
- protected readonly dockPanelFactory: TheiaDockPanel.Factory;
91
-
92
89
  readonly tabBarClasses: string[] = [];
93
90
 
94
91
  private readonly onDidCreateTabBarEmitter = new Emitter<TabBar<Widget>>();
@@ -175,6 +172,7 @@ interface WidgetDragState {
175
172
  leaveTimeout?: number;
176
173
  }
177
174
 
175
+ export const MAXIMIZED_CLASS = 'theia-maximized';
178
176
  /**
179
177
  * The application shell manages the top-level widgets of the application. Use this class to
180
178
  * add, remove, or activate a widget.
@@ -269,6 +267,8 @@ export class ApplicationShell extends Widget {
269
267
  protected initializedDeferred = new Deferred<void>();
270
268
  initialized = this.initializedDeferred.promise;
271
269
 
270
+ protected readonly maximizedElement: HTMLElement;
271
+
272
272
  /**
273
273
  * Construct a new application shell.
274
274
  */
@@ -286,6 +286,16 @@ export class ApplicationShell extends Widget {
286
286
  ) {
287
287
  super(options as Widget.IOptions);
288
288
 
289
+ this.maximizedElement = this.node.ownerDocument.createElement('div');
290
+ this.maximizedElement.style.position = 'fixed';
291
+ this.maximizedElement.style.display = 'none';
292
+ this.maximizedElement.style.left = '0px';
293
+ this.maximizedElement.style.bottom = '0px';
294
+ this.maximizedElement.style.right = '0px';
295
+ this.maximizedElement.style.background = 'var(--theia-editor-background)';
296
+ this.maximizedElement.style.zIndex = '2000';
297
+ this.node.ownerDocument.body.appendChild(this.maximizedElement);
298
+
289
299
  // Merge the user-defined application options with the default options
290
300
  this.options = {
291
301
  bottomPanel: {
@@ -301,6 +311,13 @@ export class ApplicationShell extends Widget {
301
311
  ...options?.rightPanel || {}
302
312
  }
303
313
  };
314
+ if (corePreferences) {
315
+ corePreferences.onPreferenceChanged(preference => {
316
+ if (preference.preferenceName === 'window.menuBarVisibility' && (preference.newValue === 'visible' || preference.oldValue === 'visible')) {
317
+ this.handleMenuBarVisibility(preference.newValue);
318
+ }
319
+ });
320
+ }
304
321
  }
305
322
 
306
323
  @postConstruct()
@@ -561,7 +578,7 @@ export class ApplicationShell extends Widget {
561
578
  mode: 'multiple-document',
562
579
  renderer,
563
580
  spacing: 0
564
- });
581
+ }, area => this.doToggleMaximized(area));
565
582
  dockPanel.id = MAIN_AREA_ID;
566
583
  dockPanel.widgetAdded.connect((_, widget) => this.fireDidAddWidget(widget));
567
584
  dockPanel.widgetRemoved.connect((_, widget) => this.fireDidRemoveWidget(widget));
@@ -658,7 +675,7 @@ export class ApplicationShell extends Widget {
658
675
  mode: 'multiple-document',
659
676
  renderer,
660
677
  spacing: 0
661
- });
678
+ }, area => this.doToggleMaximized(area));
662
679
  dockPanel.id = BOTTOM_AREA_ID;
663
680
  dockPanel.widgetAdded.connect((sender, widget) => {
664
681
  this.refreshBottomPanelToggleButton();
@@ -731,7 +748,7 @@ export class ApplicationShell extends Widget {
731
748
  [1, 0],
732
749
  { orientation: 'vertical', spacing: 0 }
733
750
  );
734
- const panelForBottomArea = new SplitPanel({ layout: bottomSplitLayout });
751
+ const panelForBottomArea = new TheiaSplitPanel({ layout: bottomSplitLayout });
735
752
  panelForBottomArea.id = 'theia-bottom-split-panel';
736
753
 
737
754
  const leftRightSplitLayout = this.createSplitLayout(
@@ -739,7 +756,7 @@ export class ApplicationShell extends Widget {
739
756
  [0, 1, 0],
740
757
  { orientation: 'horizontal', spacing: 0 }
741
758
  );
742
- const panelForSideAreas = new SplitPanel({ layout: leftRightSplitLayout });
759
+ const panelForSideAreas = new TheiaSplitPanel({ layout: leftRightSplitLayout });
743
760
  panelForSideAreas.id = 'theia-left-right-split-panel';
744
761
 
745
762
  return this.createBoxLayout(
@@ -1178,9 +1195,6 @@ export class ApplicationShell extends Widget {
1178
1195
  w.title.className = w.title.className.replace(' theia-mod-active', '');
1179
1196
  w = w.parent;
1180
1197
  }
1181
- // Reset the z-index to the default
1182
- // eslint-disable-next-line no-null/no-null
1183
- this.setZIndex(oldValue.node, null);
1184
1198
  }
1185
1199
  if (newValue) {
1186
1200
  let w: Widget | null = newValue;
@@ -1203,11 +1217,6 @@ export class ApplicationShell extends Widget {
1203
1217
  // if widget was undefined, we wouldn't have gotten a panel back before
1204
1218
  panel.markAsCurrent(widget!.title);
1205
1219
  }
1206
- // Add checks to ensure that the 'sash' for left panel is displayed correctly
1207
- if (newValue.node.className === 'lm-Widget theia-view-container lm-DockPanel-widget') {
1208
- // Set the z-index so elements with `position: fixed` contained in the active widget are displayed correctly
1209
- this.setZIndex(newValue.node, '1');
1210
- }
1211
1220
 
1212
1221
  // activate another widget if an active widget will be closed
1213
1222
  const onCloseRequest = newValue['onCloseRequest'];
@@ -1237,17 +1246,6 @@ export class ApplicationShell extends Widget {
1237
1246
  this.onDidChangeActiveWidgetEmitter.fire(args);
1238
1247
  }
1239
1248
 
1240
- /**
1241
- * Set the z-index of the given element and its ancestors to the value `z`.
1242
- */
1243
- private setZIndex(element: HTMLElement, z: string | null): void {
1244
- element.style.zIndex = z || '';
1245
- const parent = element.parentElement;
1246
- if (parent && parent !== this.node) {
1247
- this.setZIndex(parent, z);
1248
- }
1249
- }
1250
-
1251
1249
  /**
1252
1250
  * Track the given widget so it is considered in the `current` and `active` state of the shell.
1253
1251
  */
@@ -2118,11 +2116,75 @@ export class ApplicationShell extends Widget {
2118
2116
  toggleMaximized(widget: Widget | undefined = this.currentWidget): void {
2119
2117
  const area = widget && this.getAreaPanelFor(widget);
2120
2118
  if (area instanceof TheiaDockPanel && (area === this.mainPanel || area === this.bottomPanel)) {
2121
- area.toggleMaximized();
2119
+ this.doToggleMaximized(area);
2122
2120
  this.revealWidget(widget!.id);
2123
2121
  }
2124
2122
  }
2125
2123
 
2124
+ protected handleMenuBarVisibility(newValue: string): void {
2125
+ if (newValue === 'visible') {
2126
+ const topRect = this.topPanel.node.getBoundingClientRect();
2127
+ this.maximizedElement.style.top = `${topRect.bottom}px`;
2128
+ } else {
2129
+ this.maximizedElement.style.removeProperty('top');
2130
+ }
2131
+ }
2132
+
2133
+ protected readonly onDidToggleMaximizedEmitter = new Emitter<Widget>();
2134
+ readonly onDidToggleMaximized = this.onDidToggleMaximizedEmitter.event;
2135
+
2136
+ protected unmaximize: (() => void) | undefined;
2137
+ doToggleMaximized(area: TheiaDockPanel): void {
2138
+ if (this.unmaximize) {
2139
+ this.unmaximize();
2140
+ this.unmaximize = undefined;
2141
+ return;
2142
+ }
2143
+
2144
+ const removedListener = () => {
2145
+ if (!area.widgets().next().value) {
2146
+ this.doToggleMaximized(area);
2147
+ }
2148
+ };
2149
+
2150
+ const parent = area.parent as SplitPanel;
2151
+ const layout = area.parent?.layout as SplitLayout;
2152
+ const sizes = layout.relativeSizes().slice();
2153
+ const stretch = SplitPanel.getStretch(area);
2154
+ const index = parent.widgets.indexOf(area);
2155
+ parent.layout?.removeWidget(area);
2156
+
2157
+ // eslint-disable-next-line no-null/no-null
2158
+ this.maximizedElement.style.display = 'block';
2159
+ area.addClass(MAXIMIZED_CLASS);
2160
+ const topRect = this.topPanel.node.getBoundingClientRect();
2161
+ UnsafeWidgetUtilities.attach(area, this.maximizedElement);
2162
+ this.maximizedElement.style.top = `${topRect.bottom}px`;
2163
+ area.fit();
2164
+ const observer = new ResizeObserver(entries => {
2165
+ area.fit();
2166
+ });
2167
+ observer.observe(this.maximizedElement);
2168
+
2169
+ this.unmaximize = () => {
2170
+ observer.unobserve(this.maximizedElement);
2171
+ observer.disconnect();
2172
+ this.maximizedElement.style.display = 'none';
2173
+ area.removeClass(MAXIMIZED_CLASS);
2174
+ if (area.isAttached) {
2175
+ UnsafeWidgetUtilities.detach(area);
2176
+ }
2177
+ parent?.insertWidget(index, area);
2178
+ SplitPanel.setStretch(area, stretch);
2179
+ layout.setRelativeSizes(sizes);
2180
+ parent.fit();
2181
+ this.onDidToggleMaximizedEmitter.fire(area);
2182
+ area.widgetRemoved.disconnect(removedListener);
2183
+ };
2184
+
2185
+ area.widgetRemoved.connect(removedListener);
2186
+ this.onDidToggleMaximizedEmitter.fire(area);
2187
+ }
2126
2188
  }
2127
2189
 
2128
2190
  /**
@@ -21,3 +21,4 @@ export * from './sidebar-menu-widget';
21
21
  export * from './split-panels';
22
22
  export * from './tab-bars';
23
23
  export * from './view-contribution';
24
+ export * from './theia-split-panel';
@@ -871,7 +871,7 @@ export class ScrollableTabBar extends TabBar<Widget> {
871
871
  window.requestAnimationFrame(() => {
872
872
  const tab = this.contentNode.children[index] as HTMLElement;
873
873
  if (tab && this.isVisible) {
874
- const parent = this.contentNode;
874
+ const parent = this.contentContainer;
875
875
  if (this.orientation === 'horizontal') {
876
876
  const scroll = parent.scrollLeft;
877
877
  const left = tab.offsetLeft;
@@ -958,6 +958,7 @@ export class ToolbarAwareTabBar extends ScrollableTabBar {
958
958
  this.node.appendChild(this.breadcrumbsContainer);
959
959
 
960
960
  this.toolbar = this.tabBarToolbarFactory();
961
+ this.toDispose.push(this.toolbar);
961
962
  this.toDispose.push(this.tabBarToolbarRegistry.onDidChange(() => this.update()));
962
963
  this.toDispose.push(this.breadcrumbsRenderer);
963
964
 
@@ -1009,7 +1010,7 @@ export class ToolbarAwareTabBar extends ScrollableTabBar {
1009
1010
 
1010
1011
  protected override onBeforeDetach(msg: Message): void {
1011
1012
  if (this.toolbar && this.toolbar.isAttached) {
1012
- this.toolbar.dispose();
1013
+ Widget.detach(this.toolbar);
1013
1014
  }
1014
1015
  super.onBeforeDetach(msg);
1015
1016
  }
@@ -15,17 +15,14 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import { find, toArray } from '@lumino/algorithm';
18
- import { TabBar, Widget, DockPanel, Title, DockLayout } from '@lumino/widgets';
18
+ import { TabBar, Widget, DockPanel, Title } from '@lumino/widgets';
19
19
  import { Signal } from '@lumino/signaling';
20
20
  import { Disposable, DisposableCollection } from '../../common/disposable';
21
- import { UnsafeWidgetUtilities } from '../widgets';
22
21
  import { CorePreferences } from '../core-preferences';
23
22
  import { Emitter, Event, environment } from '../../common';
24
23
  import { ToolbarAwareTabBar } from './tab-bars';
25
24
 
26
- export const MAXIMIZED_CLASS = 'theia-maximized';
27
25
  export const ACTIVE_TABBAR_CLASS = 'theia-tabBar-active';
28
- const VISIBLE_MENU_MAXIMIZED_CLASS = 'theia-visible-menu-maximized';
29
26
 
30
27
  export const MAIN_AREA_ID = 'theia-main-content-panel';
31
28
  export const BOTTOM_AREA_ID = 'theia-bottom-content-panel';
@@ -49,15 +46,15 @@ export class TheiaDockPanel extends DockPanel {
49
46
  */
50
47
  readonly widgetRemoved = new Signal<this, Widget>(this);
51
48
 
52
- protected readonly onDidToggleMaximizedEmitter = new Emitter<Widget>();
53
- readonly onDidToggleMaximized = this.onDidToggleMaximizedEmitter.event;
54
49
  protected readonly onDidChangeCurrentEmitter = new Emitter<Title<Widget> | undefined>();
50
+
55
51
  get onDidChangeCurrent(): Event<Title<Widget> | undefined> {
56
52
  return this.onDidChangeCurrentEmitter.event;
57
53
  }
58
54
 
59
55
  constructor(options?: DockPanel.IOptions,
60
- protected readonly preferences?: CorePreferences
56
+ protected readonly preferences?: CorePreferences,
57
+ protected readonly maximizeCallback?: (area: TheiaDockPanel) => void
61
58
  ) {
62
59
  super(options);
63
60
  this['_onCurrentChanged'] = (sender: TabBar<Widget>, args: TabBar.ICurrentChangedArgs<Widget>) => {
@@ -77,12 +74,11 @@ export class TheiaDockPanel extends DockPanel {
77
74
  this.markAsCurrent(args.title);
78
75
  super['_onTabActivateRequested'](sender, args);
79
76
  };
80
- if (preferences) {
81
- preferences.onPreferenceChanged(preference => {
82
- if (!this.isElectron() && preference.preferenceName === 'window.menuBarVisibility' && (preference.newValue === 'visible' || preference.oldValue === 'visible')) {
83
- this.handleMenuBarVisibility(preference.newValue);
84
- }
85
- });
77
+ }
78
+
79
+ toggleMaximized(): void {
80
+ if (this.maximizeCallback) {
81
+ this.maximizeCallback(this);
86
82
  }
87
83
  }
88
84
 
@@ -90,19 +86,6 @@ export class TheiaDockPanel extends DockPanel {
90
86
  return environment.electron.is();
91
87
  }
92
88
 
93
- protected handleMenuBarVisibility(newValue: string): void {
94
- const areaContainer = this.node.parentElement;
95
- const maximizedElement = this.getMaximizedElement();
96
-
97
- if (areaContainer === maximizedElement) {
98
- if (newValue === 'visible') {
99
- this.addClass(VISIBLE_MENU_MAXIMIZED_CLASS);
100
- } else {
101
- this.removeClass(VISIBLE_MENU_MAXIMIZED_CLASS);
102
- }
103
- }
104
- }
105
-
106
89
  protected _currentTitle: Title<Widget> | undefined;
107
90
  get currentTitle(): Title<Widget> | undefined {
108
91
  return this._currentTitle;
@@ -195,75 +178,11 @@ export class TheiaDockPanel extends DockPanel {
195
178
  }
196
179
  return undefined;
197
180
  }
198
-
199
- protected readonly toDisposeOnToggleMaximized = new DisposableCollection();
200
- toggleMaximized(): void {
201
- const areaContainer = this.node.parentElement;
202
- if (!areaContainer) {
203
- return;
204
- }
205
- const maximizedElement = this.getMaximizedElement();
206
- if (areaContainer === maximizedElement) {
207
- this.toDisposeOnToggleMaximized.dispose();
208
- return;
209
- }
210
- if (this.isAttached) {
211
- UnsafeWidgetUtilities.detach(this);
212
- }
213
- maximizedElement.style.display = 'block';
214
- this.addClass(MAXIMIZED_CLASS);
215
- const preference = this.preferences?.get('window.menuBarVisibility');
216
- if (!this.isElectron() && preference === 'visible') {
217
- this.addClass(VISIBLE_MENU_MAXIMIZED_CLASS);
218
- }
219
- UnsafeWidgetUtilities.attach(this, maximizedElement);
220
- this.fit();
221
- this.onDidToggleMaximizedEmitter.fire(this);
222
- this.toDisposeOnToggleMaximized.push(Disposable.create(() => {
223
- maximizedElement.style.display = 'none';
224
- this.removeClass(MAXIMIZED_CLASS);
225
- this.onDidToggleMaximizedEmitter.fire(this);
226
- if (!this.isElectron()) {
227
- this.removeClass(VISIBLE_MENU_MAXIMIZED_CLASS);
228
- }
229
- if (this.isAttached) {
230
- UnsafeWidgetUtilities.detach(this);
231
- }
232
- UnsafeWidgetUtilities.attach(this, areaContainer);
233
- this.fit();
234
- }));
235
-
236
- const layout = this.layout;
237
- if (layout instanceof DockLayout) {
238
- const onResize = layout['onResize'];
239
- layout['onResize'] = () => onResize.bind(layout)(Widget.ResizeMessage.UnknownSize);
240
- this.toDisposeOnToggleMaximized.push(Disposable.create(() => layout['onResize'] = onResize));
241
- }
242
-
243
- const removedListener = () => {
244
- if (!this.widgets().next()) {
245
- this.toDisposeOnToggleMaximized.dispose();
246
- }
247
- };
248
- this.widgetRemoved.connect(removedListener);
249
- this.toDisposeOnToggleMaximized.push(Disposable.create(() => this.widgetRemoved.disconnect(removedListener)));
250
- }
251
-
252
- protected maximizedElement: HTMLElement | undefined;
253
- protected getMaximizedElement(): HTMLElement {
254
- if (!this.maximizedElement) {
255
- this.maximizedElement = document.createElement('div');
256
- this.maximizedElement.style.display = 'none';
257
- document.body.appendChild(this.maximizedElement);
258
- }
259
- return this.maximizedElement;
260
- }
261
-
262
181
  }
263
182
  export namespace TheiaDockPanel {
264
183
  export const Factory = Symbol('TheiaDockPanel#Factory');
265
184
  export interface Factory {
266
- (options?: DockPanel.IOptions): TheiaDockPanel;
185
+ (options?: DockPanel.IOptions, maximizeCallback?: (area: TheiaDockPanel) => void): TheiaDockPanel;
267
186
  }
268
187
 
269
188
  export interface AddOptions extends DockPanel.IAddOptions {