@theia/core 1.77.0-next.1 → 1.77.0-next.12

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 (32) hide show
  1. package/lib/browser/catalog.json +50 -9
  2. package/lib/browser/tree/tree-widget.d.ts +28 -0
  3. package/lib/browser/tree/tree-widget.d.ts.map +1 -1
  4. package/lib/browser/tree/tree-widget.js +59 -3
  5. package/lib/browser/tree/tree-widget.js.map +1 -1
  6. package/lib/browser/tree/tree-widget.spec.js +53 -3
  7. package/lib/browser/tree/tree-widget.spec.js.map +1 -1
  8. package/lib/common/core-preferences.js +5 -5
  9. package/lib/common/core-preferences.js.map +1 -1
  10. package/lib/node/backend-application-module.d.ts.map +1 -1
  11. package/lib/node/backend-application-module.js +3 -0
  12. package/lib/node/backend-application-module.js.map +1 -1
  13. package/lib/node/bundled-resource-provider.d.ts +86 -0
  14. package/lib/node/bundled-resource-provider.d.ts.map +1 -0
  15. package/lib/node/bundled-resource-provider.js +241 -0
  16. package/lib/node/bundled-resource-provider.js.map +1 -0
  17. package/lib/node/bundled-resource-provider.spec.d.ts +2 -0
  18. package/lib/node/bundled-resource-provider.spec.d.ts.map +1 -0
  19. package/lib/node/bundled-resource-provider.spec.js +160 -0
  20. package/lib/node/bundled-resource-provider.spec.js.map +1 -0
  21. package/lib/node/index.d.ts +1 -0
  22. package/lib/node/index.d.ts.map +1 -1
  23. package/lib/node/index.js +3 -1
  24. package/lib/node/index.js.map +1 -1
  25. package/package.json +4 -4
  26. package/src/browser/tree/tree-widget.spec.tsx +59 -3
  27. package/src/browser/tree/tree-widget.tsx +64 -2
  28. package/src/common/core-preferences.ts +5 -5
  29. package/src/node/backend-application-module.ts +4 -0
  30. package/src/node/bundled-resource-provider.spec.ts +196 -0
  31. package/src/node/bundled-resource-provider.ts +266 -0
  32. package/src/node/index.ts +1 -0
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2026 EclipseSource GmbH 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
+ require("reflect-metadata");
19
+ const chai_1 = require("chai");
20
+ const fs = require("fs");
21
+ const os = require("os");
22
+ const path = require("path");
23
+ const temp = require("temp");
24
+ const inversify_1 = require("inversify");
25
+ const env_variables_1 = require("../common/env-variables");
26
+ const logger_1 = require("../common/logger");
27
+ const mock_logger_1 = require("../common/test/mock-logger");
28
+ const file_uri_1 = require("../common/file-uri");
29
+ const bundled_resource_provider_1 = require("./bundled-resource-provider");
30
+ const filesystem_locking_1 = require("./filesystem-locking");
31
+ /**
32
+ * The provider recognizes archives by their `.asar` path segment and reads them through `fs`, which Electron
33
+ * patches to transparently read from the archive. Plain directories named `*.asar` therefore behave like
34
+ * archives from the point of view of the provider and let us test it outside of Electron.
35
+ */
36
+ describe('BundledResourceProvider', () => {
37
+ const track = temp.track();
38
+ let configDir;
39
+ let appDir;
40
+ let provider;
41
+ beforeEach(() => {
42
+ const root = track.mkdirSync();
43
+ configDir = path.join(root, 'config');
44
+ appDir = path.join(root, 'app');
45
+ fs.mkdirSync(configDir);
46
+ fs.mkdirSync(appDir);
47
+ provider = createProvider();
48
+ });
49
+ /** Each provider instance stands for one run of the application, as resolved paths are cached. */
50
+ function createProvider() {
51
+ const container = new inversify_1.Container();
52
+ container.bind(logger_1.ILogger).toConstantValue(new mock_logger_1.MockLogger());
53
+ container.bind(filesystem_locking_1.FileSystemLocking).to(filesystem_locking_1.FileSystemLockingImpl).inSingletonScope();
54
+ container.bind(env_variables_1.EnvVariablesServer).toConstantValue({
55
+ getConfigDirUri: async () => file_uri_1.FileUri.create(configDir).toString()
56
+ });
57
+ container.bind(bundled_resource_provider_1.BundledResourceProviderImpl).toSelf().inSingletonScope();
58
+ container.bind(bundled_resource_provider_1.BundledResourceProvider).toService(bundled_resource_provider_1.BundledResourceProviderImpl);
59
+ return container.get(bundled_resource_provider_1.BundledResourceProvider);
60
+ }
61
+ afterEach(() => track.cleanupSync());
62
+ /**
63
+ * Assert that the given path is nested in the given directory. The provider derives the configuration
64
+ * directory from a URI, which on Windows yields a lower-case drive letter, so the paths cannot simply be
65
+ * compared by prefix. `path.relative` ignores the case of a path on Windows.
66
+ */
67
+ function expectNestedIn(directoryPath, nestedPath) {
68
+ const relativePath = path.relative(directoryPath, nestedPath);
69
+ (0, chai_1.expect)(relativePath).to.not.be.empty;
70
+ (0, chai_1.expect)(relativePath.split(path.sep)).to.not.contain('..');
71
+ }
72
+ function writeResources(rootPath, files) {
73
+ for (const [relativePath, content] of Object.entries(files)) {
74
+ const filePath = path.join(rootPath, relativePath);
75
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
76
+ fs.writeFileSync(filePath, content);
77
+ }
78
+ return rootPath;
79
+ }
80
+ it('returns the path of a resource that is not packaged into an archive', async () => {
81
+ const resourcePath = path.join(writeResources(appDir, { 'scripts/greet.sh': 'echo hello' }), 'scripts');
82
+ (0, chai_1.expect)(await provider.resolveExternalPath(resourcePath)).to.equal(resourcePath);
83
+ });
84
+ it('rejects for a resource that does not exist', async () => {
85
+ const resourcePath = path.join(appDir, 'scripts');
86
+ await provider.resolveExternalPath(resourcePath).then(() => chai_1.expect.fail('should have been rejected'), error => (0, chai_1.expect)(String(error)).to.contain(resourcePath));
87
+ });
88
+ it('extracts a packaged resource into the configuration directory', async () => {
89
+ const archivePath = path.join(appDir, 'app.asar');
90
+ writeResources(archivePath, { 'scripts/greet.sh': 'echo hello', 'scripts/nested/.hidden': 'secret' });
91
+ const resolvedPath = await provider.resolveExternalPath(path.join(archivePath, 'scripts'));
92
+ (0, chai_1.expect)(resolvedPath).to.not.contain('.asar');
93
+ expectNestedIn(configDir, resolvedPath);
94
+ (0, chai_1.expect)(fs.readFileSync(path.join(resolvedPath, 'greet.sh'), 'utf8')).to.equal('echo hello');
95
+ (0, chai_1.expect)(fs.readFileSync(path.join(resolvedPath, 'nested', '.hidden'), 'utf8')).to.equal('secret');
96
+ });
97
+ it('extracts a packaged resource that is a plain file', async () => {
98
+ const archivePath = path.join(appDir, 'app.asar');
99
+ writeResources(archivePath, { 'scripts/greet.sh': 'echo hello' });
100
+ const resolvedPath = await provider.resolveExternalPath(path.join(archivePath, 'scripts', 'greet.sh'));
101
+ expectNestedIn(configDir, resolvedPath);
102
+ (0, chai_1.expect)(fs.readFileSync(resolvedPath, 'utf8')).to.equal('echo hello');
103
+ });
104
+ it('extracts a packaged file as executable', async function () {
105
+ if (process.platform === 'win32') {
106
+ this.skip();
107
+ }
108
+ // Electron reports the files of an asar archive with this mode, even executables.
109
+ const archivePath = path.join(appDir, 'app.asar');
110
+ writeResources(archivePath, { 'native/tool': 'binary' });
111
+ fs.chmodSync(path.join(archivePath, 'native', 'tool'), 0o644);
112
+ const resolvedPath = await provider.resolveExternalPath(path.join(archivePath, 'native', 'tool'));
113
+ (0, chai_1.expect)(fs.statSync(resolvedPath).mode & 0o700).to.equal(0o700);
114
+ });
115
+ it('prefers the copy that the packaging step has left outside of the archive', async () => {
116
+ const archivePath = path.join(appDir, 'app.asar');
117
+ writeResources(archivePath, { 'scripts/greet.sh': 'echo hello' });
118
+ const unpackedPath = writeResources(`${archivePath}.unpacked`, { 'scripts/greet.sh': 'echo hello' });
119
+ const resolvedPath = await provider.resolveExternalPath(path.join(archivePath, 'scripts'));
120
+ (0, chai_1.expect)(resolvedPath).to.equal(path.join(unpackedPath, 'scripts'));
121
+ });
122
+ it('extracts a packaged resource that was only unpacked partially', async () => {
123
+ const archivePath = path.join(appDir, 'app.asar');
124
+ writeResources(archivePath, { 'scripts/greet.sh': 'echo hello', 'scripts/farewell.sh': 'echo bye' });
125
+ writeResources(`${archivePath}.unpacked`, { 'scripts/greet.sh': 'echo hello' });
126
+ const resolvedPath = await provider.resolveExternalPath(path.join(archivePath, 'scripts'));
127
+ expectNestedIn(configDir, resolvedPath);
128
+ (0, chai_1.expect)(fs.readFileSync(path.join(resolvedPath, 'farewell.sh'), 'utf8')).to.equal('echo bye');
129
+ });
130
+ it('re-extracts a resource that was removed from the configuration directory', async () => {
131
+ const archivePath = path.join(appDir, 'app.asar');
132
+ writeResources(archivePath, { 'scripts/greet.sh': 'echo hello' });
133
+ const resourcePath = path.join(archivePath, 'scripts');
134
+ const resolvedPath = await provider.resolveExternalPath(resourcePath);
135
+ fs.rmSync(resolvedPath, { recursive: true });
136
+ (0, chai_1.expect)(await provider.resolveExternalPath(resourcePath)).to.equal(resolvedPath);
137
+ (0, chai_1.expect)(fs.readFileSync(path.join(resolvedPath, 'greet.sh'), 'utf8')).to.equal('echo hello');
138
+ });
139
+ it('extracts into a temporary directory if the configuration directory cannot be written to', async () => {
140
+ const archivePath = path.join(appDir, 'app.asar');
141
+ writeResources(archivePath, { 'scripts/greet.sh': 'echo hello' });
142
+ // a configuration directory that is a regular file cannot hold the extracted resources
143
+ configDir = path.join(appDir, 'not-a-directory');
144
+ fs.writeFileSync(configDir, '');
145
+ const resolvedPath = await createProvider().resolveExternalPath(path.join(archivePath, 'scripts'));
146
+ expectNestedIn(os.tmpdir(), resolvedPath);
147
+ (0, chai_1.expect)(fs.readFileSync(path.join(resolvedPath, 'greet.sh'), 'utf8')).to.equal('echo hello');
148
+ fs.rmSync(resolvedPath, { recursive: true, force: true });
149
+ });
150
+ it('updates an extracted resource when the application has been updated', async () => {
151
+ const archivePath = path.join(appDir, 'app.asar');
152
+ writeResources(archivePath, { 'scripts/greet.sh': 'echo hello' });
153
+ const resourcePath = path.join(archivePath, 'scripts');
154
+ await provider.resolveExternalPath(resourcePath);
155
+ writeResources(archivePath, { 'scripts/greet.sh': 'echo hello again' });
156
+ const resolvedPath = await createProvider().resolveExternalPath(resourcePath);
157
+ (0, chai_1.expect)(fs.readFileSync(path.join(resolvedPath, 'greet.sh'), 'utf8')).to.equal('echo hello again');
158
+ });
159
+ });
160
+ //# sourceMappingURL=bundled-resource-provider.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundled-resource-provider.spec.js","sourceRoot":"","sources":["../../src/node/bundled-resource-provider.spec.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@ export * from './messaging';
6
6
  export * from './cli';
