@theia/core 1.70.0-next.7 → 1.70.0-next.71
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/README.md +3 -3
- package/lib/browser/about-dialog.d.ts.map +1 -1
- package/lib/browser/about-dialog.js +3 -1
- package/lib/browser/about-dialog.js.map +1 -1
- package/lib/browser/catalog.json +83 -7
- package/lib/browser/common-frontend-contribution.d.ts +0 -2
- package/lib/browser/common-frontend-contribution.d.ts.map +1 -1
- package/lib/browser/common-frontend-contribution.js +39 -15
- package/lib/browser/common-frontend-contribution.js.map +1 -1
- package/lib/browser/frontend-application-module.d.ts.map +1 -1
- package/lib/browser/frontend-application-module.js +1 -0
- package/lib/browser/frontend-application-module.js.map +1 -1
- package/lib/browser/hover-service.d.ts.map +1 -1
- package/lib/browser/hover-service.js +5 -3
- package/lib/browser/hover-service.js.map +1 -1
- package/lib/browser/markdown-rendering/markdown-renderer.d.ts +1 -1
- package/lib/browser/markdown-rendering/markdown-renderer.d.ts.map +1 -1
- package/lib/browser/menu/browser-menu-plugin.d.ts.map +1 -1
- package/lib/browser/menu/browser-menu-plugin.js +9 -1
- package/lib/browser/menu/browser-menu-plugin.js.map +1 -1
- package/lib/browser/quick-input/quick-input-service.spec.js +53 -9
- package/lib/browser/quick-input/quick-input-service.spec.js.map +1 -1
- package/lib/browser/saveable-service.d.ts +24 -1
- package/lib/browser/saveable-service.d.ts.map +1 -1
- package/lib/browser/saveable-service.js +34 -3
- package/lib/browser/saveable-service.js.map +1 -1
- package/lib/browser/tree/fuzzy-search.d.ts +1 -60
- package/lib/browser/tree/fuzzy-search.d.ts.map +1 -1
- package/lib/browser/tree/fuzzy-search.js +3 -58
- package/lib/browser/tree/fuzzy-search.js.map +1 -1
- package/lib/browser/tree/tree-view-welcome-widget.d.ts.map +1 -1
- package/lib/browser/tree/tree-view-welcome-widget.js +1 -2
- package/lib/browser/tree/tree-view-welcome-widget.js.map +1 -1
- package/lib/browser/widgets/select-component.d.ts +1 -0
- package/lib/browser/widgets/select-component.d.ts.map +1 -1
- package/lib/browser/widgets/select-component.js +30 -0
- package/lib/browser/widgets/select-component.js.map +1 -1
- package/lib/browser/window/default-window-service.d.ts +2 -1
- package/lib/browser/window/default-window-service.d.ts.map +1 -1
- package/lib/browser/window/default-window-service.js +5 -1
- package/lib/browser/window/default-window-service.js.map +1 -1
- package/lib/browser/window/test/mock-window-service.d.ts +2 -1
- package/lib/browser/window/test/mock-window-service.d.ts.map +1 -1
- package/lib/browser/window/test/mock-window-service.js +2 -1
- package/lib/browser/window/test/mock-window-service.js.map +1 -1
- package/lib/browser/window/window-service.d.ts +8 -1
- package/lib/browser/window/window-service.d.ts.map +1 -1
- package/lib/common/fuzzy-match-utils.d.ts +27 -0
- package/lib/common/fuzzy-match-utils.d.ts.map +1 -0
- package/lib/common/fuzzy-match-utils.js +96 -0
- package/lib/common/fuzzy-match-utils.js.map +1 -0
- package/lib/common/fuzzy-match-utils.spec.d.ts +2 -0
- package/lib/common/fuzzy-match-utils.spec.d.ts.map +1 -0
- package/lib/common/fuzzy-match-utils.spec.js +109 -0
- package/lib/common/fuzzy-match-utils.spec.js.map +1 -0
- package/lib/common/fuzzy-search.d.ts +63 -0
- package/lib/common/fuzzy-search.d.ts.map +1 -0
- package/lib/common/fuzzy-search.js +101 -0
- package/lib/common/fuzzy-search.js.map +1 -0
- package/lib/common/fuzzy-search.spec.d.ts.map +1 -0
- package/lib/{browser/tree → common}/fuzzy-search.spec.js +20 -1
- package/lib/common/fuzzy-search.spec.js.map +1 -0
- package/lib/common/logger-sanitizer.d.ts +9 -0
- package/lib/common/logger-sanitizer.d.ts.map +1 -1
- package/lib/common/logger-sanitizer.js +26 -3
- package/lib/common/logger-sanitizer.js.map +1 -1
- package/lib/common/logger-sanitizer.spec.js +41 -0
- package/lib/common/logger-sanitizer.spec.js.map +1 -1
- package/lib/common/preferences/injectable-preference-proxy.d.ts +5 -3
- package/lib/common/preferences/injectable-preference-proxy.d.ts.map +1 -1
- package/lib/common/preferences/injectable-preference-proxy.js +9 -6
- package/lib/common/preferences/injectable-preference-proxy.js.map +1 -1
- package/lib/common/preferences/preference-configurations.d.ts +2 -2
- package/lib/common/preferences/preference-configurations.d.ts.map +1 -1
- package/lib/common/preferences/preference-configurations.js +1 -1
- package/lib/common/preferences/preference-configurations.js.map +1 -1
- package/lib/common/preferences/preference-provider-impl.d.ts +4 -3
- package/lib/common/preferences/preference-provider-impl.d.ts.map +1 -1
- package/lib/common/preferences/preference-provider-impl.js +9 -6
- package/lib/common/preferences/preference-provider-impl.js.map +1 -1
- package/lib/common/preferences/preference-proxy.d.ts +4 -2
- package/lib/common/preferences/preference-proxy.d.ts.map +1 -1
- package/lib/common/preferences/preference-proxy.js +4 -5
- package/lib/common/preferences/preference-proxy.js.map +1 -1
- package/lib/common/preferences/preference-service.d.ts +4 -3
- package/lib/common/preferences/preference-service.d.ts.map +1 -1
- package/lib/common/preferences/preference-service.js +13 -10
- package/lib/common/preferences/preference-service.js.map +1 -1
- package/lib/common/quick-pick-service.d.ts +18 -2
- package/lib/common/quick-pick-service.d.ts.map +1 -1
- package/lib/common/quick-pick-service.js +53 -8
- package/lib/common/quick-pick-service.js.map +1 -1
- package/lib/common/uri.js +1 -1
- package/lib/common/uri.js.map +1 -1
- package/lib/electron-browser/menu/electron-main-menu-factory.d.ts.map +1 -1
- package/lib/electron-browser/menu/electron-main-menu-factory.js +4 -6
- package/lib/electron-browser/menu/electron-main-menu-factory.js.map +1 -1
- package/lib/electron-browser/menu/electron-menu-contribution.js +3 -3
- package/lib/electron-browser/menu/electron-menu-contribution.js.map +1 -1
- package/lib/electron-browser/messaging/electron-local-ws-connection-source.d.ts +2 -0
- package/lib/electron-browser/messaging/electron-local-ws-connection-source.d.ts.map +1 -1
- package/lib/electron-browser/messaging/electron-local-ws-connection-source.js +5 -3
- package/lib/electron-browser/messaging/electron-local-ws-connection-source.js.map +1 -1
- package/lib/electron-browser/preload.js +2 -2
- package/lib/electron-browser/preload.js.map +1 -1
- package/lib/electron-browser/window/electron-secondary-window-service.d.ts +4 -0
- package/lib/electron-browser/window/electron-secondary-window-service.d.ts.map +1 -1
- package/lib/electron-browser/window/electron-secondary-window-service.js +32 -0
- package/lib/electron-browser/window/electron-secondary-window-service.js.map +1 -1
- package/lib/electron-browser/window/electron-window-module.d.ts +1 -0
- package/lib/electron-browser/window/electron-window-module.d.ts.map +1 -1
- package/lib/electron-browser/window/electron-window-module.js +4 -0
- package/lib/electron-browser/window/electron-window-module.js.map +1 -1
- package/lib/electron-browser/window/electron-window-service.d.ts +3 -2
- package/lib/electron-browser/window/electron-window-service.d.ts.map +1 -1
- package/lib/electron-browser/window/electron-window-service.js +7 -4
- package/lib/electron-browser/window/electron-window-service.js.map +1 -1
- package/lib/electron-browser/window/window-zoom-action-bar.d.ts +21 -0
- package/lib/electron-browser/window/window-zoom-action-bar.d.ts.map +1 -0
- package/lib/electron-browser/window/window-zoom-action-bar.js +71 -0
- package/lib/electron-browser/window/window-zoom-action-bar.js.map +1 -0
- package/lib/electron-browser/window/window-zoom-status-bar-item.d.ts +14 -0
- package/lib/electron-browser/window/window-zoom-status-bar-item.d.ts.map +1 -0
- package/lib/electron-browser/window/window-zoom-status-bar-item.js +87 -0
- package/lib/electron-browser/window/window-zoom-status-bar-item.js.map +1 -0
- package/lib/electron-common/electron-api.d.ts +1 -1
- package/lib/electron-common/electron-api.d.ts.map +1 -1
- package/lib/electron-common/electron-main-window-service.d.ts +2 -1
- package/lib/electron-common/electron-main-window-service.d.ts.map +1 -1
- package/lib/electron-common/electron-window-preferences.d.ts +5 -2
- package/lib/electron-common/electron-window-preferences.d.ts.map +1 -1
- package/lib/electron-common/electron-window-preferences.js +16 -10
- package/lib/electron-common/electron-window-preferences.js.map +1 -1
- package/lib/electron-main/electron-api-main.d.ts.map +1 -1
- package/lib/electron-main/electron-api-main.js +14 -2
- package/lib/electron-main/electron-api-main.js.map +1 -1
- package/lib/electron-main/electron-main-application.d.ts +1 -0
- package/lib/electron-main/electron-main-application.d.ts.map +1 -1
- package/lib/electron-main/electron-main-application.js +6 -0
- package/lib/electron-main/electron-main-application.js.map +1 -1
- package/lib/electron-main/electron-main-window-service-impl.d.ts +2 -1
- package/lib/electron-main/electron-main-window-service-impl.d.ts.map +1 -1
- package/lib/electron-main/electron-main-window-service-impl.js +6 -2
- package/lib/electron-main/electron-main-window-service-impl.js.map +1 -1
- package/package.json +7 -7
- package/src/browser/about-dialog.tsx +3 -1
- package/src/browser/common-frontend-contribution.ts +36 -17
- package/src/browser/frontend-application-module.ts +2 -1
- package/src/browser/hover-service.ts +5 -3
- package/src/browser/markdown-rendering/markdown-renderer.ts +1 -1
- package/src/browser/menu/browser-menu-plugin.ts +9 -1
- package/src/browser/quick-input/quick-input-service.spec.ts +58 -9
- package/src/browser/saveable-service.ts +56 -4
- package/src/browser/style/hover-service.css +1 -0
- package/src/browser/style/index.css +1 -1
- package/src/browser/tree/fuzzy-search.ts +2 -120
- package/src/browser/tree/tree-view-welcome-widget.tsx +1 -2
- package/src/browser/widgets/select-component.tsx +39 -2
- package/src/browser/window/default-window-service.ts +6 -1
- package/src/browser/window/test/mock-window-service.ts +2 -1
- package/src/browser/window/window-service.ts +9 -1
- package/src/common/fuzzy-match-utils.spec.ts +141 -0
- package/src/common/fuzzy-match-utils.ts +78 -0
- package/src/{browser/tree → common}/fuzzy-search.spec.ts +23 -1
- package/src/common/fuzzy-search.ts +158 -0
- package/src/common/i18n/nls.metadata.json +25379 -24577
- package/src/common/logger-sanitizer.spec.ts +54 -1
- package/src/common/logger-sanitizer.ts +38 -3
- package/src/common/preferences/injectable-preference-proxy.ts +6 -3
- package/src/common/preferences/preference-configurations.ts +2 -2
- package/src/common/preferences/preference-provider-impl.ts +6 -3
- package/src/common/preferences/preference-proxy.ts +6 -4
- package/src/common/preferences/preference-service.ts +6 -3
- package/src/common/quick-pick-service.ts +65 -11
- package/src/common/uri.ts +1 -1
- package/src/electron-browser/menu/electron-main-menu-factory.ts +4 -6
- package/src/electron-browser/menu/electron-menu-contribution.ts +4 -4
- package/src/electron-browser/messaging/electron-local-ws-connection-source.ts +4 -2
- package/src/electron-browser/preload.ts +2 -2
- package/src/electron-browser/style/window-zoom-action-bar.css +57 -0
- package/src/electron-browser/window/electron-secondary-window-service.ts +32 -1
- package/src/electron-browser/window/electron-window-module.ts +4 -0
- package/src/electron-browser/window/electron-window-service.ts +10 -7
- package/src/electron-browser/window/window-zoom-action-bar.tsx +115 -0
- package/src/electron-browser/window/window-zoom-status-bar-item.ts +81 -0
- package/src/electron-common/electron-api.ts +1 -1
- package/src/electron-common/electron-main-window-service.ts +2 -1
- package/src/electron-common/electron-window-preferences.ts +19 -11
- package/src/electron-main/electron-api-main.ts +12 -2
- package/src/electron-main/electron-main-application.ts +7 -0
- package/src/electron-main/electron-main-window-service-impl.ts +7 -2
- package/lib/browser/tree/fuzzy-search.spec.d.ts.map +0 -1
- package/lib/browser/tree/fuzzy-search.spec.js.map +0 -1
- /package/lib/{browser/tree → common}/fuzzy-search.spec.d.ts +0 -0
|
@@ -21,7 +21,7 @@ import { ReactDialog } from './dialogs/react-dialog';
|
|
|
21
21
|
import { ApplicationServer, ApplicationInfo, ExtensionInfo } from '../common/application-protocol';
|
|
22
22
|
import { Message } from './widgets/widget';
|
|
23
23
|
import { FrontendApplicationConfigProvider } from './frontend-application-config-provider';
|
|
24
|
-
import { DEFAULT_SUPPORTED_API_VERSION } from '@theia/application-package/lib/api';
|
|
24
|
+
import { DEFAULT_SUPPORTED_API_VERSION, DEFAULT_SUPPORTED_MONACO_VERSION } from '@theia/application-package/lib/api';
|
|
25
25
|
import { WindowService } from './window/window-service';
|
|
26
26
|
import { Key, KeyCode } from './keys';
|
|
27
27
|
import { nls } from '../common/nls';
|
|
@@ -73,6 +73,7 @@ export class AboutDialog extends ReactDialog<void> {
|
|
|
73
73
|
const versionLabel = nls.localizeByDefault('Version');
|
|
74
74
|
const defaultApiLabel = nls.localize('theia/core/about/defaultApi', 'Default {0} API', 'VS Code');
|
|
75
75
|
const compatibilityLabel = nls.localize('theia/core/about/compatibility', '{0} Compatibility', 'VS Code');
|
|
76
|
+
const monacoLabel = nls.localize('theia/core/about/monacoEditor', 'Monaco Editor Version');
|
|
76
77
|
|
|
77
78
|
return <>
|
|
78
79
|
<h3>{detailsLabel}</h3>
|
|
@@ -88,6 +89,7 @@ export class AboutDialog extends ReactDialog<void> {
|
|
|
88
89
|
{compatibilityLabel}
|
|
89
90
|
</a>
|
|
90
91
|
</p>
|
|
92
|
+
<p>{`${monacoLabel}: ${DEFAULT_SUPPORTED_MONACO_VERSION}`}</p>
|
|
91
93
|
</div>
|
|
92
94
|
</>;
|
|
93
95
|
}
|
|
@@ -159,7 +159,6 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
|
|
|
159
159
|
protected readonly undoRedoHandlerService: UndoRedoHandlerService;
|
|
160
160
|
|
|
161
161
|
protected pinnedKey: ContextKey<boolean>;
|
|
162
|
-
protected inputFocus: ContextKey<boolean>;
|
|
163
162
|
|
|
164
163
|
async configure(app: FrontendApplication): Promise<void> {
|
|
165
164
|
// FIXME: This request blocks valuable startup time (~200ms).
|
|
@@ -174,9 +173,9 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
|
|
|
174
173
|
this.contextKeyService.createKey<boolean>('isMac', OS.type() === OS.Type.OSX);
|
|
175
174
|
this.contextKeyService.createKey<boolean>('isWindows', OS.type() === OS.Type.Windows);
|
|
176
175
|
this.contextKeyService.createKey<boolean>('isWeb', !this.isElectron());
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
176
|
+
// Note: the 'inputFocus' context key is tracked by Monaco's ContextKeyService
|
|
177
|
+
// which sets it for <input>, <textarea>, and elements with EditContext (Monaco editors).
|
|
178
|
+
// We no longer track it separately to avoid race conditions between two focusin listeners.
|
|
180
179
|
|
|
181
180
|
this.pinnedKey = this.contextKeyService.createKey<boolean>('activeEditorIsPinned', false);
|
|
182
181
|
this.updatePinnedKey();
|
|
@@ -234,15 +233,6 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
|
|
|
234
233
|
}
|
|
235
234
|
}
|
|
236
235
|
|
|
237
|
-
protected updateInputFocus(): void {
|
|
238
|
-
const activeElement = document.activeElement;
|
|
239
|
-
if (activeElement) {
|
|
240
|
-
const isInput = activeElement.tagName?.toLowerCase() === 'input'
|
|
241
|
-
|| activeElement.tagName?.toLowerCase() === 'textarea';
|
|
242
|
-
this.inputFocus.set(isInput);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
236
|
protected updatePinnedKey(): void {
|
|
247
237
|
const activeTab = this.shell.findTabBar();
|
|
248
238
|
const pinningTarget = activeTab && this.shell.findTitle(activeTab);
|
|
@@ -498,7 +488,18 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
|
|
|
498
488
|
commandRegistry.registerCommand(CommonCommands.CUT, {
|
|
499
489
|
execute: () => {
|
|
500
490
|
if (supportCut) {
|
|
501
|
-
document.
|
|
491
|
+
const active = document.activeElement;
|
|
492
|
+
if (environment.electron.is() && (active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement)) {
|
|
493
|
+
const start = active.selectionStart ?? 0;
|
|
494
|
+
const end = active.selectionEnd ?? 0;
|
|
495
|
+
const selectedText = active.value.substring(start, end);
|
|
496
|
+
if (selectedText) {
|
|
497
|
+
this.clipboardService.writeText(selectedText);
|
|
498
|
+
document.execCommand('insertText', false, '');
|
|
499
|
+
}
|
|
500
|
+
} else {
|
|
501
|
+
document.execCommand('cut');
|
|
502
|
+
}
|
|
502
503
|
} else {
|
|
503
504
|
this.messageService.warn(nls.localize('theia/core/cutWarn', "Please use the browser's cut command or shortcut."));
|
|
504
505
|
}
|
|
@@ -507,16 +508,34 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
|
|
|
507
508
|
commandRegistry.registerCommand(CommonCommands.COPY, {
|
|
508
509
|
execute: () => {
|
|
509
510
|
if (supportCopy) {
|
|
510
|
-
document.
|
|
511
|
+
const active = document.activeElement;
|
|
512
|
+
if (environment.electron.is() && (active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement)) {
|
|
513
|
+
const start = active.selectionStart ?? 0;
|
|
514
|
+
const end = active.selectionEnd ?? 0;
|
|
515
|
+
const selectedText = active.value.substring(start, end);
|
|
516
|
+
if (selectedText) {
|
|
517
|
+
this.clipboardService.writeText(selectedText);
|
|
518
|
+
}
|
|
519
|
+
} else {
|
|
520
|
+
document.execCommand('copy');
|
|
521
|
+
}
|
|
511
522
|
} else {
|
|
512
523
|
this.messageService.warn(nls.localize('theia/core/copyWarn', "Please use the browser's copy command or shortcut."));
|
|
513
524
|
}
|
|
514
525
|
}
|
|
515
526
|
});
|
|
516
527
|
commandRegistry.registerCommand(CommonCommands.PASTE, {
|
|
517
|
-
execute: () => {
|
|
528
|
+
execute: async () => {
|
|
518
529
|
if (supportPaste) {
|
|
519
|
-
document.
|
|
530
|
+
const active = document.activeElement;
|
|
531
|
+
if (environment.electron.is() && (active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement)) {
|
|
532
|
+
const text = await this.clipboardService.readText();
|
|
533
|
+
if (text) {
|
|
534
|
+
document.execCommand('insertText', false, text);
|
|
535
|
+
}
|
|
536
|
+
} else {
|
|
537
|
+
document.execCommand('paste');
|
|
538
|
+
}
|
|
520
539
|
} else {
|
|
521
540
|
this.messageService.warn(nls.localize('theia/core/pasteWarn', "Please use the browser's paste command or shortcut."));
|
|
522
541
|
}
|
|
@@ -123,7 +123,7 @@ import { DockPanel, RendererHost } from './widgets';
|
|
|
123
123
|
import { TooltipService, TooltipServiceImpl } from './tooltip-service';
|
|
124
124
|
import { BackendRequestService, RequestService, REQUEST_SERVICE_PATH } from '@theia/request';
|
|
125
125
|
import { bindFrontendStopwatch, bindBackendStopwatch } from './performance';
|
|
126
|
-
import { SaveableService } from './saveable-service';
|
|
126
|
+
import { SaveableService, SaveErrorChecker } from './saveable-service';
|
|
127
127
|
import { SecondaryWindowHandler } from './secondary-window-handler';
|
|
128
128
|
import { UserWorkingDirectoryProvider } from './user-working-directory-provider';
|
|
129
129
|
import { WindowTitleService } from './window/window-title-service';
|
|
@@ -461,6 +461,7 @@ export const frontendApplicationModule = new ContainerModule((bind, _unbind, _is
|
|
|
461
461
|
|
|
462
462
|
bind(SaveableService).toSelf().inSingletonScope();
|
|
463
463
|
bind(FrontendApplicationContribution).toService(SaveableService);
|
|
464
|
+
bindRootContributionProvider(bind, SaveErrorChecker);
|
|
464
465
|
|
|
465
466
|
bind(UserWorkingDirectoryProvider).toSelf().inSingletonScope();
|
|
466
467
|
bind(FrontendApplicationContribution).toService(UserWorkingDirectoryProvider);
|
|
@@ -260,9 +260,11 @@ export class HoverService {
|
|
|
260
260
|
* For interactive hovers, the hover remains visible to allow interaction with its elements.
|
|
261
261
|
*/
|
|
262
262
|
protected listenForMouseClick(request: HoverRequest): void {
|
|
263
|
-
const handleMouseDown = (
|
|
264
|
-
|
|
265
|
-
|
|
263
|
+
const handleMouseDown = (e: MouseEvent) => {
|
|
264
|
+
if (this.hoverHost.contains(e.target as Node)) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (!request.interactive) {
|
|
266
268
|
this.cancelHover();
|
|
267
269
|
}
|
|
268
270
|
};
|
|
@@ -54,7 +54,7 @@ export interface MarkdownRenderOptions extends FormattedTextRenderOptions {
|
|
|
54
54
|
/** Use this directly if you aren't worried about circular dependencies in the Shell */
|
|
55
55
|
export const MarkdownRenderer = Symbol('MarkdownRenderer');
|
|
56
56
|
export interface MarkdownRenderer {
|
|
57
|
-
render(markdown: MarkdownString
|
|
57
|
+
render(markdown: MarkdownString, options?: MarkdownRenderOptions, outElement?: HTMLElement): MarkdownRenderResult;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
/** Use this to avoid circular dependencies in the Shell */
|
|
@@ -345,7 +345,15 @@ export class DynamicMenuWidget extends MenuWidget {
|
|
|
345
345
|
const enabled = node.isEnabled(nodePath, ...(this.args || []));
|
|
346
346
|
const toggled = node.isToggled ? !!node.isToggled(nodePath, ...(this.args || [])) : false;
|
|
347
347
|
phCommandRegistry.addCommand(id, {
|
|
348
|
-
execute: () => {
|
|
348
|
+
execute: () => {
|
|
349
|
+
// Restore focus to the previously focused element before executing
|
|
350
|
+
// the command so that focus-dependent commands like clipboard
|
|
351
|
+
// operations target the correct element instead of the menu.
|
|
352
|
+
if (this.previousFocusedElement) {
|
|
353
|
+
this.previousFocusedElement.focus({ preventScroll: true });
|
|
354
|
+
}
|
|
355
|
+
node.run(nodePath, ...(this.args || []));
|
|
356
|
+
},
|
|
349
357
|
isEnabled: () => enabled,
|
|
350
358
|
isToggled: () => toggled,
|
|
351
359
|
isVisible: () => true,
|
|
@@ -23,11 +23,14 @@ describe('quick-input-service', () => {
|
|
|
23
23
|
|
|
24
24
|
describe('#findMatches', () => {
|
|
25
25
|
|
|
26
|
-
it('should return
|
|
26
|
+
it('should return a single contiguous range for substring matches', () => {
|
|
27
27
|
expect(findMatches('abc', 'a')).deep.equal([{ start: 0, end: 1 }]);
|
|
28
|
-
expect(findMatches('abc', 'ab')).deep.equal([{ start: 0, end:
|
|
28
|
+
expect(findMatches('abc', 'ab')).deep.equal([{ start: 0, end: 2 }]);
|
|
29
|
+
expect(findMatches('abc', 'abc')).deep.equal([{ start: 0, end: 3 }]);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should return per-character ranges for fuzzy-only matches', () => {
|
|
29
33
|
expect(findMatches('abc', 'ac')).deep.equal([{ start: 0, end: 1 }, { start: 2, end: 3 }]);
|
|
30
|
-
expect(findMatches('abc', 'abc')).deep.equal([{ start: 0, end: 1 }, { start: 1, end: 2 }, { start: 2, end: 3 }]);
|
|
31
34
|
});
|
|
32
35
|
|
|
33
36
|
it('should fail when out of order', () => {
|
|
@@ -67,9 +70,7 @@ describe('quick-input-service', () => {
|
|
|
67
70
|
label: 'abc',
|
|
68
71
|
highlights: {
|
|
69
72
|
label: [
|
|
70
|
-
{ start: 0, end:
|
|
71
|
-
{ start: 1, end: 2 },
|
|
72
|
-
{ start: 2, end: 3 }
|
|
73
|
+
{ start: 0, end: 3 }
|
|
73
74
|
]
|
|
74
75
|
}
|
|
75
76
|
};
|
|
@@ -152,9 +153,7 @@ describe('quick-input-service', () => {
|
|
|
152
153
|
label: 'abc',
|
|
153
154
|
highlights: {
|
|
154
155
|
label: [
|
|
155
|
-
{ start: 0, end:
|
|
156
|
-
{ start: 1, end: 2 },
|
|
157
|
-
{ start: 2, end: 3 }
|
|
156
|
+
{ start: 0, end: 3 }
|
|
158
157
|
]
|
|
159
158
|
}
|
|
160
159
|
};
|
|
@@ -171,6 +170,56 @@ describe('quick-input-service', () => {
|
|
|
171
170
|
expect(filterItems(items, 'yyy')).deep.equal([]);
|
|
172
171
|
});
|
|
173
172
|
|
|
173
|
+
it('should rank substring matches before fuzzy-only matches', () => {
|
|
174
|
+
const testItems: QuickPickItem[] = [
|
|
175
|
+
{ label: 'reformatting' },
|
|
176
|
+
{ label: 'fontSize' },
|
|
177
|
+
{ label: 'fontFamily' },
|
|
178
|
+
];
|
|
179
|
+
const result = filterItems(testItems, 'font').filter(QuickPickItem.is);
|
|
180
|
+
expect(result).length(2);
|
|
181
|
+
expect(result[0].label).equal('fontSize');
|
|
182
|
+
expect(result[1].label).equal('fontFamily');
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it('should rank prefix matches before other substring matches', () => {
|
|
186
|
+
const testItems: QuickPickItem[] = [
|
|
187
|
+
{ label: 'setFont' },
|
|
188
|
+
{ label: 'fontSize' },
|
|
189
|
+
{ label: 'fontFamily' },
|
|
190
|
+
];
|
|
191
|
+
const result = filterItems(testItems, 'font').filter(QuickPickItem.is);
|
|
192
|
+
expect(result).length(3);
|
|
193
|
+
expect(result[0].label).equal('fontSize');
|
|
194
|
+
expect(result[1].label).equal('fontFamily');
|
|
195
|
+
expect(result[2].label).equal('setFont');
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('should treat segmented prefix matches as prefix matches', () => {
|
|
199
|
+
const testItems: QuickPickItem[] = [
|
|
200
|
+
{ label: 'backend-workspace-service.ts' },
|
|
201
|
+
{ label: 'workspace-backend-service.ts' },
|
|
202
|
+
];
|
|
203
|
+
const result = filterItems(testItems, 'works-ser').filter(QuickPickItem.is);
|
|
204
|
+
expect(result).length(2);
|
|
205
|
+
expect(result[0].label).equal('workspace-backend-service.ts');
|
|
206
|
+
expect(result[1].label).equal('backend-workspace-service.ts');
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('should drop separators when their group has no matches', () => {
|
|
210
|
+
const testItems = [
|
|
211
|
+
{ type: 'separator' as const, label: 'Group A' },
|
|
212
|
+
{ label: 'fontSize' },
|
|
213
|
+
{ type: 'separator' as const, label: 'Group B' },
|
|
214
|
+
{ label: 'xyz' },
|
|
215
|
+
];
|
|
216
|
+
const result = filterItems(testItems, 'font');
|
|
217
|
+
// Group B's only item "xyz" doesn't match, so Group B separator is dropped
|
|
218
|
+
expect(result).length(2);
|
|
219
|
+
expect(result[0]).to.have.property('type', 'separator');
|
|
220
|
+
expect(result[1]).to.have.property('label', 'fontSize');
|
|
221
|
+
});
|
|
222
|
+
|
|
174
223
|
});
|
|
175
224
|
|
|
176
225
|
});
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
********************************************************************************/
|
|
16
16
|
|
|
17
17
|
import type { ApplicationShell } from './shell';
|
|
18
|
-
import { injectable } from 'inversify';
|
|
19
|
-
import { UNTITLED_SCHEME, URI, Disposable, DisposableCollection, Emitter, Event } from '../common';
|
|
18
|
+
import { inject, injectable, named } from 'inversify';
|
|
19
|
+
import { ContributionProvider, UNTITLED_SCHEME, URI, Disposable, DisposableCollection, Emitter, Event } from '../common';
|
|
20
20
|
import { Navigatable, NavigatableWidget } from './navigatable-types';
|
|
21
21
|
import { AutoSaveMode, Saveable, SaveableSource, SaveableWidget, SaveOptions, SaveReason, setDirty, close, PostCreationSaveableWidget, ShouldSaveDialog } from './saveable';
|
|
22
22
|
import { waitForClosed, Widget } from './widgets';
|
|
@@ -24,16 +24,40 @@ import { FrontendApplicationContribution } from './frontend-application-contribu
|
|
|
24
24
|
import { FrontendApplication } from './frontend-application';
|
|
25
25
|
import throttle = require('lodash.throttle');
|
|
26
26
|
|
|
27
|
+
export const SaveErrorChecker = Symbol('SaveErrorChecker');
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Contribution point for checking whether a given URI has errors.
|
|
31
|
+
* When `files.autoSaveWhenNoErrors` is enabled, auto-save will be suppressed
|
|
32
|
+
* for files where any registered checker reports errors.
|
|
33
|
+
*/
|
|
34
|
+
export interface SaveErrorChecker {
|
|
35
|
+
/**
|
|
36
|
+
* Returns `true` if the given URI has errors that should prevent auto-save.
|
|
37
|
+
*/
|
|
38
|
+
hasErrors(uri: URI): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Event fired when the error state may have changed (e.g. diagnostics updated).
|
|
41
|
+
* The SaveableService listens to this to re-evaluate auto-save for dirty widgets.
|
|
42
|
+
*/
|
|
43
|
+
onDidErrorStateChange: Event<void>;
|
|
44
|
+
}
|
|
45
|
+
|
|
27
46
|
@injectable()
|
|
28
47
|
export class SaveableService implements FrontendApplicationContribution {
|
|
29
48
|
|
|
49
|
+
@inject(ContributionProvider) @named(SaveErrorChecker)
|
|
50
|
+
protected readonly errorCheckers: ContributionProvider<SaveErrorChecker>;
|
|
51
|
+
|
|
30
52
|
protected saveThrottles = new Map<Widget, AutoSaveThrottle>();
|
|
31
53
|
protected saveMode: AutoSaveMode = 'off';
|
|
32
54
|
protected saveDelay = 1000;
|
|
55
|
+
protected saveWhenNoErrors = false;
|
|
33
56
|
protected shell: ApplicationShell;
|
|
34
57
|
|
|
35
58
|
protected readonly onDidAutoSaveChangeEmitter = new Emitter<AutoSaveMode>();
|
|
36
59
|
protected readonly onDidAutoSaveDelayChangeEmitter = new Emitter<number>();
|
|
60
|
+
protected readonly onDidAutoSaveConditionsChangeEmitter = new Emitter<void>();
|
|
37
61
|
|
|
38
62
|
get onDidAutoSaveChange(): Event<AutoSaveMode> {
|
|
39
63
|
return this.onDidAutoSaveChangeEmitter.event;
|
|
@@ -43,6 +67,10 @@ export class SaveableService implements FrontendApplicationContribution {
|
|
|
43
67
|
return this.onDidAutoSaveDelayChangeEmitter.event;
|
|
44
68
|
}
|
|
45
69
|
|
|
70
|
+
get onDidAutoSaveConditionsChange(): Event<void> {
|
|
71
|
+
return this.onDidAutoSaveConditionsChangeEmitter.event;
|
|
72
|
+
}
|
|
73
|
+
|
|
46
74
|
get autoSave(): AutoSaveMode {
|
|
47
75
|
return this.saveMode;
|
|
48
76
|
}
|
|
@@ -59,8 +87,22 @@ export class SaveableService implements FrontendApplicationContribution {
|
|
|
59
87
|
this.updateAutoSaveDelay(value);
|
|
60
88
|
}
|
|
61
89
|
|
|
90
|
+
get autoSaveWhenNoErrors(): boolean {
|
|
91
|
+
return this.saveWhenNoErrors;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
set autoSaveWhenNoErrors(value: boolean) {
|
|
95
|
+
this.saveWhenNoErrors = value;
|
|
96
|
+
}
|
|
97
|
+
|
|
62
98
|
onDidInitializeLayout(app: FrontendApplication): void {
|
|
63
99
|
this.shell = app.shell;
|
|
100
|
+
// Listen to error state changes from all registered error checkers
|
|
101
|
+
for (const checker of this.errorCheckers.getContributions()) {
|
|
102
|
+
checker.onDidErrorStateChange(() => {
|
|
103
|
+
this.onDidAutoSaveConditionsChangeEmitter.fire();
|
|
104
|
+
});
|
|
105
|
+
}
|
|
64
106
|
// Register restored editors first
|
|
65
107
|
for (const widget of this.shell.widgets) {
|
|
66
108
|
const saveable = Saveable.get(widget);
|
|
@@ -165,9 +207,16 @@ export class SaveableService implements FrontendApplicationContribution {
|
|
|
165
207
|
if (uri?.scheme === UNTITLED_SCHEME) {
|
|
166
208
|
// Never auto-save untitled documents
|
|
167
209
|
return false;
|
|
168
|
-
} else {
|
|
169
|
-
return saveable.autosaveable !== false && saveable.dirty;
|
|
170
210
|
}
|
|
211
|
+
if (saveable.autosaveable === false || !saveable.dirty) {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
if (this.saveWhenNoErrors && uri) {
|
|
215
|
+
if (this.errorCheckers.getContributions().some(checker => checker.hasErrors(uri))) {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return true;
|
|
171
220
|
}
|
|
172
221
|
|
|
173
222
|
protected applySaveableWidget(widget: Widget, saveable: Saveable): void {
|
|
@@ -314,6 +363,9 @@ export class AutoSaveThrottle implements Disposable {
|
|
|
314
363
|
}),
|
|
315
364
|
saveService.onDidAutoSaveDelayChange(() => {
|
|
316
365
|
this.throttledSave(true);
|
|
366
|
+
}),
|
|
367
|
+
saveService.onDidAutoSaveConditionsChange(() => {
|
|
368
|
+
this.throttledSave();
|
|
317
369
|
})
|
|
318
370
|
);
|
|
319
371
|
}
|
|
@@ -78,13 +78,13 @@
|
|
|
78
78
|
|
|
79
79
|
html,
|
|
80
80
|
body {
|
|
81
|
+
overflow: hidden;
|
|
81
82
|
height: 100vh;
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
body {
|
|
85
86
|
margin: 0;
|
|
86
87
|
padding: 0;
|
|
87
|
-
overflow: hidden;
|
|
88
88
|
font-family: var(--theia-ui-font-family);
|
|
89
89
|
background: var(--theia-editor-background);
|
|
90
90
|
color: var(--theia-foreground);
|
|
@@ -14,123 +14,5 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@injectable()
|
|
21
|
-
export class FuzzySearch {
|
|
22
|
-
|
|
23
|
-
private static readonly PRE = '\x01';
|
|
24
|
-
private static readonly POST = '\x02';
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Filters the input and returns with an array that contains all items that match the pattern.
|
|
28
|
-
*/
|
|
29
|
-
async filter<T>(input: FuzzySearch.Input<T>): Promise<FuzzySearch.Match<T>[]> {
|
|
30
|
-
return fuzzy.filter(input.pattern, input.items.slice(), {
|
|
31
|
-
pre: FuzzySearch.PRE,
|
|
32
|
-
post: FuzzySearch.POST,
|
|
33
|
-
extract: input.transform
|
|
34
|
-
}).sort(this.sortResults.bind(this)).map(this.mapResult.bind(this));
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
protected sortResults<T>(left: fuzzy.FilterResult<T>, right: fuzzy.FilterResult<T>): number {
|
|
38
|
-
return left.index - right.index;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
protected mapResult<T>(result: fuzzy.FilterResult<T>): FuzzySearch.Match<T> {
|
|
42
|
-
return {
|
|
43
|
-
item: result.original,
|
|
44
|
-
ranges: this.mapRanges(result.string)
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
protected mapRanges(input: string): ReadonlyArray<FuzzySearch.Range> {
|
|
49
|
-
const copy = input.split('').filter(s => s !== '');
|
|
50
|
-
const ranges: FuzzySearch.Range[] = [];
|
|
51
|
-
const validate = (pre: number, post: number) => {
|
|
52
|
-
if (preIndex > postIndex || (preIndex === -1) !== (postIndex === -1)) {
|
|
53
|
-
throw new Error(`Error when trying to map ranges. Escaped string was: '${input}. [${[...input].join('|')}]'`);
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
let preIndex = copy.indexOf(FuzzySearch.PRE);
|
|
57
|
-
let postIndex = copy.indexOf(FuzzySearch.POST);
|
|
58
|
-
validate(preIndex, postIndex);
|
|
59
|
-
while (preIndex !== -1 && postIndex !== -1) {
|
|
60
|
-
ranges.push({
|
|
61
|
-
offset: preIndex,
|
|
62
|
-
length: postIndex - preIndex - 1
|
|
63
|
-
});
|
|
64
|
-
copy.splice(postIndex, 1);
|
|
65
|
-
copy.splice(preIndex, 1);
|
|
66
|
-
preIndex = copy.indexOf(FuzzySearch.PRE);
|
|
67
|
-
postIndex = copy.indexOf(FuzzySearch.POST);
|
|
68
|
-
}
|
|
69
|
-
if (ranges.length === 0) {
|
|
70
|
-
throw new Error(`Unexpected zero ranges for match-string: ${input}.`);
|
|
71
|
-
}
|
|
72
|
-
return ranges;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Fuzzy searcher.
|
|
79
|
-
*/
|
|
80
|
-
export namespace FuzzySearch {
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* A range representing the match region.
|
|
84
|
-
*/
|
|
85
|
-
export interface Range {
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* The zero based offset of the match region.
|
|
89
|
-
*/
|
|
90
|
-
readonly offset: number;
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* The length of the match region.
|
|
94
|
-
*/
|
|
95
|
-
readonly length: number;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* A fuzzy search match.
|
|
100
|
-
*/
|
|
101
|
-
export interface Match<T> {
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* The original item.
|
|
105
|
-
*/
|
|
106
|
-
readonly item: T;
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* An array of ranges representing the match regions.
|
|
110
|
-
*/
|
|
111
|
-
readonly ranges: ReadonlyArray<Range>;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* The fuzzy search input.
|
|
116
|
-
*/
|
|
117
|
-
export interface Input<T> {
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* The pattern to match.
|
|
121
|
-
*/
|
|
122
|
-
readonly pattern: string;
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* The items to filter based on the `pattern`.
|
|
126
|
-
*/
|
|
127
|
-
readonly items: ReadonlyArray<T>;
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Function that extracts the string from the inputs which will be used to evaluate the fuzzy matching filter.
|
|
131
|
-
*/
|
|
132
|
-
readonly transform: (item: T) => string;
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
}
|
|
17
|
+
// Re-export from common location for backward compatibility.
|
|
18
|
+
export { FuzzySearch } from '../../common/fuzzy-search';
|
|
@@ -257,8 +257,7 @@ export class TreeViewWelcomeWidget extends TreeWidget {
|
|
|
257
257
|
event.stopPropagation();
|
|
258
258
|
|
|
259
259
|
if (value.startsWith('command:')) {
|
|
260
|
-
|
|
261
|
-
this.commands.executeCommand(command);
|
|
260
|
+
open(this.openerService, new URI(value));
|
|
262
261
|
} else if (value.startsWith('file:')) {
|
|
263
262
|
const uri = value.replace('file:', '');
|
|
264
263
|
open(this.openerService, new URI(CodeUri.file(uri).toString()));
|
|
@@ -60,6 +60,7 @@ export class SelectComponent extends React.Component<SelectComponentProps, Selec
|
|
|
60
60
|
protected mountedListeners: Map<string, EventListenerOrEventListenerObject> = new Map();
|
|
61
61
|
protected optimalWidth = 0;
|
|
62
62
|
protected optimalHeight = 0;
|
|
63
|
+
protected resizeObserver: ResizeObserver | undefined;
|
|
63
64
|
|
|
64
65
|
constructor(props: SelectComponentProps) {
|
|
65
66
|
super(props);
|
|
@@ -148,14 +149,16 @@ export class SelectComponent extends React.Component<SelectComponentProps, Selec
|
|
|
148
149
|
return optimal + 20; // Just to be safe, add another 20 pixels here
|
|
149
150
|
}
|
|
150
151
|
|
|
151
|
-
|
|
152
|
-
const hide = (event:
|
|
152
|
+
protected attachListeners(): void {
|
|
153
|
+
const hide = (event: Event) => {
|
|
153
154
|
if (!this.dropdownRef.current?.contains(event.target as Node)) {
|
|
154
155
|
this.hide();
|
|
155
156
|
}
|
|
156
157
|
};
|
|
158
|
+
const hideOnResize = () => this.hide();
|
|
157
159
|
this.mountedListeners.set('scroll', hide);
|
|
158
160
|
this.mountedListeners.set('wheel', hide);
|
|
161
|
+
this.mountedListeners.set('resize', hideOnResize);
|
|
159
162
|
|
|
160
163
|
let parent = this.fieldRef.current?.parentElement;
|
|
161
164
|
while (parent) {
|
|
@@ -170,9 +173,43 @@ export class SelectComponent extends React.Component<SelectComponentProps, Selec
|
|
|
170
173
|
for (const [key, listener] of this.mountedListeners.entries()) {
|
|
171
174
|
window.addEventListener(key, listener);
|
|
172
175
|
}
|
|
176
|
+
|
|
177
|
+
// Catch Lumino sash drags globally - observe the closest lm-Widget panel
|
|
178
|
+
const fieldEl = this.fieldRef.current;
|
|
179
|
+
const resizablePanel = fieldEl?.closest('.lm-Widget') ?? fieldEl?.parentElement;
|
|
180
|
+
|
|
181
|
+
if (resizablePanel && typeof ResizeObserver !== 'undefined') {
|
|
182
|
+
let lastWidth = 0;
|
|
183
|
+
let lastHeight = 0;
|
|
184
|
+
let isFirstFire = true;
|
|
185
|
+
|
|
186
|
+
this.resizeObserver = new ResizeObserver(entries => {
|
|
187
|
+
for (const entry of entries) {
|
|
188
|
+
const { width, height } = entry.contentRect;
|
|
189
|
+
|
|
190
|
+
// Ignore the initial automatic fire when the observer attaches
|
|
191
|
+
if (isFirstFire) {
|
|
192
|
+
lastWidth = width;
|
|
193
|
+
lastHeight = height;
|
|
194
|
+
isFirstFire = false;
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Only hide if the panel dimensions actually changed by more than 2 pixels
|
|
199
|
+
if (this.state.dimensions && (Math.abs(width - lastWidth) > 2 || Math.abs(height - lastHeight) > 2)) {
|
|
200
|
+
this.hide();
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
lastWidth = width;
|
|
204
|
+
lastHeight = height;
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
this.resizeObserver.observe(resizablePanel);
|
|
208
|
+
}
|
|
173
209
|
}
|
|
174
210
|
|
|
175
211
|
override componentWillUnmount(): void {
|
|
212
|
+
this.resizeObserver?.disconnect();
|
|
176
213
|
if (this.mountedListeners.size > 0) {
|
|
177
214
|
const eventListener = this.mountedListeners.get('scroll')!;
|
|
178
215
|
let parent = this.fieldRef.current?.parentElement;
|
|
@@ -53,8 +53,13 @@ export class DefaultWindowService implements WindowService, FrontendApplicationC
|
|
|
53
53
|
return undefined;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
openNewDefaultWindow():
|
|
56
|
+
async openNewDefaultWindow(): Promise<number> {
|
|
57
57
|
this.openNewWindow(`#${DEFAULT_WINDOW_HASH}`);
|
|
58
|
+
return -1;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
closeWindow(windowId: number): void {
|
|
62
|
+
// No-op in browser-only mode
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
focus(): void {
|
|
@@ -20,7 +20,8 @@ import { WindowService } from '../window-service';
|
|
|
20
20
|
@injectable()
|
|
21
21
|
export class MockWindowService implements WindowService {
|
|
22
22
|
openNewWindow(): undefined { return undefined; }
|
|
23
|
-
openNewDefaultWindow():
|
|
23
|
+
async openNewDefaultWindow(): Promise<number> { return -1; }
|
|
24
|
+
closeWindow(): void { }
|
|
24
25
|
focus(): void { }
|
|
25
26
|
reload(): void { }
|
|
26
27
|
isSafeToShutDown(): Promise<boolean> { return Promise.resolve(true); }
|