@theia/preferences 1.59.0 → 1.60.0-next.47
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/browser/util/preference-layout.d.ts.map +1 -1
- package/lib/browser/util/preference-layout.js +73 -1
- package/lib/browser/util/preference-layout.js.map +1 -1
- package/lib/browser/util/preference-tree-generator.d.ts +6 -0
- package/lib/browser/util/preference-tree-generator.d.ts.map +1 -1
- package/lib/browser/util/preference-tree-generator.js +37 -23
- package/lib/browser/util/preference-tree-generator.js.map +1 -1
- package/lib/browser/util/preference-tree-label-provider.d.ts +1 -1
- package/lib/browser/util/preference-tree-label-provider.d.ts.map +1 -1
- package/lib/browser/util/preference-tree-label-provider.js.map +1 -1
- package/lib/browser/util/preference-types.d.ts +1 -1
- package/lib/browser/util/preference-types.d.ts.map +1 -1
- package/lib/browser/views/components/preference-json-input.d.ts +1 -1
- package/lib/browser/views/components/preference-json-input.d.ts.map +1 -1
- package/lib/browser/views/components/preference-node-renderer.d.ts +1 -1
- package/lib/browser/views/components/preference-node-renderer.d.ts.map +1 -1
- package/lib/browser/views/components/preference-null-input.d.ts +16 -0
- package/lib/browser/views/components/preference-null-input.d.ts.map +1 -0
- package/lib/browser/views/components/preference-null-input.js +59 -0
- package/lib/browser/views/components/preference-null-input.js.map +1 -0
- package/lib/browser/views/components/preference-number-input.d.ts.map +1 -1
- package/lib/browser/views/components/preference-number-input.js +44 -8
- package/lib/browser/views/components/preference-number-input.js.map +1 -1
- package/lib/browser/views/components/preference-select-input.d.ts +1 -1
- package/lib/browser/views/components/preference-select-input.d.ts.map +1 -1
- package/lib/browser/views/preference-editor-widget.d.ts +3 -0
- package/lib/browser/views/preference-editor-widget.d.ts.map +1 -1
- package/lib/browser/views/preference-editor-widget.js +15 -2
- package/lib/browser/views/preference-editor-widget.js.map +1 -1
- package/lib/browser/views/preference-scope-tabbar-widget.d.ts +1 -1
- package/lib/browser/views/preference-scope-tabbar-widget.d.ts.map +1 -1
- package/lib/browser/views/preference-scope-tabbar-widget.js +1 -1
- package/lib/browser/views/preference-scope-tabbar-widget.js.map +1 -1
- package/lib/browser/views/preference-widget-bindings.d.ts.map +1 -1
- package/lib/browser/views/preference-widget-bindings.js +3 -0
- package/lib/browser/views/preference-widget-bindings.js.map +1 -1
- package/package.json +8 -8
- package/src/browser/style/index.css +7 -10
- package/src/browser/util/preference-layout.ts +74 -1
- package/src/browser/util/preference-tree-generator.ts +38 -22
- package/src/browser/util/preference-tree-label-provider.ts +1 -1
- package/src/browser/util/preference-types.ts +1 -1
- package/src/browser/views/components/preference-json-input.ts +1 -1
- package/src/browser/views/components/preference-node-renderer.ts +1 -1
- package/src/browser/views/components/preference-null-input.ts +52 -0
- package/src/browser/views/components/preference-number-input.ts +43 -7
- package/src/browser/views/components/preference-select-input.ts +1 -1
- package/src/browser/views/preference-editor-widget.ts +13 -2
- package/src/browser/views/preference-scope-tabbar-widget.tsx +1 -1
- package/src/browser/views/preference-widget-bindings.ts +3 -0
|
@@ -18,7 +18,7 @@ import { PreferenceLeafNodeRenderer, PreferenceNodeRenderer } from './preference
|
|
|
18
18
|
import { injectable, inject, interfaces } from '@theia/core/shared/inversify';
|
|
19
19
|
import { CommandService, nls } from '@theia/core/lib/common';
|
|
20
20
|
import { Preference, PreferencesCommands } from '../../util/preference-types';
|
|
21
|
-
import { JSONValue } from '@theia/core/shared/@
|
|
21
|
+
import { JSONValue } from '@theia/core/shared/@lumino/coreutils';
|
|
22
22
|
import { PreferenceLeafNodeRendererContribution } from './preference-node-renderer-creator';
|
|
23
23
|
|
|
24
24
|
@injectable()
|
|
@@ -23,7 +23,7 @@ import { Preference, PreferenceMenus } from '../../util/preference-types';
|
|
|
23
23
|
import { PreferenceTreeLabelProvider } from '../../util/preference-tree-label-provider';
|
|
24
24
|
import { PreferencesScopeTabBar } from '../preference-scope-tabbar-widget';
|
|
25
25
|
import { Disposable, nls } from '@theia/core/lib/common';
|
|
26
|
-
import { JSONValue } from '@theia/core/shared/@
|
|
26
|
+
import { JSONValue } from '@theia/core/shared/@lumino/coreutils';
|
|
27
27
|
import debounce = require('@theia/core/shared/lodash.debounce');
|
|
28
28
|
import { PreferenceTreeModel } from '../../preference-tree-model';
|
|
29
29
|
import { PreferencesSearchbarWidget } from '../preference-searchbar-widget';
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 EclipseSource GmbH 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 { injectable, interfaces } from '@theia/core/shared/inversify';
|
|
18
|
+
import { PreferenceLeafNodeRenderer, PreferenceNodeRenderer } from './preference-node-renderer';
|
|
19
|
+
import { Preference } from '../../util/preference-types';
|
|
20
|
+
import { PreferenceLeafNodeRendererContribution } from './preference-node-renderer-creator';
|
|
21
|
+
|
|
22
|
+
@injectable()
|
|
23
|
+
/** For rendering preference items for which the only interesting feature is the description */
|
|
24
|
+
export class PreferenceNullInputRenderer extends PreferenceLeafNodeRenderer<null, HTMLElement> {
|
|
25
|
+
protected override createInteractable(container: HTMLElement): void {
|
|
26
|
+
const span = document.createElement('span');
|
|
27
|
+
this.interactable = span;
|
|
28
|
+
container.appendChild(span);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
protected override getFallbackValue(): null {
|
|
32
|
+
// eslint-disable-next-line no-null/no-null
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
protected override doHandleValueChange(): void { }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@injectable()
|
|
40
|
+
export class PreferenceNullRendererContribution extends PreferenceLeafNodeRendererContribution {
|
|
41
|
+
static ID = 'preference-null-renderer';
|
|
42
|
+
id = PreferenceNullRendererContribution.ID;
|
|
43
|
+
|
|
44
|
+
canHandleLeafNode(node: Preference.LeafNode): number {
|
|
45
|
+
const isOnlyNull = node.preference.data.type === 'null' || Array.isArray(node.preference.data.type) && node.preference.data.type.every(candidate => candidate === 'null');
|
|
46
|
+
return isOnlyNull ? 5 : 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
createLeafNodeRenderer(container: interfaces.Container): PreferenceNodeRenderer {
|
|
50
|
+
return container.get(PreferenceNullInputRenderer);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import { nls } from '@theia/core';
|
|
17
|
+
import { nls, isBoolean, isNumber } from '@theia/core';
|
|
18
18
|
import { injectable, interfaces } from '@theia/core/shared/inversify';
|
|
19
19
|
import { Preference } from '../../util/preference-types';
|
|
20
20
|
import { PreferenceLeafNodeRenderer, PreferenceNodeRenderer } from './preference-node-renderer';
|
|
@@ -105,15 +105,51 @@ export class PreferenceNumberInputRenderer extends PreferenceLeafNodeRenderer<nu
|
|
|
105
105
|
if (input === '' || isNaN(inputValue)) {
|
|
106
106
|
return { value: NaN, message: nls.localizeByDefault('Value must be a number.') };
|
|
107
107
|
}
|
|
108
|
-
if (data.minimum && inputValue < data.minimum) {
|
|
109
|
-
errorMessages.push(nls.localizeByDefault('Value must be greater than or equal to {0}.', data.minimum));
|
|
110
|
-
};
|
|
111
|
-
if (data.maximum && inputValue > data.maximum) {
|
|
112
|
-
errorMessages.push(nls.localizeByDefault('Value must be less than or equal to {0}.', data.maximum));
|
|
113
|
-
};
|
|
114
108
|
if (data.type === 'integer' && !Number.isInteger(inputValue)) {
|
|
115
109
|
errorMessages.push(nls.localizeByDefault('Value must be an integer.'));
|
|
116
110
|
}
|
|
111
|
+
if (data.minimum !== undefined && isFinite(data.minimum)) {
|
|
112
|
+
// https://json-schema.org/understanding-json-schema/reference/numeric
|
|
113
|
+
// "In JSON Schema Draft 4, exclusiveMinimum and exclusiveMaximum work differently.
|
|
114
|
+
// There they are boolean values, that indicate whether minimum and maximum are exclusive of the value"
|
|
115
|
+
if (isBoolean(data.exclusiveMinimum) && data.exclusiveMinimum) {
|
|
116
|
+
if (inputValue <= data.minimum) {
|
|
117
|
+
errorMessages.push(nls.localizeByDefault('Value must be strictly greater than {0}.', data.minimum));
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
if (inputValue < data.minimum) {
|
|
121
|
+
errorMessages.push(nls.localizeByDefault('Value must be greater than or equal to {0}.', data.minimum));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (data.maximum !== undefined && isFinite(data.maximum)) {
|
|
126
|
+
// https://json-schema.org/understanding-json-schema/reference/numeric
|
|
127
|
+
// "In JSON Schema Draft 4, exclusiveMinimum and exclusiveMaximum work differently.
|
|
128
|
+
// There they are boolean values, that indicate whether minimum and maximum are exclusive of the value"
|
|
129
|
+
if (isBoolean(data.exclusiveMaximum) && data.exclusiveMaximum) {
|
|
130
|
+
if (inputValue >= data.maximum) {
|
|
131
|
+
errorMessages.push(nls.localizeByDefault('Value must be strictly less than {0}.', data.maximum));
|
|
132
|
+
}
|
|
133
|
+
} else {
|
|
134
|
+
if (inputValue > data.maximum) {
|
|
135
|
+
errorMessages.push(nls.localizeByDefault('Value must be less than or equal to {0}.', data.maximum));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Using JSON Schema before Draft 4 both exclusive and non-exclusive variants can be set
|
|
140
|
+
if (isNumber(data.exclusiveMinimum) && isFinite(data.exclusiveMinimum)) {
|
|
141
|
+
if (inputValue <= data.exclusiveMinimum) {
|
|
142
|
+
errorMessages.push(nls.localizeByDefault('Value must be strictly greater than {0}.', data.exclusiveMinimum));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (isNumber(data.exclusiveMaximum) && isFinite(data.exclusiveMaximum)) {
|
|
146
|
+
if (inputValue >= data.exclusiveMaximum) {
|
|
147
|
+
errorMessages.push(nls.localizeByDefault('Value must be strictly less than {0}.', data.exclusiveMaximum));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (isNumber(data.multipleOf) && data.multipleOf !== 0 && !Number.isInteger(inputValue / data.multipleOf)) {
|
|
151
|
+
errorMessages.push(nls.localizeByDefault('Value must be a multiple of {0}.', data.multipleOf));
|
|
152
|
+
}
|
|
117
153
|
|
|
118
154
|
return {
|
|
119
155
|
value: errorMessages.length ? NaN : inputValue,
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { PreferenceLeafNodeRenderer, PreferenceNodeRenderer } from './preference-node-renderer';
|
|
18
18
|
import { injectable, interfaces } from '@theia/core/shared/inversify';
|
|
19
|
-
import { JSONValue } from '@theia/core/shared/@
|
|
19
|
+
import { JSONValue } from '@theia/core/shared/@lumino/coreutils';
|
|
20
20
|
import { PreferenceProvider } from '@theia/core/lib/browser/preferences/preference-provider';
|
|
21
21
|
import { SelectComponent, SelectOption } from '@theia/core/lib/browser/widgets/select-component';
|
|
22
22
|
import { Preference } from '../../util/preference-types';
|
|
@@ -275,9 +275,12 @@ export class PreferencesEditorWidget extends BaseWidget implements StatefulWidge
|
|
|
275
275
|
}
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
protected shouldUpdateModelSelection = true;
|
|
279
|
+
|
|
278
280
|
protected setFirstVisibleChildID(id?: string): void {
|
|
279
281
|
if (id && id !== this.firstVisibleChildID) {
|
|
280
282
|
this.firstVisibleChildID = id;
|
|
283
|
+
if (!this.shouldUpdateModelSelection) { return; }
|
|
281
284
|
let currentNode = this.model.getNode(id);
|
|
282
285
|
let expansionAncestor;
|
|
283
286
|
let selectionAncestor;
|
|
@@ -314,18 +317,26 @@ export class PreferencesEditorWidget extends BaseWidget implements StatefulWidge
|
|
|
314
317
|
if (renderer?.visible) {
|
|
315
318
|
// When filtered, treat the first visible child as the selected node, since it will be the one scrolled to.
|
|
316
319
|
this.lastUserSelection = renderer.nodeId;
|
|
317
|
-
renderer.node
|
|
320
|
+
this.scrollWithoutModelUpdate(renderer.node);
|
|
318
321
|
return;
|
|
319
322
|
}
|
|
320
323
|
}
|
|
321
324
|
} else {
|
|
322
325
|
const { id, collection } = this.analyzeIDAndGetRendererGroup(node.id);
|
|
323
326
|
const renderer = collection.get(id);
|
|
324
|
-
renderer?.node
|
|
327
|
+
this.scrollWithoutModelUpdate(renderer?.node);
|
|
325
328
|
}
|
|
326
329
|
}
|
|
327
330
|
}
|
|
328
331
|
|
|
332
|
+
/** Ensures that we don't set the model's selection while attempting to scroll in reaction to a model selection change. */
|
|
333
|
+
protected scrollWithoutModelUpdate(node?: HTMLElement): void {
|
|
334
|
+
if (!node) { return; }
|
|
335
|
+
this.shouldUpdateModelSelection = false;
|
|
336
|
+
node.scrollIntoView();
|
|
337
|
+
requestAnimationFrame(() => this.shouldUpdateModelSelection = true);
|
|
338
|
+
}
|
|
339
|
+
|
|
329
340
|
protected analyzeIDAndGetRendererGroup(nodeID: string): { id: string, group: string, collection: Map<string, GeneralPreferenceNodeRenderer> } {
|
|
330
341
|
const { id, group } = Preference.TreeNode.getGroupAndIdFromNodeId(nodeID);
|
|
331
342
|
const collection = group === COMMONLY_USED_SECTION_PREFIX ? this.commonlyUsedRenderers : this.renderers;
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
17
|
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
|
|
18
|
-
import { TabBar, Widget, Title } from '@theia/core/shared/@
|
|
18
|
+
import { TabBar, Widget, Title } from '@theia/core/shared/@lumino/widgets';
|
|
19
19
|
import { PreferenceScope, Message, ContextMenuRenderer, LabelProvider, StatefulWidget, codicon } from '@theia/core/lib/browser';
|
|
20
20
|
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
|
|
21
21
|
import URI from '@theia/core/lib/common/uri';
|
|
@@ -36,6 +36,7 @@ import { PreferencesScopeTabBar } from './preference-scope-tabbar-widget';
|
|
|
36
36
|
import { PreferencesSearchbarWidget } from './preference-searchbar-widget';
|
|
37
37
|
import { PreferencesTreeWidget } from './preference-tree-widget';
|
|
38
38
|
import { PreferencesWidget } from './preference-widget';
|
|
39
|
+
import { PreferenceNullInputRenderer, PreferenceNullRendererContribution } from './components/preference-null-input';
|
|
39
40
|
|
|
40
41
|
export function bindPreferencesWidgets(bind: interfaces.Bind): void {
|
|
41
42
|
bind(PreferenceTreeLabelProvider).toSelf().inSingletonScope();
|
|
@@ -58,6 +59,8 @@ export function bindPreferencesWidgets(bind: interfaces.Bind): void {
|
|
|
58
59
|
|
|
59
60
|
bind(PreferenceStringInputRenderer).toSelf();
|
|
60
61
|
bind(PreferenceNodeRendererContribution).to(PreferenceStringInputRendererContribution).inSingletonScope();
|
|
62
|
+
bind(PreferenceNullInputRenderer).toSelf();
|
|
63
|
+
bind(PreferenceNodeRendererContribution).to(PreferenceNullRendererContribution).inSingletonScope();
|
|
61
64
|
|
|
62
65
|
bind(PreferenceBooleanInputRenderer).toSelf();
|
|
63
66
|
bind(PreferenceNodeRendererContribution).to(PreferenceBooleanInputRendererContribution).inSingletonScope();
|