7
7
  export * from './setting-service';
8
8
  export { FileSystemLocking } from './filesystem-locking';
9
+ export { BundledResourceProvider } from './bundled-resource-provider';
9
10
  export { BackendRequestAllowedContribution } from './request/backend-request-facade';
10
11
  export { HttpConnectionValidator } from './hosting/browser-connection-token';
11
12
  //# 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,kBAAkB,CAAC;AACjC,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;AACzD,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAgBA,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,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;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC"}
package/lib/node/index.js CHANGED
@@ -15,7 +15,7 @@
15
15
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
16
  // *****************************************************************************
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.HttpConnectionValidator = exports.BackendRequestAllowedContribution = exports.FileSystemLocking = void 0;
18
+ exports.HttpConnectionValidator = exports.BackendRequestAllowedContribution = exports.BundledResourceProvider = exports.FileSystemLocking = void 0;
19
19
  const tslib_1 = require("tslib");
20
20
  tslib_1.__exportStar(require("./backend-application"), exports);
21
21
  tslib_1.__exportStar(require("./backend-global"), exports);
@@ -26,6 +26,8 @@ tslib_1.__exportStar(require("./cli"), exports);
26
26
  tslib_1.__exportStar(require("./setting-service"), exports);
27
27
  var filesystem_locking_1 = require("./filesystem-locking");
