@theia/plugin-ext 1.34.0 → 1.35.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/common/plugin-api-rpc-model.d.ts +18 -1
- package/lib/common/plugin-api-rpc-model.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc-model.js.map +1 -1
- package/lib/common/plugin-api-rpc.d.ts +11 -6
- package/lib/common/plugin-api-rpc.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc.js.map +1 -1
- package/lib/common/plugin-protocol.d.ts +30 -0
- package/lib/common/plugin-protocol.d.ts.map +1 -1
- package/lib/common/plugin-protocol.js.map +1 -1
- package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/browser/hosted-plugin.js +10 -17
- package/lib/hosted/browser/hosted-plugin.js.map +1 -1
- package/lib/hosted/node/hosted-plugin-process.js.map +1 -1
- package/lib/hosted/node/plugin-activation-events.d.ts +7 -0
- package/lib/hosted/node/plugin-activation-events.d.ts.map +1 -0
- package/lib/hosted/node/plugin-activation-events.js +96 -0
- package/lib/hosted/node/plugin-activation-events.js.map +1 -0
- package/lib/hosted/node/plugin-manifest-loader.d.ts +2 -1
- package/lib/hosted/node/plugin-manifest-loader.d.ts.map +1 -1
- package/lib/hosted/node/plugin-manifest-loader.js +2 -1
- package/lib/hosted/node/plugin-manifest-loader.js.map +1 -1
- package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
- package/lib/hosted/node/scanners/scanner-theia.js +27 -36
- package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
- package/lib/main/browser/data-transfer/data-transfer-type-converters.d.ts +9 -0
- package/lib/main/browser/data-transfer/data-transfer-type-converters.d.ts.map +1 -0
- package/lib/main/browser/data-transfer/data-transfer-type-converters.js +65 -0
- package/lib/main/browser/data-transfer/data-transfer-type-converters.js.map +1 -0
- package/lib/main/browser/dialogs/modal-notification.d.ts.map +1 -1
- package/lib/main/browser/dialogs/modal-notification.js +4 -2
- package/lib/main/browser/dialogs/modal-notification.js.map +1 -1
- package/lib/main/browser/languages-main.d.ts +8 -1
- package/lib/main/browser/languages-main.d.ts.map +1 -1
- package/lib/main/browser/languages-main.js +26 -2
- package/lib/main/browser/languages-main.js.map +1 -1
- package/lib/main/browser/main-context.d.ts.map +1 -1
- package/lib/main/browser/main-context.js +3 -0
- package/lib/main/browser/main-context.js.map +1 -1
- package/lib/main/browser/plugin-ext-frontend-module.d.ts.map +1 -1
- package/lib/main/browser/plugin-ext-frontend-module.js +3 -0
- package/lib/main/browser/plugin-ext-frontend-module.js.map +1 -1
- package/lib/main/browser/tabs/tabs-main.d.ts +33 -2
- package/lib/main/browser/tabs/tabs-main.d.ts.map +1 -1
- package/lib/main/browser/tabs/tabs-main.js +256 -6
- package/lib/main/browser/tabs/tabs-main.js.map +1 -1
- package/lib/main/browser/text-editors-main.d.ts +2 -2
- package/lib/main/browser/text-editors-main.d.ts.map +1 -1
- package/lib/main/browser/text-editors-main.js +2 -2
- package/lib/main/browser/text-editors-main.js.map +1 -1
- package/lib/main/browser/webview/webview-context-keys.d.ts +13 -0
- package/lib/main/browser/webview/webview-context-keys.d.ts.map +1 -0
- package/lib/main/browser/webview/webview-context-keys.js +64 -0
- package/lib/main/browser/webview/webview-context-keys.js.map +1 -0
- package/lib/plugin/dialogs.js +2 -2
- package/lib/plugin/dialogs.js.map +1 -1
- package/lib/plugin/file-system-ext-impl.d.ts +11 -5
- package/lib/plugin/file-system-ext-impl.d.ts.map +1 -1
- package/lib/plugin/file-system-ext-impl.js +8 -16
- package/lib/plugin/file-system-ext-impl.js.map +1 -1
- package/lib/plugin/known-commands.d.ts.map +1 -1
- package/lib/plugin/known-commands.js +13 -0
- package/lib/plugin/known-commands.js.map +1 -1
- package/lib/plugin/languages/document-drop-edit.d.ts +16 -0
- package/lib/plugin/languages/document-drop-edit.d.ts.map +1 -0
- package/lib/plugin/languages/document-drop-edit.js +23 -0
- package/lib/plugin/languages/document-drop-edit.js.map +1 -0
- package/lib/plugin/languages.d.ts +9 -2
- package/lib/plugin/languages.d.ts.map +1 -1
- package/lib/plugin/languages.js +27 -1
- package/lib/plugin/languages.js.map +1 -1
- package/lib/plugin/plugin-context.d.ts.map +1 -1
- package/lib/plugin/plugin-context.js +8 -4
- package/lib/plugin/plugin-context.js.map +1 -1
- package/lib/plugin/preference-registry.d.ts +5 -3
- package/lib/plugin/preference-registry.d.ts.map +1 -1
- package/lib/plugin/preference-registry.js +31 -42
- package/lib/plugin/preference-registry.js.map +1 -1
- package/lib/plugin/preference-registry.spec.js +29 -41
- package/lib/plugin/preference-registry.spec.js.map +1 -1
- package/lib/plugin/tabs.d.ts.map +1 -1
- package/lib/plugin/tabs.js +10 -13
- package/lib/plugin/tabs.js.map +1 -1
- package/lib/plugin/text-editors.d.ts +1 -1
- package/lib/plugin/text-editors.d.ts.map +1 -1
- package/lib/plugin/text-editors.js +2 -2
- package/lib/plugin/text-editors.js.map +1 -1
- package/lib/plugin/type-converters.d.ts +6 -0
- package/lib/plugin/type-converters.d.ts.map +1 -1
- package/lib/plugin/type-converters.js +37 -1
- package/lib/plugin/type-converters.js.map +1 -1
- package/lib/plugin/types-impl.d.ts +5 -0
- package/lib/plugin/types-impl.d.ts.map +1 -1
- package/lib/plugin/types-impl.js +13 -3
- package/lib/plugin/types-impl.js.map +1 -1
- package/package.json +27 -26
- package/src/common/plugin-api-rpc-model.ts +22 -1
- package/src/common/plugin-api-rpc.ts +19 -6
- package/src/common/plugin-protocol.ts +32 -4
- package/src/hosted/browser/hosted-plugin.ts +9 -16
- package/src/hosted/node/hosted-plugin-process.ts +2 -2
- package/src/hosted/node/plugin-activation-events.ts +111 -0
- package/src/hosted/node/plugin-manifest-loader.ts +4 -3
- package/src/hosted/node/scanners/scanner-theia.ts +59 -75
- package/src/main/browser/data-transfer/data-transfer-type-converters.ts +70 -0
- package/src/main/browser/dialogs/modal-notification.ts +4 -2
- package/src/main/browser/languages-main.ts +34 -4
- package/src/main/browser/main-context.ts +4 -0
- package/src/main/browser/plugin-ext-frontend-module.ts +3 -0
- package/src/main/browser/tabs/tabs-main.ts +287 -6
- package/src/main/browser/text-editors-main.ts +3 -2
- package/src/main/browser/webview/webview-context-keys.ts +49 -0
- package/src/plugin/dialogs.ts +2 -2
- package/src/plugin/file-system-ext-impl.ts +8 -18
- package/src/plugin/known-commands.ts +16 -1
- package/src/plugin/languages/document-drop-edit.ts +44 -0
- package/src/plugin/languages.ts +41 -3
- package/src/plugin/plugin-context.ts +9 -4
- package/src/plugin/preference-registry.spec.ts +29 -45
- package/src/plugin/preference-registry.ts +33 -45
- package/src/plugin/tabs.ts +10 -14
- package/src/plugin/text-editors.ts +2 -2
- package/src/plugin/type-converters.ts +37 -0
- package/src/plugin/types-impl.ts +11 -0
|
@@ -87,6 +87,7 @@ import {
|
|
|
87
87
|
DocumentHighlightKind,
|
|
88
88
|
DocumentHighlight,
|
|
89
89
|
DocumentLink,
|
|
90
|
+
DocumentDropEdit,
|
|
90
91
|
CodeLens,
|
|
91
92
|
CodeActionKind,
|
|
92
93
|
CodeActionTrigger,
|
|
@@ -257,11 +258,11 @@ export function createAPIFactory(
|
|
|
257
258
|
const statusBarMessageRegistryExt = new StatusBarMessageRegistryExt(rpc);
|
|
258
259
|
const terminalExt = rpc.set(MAIN_RPC_CONTEXT.TERMINAL_EXT, new TerminalServiceExtImpl(rpc));
|
|
259
260
|
const outputChannelRegistryExt = rpc.set(MAIN_RPC_CONTEXT.OUTPUT_CHANNEL_REGISTRY_EXT, new OutputChannelRegistryExtImpl(rpc));
|
|
260
|
-
const languagesExt = rpc.set(MAIN_RPC_CONTEXT.LANGUAGES_EXT, new LanguagesExtImpl(rpc, documents, commandRegistry));
|
|
261
261
|
const treeViewsExt = rpc.set(MAIN_RPC_CONTEXT.TREE_VIEWS_EXT, new TreeViewsExtImpl(rpc, commandRegistry));
|
|
262
262
|
const tasksExt = rpc.set(MAIN_RPC_CONTEXT.TASKS_EXT, new TasksExtImpl(rpc, terminalExt));
|
|
263
263
|
const connectionExt = rpc.set(MAIN_RPC_CONTEXT.CONNECTION_EXT, new ConnectionImpl(rpc.getProxy(PLUGIN_RPC_CONTEXT.CONNECTION_MAIN)));
|
|
264
|
-
const fileSystemExt = rpc.set(MAIN_RPC_CONTEXT.FILE_SYSTEM_EXT, new FileSystemExtImpl(rpc
|
|
264
|
+
const fileSystemExt = rpc.set(MAIN_RPC_CONTEXT.FILE_SYSTEM_EXT, new FileSystemExtImpl(rpc));
|
|
265
|
+
const languagesExt = rpc.set(MAIN_RPC_CONTEXT.LANGUAGES_EXT, new LanguagesExtImpl(rpc, documents, commandRegistry, fileSystemExt));
|
|
265
266
|
const extHostFileSystemEvent = rpc.set(MAIN_RPC_CONTEXT.ExtHostFileSystemEventService, new ExtHostFileSystemEventService(rpc, editorsAndDocumentsExt));
|
|
266
267
|
const scmExt = rpc.set(MAIN_RPC_CONTEXT.SCM_EXT, new ScmExtImpl(rpc, commandRegistry));
|
|
267
268
|
const decorationsExt = rpc.set(MAIN_RPC_CONTEXT.DECORATIONS_EXT, new DecorationsExtImpl(rpc));
|
|
@@ -669,8 +670,8 @@ export function createAPIFactory(
|
|
|
669
670
|
saveAll(includeUntitled?: boolean): PromiseLike<boolean> {
|
|
670
671
|
return editors.saveAll(includeUntitled);
|
|
671
672
|
},
|
|
672
|
-
applyEdit(edit: theia.WorkspaceEdit): PromiseLike<boolean> {
|
|
673
|
-
return editors.applyWorkspaceEdit(edit);
|
|
673
|
+
applyEdit(edit: theia.WorkspaceEdit, metadata?: theia.WorkspaceEditMetadata): PromiseLike<boolean> {
|
|
674
|
+
return editors.applyWorkspaceEdit(edit, metadata);
|
|
674
675
|
},
|
|
675
676
|
registerTextDocumentContentProvider(scheme: string, provider: theia.TextDocumentContentProvider): theia.Disposable {
|
|
676
677
|
return workspaceExt.registerTextDocumentContentProvider(scheme, provider);
|
|
@@ -853,6 +854,9 @@ export function createAPIFactory(
|
|
|
853
854
|
): theia.Disposable {
|
|
854
855
|
return languagesExt.registerOnTypeFormattingEditProvider(selector, provider, [firstTriggerCharacter].concat(moreTriggerCharacters), pluginToPluginInfo(plugin));
|
|
855
856
|
},
|
|
857
|
+
registerDocumentDropEditProvider(selector: theia.DocumentSelector, provider: theia.DocumentDropEditProvider) {
|
|
858
|
+
return languagesExt.registerDocumentDropEditProvider(selector, provider);
|
|
859
|
+
},
|
|
856
860
|
registerDocumentLinkProvider(selector: theia.DocumentSelector, provider: theia.DocumentLinkProvider): theia.Disposable {
|
|
857
861
|
return languagesExt.registerDocumentLinkProvider(selector, provider, pluginToPluginInfo(plugin));
|
|
858
862
|
},
|
|
@@ -1195,6 +1199,7 @@ export function createAPIFactory(
|
|
|
1195
1199
|
DocumentHighlightKind,
|
|
1196
1200
|
DocumentHighlight,
|
|
1197
1201
|
DocumentLink,
|
|
1202
|
+
DocumentDropEdit,
|
|
1198
1203
|
CodeLens,
|
|
1199
1204
|
CodeActionKind,
|
|
1200
1205
|
CodeActionTrigger,
|
|
@@ -41,36 +41,6 @@ describe('PreferenceRegistryExtImpl:', () => {
|
|
|
41
41
|
preferenceRegistryExtImpl = new PreferenceRegistryExtImpl(mockRPC, mockWorkspace);
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
-
it('should parse configuration data without overrides', () => {
|
|
45
|
-
const value: Record<string, any> = {
|
|
46
|
-
'my.key1.foo': 'value1',
|
|
47
|
-
'my.key1.bar': 'value2',
|
|
48
|
-
};
|
|
49
|
-
const result = preferenceRegistryExtImpl['parseConfigurationData'](value);
|
|
50
|
-
expect(result.contents.my).to.be.an('object');
|
|
51
|
-
expect(result.contents.my.key1).to.be.an('object');
|
|
52
|
-
|
|
53
|
-
expect(result.contents.my.key1.foo).to.be.an('string');
|
|
54
|
-
expect(result.contents.my.key1.foo).to.equal('value1');
|
|
55
|
-
|
|
56
|
-
expect(result.contents.my.key1.bar).to.be.an('string');
|
|
57
|
-
expect(result.contents.my.key1.bar).to.equal('value2');
|
|
58
|
-
expect(result.keys).deep.equal(['my.key1.foo', 'my.key1.bar']);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('should parse configuration with overrides', () => {
|
|
62
|
-
const value: Record<string, any> = {
|
|
63
|
-
'editor.tabSize': 2,
|
|
64
|
-
'[typescript].editor.tabSize': 4,
|
|
65
|
-
};
|
|
66
|
-
const result = preferenceRegistryExtImpl['parseConfigurationData'](value);
|
|
67
|
-
expect(result.contents.editor.tabSize).to.equal(2);
|
|
68
|
-
const tsOverride = result.overrides[0];
|
|
69
|
-
expect(tsOverride.contents.editor.tabSize).to.equal(4);
|
|
70
|
-
expect(tsOverride.identifiers).deep.equal(['typescript']);
|
|
71
|
-
expect(tsOverride.keys).deep.equal(['editor.tabSize']);
|
|
72
|
-
});
|
|
73
|
-
|
|
74
44
|
describe('Prototype pollution', () => {
|
|
75
45
|
it('Ignores key `__proto__`', () => {
|
|
76
46
|
const value: Record<string, any> = {
|
|
@@ -80,16 +50,18 @@ describe('PreferenceRegistryExtImpl:', () => {
|
|
|
80
50
|
'__proto__': {},
|
|
81
51
|
'[typescript].someKey.foo': 'value',
|
|
82
52
|
'[typescript].__proto__.injectedParsedPrototype': true,
|
|
53
|
+
'b': { '__proto__.injectedParsedPrototype': true },
|
|
54
|
+
'c': { '__proto__': { 'injectedParsedPrototype': true } }
|
|
83
55
|
};
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
expect(result.
|
|
87
|
-
expect(result.
|
|
88
|
-
expect(result.
|
|
56
|
+
const configuration = preferenceRegistryExtImpl['getConfigurationModel']('test', value);
|
|
57
|
+
const result = configuration['_contents'];
|
|
58
|
+
expect(result.my, 'Safe keys are preserved.').to.be.an('object');
|
|
59
|
+
expect(result.__proto__, 'Keys containing __proto__ are ignored').to.be.an('undefined');
|
|
60
|
+
expect(result.my.key1.foo, 'Safe keys are dendrified.').to.equal('value1');
|
|
89
61
|
const prototypeObject = Object.prototype as any;
|
|
90
|
-
expect(prototypeObject.injectedParsedPrototype).to.be.an('undefined');
|
|
62
|
+
expect(prototypeObject.injectedParsedPrototype, 'Object.prototype is unaffected').to.be.an('undefined');
|
|
91
63
|
const rawObject = {} as any;
|
|
92
|
-
expect(rawObject.injectedParsedPrototype).to.be.an('undefined');
|
|
64
|
+
expect(rawObject.injectedParsedPrototype, 'Instantiated objects are unaffected.').to.be.an('undefined');
|
|
93
65
|
});
|
|
94
66
|
|
|
95
67
|
it('Ignores key `constructor.prototype`', () => {
|
|
@@ -98,17 +70,19 @@ describe('PreferenceRegistryExtImpl:', () => {
|
|
|
98
70
|
'a.constructor.prototype.injectedParsedConstructorPrototype': true,
|
|
99
71
|
'constructor.prototype.injectedParsedConstructorPrototype': true,
|
|
100
72
|
'[python].some.key.foo': 'value',
|
|
101
|
-
'[python].a.constructor.prototype.injectedParsedConstructorPrototype': true
|
|
73
|
+
'[python].a.constructor.prototype.injectedParsedConstructorPrototype': true,
|
|
74
|
+
'constructor': { 'prototype.injectedParsedConstructorPrototype': true },
|
|
75
|
+
'b': { 'constructor': { 'prototype': { 'injectedParsedConstructorPrototype': true } } }
|
|
102
76
|
};
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
expect(result.
|
|
106
|
-
expect(result.
|
|
77
|
+
const configuration = preferenceRegistryExtImpl['getConfigurationModel']('test', value);
|
|
78
|
+
const result = configuration['_contents'];
|
|
79
|
+
expect(result.my, 'Safe keys are preserved').to.be.an('object');
|
|
80
|
+
expect(result.__proto__, 'Keys containing __proto__ are ignored').to.be.an('undefined');
|
|
81
|
+
expect(result.my.key1.foo, 'Safe keys are dendrified.').to.equal('value1');
|
|
107
82
|
const prototypeObject = Object.prototype as any;
|
|
108
|
-
expect(prototypeObject.injectedParsedConstructorPrototype).to.be.an('undefined');
|
|
109
|
-
expect(result.overrides[0].contents.__proto__).to.be.an('undefined');
|
|
83
|
+
expect(prototypeObject.injectedParsedConstructorPrototype, 'Object.prototype is unaffected').to.be.an('undefined');
|
|
110
84
|
const rawObject = {} as any;
|
|
111
|
-
expect(rawObject.injectedParsedConstructorPrototype).to.be.an('undefined');
|
|
85
|
+
expect(rawObject.injectedParsedConstructorPrototype, 'Instantiated objects are unaffected.').to.be.an('undefined');
|
|
112
86
|
});
|
|
113
87
|
});
|
|
114
88
|
|
|
@@ -250,6 +224,16 @@ describe('PreferenceRegistryExtImpl:', () => {
|
|
|
250
224
|
const valuesRetrieved = preferenceRegistryExtImpl.getConfiguration(undefined, { uri: workspaceRoot, languageId: 'python' }).get('editor') as Record<string, unknown>;
|
|
251
225
|
expect(valuesRetrieved.tabSize).equal(4);
|
|
252
226
|
});
|
|
227
|
+
it('Allows access to language overrides in bracket form', () => {
|
|
228
|
+
const pythonOverrides = preferenceRegistryExtImpl.getConfiguration().get<Record<string, any>>('[python]');
|
|
229
|
+
expect(pythonOverrides).not.to.be.undefined;
|
|
230
|
+
expect(pythonOverrides?.['editor.renderWhitespace']).equal('all');
|
|
231
|
+
});
|
|
232
|
+
// https://github.com/eclipse-theia/theia/issues/12043
|
|
233
|
+
it('Allows access to preferences without specifying the section', () => {
|
|
234
|
+
const inspection = preferenceRegistryExtImpl.getConfiguration().inspect('editor.fontSize');
|
|
235
|
+
expect(inspection?.defaultValue).equal(14);
|
|
236
|
+
});
|
|
253
237
|
});
|
|
254
238
|
|
|
255
239
|
describe('Proxy Behavior', () => {
|
|
@@ -20,8 +20,8 @@ import { Emitter, Event } from '@theia/core/lib/common/event';
|
|
|
20
20
|
import { isOSX, isWindows } from '@theia/core/lib/common/os';
|
|
21
21
|
import { URI } from '@theia/core/shared/vscode-uri';
|
|
22
22
|
import { ResourceMap } from '@theia/monaco-editor-core/esm/vs/base/common/map';
|
|
23
|
-
import { IConfigurationOverrides
|
|
24
|
-
import { Configuration, ConfigurationModel } from '@theia/monaco-editor-core/esm/vs/platform/configuration/common/configurationModels';
|
|
23
|
+
import { IConfigurationOverrides } from '@theia/monaco-editor-core/esm/vs/platform/configuration/common/configuration';
|
|
24
|
+
import { Configuration, ConfigurationModel, ConfigurationModelParser } from '@theia/monaco-editor-core/esm/vs/platform/configuration/common/configurationModels';
|
|
25
25
|
import { Workspace, WorkspaceFolder } from '@theia/monaco-editor-core/esm/vs/platform/workspace/common/workspace';
|
|
26
26
|
import * as theia from '@theia/plugin';
|
|
27
27
|
import { v4 } from 'uuid';
|
|
@@ -234,12 +234,12 @@ export class PreferenceRegistryExtImpl implements PreferenceRegistryExt {
|
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
private parse(data: PreferenceData): Configuration {
|
|
237
|
-
const defaultConfiguration = this.getConfigurationModel(data[PreferenceScope.Default]);
|
|
238
|
-
const userConfiguration = this.getConfigurationModel(data[PreferenceScope.User]);
|
|
239
|
-
const workspaceConfiguration = this.getConfigurationModel(data[PreferenceScope.Workspace]);
|
|
237
|
+
const defaultConfiguration = this.getConfigurationModel('Default', data[PreferenceScope.Default]);
|
|
238
|
+
const userConfiguration = this.getConfigurationModel('User', data[PreferenceScope.User]);
|
|
239
|
+
const workspaceConfiguration = this.getConfigurationModel('Workspace', data[PreferenceScope.Workspace]);
|
|
240
240
|
const folderConfigurations = new ResourceMap<ConfigurationModel>();
|
|
241
241
|
Object.keys(data[PreferenceScope.Folder]).forEach(resource => {
|
|
242
|
-
folderConfigurations.set(URI.parse(resource), this.getConfigurationModel(data[PreferenceScope.Folder][resource]));
|
|
242
|
+
folderConfigurations.set(URI.parse(resource), this.getConfigurationModel(`Folder: ${resource}`, data[PreferenceScope.Folder][resource]));
|
|
243
243
|
});
|
|
244
244
|
return new Configuration(
|
|
245
245
|
defaultConfiguration,
|
|
@@ -252,53 +252,41 @@ export class PreferenceRegistryExtImpl implements PreferenceRegistryExt {
|
|
|
252
252
|
);
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
private getConfigurationModel(data: { [key: string]: any }): ConfigurationModel {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
return new ConfigurationModel(configData.contents, configData.keys, configData.overrides);
|
|
255
|
+
private getConfigurationModel(label: string, data: { [key: string]: any }): ConfigurationModel {
|
|
256
|
+
const parser = new ConfigurationModelParser(label);
|
|
257
|
+
const sanitized = this.sanitize(data);
|
|
258
|
+
parser.parseRaw(sanitized);
|
|
259
|
+
return parser.configurationModel;
|
|
261
260
|
}
|
|
262
261
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
private
|
|
268
|
-
|
|
269
|
-
const
|
|
270
|
-
const
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
280
|
-
for (let i = 0; i < parts.length; i++) {
|
|
281
|
-
if (i === 0 && isOverride) {
|
|
282
|
-
const identifier = this.OVERRIDE_PROPERTY_PATTERN.exec(parts[i])![1];
|
|
283
|
-
if (!overrides[identifier]) {
|
|
284
|
-
overrides[identifier] = { keys: [], identifiers: [identifier], contents: Object.create(null) };
|
|
262
|
+
/**
|
|
263
|
+
* Creates a new object and assigns those keys of raw to it that are not likely to cause prototype polution.
|
|
264
|
+
* Also preprocesses override identifiers so that they take the form [identifier]: {...contents}.
|
|
265
|
+
*/
|
|
266
|
+
private sanitize<T = unknown>(raw: T): T {
|
|
267
|
+
if (!isObject(raw)) { return raw; }
|
|
268
|
+
const asObject = raw as Record<string, unknown>;
|
|
269
|
+
const sanitized = Object.create(null);
|
|
270
|
+
for (const key of Object.keys(asObject)) {
|
|
271
|
+
if (!injectionRe.test(key)) {
|
|
272
|
+
const override = this.OVERRIDE_KEY_TEST.exec(key);
|
|
273
|
+
if (override) {
|
|
274
|
+
const overrideKey = `[${override[1]}]`;
|
|
275
|
+
const remainder = key.slice(override[0].length);
|
|
276
|
+
if (!isObject(sanitized[overrideKey])) {
|
|
277
|
+
sanitized[overrideKey] = Object.create(null);
|
|
285
278
|
}
|
|
286
|
-
|
|
287
|
-
overrides[identifier].keys.push(key.slice(parts[i].length + 1));
|
|
288
|
-
} else if (i === parts.length - 1) {
|
|
289
|
-
branch[parts[i]] = data[key];
|
|
279
|
+
sanitized[overrideKey][remainder] = this.sanitize(asObject[key]);
|
|
290
280
|
} else {
|
|
291
|
-
|
|
292
|
-
branch[parts[i]] = Object.create(null);
|
|
293
|
-
}
|
|
294
|
-
branch = branch[parts[i]];
|
|
281
|
+
sanitized[key] = this.sanitize(asObject[key]);
|
|
295
282
|
}
|
|
296
283
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
return { contents, keys, overrides: Object.values(overrides) };
|
|
284
|
+
}
|
|
285
|
+
return sanitized;
|
|
300
286
|
}
|
|
301
287
|
|
|
288
|
+
private readonly OVERRIDE_KEY_TEST = /^\[([^\]]+)\]\./;
|
|
289
|
+
|
|
302
290
|
private toConfigurationChangeEvent(eventData: PreferenceChangeExt[]): theia.ConfigurationChangeEvent {
|
|
303
291
|
return Object.freeze({
|
|
304
292
|
affectsConfiguration: (section: string, scope?: theia.ConfigurationScope): boolean => {
|
package/src/plugin/tabs.ts
CHANGED
|
@@ -291,14 +291,6 @@ export class TabsExtImpl implements TabsExt {
|
|
|
291
291
|
return this._closeTabs(tabsOrTabGroups as theia.Tab[], preserveFocus);
|
|
292
292
|
}
|
|
293
293
|
},
|
|
294
|
-
// move: async (tab: theia.Tab, viewColumn: ViewColumn, index: number, preserveFocus?: boolean) => {
|
|
295
|
-
// const extHostTab = this._findExtHostTabFromApi(tab);
|
|
296
|
-
// if (!extHostTab) {
|
|
297
|
-
// throw new Error('Invalid tab');
|
|
298
|
-
// }
|
|
299
|
-
// this._proxy.$moveTab(extHostTab.tabId, index, typeConverters.ViewColumn.from(viewColumn), preserveFocus);
|
|
300
|
-
// return;
|
|
301
|
-
// }
|
|
302
294
|
};
|
|
303
295
|
this.apiObject = Object.freeze(obj);
|
|
304
296
|
}
|
|
@@ -306,7 +298,6 @@ export class TabsExtImpl implements TabsExt {
|
|
|
306
298
|
}
|
|
307
299
|
|
|
308
300
|
$acceptEditorTabModel(tabGroups: TabGroupDto[]): void {
|
|
309
|
-
|
|
310
301
|
const groupIdsBefore = new Set(this.tabGroupArr.map(group => group.groupId));
|
|
311
302
|
const groupIdsAfter = new Set(tabGroups.map(dto => dto.groupId));
|
|
312
303
|
const diff = diffSets(groupIdsBefore, groupIdsAfter);
|
|
@@ -314,23 +305,28 @@ export class TabsExtImpl implements TabsExt {
|
|
|
314
305
|
const closed: theia.TabGroup[] = this.tabGroupArr.filter(group => diff.removed.includes(group.groupId)).map(group => group.apiObject);
|
|
315
306
|
const opened: theia.TabGroup[] = [];
|
|
316
307
|
const changed: theia.TabGroup[] = [];
|
|
308
|
+
const tabsOpened: theia.Tab[] = [];
|
|
317
309
|
|
|
318
310
|
this.tabGroupArr = tabGroups.map(tabGroup => {
|
|
319
311
|
const group = new TabGroupExt(tabGroup, () => this.activeGroupId);
|
|
320
312
|
if (diff.added.includes(group.groupId)) {
|
|
321
|
-
opened.push(group.apiObject);
|
|
313
|
+
opened.push({ activeTab: undefined, isActive: group.apiObject.isActive, tabs: [], viewColumn: group.apiObject.viewColumn });
|
|
314
|
+
tabsOpened.push(...group.apiObject.tabs);
|
|
322
315
|
} else {
|
|
323
316
|
changed.push(group.apiObject);
|
|
324
317
|
}
|
|
325
318
|
return group;
|
|
326
319
|
});
|
|
327
320
|
|
|
328
|
-
// Set the active tab group id
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
this.activeGroupId
|
|
321
|
+
// Set the active tab group id. skip if no tabgroups are open
|
|
322
|
+
if (tabGroups.length > 0) {
|
|
323
|
+
const activeTabGroupId = assertIsDefined(tabGroups.find(group => group.isActive === true)?.groupId);
|
|
324
|
+
if (this.activeGroupId !== activeTabGroupId) {
|
|
325
|
+
this.activeGroupId = activeTabGroupId;
|
|
326
|
+
}
|
|
332
327
|
}
|
|
333
328
|
this.onDidChangeTabGroups.fire(Object.freeze({ opened, closed, changed }));
|
|
329
|
+
this.onDidChangeTabs.fire({ opened: tabsOpened, changed: [], closed: [] });
|
|
334
330
|
}
|
|
335
331
|
|
|
336
332
|
$acceptTabGroupUpdate(groupDto: TabGroupDto): void {
|
|
@@ -119,9 +119,9 @@ export class TextEditorsExtImpl implements TextEditorsExt {
|
|
|
119
119
|
return new TextEditorDecorationType(this.proxy, options);
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
applyWorkspaceEdit(edit: theia.WorkspaceEdit): Promise<boolean> {
|
|
122
|
+
applyWorkspaceEdit(edit: theia.WorkspaceEdit, metadata?: theia.WorkspaceEditMetadata): Promise<boolean> {
|
|
123
123
|
const dto = Converters.fromWorkspaceEdit(edit, this.editorsAndDocuments);
|
|
124
|
-
return this.proxy.$tryApplyWorkspaceEdit(dto);
|
|
124
|
+
return this.proxy.$tryApplyWorkspaceEdit(dto, metadata);
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
saveAll(includeUntitled?: boolean): PromiseLike<boolean> {
|
|
@@ -1348,3 +1348,40 @@ export namespace InlayHintKind {
|
|
|
1348
1348
|
return kind;
|
|
1349
1349
|
}
|
|
1350
1350
|
}
|
|
1351
|
+
|
|
1352
|
+
export namespace DataTransferItem {
|
|
1353
|
+
export function to(mime: string, item: model.DataTransferItemDTO, resolveFileData: (itemId: string) => Promise<Uint8Array>): theia.DataTransferItem {
|
|
1354
|
+
const file = item.fileData;
|
|
1355
|
+
if (file) {
|
|
1356
|
+
return new class extends types.DataTransferItem {
|
|
1357
|
+
override asFile(): theia.DataTransferFile {
|
|
1358
|
+
return {
|
|
1359
|
+
name: file.name,
|
|
1360
|
+
uri: URI.revive(file.uri),
|
|
1361
|
+
data: () => resolveFileData(item.id),
|
|
1362
|
+
};
|
|
1363
|
+
}
|
|
1364
|
+
}('');
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
if (mime === 'text/uri-list' && item.uriListData) {
|
|
1368
|
+
return new types.DataTransferItem(reviveUriList(item.uriListData));
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
return new types.DataTransferItem(item.asString);
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
function reviveUriList(parts: ReadonlyArray<string | UriComponents>): string {
|
|
1375
|
+
return parts.map(part => typeof part === 'string' ? part : URI.revive(part).toString()).join('\r\n');
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
export namespace DataTransfer {
|
|
1380
|
+
export function toDataTransfer(value: model.DataTransferDTO, resolveFileData: (itemId: string) => Promise<Uint8Array>): theia.DataTransfer {
|
|
1381
|
+
const dataTransfer = new types.DataTransfer();
|
|
1382
|
+
for (const [mimeType, item] of value.items) {
|
|
1383
|
+
dataTransfer.set(mimeType, DataTransferItem.to(mimeType, item, resolveFileData));
|
|
1384
|
+
}
|
|
1385
|
+
return dataTransfer;
|
|
1386
|
+
}
|
|
1387
|
+
}
|
package/src/plugin/types-impl.ts
CHANGED
|
@@ -1530,6 +1530,17 @@ export class DocumentLink {
|
|
|
1530
1530
|
}
|
|
1531
1531
|
}
|
|
1532
1532
|
|
|
1533
|
+
@es5ClassCompat
|
|
1534
|
+
export class DocumentDropEdit {
|
|
1535
|
+
insertText: string | SnippetString;
|
|
1536
|
+
|
|
1537
|
+
additionalEdit?: WorkspaceEdit;
|
|
1538
|
+
|
|
1539
|
+
constructor(insertText: string | SnippetString) {
|
|
1540
|
+
this.insertText = insertText;
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1533
1544
|
@es5ClassCompat
|
|
1534
1545
|
export class CodeLens {
|
|
1535
1546
|
|