@theia/plugin-ext 1.74.0-next.9 → 1.74.0
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/hosted/browser/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/browser/hosted-plugin.js +14 -3
- package/lib/hosted/browser/hosted-plugin.js.map +1 -1
- package/lib/hosted/common/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/common/hosted-plugin.js +4 -0
- package/lib/hosted/common/hosted-plugin.js.map +1 -1
- package/lib/hosted/node/plugin-reader.d.ts +6 -5
- package/lib/hosted/node/plugin-reader.d.ts.map +1 -1
- package/lib/hosted/node/plugin-reader.js +14 -7
- package/lib/hosted/node/plugin-reader.js.map +1 -1
- package/lib/hosted/node/plugin-reader.spec.d.ts +2 -0
- package/lib/hosted/node/plugin-reader.spec.d.ts.map +1 -0
- package/lib/hosted/node/plugin-reader.spec.js +72 -0
- package/lib/hosted/node/plugin-reader.spec.js.map +1 -0
- package/lib/main/browser/custom-editors/custom-editor-opener.d.ts +3 -1
- package/lib/main/browser/custom-editors/custom-editor-opener.d.ts.map +1 -1
- package/lib/main/browser/custom-editors/custom-editor-opener.js +41 -1
- package/lib/main/browser/custom-editors/custom-editor-opener.js.map +1 -1
- package/lib/main/browser/custom-editors/custom-editor-opener.spec.d.ts +2 -0
- package/lib/main/browser/custom-editors/custom-editor-opener.spec.d.ts.map +1 -0
- package/lib/main/browser/custom-editors/custom-editor-opener.spec.js +120 -0
- package/lib/main/browser/custom-editors/custom-editor-opener.spec.js.map +1 -0
- package/lib/main/browser/custom-editors/custom-editor-widget.d.ts +12 -3
- package/lib/main/browser/custom-editors/custom-editor-widget.d.ts.map +1 -1
- package/lib/main/browser/custom-editors/custom-editor-widget.js +31 -1
- package/lib/main/browser/custom-editors/custom-editor-widget.js.map +1 -1
- package/lib/main/browser/preference-registry-main.d.ts.map +1 -1
- package/lib/main/browser/preference-registry-main.js +8 -0
- package/lib/main/browser/preference-registry-main.js.map +1 -1
- package/lib/main/browser/tabs/tabs-main.d.ts.map +1 -1
- package/lib/main/browser/tabs/tabs-main.js +9 -1
- package/lib/main/browser/tabs/tabs-main.js.map +1 -1
- package/lib/main/node/plugin-http-resolver.d.ts.map +1 -1
- package/lib/main/node/plugin-http-resolver.js +5 -3
- package/lib/main/node/plugin-http-resolver.js.map +1 -1
- package/lib/main/node/plugin-http-resolver.spec.d.ts +2 -0
- package/lib/main/node/plugin-http-resolver.spec.d.ts.map +1 -0
- package/lib/main/node/plugin-http-resolver.spec.js +40 -0
- package/lib/main/node/plugin-http-resolver.spec.js.map +1 -0
- package/lib/main/node/plugin-service.d.ts.map +1 -1
- package/lib/main/node/plugin-service.js +8 -3
- package/lib/main/node/plugin-service.js.map +1 -1
- package/lib/plugin/telemetry-ext.d.ts +4 -1
- package/lib/plugin/telemetry-ext.d.ts.map +1 -1
- package/lib/plugin/telemetry-ext.js +19 -3
- package/lib/plugin/telemetry-ext.js.map +1 -1
- package/lib/plugin/telemetry-ext.spec.d.ts +2 -0
- package/lib/plugin/telemetry-ext.spec.d.ts.map +1 -0
- package/lib/plugin/telemetry-ext.spec.js +51 -0
- package/lib/plugin/telemetry-ext.spec.js.map +1 -0
- package/package.json +32 -32
- package/src/hosted/browser/hosted-plugin.ts +14 -3
- package/src/hosted/common/hosted-plugin.ts +4 -0
- package/src/hosted/node/plugin-reader.spec.ts +80 -0
- package/src/hosted/node/plugin-reader.ts +16 -7
- package/src/main/browser/custom-editors/custom-editor-opener.spec.ts +142 -0
- package/src/main/browser/custom-editors/custom-editor-opener.tsx +45 -2
- package/src/main/browser/custom-editors/custom-editor-widget.ts +43 -4
- package/src/main/browser/preference-registry-main.ts +8 -0
- package/src/main/browser/tabs/tabs-main.ts +8 -1
- package/src/main/node/plugin-http-resolver.spec.ts +41 -0
- package/src/main/node/plugin-http-resolver.ts +4 -3
- package/src/main/node/plugin-service.ts +7 -3
- package/src/plugin/telemetry-ext.spec.ts +61 -0
- package/src/plugin/telemetry-ext.ts +23 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry-ext.d.ts","sourceRoot":"","sources":["../../src/plugin/telemetry-ext.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,EAAW,MAAM,8BAA8B,CAAC;AAG9D,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAE7E,qBAAa,gBAAgB;IAEzB,mBAAmB,EAAE,OAAO,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,kCAAkC,CAA0B;IAC7E,QAAQ,CAAC,2BAA2B,EAAE,KAAK,CAAC,OAAO,CAAC,CAAiD;IAErG,IAAI,kBAAkB,IAAI,OAAO,CAEhC;IAED,IAAI,kBAAkB,CAAC,kBAAkB,EAAE,OAAO,EAKjD;IAED,qBAAqB,CAAC,MAAM,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,SAAS,GAAG,eAAe;CAOhH;AAED,qBAAa,eAAe;IACxB,OAAO,CAAC,MAAM,CAA8B;IAC5C,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,SAAS,CAAC;IAErD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/C,
|
|
1
|
+
{"version":3,"file":"telemetry-ext.d.ts","sourceRoot":"","sources":["../../src/plugin/telemetry-ext.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,EAAW,MAAM,8BAA8B,CAAC;AAG9D,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAE7E,qBAAa,gBAAgB;IAEzB,mBAAmB,EAAE,OAAO,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,kCAAkC,CAA0B;IAC7E,QAAQ,CAAC,2BAA2B,EAAE,KAAK,CAAC,OAAO,CAAC,CAAiD;IAErG,IAAI,kBAAkB,IAAI,OAAO,CAEhC;IAED,IAAI,kBAAkB,CAAC,kBAAkB,EAAE,OAAO,EAKjD;IAED,qBAAqB,CAAC,MAAM,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,SAAS,GAAG,eAAe;CAOhH;AAED,qBAAa,eAAe;IACxB,OAAO,CAAC,MAAM,CAA8B;IAC5C,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,SAAS,CAAC;IAErD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/C,OAAO,CAAC,iBAAiB,CAAU;IAEnC,OAAO,CAAC,QAAQ,CAAC,8BAA8B,CAA2C;IAC1F,QAAQ,CAAC,uBAAuB,EAAE,KAAK,CAAC,eAAe,CAAC,CAA6C;IACrG,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,gBAAgB,CAAU;gBAEtB,MAAM,EAAE,eAAe,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,sBAAsB;IAShG,IAAI,gBAAgB,IAAI,OAAO,CAE9B;IAED,IAAI,gBAAgB,CAAC,gBAAgB,EAAE,OAAO,EAK7C;IAED,IAAI,cAAc,IAAI,OAAO,CAE5B;IAED,IAAI,cAAc,CAAC,cAAc,EAAE,OAAO,EAKzC;IAED,IAAI,eAAe,IAAI,OAAO,CAE7B;IAED,IAAI,eAAe,CAAC,eAAe,EAAE,OAAO,EAK3C;IAED,OAAO,CAAC,kBAAkB;IAS1B,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI;IAQ1F,QAAQ,CAAC,oBAAoB,EAAE,MAAM,GAAG,KAAK,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI;IAY7G,OAAO,IAAI,IAAI;IAWf,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,mBAAmB;CAG9B;AAED,UAAU,eAAe;IAErB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IAEnE,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IAC9D,KAAK,CAAC,IAAI,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;CACnC;AAyHD;;;;;GAKG;AAEH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CA2BnG"}
|
|
@@ -51,9 +51,18 @@ class TelemetryLogger {
|
|
|
51
51
|
this.sender = sender;
|
|
52
52
|
this.options = options;
|
|
53
53
|
this.commonProperties = this.getCommonProperties();
|
|
54
|
-
this.
|
|
55
|
-
this.
|
|
56
|
-
this.
|
|
54
|
+
this._telemetryEnabled = telemetryEnabled;
|
|
55
|
+
this._isErrorsEnabled = telemetryEnabled;
|
|
56
|
+
this._isUsageEnabled = telemetryEnabled;
|
|
57
|
+
}
|
|
58
|
+
get telemetryEnabled() {
|
|
59
|
+
return this._telemetryEnabled;
|
|
60
|
+
}
|
|
61
|
+
set telemetryEnabled(telemetryEnabled) {
|
|
62
|
+
if (this._telemetryEnabled !== telemetryEnabled) {
|
|
63
|
+
this._telemetryEnabled = telemetryEnabled;
|
|
64
|
+
this.updateEnableStates(telemetryEnabled, telemetryEnabled);
|
|
65
|
+
}
|
|
57
66
|
}
|
|
58
67
|
get isUsageEnabled() {
|
|
59
68
|
return this._isUsageEnabled;
|
|
@@ -73,6 +82,13 @@ class TelemetryLogger {
|
|
|
73
82
|
this.onDidChangeEnableStatesEmitter.fire(this);
|
|
74
83
|
}
|
|
75
84
|
}
|
|
85
|
+
updateEnableStates(isUsageEnabled, isErrorsEnabled) {
|
|
86
|
+
if (this._isUsageEnabled !== isUsageEnabled || this._isErrorsEnabled !== isErrorsEnabled) {
|
|
87
|
+
this._isUsageEnabled = isUsageEnabled;
|
|
88
|
+
this._isErrorsEnabled = isErrorsEnabled;
|
|
89
|
+
this.onDidChangeEnableStatesEmitter.fire(this);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
76
92
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
77
93
|
logUsage(eventName, data) {
|
|
78
94
|
if (!this.telemetryEnabled || !this.isUsageEnabled) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry-ext.js","sourceRoot":"","sources":["../../src/plugin/telemetry-ext.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;;;
|
|
1
|
+
{"version":3,"file":"telemetry-ext.js","sourceRoot":"","sources":["../../src/plugin/telemetry-ext.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry-ext.spec.d.ts","sourceRoot":"","sources":["../../src/plugin/telemetry-ext.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2026 suzunn 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
|
+
const chai = require("chai");
|
|
19
|
+
const telemetry_ext_1 = require("./telemetry-ext");
|
|
20
|
+
const expect = chai.expect;
|
|
21
|
+
describe('TelemetryLogger', () => {
|
|
22
|
+
const sender = {
|
|
23
|
+
sendEventData: () => { },
|
|
24
|
+
sendErrorData: () => { }
|
|
25
|
+
};
|
|
26
|
+
it('reflects the current telemetry enabled state', () => {
|
|
27
|
+
const telemetry = new telemetry_ext_1.TelemetryExtImpl();
|
|
28
|
+
const logger = telemetry.createTelemetryLogger(sender);
|
|
29
|
+
expect(logger.telemetryEnabled).to.equal(false);
|
|
30
|
+
expect(logger.isUsageEnabled).to.equal(false);
|
|
31
|
+
expect(logger.isErrorsEnabled).to.equal(false);
|
|
32
|
+
telemetry.isTelemetryEnabled = true;
|
|
33
|
+
expect(logger.telemetryEnabled).to.equal(true);
|
|
34
|
+
expect(logger.isUsageEnabled).to.equal(true);
|
|
35
|
+
expect(logger.isErrorsEnabled).to.equal(true);
|
|
36
|
+
telemetry.isTelemetryEnabled = false;
|
|
37
|
+
expect(logger.telemetryEnabled).to.equal(false);
|
|
38
|
+
expect(logger.isUsageEnabled).to.equal(false);
|
|
39
|
+
expect(logger.isErrorsEnabled).to.equal(false);
|
|
40
|
+
});
|
|
41
|
+
it('emits enable-state changes when telemetry is toggled', () => {
|
|
42
|
+
const telemetry = new telemetry_ext_1.TelemetryExtImpl();
|
|
43
|
+
const logger = telemetry.createTelemetryLogger(sender);
|
|
44
|
+
let changes = 0;
|
|
45
|
+
logger.onDidChangeEnableStates(() => changes++);
|
|
46
|
+
telemetry.isTelemetryEnabled = true;
|
|
47
|
+
telemetry.isTelemetryEnabled = false;
|
|
48
|
+
expect(changes).to.equal(2);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
//# sourceMappingURL=telemetry-ext.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry-ext.spec.js","sourceRoot":"","sources":["../../src/plugin/telemetry-ext.spec.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,wCAAwC;AACxC,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,6BAA6B;AAC7B,mDAAmD;AAEnD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;AAE3B,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC7B,MAAM,MAAM,GAAG;QACX,aAAa,EAAE,GAAG,EAAE,GAAG,CAAC;QACxB,aAAa,EAAE,GAAG,EAAE,GAAG,CAAC;KAC3B,CAAC;IAEF,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACpD,MAAM,SAAS,GAAG,IAAI,gCAAgB,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,SAAS,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAEvD,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAE/C,SAAS,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAEpC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE9C,SAAS,CAAC,kBAAkB,GAAG,KAAK,CAAC;QAErC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC5D,MAAM,SAAS,GAAG,IAAI,gCAAgB,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,SAAS,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;QACvD,IAAI,OAAO,GAAG,CAAC,CAAC;QAEhB,MAAM,CAAC,uBAAuB,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;QAEhD,SAAS,CAAC,kBAAkB,GAAG,IAAI,CAAC;QACpC,SAAS,CAAC,kBAAkB,GAAG,KAAK,CAAC;QAErC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theia/plugin-ext",
|
|
3
|
-
"version": "1.74.0
|
|
3
|
+
"version": "1.74.0",
|
|
4
4
|
"description": "Theia - Plugin Extension",
|
|
5
5
|
"main": "lib/common/index.js",
|
|
6
6
|
"typings": "lib/common/index.d.ts",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@theia/ai-core": "1.74.0
|
|
9
|
-
"@theia/ai-mcp": "1.74.0
|
|
10
|
-
"@theia/bulk-edit": "1.74.0
|
|
11
|
-
"@theia/callhierarchy": "1.74.0
|
|
12
|
-
"@theia/console": "1.74.0
|
|
13
|
-
"@theia/core": "1.74.0
|
|
14
|
-
"@theia/debug": "1.74.0
|
|
15
|
-
"@theia/editor": "1.74.0
|
|
16
|
-
"@theia/editor-preview": "1.74.0
|
|
17
|
-
"@theia/file-search": "1.74.0
|
|
18
|
-
"@theia/filesystem": "1.74.0
|
|
19
|
-
"@theia/markers": "1.74.0
|
|
20
|
-
"@theia/messages": "1.74.0
|
|
21
|
-
"@theia/monaco": "1.74.0
|
|
8
|
+
"@theia/ai-core": "1.74.0",
|
|
9
|
+
"@theia/ai-mcp": "1.74.0",
|
|
10
|
+
"@theia/bulk-edit": "1.74.0",
|
|
11
|
+
"@theia/callhierarchy": "1.74.0",
|
|
12
|
+
"@theia/console": "1.74.0",
|
|
13
|
+
"@theia/core": "1.74.0",
|
|
14
|
+
"@theia/debug": "1.74.0",
|
|
15
|
+
"@theia/editor": "1.74.0",
|
|
16
|
+
"@theia/editor-preview": "1.74.0",
|
|
17
|
+
"@theia/file-search": "1.74.0",
|
|
18
|
+
"@theia/filesystem": "1.74.0",
|
|
19
|
+
"@theia/markers": "1.74.0",
|
|
20
|
+
"@theia/messages": "1.74.0",
|
|
21
|
+
"@theia/monaco": "1.74.0",
|
|
22
22
|
"@theia/monaco-editor-core": "1.108.201",
|
|
23
|
-
"@theia/navigator": "1.74.0
|
|
24
|
-
"@theia/notebook": "1.74.0
|
|
25
|
-
"@theia/output": "1.74.0
|
|
26
|
-
"@theia/plugin": "1.74.0
|
|
27
|
-
"@theia/preferences": "1.74.0
|
|
28
|
-
"@theia/scm": "1.74.0
|
|
29
|
-
"@theia/search-in-workspace": "1.74.0
|
|
30
|
-
"@theia/task": "1.74.0
|
|
31
|
-
"@theia/terminal": "1.74.0
|
|
32
|
-
"@theia/test": "1.74.0
|
|
33
|
-
"@theia/timeline": "1.74.0
|
|
34
|
-
"@theia/typehierarchy": "1.74.0
|
|
35
|
-
"@theia/variable-resolver": "1.74.0
|
|
36
|
-
"@theia/workspace": "1.74.0
|
|
23
|
+
"@theia/navigator": "1.74.0",
|
|
24
|
+
"@theia/notebook": "1.74.0",
|
|
25
|
+
"@theia/output": "1.74.0",
|
|
26
|
+
"@theia/plugin": "1.74.0",
|
|
27
|
+
"@theia/preferences": "1.74.0",
|
|
28
|
+
"@theia/scm": "1.74.0",
|
|
29
|
+
"@theia/search-in-workspace": "1.74.0",
|
|
30
|
+
"@theia/task": "1.74.0",
|
|
31
|
+
"@theia/terminal": "1.74.0",
|
|
32
|
+
"@theia/test": "1.74.0",
|
|
33
|
+
"@theia/timeline": "1.74.0",
|
|
34
|
+
"@theia/typehierarchy": "1.74.0",
|
|
35
|
+
"@theia/variable-resolver": "1.74.0",
|
|
36
|
+
"@theia/workspace": "1.74.0",
|
|
37
37
|
"@types/mime": "^2.0.3",
|
|
38
38
|
"@vscode/debugprotocol": "^1.68.0",
|
|
39
39
|
"@vscode/proxy-agent": "^0.13.2",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"macaddress": "^0.5.4",
|
|
48
48
|
"mime": "^2.6.0",
|
|
49
49
|
"node-pty": "1.2.0-beta.12",
|
|
50
|
-
"semver": "^7.8.
|
|
50
|
+
"semver": "^7.8.5",
|
|
51
51
|
"tslib": "^2.8.1",
|
|
52
52
|
"vhost": "^3.0.2",
|
|
53
53
|
"vscode-textmate": "^9.3.2"
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"watch": "theiaext watch"
|
|
91
91
|
},
|
|
92
92
|
"devDependencies": {
|
|
93
|
-
"@theia/ext-scripts": "1.
|
|
93
|
+
"@theia/ext-scripts": "1.74.0",
|
|
94
94
|
"@types/decompress": "^4.2.7",
|
|
95
95
|
"@types/escape-html": "^0.0.20",
|
|
96
96
|
"@types/lodash.clonedeep": "^4.5.9"
|
|
@@ -98,5 +98,5 @@
|
|
|
98
98
|
"nyc": {
|
|
99
99
|
"extends": "../../configs/nyc.json"
|
|
100
100
|
},
|
|
101
|
-
"gitHead": "
|
|
101
|
+
"gitHead": "7b7376225f0825b4f13d296d686cc13db95fdb69"
|
|
102
102
|
}
|
|
@@ -277,9 +277,20 @@ export class HostedPluginSupport extends AbstractHostedPluginSupport<PluginManag
|
|
|
277
277
|
}
|
|
278
278
|
|
|
279
279
|
protected override async afterLoadContributions(toDisconnect: DisposableCollection): Promise<void> {
|
|
280
|
-
|
|
281
|
-
//
|
|
282
|
-
|
|
280
|
+
// Defer view initialization until the layout has been restored: initWidgets/removeStaleWidgets
|
|
281
|
+
// must not run while the ShellLayoutRestorer still holds restored plugin view widgets, otherwise
|
|
282
|
+
// removeStaleWidgets can dispose a restored view container mid-restore and abort the whole
|
|
283
|
+
// layout restoration (see https://github.com/eclipse-theia/theia/issues/17770).
|
|
284
|
+
// Deliberately not awaited: startPlugins runs after this hook and may register file system
|
|
285
|
+
// providers the layout restoration depends on (see beforeLoadContributions).
|
|
286
|
+
this.appState.reachedState('initialized_layout').then(async () => {
|
|
287
|
+
if (toDisconnect.disposed) {
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
await this.viewRegistry.initWidgets();
|
|
291
|
+
// remove restored plugin widgets which were not registered by contributions
|
|
292
|
+
this.viewRegistry.removeStaleWidgets();
|
|
293
|
+
}).catch(console.error);
|
|
283
294
|
this.workspaceTrustService.refreshRestrictedModeIndicator();
|
|
284
295
|
}
|
|
285
296
|
|
|
@@ -148,6 +148,10 @@ export abstract class AbstractHostedPluginSupport<PM extends AbstractPluginManag
|
|
|
148
148
|
await this.runOperation(() => this.doLoad());
|
|
149
149
|
} catch (e) {
|
|
150
150
|
console.error('Failed to load plugins:', e);
|
|
151
|
+
// Resolve the startup deferreds so that clients awaiting `willStart` or `didStart`,
|
|
152
|
+
// e.g. file system provider activations, do not hang forever on a failed load.
|
|
153
|
+
this.deferredWillStart.resolve();
|
|
154
|
+
this.deferredDidStart.resolve();
|
|
151
155
|
}
|
|
152
156
|
}), 50, { leading: true });
|
|
153
157
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 EclipseSource and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { expect } from 'chai';
|
|
18
|
+
import * as fs from 'fs';
|
|
19
|
+
import * as os from 'os';
|
|
20
|
+
import * as path from 'path';
|
|
21
|
+
import { HostedPluginReader } from './plugin-reader';
|
|
22
|
+
|
|
23
|
+
class TestHostedPluginReader extends HostedPluginReader {
|
|
24
|
+
resolve(localPath: string, filePath: string): Promise<string | undefined> {
|
|
25
|
+
return this.resolveFile(localPath, filePath);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe('HostedPluginReader#resolveFile', () => {
|
|
30
|
+
|
|
31
|
+
let pluginDir: string;
|
|
32
|
+
let nearSiblingFile: string;
|
|
33
|
+
let farSiblingFile: string;
|
|
34
|
+
const reader = new TestHostedPluginReader();
|
|
35
|
+
|
|
36
|
+
before(() => {
|
|
37
|
+
// Layout:
|
|
38
|
+
// <root>/far-sibling.txt (reachable via `../../far-sibling.txt`)
|
|
39
|
+
// <root>/wrapper/sibling.txt (reachable via `../sibling.txt`)
|
|
40
|
+
// <root>/wrapper/plugin/ (pluginDir)
|
|
41
|
+
// ├── main.js
|
|
42
|
+
// └── media/icon.png
|
|
43
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'theia-plugin-reader-'));
|
|
44
|
+
const wrapper = path.join(root, 'wrapper');
|
|
45
|
+
pluginDir = path.join(wrapper, 'plugin');
|
|
46
|
+
fs.mkdirSync(pluginDir, { recursive: true });
|
|
47
|
+
fs.writeFileSync(path.join(pluginDir, 'main.js'), 'console.log("ok");');
|
|
48
|
+
fs.mkdirSync(path.join(pluginDir, 'media'));
|
|
49
|
+
fs.writeFileSync(path.join(pluginDir, 'media', 'icon.png'), 'png');
|
|
50
|
+
nearSiblingFile = path.join(wrapper, 'sibling.txt');
|
|
51
|
+
fs.writeFileSync(nearSiblingFile, 'near');
|
|
52
|
+
farSiblingFile = path.join(root, 'far-sibling.txt');
|
|
53
|
+
fs.writeFileSync(farSiblingFile, 'far');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('serves a file inside the plugin directory', async () => {
|
|
57
|
+
expect(await reader.resolve(pluginDir, 'main.js')).to.equal(path.join(pluginDir, 'main.js'));
|
|
58
|
+
expect(await reader.resolve(pluginDir, 'media/icon.png')).to.equal(path.join(pluginDir, 'media', 'icon.png'));
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('resolves extensionless references with the .js fallback', async () => {
|
|
62
|
+
expect(await reader.resolve(pluginDir, 'main')).to.equal(path.join(pluginDir, 'main.js'));
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('returns undefined for a relative path pointing outside the plugin directory', async () => {
|
|
66
|
+
expect(await reader.resolve(pluginDir, '../sibling.txt')).to.be.undefined;
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('returns undefined for a relative path composed of parent-directory segments', async () => {
|
|
70
|
+
expect(await reader.resolve(pluginDir, '../../far-sibling.txt')).to.be.undefined;
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('returns undefined for an absolute path outside the plugin directory', async () => {
|
|
74
|
+
expect(await reader.resolve(pluginDir, nearSiblingFile)).to.be.undefined;
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('returns undefined for a missing file inside the plugin directory', async () => {
|
|
78
|
+
expect(await reader.resolve(pluginDir, 'does-not-exist.js')).to.be.undefined;
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -49,8 +49,7 @@ export class HostedPluginReader implements BackendApplicationContribution {
|
|
|
49
49
|
|
|
50
50
|
const localPath = this.pluginsIdsFiles.get(pluginId);
|
|
51
51
|
if (localPath) {
|
|
52
|
-
const
|
|
53
|
-
const resolvedFile = await this.resolveFile(absolutePath);
|
|
52
|
+
const resolvedFile = await this.resolveFile(localPath, filePath);
|
|
54
53
|
if (!resolvedFile) {
|
|
55
54
|
res.status(404).send(`No such file found in '${escape_html(pluginId)}' plugin.`);
|
|
56
55
|
return;
|
|
@@ -79,13 +78,23 @@ export class HostedPluginReader implements BackendApplicationContribution {
|
|
|
79
78
|
}
|
|
80
79
|
|
|
81
80
|
/**
|
|
82
|
-
* Resolves
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* which is common in Node.js/CommonJS environments.
|
|
81
|
+
* Resolves `filePath` under `localPath`, with fallback to `.js`, `.cjs` and `.mjs`
|
|
82
|
+
* extensions. Returns `undefined` if the resolved path is not under `localPath`
|
|
83
|
+
* or if no candidate exists on disk.
|
|
86
84
|
*
|
|
85
|
+
* The extension fallback handles cases where plugins reference modules without
|
|
86
|
+
* extensions, which is common in Node.js/CommonJS environments.
|
|
87
87
|
*/
|
|
88
|
-
protected async resolveFile(
|
|
88
|
+
protected async resolveFile(localPath: string, filePath: string): Promise<string | undefined> {
|
|
89
|
+
const absolutePath = path.resolve(localPath, filePath);
|
|
90
|
+
|
|
91
|
+
// `path.relative` yields a path starting with '..' (or an absolute path on
|
|
92
|
+
// Windows when the drive differs) when `absolutePath` is not under `localPath`.
|
|
93
|
+
const relativePath = path.relative(localPath, absolutePath);
|
|
94
|
+
if (relativePath.startsWith('..') || path.isAbsolute(relativePath)) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
|
|
89
98
|
const candidates = [absolutePath];
|
|
90
99
|
const pathExtension = path.extname(absolutePath).toLowerCase();
|
|
91
100
|
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 Safi Seid-Ahmad, K2view and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { enableJSDOM } from '@theia/core/lib/browser/test/jsdom';
|
|
18
|
+
let disableJSDOM = enableJSDOM();
|
|
19
|
+
|
|
20
|
+
import * as chai from 'chai';
|
|
21
|
+
import URI from '@theia/core/lib/common/uri';
|
|
22
|
+
import { PreferenceService } from '@theia/core';
|
|
23
|
+
import { EditorOpenerOptions } from '@theia/editor/lib/browser';
|
|
24
|
+
import { CustomEditorOpener } from './custom-editor-opener';
|
|
25
|
+
import { CustomEditor, CustomEditorPriority } from '../../../common';
|
|
26
|
+
|
|
27
|
+
disableJSDOM();
|
|
28
|
+
|
|
29
|
+
const expect = chai.expect;
|
|
30
|
+
|
|
31
|
+
describe('CustomEditorOpener#selectorMatches', () => {
|
|
32
|
+
|
|
33
|
+
before(() => {
|
|
34
|
+
disableJSDOM = enableJSDOM();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
after(() => {
|
|
38
|
+
disableJSDOM();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Only selector matching is exercised — none of the collaborators are touched.
|
|
42
|
+
function createOpener(filenamePattern: string): CustomEditorOpener {
|
|
43
|
+
const editor: CustomEditor = {
|
|
44
|
+
viewType: 'test.editor',
|
|
45
|
+
displayName: 'Test Editor',
|
|
46
|
+
selector: [{ filenamePattern }],
|
|
47
|
+
priority: CustomEditorPriority.default
|
|
48
|
+
};
|
|
49
|
+
return new CustomEditorOpener(editor, undefined!, undefined!, undefined!, undefined!);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function matches(filenamePattern: string, path: string): boolean {
|
|
53
|
+
const opener = createOpener(filenamePattern);
|
|
54
|
+
return opener.matches([{ filenamePattern }], new URI(`file://${path}`));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function matchesUri(filenamePattern: string, uri: string): boolean {
|
|
58
|
+
const opener = createOpener(filenamePattern);
|
|
59
|
+
return opener.matches([{ filenamePattern }], new URI(uri));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
it('matches a plain extension pattern against the basename', () => {
|
|
63
|
+
expect(matches('*.custom', '/project/src/file.custom')).true;
|
|
64
|
+
expect(matches('*.custom', '/project/src/file.other')).false;
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('matches a plain filename pattern against the basename anywhere', () => {
|
|
68
|
+
expect(matches('config.json', '/anywhere/at/all/config.json')).true;
|
|
69
|
+
expect(matches('config.json', '/anywhere/at/all/other.json')).false;
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('matches case-insensitively', () => {
|
|
73
|
+
expect(matches('*.CUSTOM', '/project/file.custom')).true;
|
|
74
|
+
expect(matches('*.custom', '/project/FILE.CUSTOM')).true;
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('matches a pattern containing a path separator against the full path (VS Code parity)', () => {
|
|
78
|
+
const pattern = '**/components/*/config.json';
|
|
79
|
+
expect(matches(pattern, '/project/src/components/button/config.json')).true;
|
|
80
|
+
expect(matches(pattern, '/project/elsewhere/config.json')).false;
|
|
81
|
+
expect(matches(pattern, '/project/src/components/button/nested/config.json')).false;
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('matches nested path patterns', () => {
|
|
85
|
+
const pattern = '**/components/*/styles/*.css';
|
|
86
|
+
expect(matches(pattern, '/project/src/components/button/styles/theme.css')).true;
|
|
87
|
+
expect(matches(pattern, '/project/src/components/button/config.json')).false;
|
|
88
|
+
expect(matches(pattern, '/project/src/components/button/styles/dark/theme.css')).false;
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('does not let a path pattern match a bare basename', () => {
|
|
92
|
+
expect(matches('**/components/*/config.json', '/config.json')).false;
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('never matches the excluded schemes, mirroring VS Code (globMatchesResource)', () => {
|
|
96
|
+
// Patterns that would match the basename or full path on a `file:` resource...
|
|
97
|
+
expect(matchesUri('*.json', 'file:///project/settings.json')).true;
|
|
98
|
+
expect(matchesUri('**/settings.json', 'file:///project/settings.json')).true;
|
|
99
|
+
// ...must not match on VS Code's internal schemes.
|
|
100
|
+
expect(matchesUri('*.json', 'vscode-settings:/settings.json')).false;
|
|
101
|
+
expect(matchesUri('**/settings.json', 'vscode-settings:/project/settings.json')).false;
|
|
102
|
+
expect(matchesUri('*.json', 'webview-panel:/panel/config.json')).false;
|
|
103
|
+
expect(matchesUri('*', 'extension:/some/resource')).false;
|
|
104
|
+
expect(matchesUri('*', 'vscode-workspace-trust:/trust')).false;
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe('CustomEditorOpener#isPreviewEnabled', () => {
|
|
109
|
+
|
|
110
|
+
class TestableCustomEditorOpener extends CustomEditorOpener {
|
|
111
|
+
override isPreviewEnabled(options?: EditorOpenerOptions): boolean {
|
|
112
|
+
return super.isPreviewEnabled(options);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function createOpener(enablePreview: boolean): TestableCustomEditorOpener {
|
|
117
|
+
const editor: CustomEditor = {
|
|
118
|
+
viewType: 'test.editor',
|
|
119
|
+
displayName: 'Test Editor',
|
|
120
|
+
selector: [{ filenamePattern: '*.custom' }],
|
|
121
|
+
priority: CustomEditorPriority.default
|
|
122
|
+
};
|
|
123
|
+
const preferenceService = { get: () => enablePreview } as unknown as PreferenceService;
|
|
124
|
+
// Only `preferenceService` is exercised by `isPreviewEnabled`; the other collaborators are unused here.
|
|
125
|
+
return new TestableCustomEditorOpener(editor, undefined!, undefined!, undefined!, preferenceService);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
it('enables preview when requested and the `editor.enablePreview` preference is on', () => {
|
|
129
|
+
expect(createOpener(true).isPreviewEnabled({ preview: true })).true;
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('disables preview when the `editor.enablePreview` preference is off', () => {
|
|
133
|
+
expect(createOpener(false).isPreviewEnabled({ preview: true })).false;
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('disables preview when it is not requested', () => {
|
|
137
|
+
const opener = createOpener(true);
|
|
138
|
+
expect(opener.isPreviewEnabled({ preview: false })).false;
|
|
139
|
+
expect(opener.isPreviewEnabled({})).false;
|
|
140
|
+
expect(opener.isPreviewEnabled(undefined)).false;
|
|
141
|
+
});
|
|
142
|
+
});
|
|
@@ -23,7 +23,24 @@ import { CustomEditorWidget } from './custom-editor-widget';
|
|
|
23
23
|
import { PluginCustomEditorRegistry } from './plugin-custom-editor-registry';
|
|
24
24
|
import { generateUuid } from '@theia/core/lib/common/uuid';
|
|
25
25
|
import { DisposableCollection, Emitter, PreferenceService } from '@theia/core';
|
|
26
|
+
import { EditorOpenerOptions } from '@theia/editor/lib/browser';
|
|
27
|
+
import { PreviewTabWidget } from '@theia/editor-preview/lib/browser/preview-tab-widget';
|
|
28
|
+
import { ENABLE_PREVIEW_PREFERENCE } from '@theia/editor-preview/lib/common/editor-preview-preferences';
|
|
26
29
|
import { match } from '@theia/core/lib/common/glob';
|
|
30
|
+
import { Schemes } from '../../../common/uri-components';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Schemes that never match a custom editor's `filenamePattern`, mirroring the
|
|
34
|
+
* excluded schemes in VS Code's `editorResolverService#globMatchesResource`.
|
|
35
|
+
* Theia has no scheme constants for `extension` and `vscode-workspace-trust`,
|
|
36
|
+
* so those are referenced by their literal values.
|
|
37
|
+
*/
|
|
38
|
+
const nonMatchingSchemes = new Set<string>([
|
|
39
|
+
'extension',
|
|
40
|
+
Schemes.webviewPanel,
|
|
41
|
+
'vscode-workspace-trust',
|
|
42
|
+
Schemes.vscodeSettings
|
|
43
|
+
]);
|
|
27
44
|
|
|
28
45
|
export class CustomEditorOpener implements OpenHandler {
|
|
29
46
|
|
|
@@ -88,10 +105,11 @@ export class CustomEditorOpener implements OpenHandler {
|
|
|
88
105
|
}
|
|
89
106
|
|
|
90
107
|
protected readonly pendingWidgetPromises = new Map<string, Promise<CustomEditorWidget>>();
|
|
91
|
-
protected async openCustomEditor(uri: URI, options?:
|
|
108
|
+
protected async openCustomEditor(uri: URI, options?: EditorOpenerOptions): Promise<CustomEditorWidget> {
|
|
92
109
|
let widget: CustomEditorWidget | undefined;
|
|
93
110
|
let isNewWidget = false;
|
|
94
111
|
const uriString = uri.toString();
|
|
112
|
+
const preview = this.isPreviewEnabled(options);
|
|
95
113
|
let widgetPromise = this.pendingWidgetPromises.get(uriString);
|
|
96
114
|
if (widgetPromise) {
|
|
97
115
|
widget = await widgetPromise;
|
|
@@ -106,9 +124,16 @@ export class CustomEditorOpener implements OpenHandler {
|
|
|
106
124
|
w.viewType = this.editor.viewType;
|
|
107
125
|
w.resource = uri;
|
|
108
126
|
w.updateID();
|
|
127
|
+
if (preview) {
|
|
128
|
+
w.initializePreview();
|
|
129
|
+
}
|
|
109
130
|
await this.editorRegistry.resolveWidget(w);
|
|
110
131
|
if (options?.widgetOptions) {
|
|
111
132
|
await this.shell.addWidget(w, options.widgetOptions);
|
|
133
|
+
if (preview) {
|
|
134
|
+
// Dispose the superseded preview as soon as the new preview tab attaches.
|
|
135
|
+
PreviewTabWidget.disposeOtherPreviews(this.shell, w);
|
|
136
|
+
}
|
|
112
137
|
}
|
|
113
138
|
return w;
|
|
114
139
|
} catch (e) {
|
|
@@ -120,6 +145,9 @@ export class CustomEditorOpener implements OpenHandler {
|
|
|
120
145
|
widget = await widgetPromise;
|
|
121
146
|
}
|
|
122
147
|
}
|
|
148
|
+
if (!isNewWidget && !preview && widget.isPreview) {
|
|
149
|
+
widget.convertToNonPreview();
|
|
150
|
+
}
|
|
123
151
|
if (options?.mode === 'activate') {
|
|
124
152
|
await this.shell.activateWidget(widget.id);
|
|
125
153
|
} else if (options?.mode === 'reveal') {
|
|
@@ -131,6 +159,10 @@ export class CustomEditorOpener implements OpenHandler {
|
|
|
131
159
|
return widget;
|
|
132
160
|
}
|
|
133
161
|
|
|
162
|
+
protected isPreviewEnabled(options?: EditorOpenerOptions): boolean {
|
|
163
|
+
return !!options?.preview && !!this.preferenceService.get<boolean>(ENABLE_PREVIEW_PREFERENCE);
|
|
164
|
+
}
|
|
165
|
+
|
|
134
166
|
protected async openSideBySide(uri: URI, options?: WidgetOpenerOptions): Promise<Widget | undefined> {
|
|
135
167
|
const [leftUri, rightUri] = DiffUris.decode(uri);
|
|
136
168
|
const widget = await this.widgetManager.getOrCreateWidget<SplitWidget>(
|
|
@@ -200,8 +232,19 @@ export class CustomEditorOpener implements OpenHandler {
|
|
|
200
232
|
}
|
|
201
233
|
|
|
202
234
|
selectorMatches(selector: CustomEditorSelector, resource: URI): boolean {
|
|
235
|
+
if (nonMatchingSchemes.has(resource.scheme)) {
|
|
236
|
+
// These schemes match no glob pattern, mirroring VS Code's `globMatchesResource`.
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
203
239
|
if (selector.filenamePattern) {
|
|
204
|
-
|
|
240
|
+
const filenamePattern = selector.filenamePattern.toLowerCase();
|
|
241
|
+
// Mirror VS Code's editor-association matching (editorResolverService#globMatchesResource):
|
|
242
|
+
// a pattern containing a path separator is matched against the full `scheme:path`,
|
|
243
|
+
// a plain pattern is matched against the basename only.
|
|
244
|
+
const target = filenamePattern.includes('/')
|
|
245
|
+
? `${resource.scheme}:${resource.path.toString()}`.toLowerCase()
|
|
246
|
+
: resource.path.base.toLowerCase();
|
|
247
|
+
if (match(filenamePattern, target)) {
|
|
205
248
|
return true;
|
|
206
249
|
}
|
|
207
250
|
}
|