28
28
  Object.defineProperty(exports, "FileSystemLocking", { enumerable: true, get: function () { return filesystem_locking_1.FileSystemLocking; } });
29
+ var bundled_resource_provider_1 = require("./bundled-resource-provider");
30
+ Object.defineProperty(exports, "BundledResourceProvider", { enumerable: true, get: function () { return bundled_resource_provider_1.BundledResourceProvider; } });
29
31
  var backend_request_facade_1 = require("./request/backend-request-facade");
30
32
  Object.defineProperty(exports, "BackendRequestAllowedContribution", { enumerable: true, get: function () { return backend_request_facade_1.BackendRequestAllowedContribution; } });
31
33
  var browser_connection_token_1 = require("./hosting/browser-connection-token");
@@ -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,2DAAiC;AACjC,kDAAwB;AACxB,6DAAmC;AACnC,sDAA4B;AAC5B,gDAAsB;AACtB,4DAAkC;AAClC,2DAAyD;AAAhD,uHAAA,iBAAiB,OAAA;AAC1B,2EAAqF;AAA5E,2IAAA,iCAAiC,OAAA;AAC1C,+EAA6E;AAApE,mIAAA,uBAAuB,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,2DAAiC;AACjC,kDAAwB;AACxB,6DAAmC;AACnC,sDAA4B;AAC5B,gDAAsB;AACtB,4DAAkC;AAClC,2DAAyD;AAAhD,uHAAA,iBAAiB,OAAA;AAC1B,yEAAsE;AAA7D,oIAAA,uBAAuB,OAAA;AAChC,2EAAqF;AAA5E,2IAAA,iCAAiC,OAAA;AAC1C,+EAA6E;AAApE,mIAAA,uBAAuB,OAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theia/core",
3
- "version": "1.77.0-next.1+8b94967c4",
3
+ "version": "1.77.0-next.12+3980769cc",
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,8 +17,8 @@
17
17
  "@lumino/virtualdom": "^2.0.5",
18
18
  "@lumino/widgets": "2.7.5",
19
19
  "@parcel/watcher": "^2.6.0",
20
- "@theia/application-package": "1.77.0-next.1+8b94967c4",
21
- "@theia/request": "1.77.0-next.1+8b94967c4",
20
+ "@theia/application-package": "1.77.0-next.12+3980769cc",
21
+ "@theia/request": "1.77.0-next.12+3980769cc",
22
22
  "@types/body-parser": "^1.19.6",
23
23
  "@types/express": "^4.17.25",
24
24
  "@types/fs-extra": "^4.0.15",
@@ -233,5 +233,5 @@
233
233
  "nyc": {
234
234
  "extends": "../../configs/nyc.json"
235
235
  },
236
- "gitHead": "8b94967c4cfa0dcf688a345d28b3ac2e0d7e298a"
236
+ "gitHead": "3980769cc0ccf74ccac5a5a995f41dce3773d759"
237
237
  }
@@ -38,6 +38,14 @@ class CountingView extends TreeWidget.View {
38
38
  this.scrollCount++;
39
39
  }
40
40
  };
41
+ /** Reports the list height the way Virtuoso does once it has measured the list. */
42
+ measure(height: number, renderedHeight = height): void {
43
+ this.setRenderedHeight(renderedHeight);
44
+ this.onTotalListHeightChanged(height);
45
+ }
46
+ setRenderedHeight(scrollHeight: number): void {
47
+ this.scroller = { scrollHeight } as HTMLElement;
48
+ }
41
49
  }
42
50
 
43
51
  class TestTreeWidget extends TreeWidget {
@@ -190,6 +198,8 @@ describe('TreeWidget', () => {
190
198
  let container: HTMLElement;
191
199
  let root: Root;
192
200
  let view: CountingView | undefined;
201
+ let frames: FrameRequestCallback[];
202
+ let requestAnimationFrame: typeof window.requestAnimationFrame;
193
203
  const rows: TreeWidget.NodeRow[] = [0, 1, 2].map(index => ({ index, depth: 0, node: leaf(`node-${index}`) }));
194
204
 
195
205
  const render = (props: Partial<TreeWidget.ViewProps>): void => flushSync(() => root.render(
@@ -202,20 +212,66 @@ describe('TreeWidget', () => {
202
212
  {...props}
203
213
  />
204
214
  ));
215
+ const runFrames = (): void => frames.splice(0).forEach(frame => frame(0));
216
+ /** Mount and measure the list, and serve the mount-time request. */
217
+ const mount = (props: Partial<TreeWidget.ViewProps>): void => {
218
+ render(props);
219
+ view!.measure(300);
220
+ runFrames();
221
+ };
205
222
 
206
223
  beforeEach(() => {
207
224
  container = document.createElement('div');
208
225
  document.body.appendChild(container);
209
226
  root = createRoot(container);
227
+ frames = [];
228
+ requestAnimationFrame = window.requestAnimationFrame;
229
+ window.requestAnimationFrame = frame => frames.push(frame);
210
230
  });
211
231
 
212
232
  afterEach(() => {
233
+ window.requestAnimationFrame = requestAnimationFrame;
213
234
  flushSync(() => root.unmount());
214
235
  document.body.removeChild(container);
215
236
  });
216
237
 
217
- it('does not scroll again when re-rendered without a new scroll request', () => {
238
+ it('holds a scroll request made before the list is measured until the list is rendered at its height', () => {
239
+ render({ scrollToRow: 2, scrollToRowRequestId: 1 });
240
+ expect(view!.scrollCount).to.equal(0);
241
+
242
+ view!.measure(300, 100);
243
+ runFrames();
244
+ expect(view!.scrollCount).to.equal(0);
245
+
246
+ view!.setRenderedHeight(300);
247
+ runFrames();
248
+ expect(view!.scrollCount).to.equal(1);
249
+
250
+ runFrames();
251
+ expect(view!.scrollCount).to.equal(1);
252
+ });
253
+
254
+ it('waits for the latest list height when the first reported height shrinks', () => {
255
+ render({ scrollToRow: 2, scrollToRowRequestId: 1 });
256
+ view!.measure(300, 100);
257
+ view!.measure(200, 200);
258
+ runFrames();
259
+ expect(view!.scrollCount).to.equal(1);
260
+ });
261
+
262
+ it('serves a held scroll request when the list is never rendered at its height', () => {
218
263
  render({ scrollToRow: 2, scrollToRowRequestId: 1 });
264
+ view!.measure(300, 100);
265
+ for (let frame = 0; frame < 30; frame++) {
266
+ runFrames();
267
+ expect(view!.scrollCount).to.equal(0);
268
+ }
269
+ runFrames();
270
+ expect(view!.scrollCount).to.equal(1);
271
+ });
272
+
273
+ it('does not scroll again when re-rendered without a new scroll request', () => {
274
+ mount({ scrollToRow: 2, scrollToRowRequestId: 1 });
219
275
  const scrollsAfterMount = view!.scrollCount;
220
276
 
221
277
  render({ scrollToRow: 2, scrollToRowRequestId: 1 });
@@ -225,7 +281,7 @@ describe('TreeWidget', () => {
225
281
  });
226
282
 
227
283
  it('scrolls again when a new scroll request arrives for the same row', () => {
228
- render({ scrollToRow: 2, scrollToRowRequestId: 1 });
284
+ mount({ scrollToRow: 2, scrollToRowRequestId: 1 });
229
285
  const scrollsAfterMount = view!.scrollCount;
230
286
 
231
287
  render({ scrollToRow: 2, scrollToRowRequestId: 2 });
@@ -234,7 +290,7 @@ describe('TreeWidget', () => {
234
290
  });
235
291
 
236
292
  it('scrolls when the row to scroll to changes', () => {
237
- render({ scrollToRow: 1 });
293
+ mount({ scrollToRow: 1 });
238
294
  const scrollsAfterMount = view!.scrollCount;
239
295
 
240
296
  render({ scrollToRow: 2 });
@@ -1655,13 +1655,73 @@ export namespace TreeWidget {
1655
1655
  }
1656
1656
  };
1657
1657
 
1658
+ /**
1659
+ * `true` once Virtuoso has measured the list. Before that, `scrollIntoView` sees every row as visible and does nothing.
1660
+ */
1661
+ protected measured = false;
1662
+ /**
1663
+ * `true` while a scroll request made before the list was measured waits to be served.
1664
+ */
1665
+ protected scrollHeld = false;
1666
+ /**
1667
+ * The latest list height reported by Virtuoso. It can still change after the first report, as more rows are measured.
1668
+ */
1669
+ protected listHeight = 0;
1670
+ /**
1671
+ * How many frames a held scroll request waits for the list to be rendered at its height, about half a second at 60 Hz.
1672
+ */
1673
+ protected readonly maxRenderWaitFrames = 30;
1674
+ protected scroller: HTMLElement | undefined;
1675
+
1676
+ /**
1677
+ * Scroll now, or hold the request until the list is measured, e.g. for the focus restored when the view mounts.
1678
+ */
1679
+ protected requestScroll(): void {
1680
+ if (this.measured) {
1681
+ this.scrollIntoViewIfNeeded();
1682
+ } else {
1683
+ this.scrollHeld = this.props.scrollToRow !== undefined;
1684
+ }
1685
+ }
1686
+
1687
+ protected readonly onTotalListHeightChanged = (height: number): void => {
1688
+ this.listHeight = height;
1689
+ if (!this.measured && height > 0) {
1690
+ this.measured = true;
1691
+ if (this.scrollHeld) {
1692
+ this.scrollHeld = false;
1693
+ this.scrollWhenRendered();
1694
+ }
1695
+ }
1696
+ this.props.totalListHeightChanged?.(height);
1697
+ };
1698
+
1699
+ protected readonly setScroller = (scroller: HTMLElement | Window | null): void => {
1700
+ this.scroller = scroller instanceof HTMLElement ? scroller : undefined;
1701
+ this.props.scrollerRef?.(scroller);
1702
+ };
1703
+
1704
+ /**
1705
+ * Virtuoso reports the list height before React renders the list at it, and a scroll before that is clamped
1706
+ * to the old height. Wait for the rendered height, at most `maxRenderWaitFrames` frames.
1707
+ */
1708
+ protected scrollWhenRendered(framesLeft = this.maxRenderWaitFrames): void {
1709
+ window.requestAnimationFrame(() => {
1710
+ if (this.scroller && this.scroller.scrollHeight < this.listHeight && framesLeft > 0) {
1711
+ this.scrollWhenRendered(framesLeft - 1);
1712
+ } else {
1713
+ this.scrollIntoViewIfNeeded();
1714
+ }
1715
+ });
1716
+ }
1717
+
1658
1718
  override componentDidMount(): void {
1659
- this.scrollIntoViewIfNeeded();
1719
+ this.requestScroll();
1660
1720
  }
1661
1721
 
1662
1722
  override componentDidUpdate(prevProps: ViewProps): void {
1663
1723
  if (this.props.scrollToRow !== prevProps.scrollToRow || this.props.scrollToRowRequestId !== prevProps.scrollToRowRequestId) {
1664
- this.scrollIntoViewIfNeeded();
1724
+ this.requestScroll();
1665
1725
  }
1666
1726
  }
1667
1727
 
@@ -1681,6 +1741,8 @@ export namespace TreeWidget {
1681
1741
  // Higher value provides smoother scrolling experience especially during inference, but uses more memory
1682
1742
  overscan={800}
1683
1743
  {...other}
1744
+ totalListHeightChanged={this.onTotalListHeightChanged}
1745
+ scrollerRef={this.setScroller}
1684
1746
  />;
1685
1747
  }
1686
1748
  }
@@ -153,18 +153,18 @@ export const corePreferenceSchema: PreferenceSchema = {
153
153
  'http.proxy': {
154
154
  type: 'string',
155
155
  pattern: '^https?://([^:]*(:[^@]*)?@)?([^:]+|\\[[:0-9a-fA-F]+\\])(:\\d+)?/?$|^$',
156
- markdownDescription: nls.localizeByDefault('The proxy setting to use. If not set, will be inherited from the `http_proxy` and `https_proxy` environment variables. When during [remote development](https://aka.ms/vscode-remote) the {0} setting is disabled this setting can be configured in the local and the remote settings separately.'),
156
+ markdownDescription: nls.localize('theia/core/http/proxy', 'The proxy setting to use. If not set, will be inherited from the `http_proxy` and `https_proxy` environment variables.'),
157
157
  scope: PreferenceScope.User
158
158
  },
159
159
  'http.proxyStrictSSL': {
160
160
  type: 'boolean',
161
161
  default: true,
162
- description: nls.localizeByDefault('Controls whether the proxy server certificate should be verified against the list of supplied CAs. When during [remote development](https://aka.ms/vscode-remote) the {0} setting is disabled this setting can be configured in the local and the remote settings separately.'),
162
+ description: nls.localize('theia/core/http/proxyStrictSSL', 'Controls whether the proxy server certificate should be verified against the list of supplied CAs.'),
163
163
  scope: PreferenceScope.User
164
164
  },
165
165
  'http.proxyAuthorization': {
166
166
  type: 'string',
167
- markdownDescription: nls.localizeByDefault('The value to send as the `Proxy-Authorization` header for every network request. When during [remote development](https://aka.ms/vscode-remote) the {0} setting is disabled this setting can be configured in the local and the remote settings separately.'),
167
+ markdownDescription: nls.localize('theia/core/http/proxyAuthorization', 'The value to send as the `Proxy-Authorization` header for every network request.'),
168
168
  scope: PreferenceScope.User
169
169
  },
170
170
  'http.proxySupport': {
@@ -177,13 +177,13 @@ export const corePreferenceSchema: PreferenceSchema = {
177
177
  nls.localizeByDefault('Enable proxy support for extensions, override request options.'),
178
178
  ],
179
179
  default: 'override',
180
- description: nls.localizeByDefault('Use the proxy support for extensions. When during [remote development](https://aka.ms/vscode-remote) the {0} setting is disabled this setting can be configured in the local and the remote settings separately.'),
180
+ description: nls.localize('theia/core/http/proxySupport', 'Use the proxy support for extensions.'),
181
181
  scope: PreferenceScope.User
182
182
  },
183
183
  'http.systemCertificates': {
184
184
  type: 'boolean',
185
185
  default: true,
186
- description: nls.localizeByDefault('Controls whether CA certificates should be loaded from the OS. On Windows and macOS, a reload of the window is required after turning this off. When during [remote development](https://aka.ms/vscode-remote) the {0} setting is disabled this setting can be configured in the local and the remote settings separately.'),
186
+ description: nls.localize('theia/core/http/systemCertificates', 'Controls whether CA certificates should be loaded from the OS. On Windows and macOS, a reload of the window is required after turning this off.'),
187
187
  scope: PreferenceScope.User
188
188
  },
189
189
  'workbench.list.openMode': {
@@ -57,6 +57,7 @@ import { bindNodeStopwatch, bindBackendStopwatchServer } from './performance';
57
57
  import { OSBackendProviderImpl } from './os-backend-provider';
58
58
  import { BackendRequestFacade, BackendRequestAllowedContribution } from './request/backend-request-facade';
59
59
  import { FileSystemLocking, FileSystemLockingImpl } from './filesystem-locking';
60
+ import { BundledResourceProvider, BundledResourceProviderImpl } from './bundled-resource-provider';
60
61
  import { BackendRemoteService } from './remote/backend-remote-service';
61
62
  import { RemoteCliContribution } from './remote/remote-cli-contribution';
62
63
  import { SettingService, SettingServiceImpl } from './setting-service';
@@ -164,6 +165,9 @@ export const backendApplicationModule = new ContainerModule(bind => {
164
165
 
165
166
  bind(FileSystemLocking).to(FileSystemLockingImpl).inSingletonScope();
166
167
 
168
+ bind(BundledResourceProviderImpl).toSelf().inSingletonScope();
169
+ bind(BundledResourceProvider).toService(BundledResourceProviderImpl);
170
+
167
171
  bind(SettingServiceImpl).toSelf().inSingletonScope();
168
172
  bind(SettingService).toService(SettingServiceImpl);
169
173