@theia/core 1.37.0-next.9 → 1.38.0-next.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/README.md +7 -9
- package/i18n/nls.cs.json +6 -1
- package/i18n/nls.de.json +6 -1
- package/i18n/nls.es.json +6 -1
- package/i18n/nls.fr.json +6 -1
- package/i18n/nls.hu.json +6 -1
- package/i18n/nls.it.json +6 -1
- package/i18n/nls.ja.json +6 -1
- package/i18n/nls.json +6 -1
- package/i18n/nls.pl.json +6 -1
- package/i18n/nls.pt-br.json +6 -1
- package/i18n/nls.pt-pt.json +6 -1
- package/i18n/nls.ru.json +6 -1
- package/i18n/nls.zh-cn.json +6 -1
- package/lib/browser/core-preferences.d.ts +4 -0
- package/lib/browser/core-preferences.d.ts.map +1 -1
- package/lib/browser/core-preferences.js +22 -0
- package/lib/browser/core-preferences.js.map +1 -1
- package/lib/browser/hover-service.d.ts +5 -0
- package/lib/browser/hover-service.d.ts.map +1 -1
- package/lib/browser/hover-service.js +7 -1
- package/lib/browser/hover-service.js.map +1 -1
- package/lib/browser/icon-theme-service.js +1 -1
- package/lib/browser/icon-theme-service.js.map +1 -1
- package/lib/browser/shell/application-shell.d.ts +2 -1
- package/lib/browser/shell/application-shell.d.ts.map +1 -1
- package/lib/browser/shell/application-shell.js +30 -3
- package/lib/browser/shell/application-shell.js.map +1 -1
- package/lib/browser/shell/tab-bars.d.ts +21 -5
- package/lib/browser/shell/tab-bars.d.ts.map +1 -1
- package/lib/browser/shell/tab-bars.js +94 -17
- package/lib/browser/shell/tab-bars.js.map +1 -1
- package/lib/browser/test/jsdom.js +1 -1
- package/lib/browser/test/jsdom.js.map +1 -1
- package/lib/browser/tree/tree-iterator.js +4 -4
- package/lib/browser/tree/tree-iterator.js.map +1 -1
- package/lib/browser/tree/tree-selection-state.spec.js +26 -2
- package/lib/browser/tree/tree-selection-state.spec.js.map +1 -1
- package/lib/common/i18n/localization.d.ts +1 -0
- package/lib/common/i18n/localization.d.ts.map +1 -1
- package/lib/common/i18n/localization.js +2 -16
- package/lib/common/i18n/localization.js.map +1 -1
- package/lib/common/nls.d.ts +1 -0
- package/lib/common/nls.d.ts.map +1 -1
- package/lib/common/nls.js +2 -1
- package/lib/common/nls.js.map +1 -1
- package/lib/common/quick-pick-service.d.ts +2 -1
- package/lib/common/quick-pick-service.d.ts.map +1 -1
- package/lib/common/quick-pick-service.js.map +1 -1
- package/lib/electron-browser/electron-clipboard-service.d.ts.map +1 -1
- package/lib/electron-browser/electron-clipboard-service.js +2 -3
- package/lib/electron-browser/electron-clipboard-service.js.map +1 -1
- package/lib/electron-browser/keyboard/electron-keyboard-layout-change-notifier.d.ts.map +1 -1
- package/lib/electron-browser/keyboard/electron-keyboard-layout-change-notifier.js +1 -2
- package/lib/electron-browser/keyboard/electron-keyboard-layout-change-notifier.js.map +1 -1
- package/lib/electron-browser/menu/electron-context-menu-renderer.d.ts +2 -3
- package/lib/electron-browser/menu/electron-context-menu-renderer.d.ts.map +1 -1
- package/lib/electron-browser/menu/electron-context-menu-renderer.js +10 -18
- package/lib/electron-browser/menu/electron-context-menu-renderer.js.map +1 -1
- package/lib/electron-browser/menu/electron-main-menu-factory.d.ts +10 -8
- package/lib/electron-browser/menu/electron-main-menu-factory.d.ts.map +1 -1
- package/lib/electron-browser/menu/electron-main-menu-factory.js +33 -32
- package/lib/electron-browser/menu/electron-main-menu-factory.js.map +1 -1
- package/lib/electron-browser/menu/electron-menu-contribution.d.ts +6 -6
- package/lib/electron-browser/menu/electron-menu-contribution.d.ts.map +1 -1
- package/lib/electron-browser/menu/electron-menu-contribution.js +39 -54
- package/lib/electron-browser/menu/electron-menu-contribution.js.map +1 -1
- package/lib/electron-browser/messaging/electron-ipc-connection-provider.d.ts.map +1 -1
- package/lib/electron-browser/messaging/electron-ipc-connection-provider.js +2 -6
- package/lib/electron-browser/messaging/electron-ipc-connection-provider.js.map +1 -1
- package/lib/electron-browser/preload.d.ts +2 -0
- package/lib/electron-browser/preload.d.ts.map +1 -0
- package/lib/electron-browser/preload.js +183 -0
- package/lib/electron-browser/preload.js.map +1 -0
- package/lib/electron-browser/token/electron-token-frontend-module.d.ts.map +1 -1
- package/lib/electron-browser/token/electron-token-frontend-module.js +1 -2
- package/lib/electron-browser/token/electron-token-frontend-module.js.map +1 -1
- package/lib/electron-browser/window/electron-frontend-application-state.d.ts.map +1 -1
- package/lib/electron-browser/window/electron-frontend-application-state.js +1 -3
- package/lib/electron-browser/window/electron-frontend-application-state.js.map +1 -1
- package/lib/electron-browser/window/electron-secondary-window-service.d.ts +1 -3
- package/lib/electron-browser/window/electron-secondary-window-service.d.ts.map +1 -1
- package/lib/electron-browser/window/electron-secondary-window-service.js +6 -34
- package/lib/electron-browser/window/electron-secondary-window-service.js.map +1 -1
- package/lib/electron-browser/window/electron-window-service.d.ts +1 -8
- package/lib/electron-browser/window/electron-window-service.d.ts.map +1 -1
- package/lib/electron-browser/window/electron-window-service.js +8 -25
- package/lib/electron-browser/window/electron-window-service.js.map +1 -1
- package/lib/electron-common/electron-api.d.ts +94 -0
- package/lib/electron-common/electron-api.d.ts.map +1 -0
- package/lib/electron-common/electron-api.js +53 -0
- package/lib/electron-common/electron-api.js.map +1 -0
- package/lib/electron-common/messaging/electron-connection-handler.d.ts +0 -7
- package/lib/electron-common/messaging/electron-connection-handler.d.ts.map +1 -1
- package/lib/electron-common/messaging/electron-connection-handler.js +1 -5
- package/lib/electron-common/messaging/electron-connection-handler.js.map +1 -1
- package/lib/electron-main/electron-api-main.d.ts +21 -0
- package/lib/electron-main/electron-api-main.d.ts.map +1 -0
- package/lib/electron-main/electron-api-main.js +261 -0
- package/lib/electron-main/electron-api-main.js.map +1 -0
- package/lib/electron-main/electron-main-application-module.d.ts.map +1 -1
- package/lib/electron-main/electron-main-application-module.js +3 -3
- package/lib/electron-main/electron-main-application-module.js.map +1 -1
- package/lib/electron-main/electron-main-application.d.ts +8 -2
- package/lib/electron-main/electron-main-application.d.ts.map +1 -1
- package/lib/electron-main/electron-main-application.js +32 -29
- package/lib/electron-main/electron-main-application.js.map +1 -1
- package/lib/electron-main/electron-security-token-service.d.ts.map +1 -1
- package/lib/electron-main/electron-security-token-service.js +2 -1
- package/lib/electron-main/electron-security-token-service.js.map +1 -1
- package/lib/electron-main/messaging/electron-messaging-contribution.d.ts +4 -5
- package/lib/electron-main/messaging/electron-messaging-contribution.d.ts.map +1 -1
- package/lib/electron-main/messaging/electron-messaging-contribution.js +4 -7
- package/lib/electron-main/messaging/electron-messaging-contribution.js.map +1 -1
- package/lib/electron-main/theia-electron-window.d.ts +2 -4
- package/lib/electron-main/theia-electron-window.d.ts.map +1 -1
- package/lib/electron-main/theia-electron-window.js +11 -34
- package/lib/electron-main/theia-electron-window.js.map +1 -1
- package/lib/node/i18n/localization-backend-contribution.d.ts.map +1 -1
- package/lib/node/i18n/localization-backend-contribution.js +2 -1
- package/lib/node/i18n/localization-backend-contribution.js.map +1 -1
- package/lib/node/i18n/localization-provider.d.ts.map +1 -1
- package/lib/node/i18n/localization-provider.js +2 -1
- package/lib/node/i18n/localization-provider.js.map +1 -1
- package/package.json +9 -6
- package/src/browser/core-preferences.ts +26 -0
- package/src/browser/hover-service.ts +12 -1
- package/src/browser/icon-theme-service.ts +1 -1
- package/src/browser/shell/application-shell.ts +29 -1
- package/src/browser/shell/tab-bars.ts +111 -17
- package/src/browser/style/hover-service.css +4 -0
- package/src/browser/style/tabs.css +25 -0
- package/src/browser/style/tree.css +1 -0
- package/src/browser/test/jsdom.ts +1 -1
- package/src/browser/tree/tree-iterator.ts +4 -4
- package/src/browser/tree/tree-selection-state.spec.ts +29 -2
- package/src/common/i18n/localization.ts +6 -16
- package/src/common/nls.ts +3 -1
- package/src/common/quick-pick-service.ts +2 -1
- package/src/electron-browser/electron-clipboard-service.ts +2 -3
- package/src/electron-browser/keyboard/electron-keyboard-layout-change-notifier.ts +1 -2
- package/src/electron-browser/menu/electron-context-menu-renderer.ts +10 -17
- package/src/electron-browser/menu/electron-main-menu-factory.ts +51 -44
- package/src/electron-browser/menu/electron-menu-contribution.ts +46 -57
- package/src/electron-browser/messaging/electron-ipc-connection-provider.ts +4 -9
- package/src/electron-browser/preload.ts +208 -0
- package/src/electron-browser/token/electron-token-frontend-module.ts +1 -2
- package/src/electron-browser/window/electron-frontend-application-state.ts +1 -3
- package/src/electron-browser/window/electron-secondary-window-service.ts +7 -31
- package/src/electron-browser/window/electron-window-service.ts +8 -25
- package/src/electron-common/electron-api.ts +134 -0
- package/src/electron-common/messaging/electron-connection-handler.ts +0 -9
- package/src/electron-main/electron-api-main.ts +291 -0
- package/src/electron-main/electron-main-application-module.ts +3 -4
- package/src/electron-main/electron-main-application.ts +33 -37
- package/src/electron-main/electron-security-token-service.ts +2 -1
- package/src/electron-main/messaging/electron-messaging-contribution.ts +8 -10
- package/src/electron-main/theia-electron-window.ts +8 -33
- package/src/node/i18n/localization-backend-contribution.ts +2 -1
- package/src/node/i18n/localization-provider.ts +2 -1
- package/LICENSE +0 -642
- package/electron-shared/@electron/remote/index.d.ts +0 -1
- package/electron-shared/@electron/remote/index.js +0 -1
- package/electron-shared/@electron/remote/main/index.d.ts +0 -1
- package/electron-shared/@electron/remote/main/index.js +0 -1
- package/lib/electron-common/messaging/electron-messages.d.ts +0 -25
- package/lib/electron-common/messaging/electron-messages.d.ts.map +0 -1
- package/lib/electron-common/messaging/electron-messages.js +0 -37
- package/lib/electron-common/messaging/electron-messages.js.map +0 -1
- package/lib/electron-main/electron-native-keymap.d.ts +0 -8
- package/lib/electron-main/electron-native-keymap.d.ts.map +0 -1
- package/lib/electron-main/electron-native-keymap.js +0 -48
- package/lib/electron-main/electron-native-keymap.js.map +0 -1
- package/src/electron-common/messaging/electron-messages.ts +0 -42
- package/src/electron-main/electron-native-keymap.ts +0 -40
|
@@ -67,6 +67,10 @@ export interface SideBarRenderData extends TabBar.IRenderData<Widget> {
|
|
|
67
67
|
paddingBottom?: number;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
export interface ScrollableRenderData extends TabBar.IRenderData<Widget> {
|
|
71
|
+
tabWidth?: number;
|
|
72
|
+
}
|
|
73
|
+
|
|
70
74
|
/**
|
|
71
75
|
* A tab bar renderer that offers a context menu. In addition, this renderer is able to
|
|
72
76
|
* set an explicit position and size on the icon and label of each tab in a side bar.
|
|
@@ -157,9 +161,7 @@ export class TabBarRenderer extends TabBar.Renderer {
|
|
|
157
161
|
? nls.localizeByDefault('Unpin')
|
|
158
162
|
: nls.localizeByDefault('Close');
|
|
159
163
|
|
|
160
|
-
const hover = this.tabBar && this.tabBar.orientation === 'horizontal' ? {
|
|
161
|
-
title: title.caption
|
|
162
|
-
} : {
|
|
164
|
+
const hover = this.tabBar && (this.tabBar.orientation === 'horizontal' && !this.corePreferences?.['window.tabbar.enhancedPreview']) ? { title: title.caption } : {
|
|
163
165
|
onmouseenter: this.handleMouseEnterEvent
|
|
164
166
|
};
|
|
165
167
|
|
|
@@ -204,11 +206,12 @@ export class TabBarRenderer extends TabBar.Renderer {
|
|
|
204
206
|
* If size information is available for the label and icon, set an explicit height on the tab.
|
|
205
207
|
* The height value also considers padding, which should be derived from CSS settings.
|
|
206
208
|
*/
|
|
207
|
-
override createTabStyle(data: SideBarRenderData): ElementInlineStyle {
|
|
209
|
+
override createTabStyle(data: SideBarRenderData & ScrollableRenderData): ElementInlineStyle {
|
|
208
210
|
const zIndex = `${data.zIndex}`;
|
|
209
211
|
const labelSize = data.labelSize;
|
|
210
212
|
const iconSize = data.iconSize;
|
|
211
213
|
let height: string | undefined;
|
|
214
|
+
let width: string | undefined;
|
|
212
215
|
if (labelSize || iconSize) {
|
|
213
216
|
const labelHeight = labelSize ? (this.tabBar && this.tabBar.orientation === 'horizontal' ? labelSize.height : labelSize.width) : 0;
|
|
214
217
|
const iconHeight = iconSize ? iconSize.height : 0;
|
|
@@ -220,7 +223,12 @@ export class TabBarRenderer extends TabBar.Renderer {
|
|
|
220
223
|
const paddingBottom = data.paddingBottom || 0;
|
|
221
224
|
height = `${labelHeight + iconHeight + paddingTop + paddingBottom}px`;
|
|
222
225
|
}
|
|
223
|
-
|
|
226
|
+
if (data.tabWidth) {
|
|
227
|
+
width = `${data.tabWidth}px`;
|
|
228
|
+
} else {
|
|
229
|
+
width = '';
|
|
230
|
+
}
|
|
231
|
+
return { zIndex, height, width };
|
|
224
232
|
}
|
|
225
233
|
|
|
226
234
|
/**
|
|
@@ -474,16 +482,41 @@ export class TabBarRenderer extends TabBar.Renderer {
|
|
|
474
482
|
return h.div({ className: baseClassName, style }, data.title.iconLabel);
|
|
475
483
|
}
|
|
476
484
|
|
|
485
|
+
protected renderEnhancedPreview = (title: Title<Widget>) => {
|
|
486
|
+
const hoverBox = document.createElement('div');
|
|
487
|
+
hoverBox.classList.add('theia-horizontal-tabBar-hover-div');
|
|
488
|
+
const labelElement = document.createElement('p');
|
|
489
|
+
labelElement.classList.add('theia-horizontal-tabBar-hover-title');
|
|
490
|
+
labelElement.textContent = title.label;
|
|
491
|
+
hoverBox.append(labelElement);
|
|
492
|
+
if (title.caption) {
|
|
493
|
+
const captionElement = document.createElement('p');
|
|
494
|
+
captionElement.classList.add('theia-horizontal-tabBar-hover-caption');
|
|
495
|
+
captionElement.textContent = title.caption;
|
|
496
|
+
hoverBox.appendChild(captionElement);
|
|
497
|
+
}
|
|
498
|
+
return hoverBox;
|
|
499
|
+
};
|
|
500
|
+
|
|
477
501
|
protected handleMouseEnterEvent = (event: MouseEvent) => {
|
|
478
502
|
if (this.tabBar && this.hoverService && event.currentTarget instanceof HTMLElement) {
|
|
479
503
|
const id = event.currentTarget.id;
|
|
480
504
|
const title = this.tabBar.titles.find(t => this.createTabId(t) === id);
|
|
481
505
|
if (title) {
|
|
482
|
-
this.
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
506
|
+
if (this.tabBar.orientation === 'horizontal') {
|
|
507
|
+
this.hoverService.requestHover({
|
|
508
|
+
content: this.renderEnhancedPreview(title),
|
|
509
|
+
target: event.currentTarget,
|
|
510
|
+
position: 'bottom',
|
|
511
|
+
cssClasses: ['extended-tab-preview']
|
|
512
|
+
});
|
|
513
|
+
} else {
|
|
514
|
+
this.hoverService.requestHover({
|
|
515
|
+
content: title.caption,
|
|
516
|
+
target: event.currentTarget,
|
|
517
|
+
position: 'right'
|
|
518
|
+
});
|
|
519
|
+
}
|
|
487
520
|
}
|
|
488
521
|
}
|
|
489
522
|
};
|
|
@@ -542,6 +575,13 @@ export class TabBarRenderer extends TabBar.Renderer {
|
|
|
542
575
|
|
|
543
576
|
}
|
|
544
577
|
|
|
578
|
+
export namespace ScrollableTabBar {
|
|
579
|
+
export interface Options {
|
|
580
|
+
minimumTabSize: number;
|
|
581
|
+
defaultTabSize: number;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
545
585
|
/**
|
|
546
586
|
* A specialized tab bar for the main and bottom areas.
|
|
547
587
|
*/
|
|
@@ -551,12 +591,26 @@ export class ScrollableTabBar extends TabBar<Widget> {
|
|
|
551
591
|
|
|
552
592
|
private scrollBarFactory: () => PerfectScrollbar;
|
|
553
593
|
private pendingReveal?: Promise<void>;
|
|
594
|
+
private isMouseOver = false;
|
|
595
|
+
protected needsRecompute = false;
|
|
596
|
+
protected tabSize = 0;
|
|
597
|
+
private _dynamicTabOptions?: ScrollableTabBar.Options;
|
|
554
598
|
|
|
555
599
|
protected readonly toDispose = new DisposableCollection();
|
|
556
600
|
|
|
557
|
-
constructor(options?: TabBar.IOptions<Widget> & PerfectScrollbar.Options) {
|
|
601
|
+
constructor(options?: TabBar.IOptions<Widget> & PerfectScrollbar.Options, dynamicTabOptions?: ScrollableTabBar.Options) {
|
|
558
602
|
super(options);
|
|
559
603
|
this.scrollBarFactory = () => new PerfectScrollbar(this.scrollbarHost, options);
|
|
604
|
+
this._dynamicTabOptions = dynamicTabOptions;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
set dynamicTabOptions(options: ScrollableTabBar.Options | undefined) {
|
|
608
|
+
this._dynamicTabOptions = options;
|
|
609
|
+
this.updateTabs();
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
get dynamicTabOptions(): ScrollableTabBar.Options | undefined {
|
|
613
|
+
return this._dynamicTabOptions;
|
|
560
614
|
}
|
|
561
615
|
|
|
562
616
|
override dispose(): void {
|
|
@@ -571,6 +625,14 @@ export class ScrollableTabBar extends TabBar<Widget> {
|
|
|
571
625
|
if (!this.scrollBar) {
|
|
572
626
|
this.scrollBar = this.scrollBarFactory();
|
|
573
627
|
}
|
|
628
|
+
this.node.addEventListener('mouseenter', () => { this.isMouseOver = true; });
|
|
629
|
+
this.node.addEventListener('mouseleave', () => {
|
|
630
|
+
this.isMouseOver = false;
|
|
631
|
+
if (this.needsRecompute) {
|
|
632
|
+
this.updateTabs();
|
|
633
|
+
}
|
|
634
|
+
});
|
|
635
|
+
|
|
574
636
|
super.onAfterAttach(msg);
|
|
575
637
|
}
|
|
576
638
|
|
|
@@ -583,7 +645,34 @@ export class ScrollableTabBar extends TabBar<Widget> {
|
|
|
583
645
|
}
|
|
584
646
|
|
|
585
647
|
protected override onUpdateRequest(msg: Message): void {
|
|
586
|
-
|
|
648
|
+
this.updateTabs();
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
protected updateTabs(): void {
|
|
652
|
+
|
|
653
|
+
const content = [];
|
|
654
|
+
if (this.dynamicTabOptions) {
|
|
655
|
+
if (this.isMouseOver) {
|
|
656
|
+
this.needsRecompute = true;
|
|
657
|
+
} else {
|
|
658
|
+
this.needsRecompute = false;
|
|
659
|
+
if (this.orientation === 'horizontal') {
|
|
660
|
+
this.tabSize = Math.max(Math.min(this.scrollbarHost.clientWidth / this.titles.length,
|
|
661
|
+
this.dynamicTabOptions.defaultTabSize), this.dynamicTabOptions.minimumTabSize);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
for (let i = 0, n = this.titles.length; i < n; ++i) {
|
|
666
|
+
const title = this.titles[i];
|
|
667
|
+
const current = title === this.currentTitle;
|
|
668
|
+
const zIndex = current ? n : n - i - 1;
|
|
669
|
+
const renderData: ScrollableRenderData = { title: title, current: current, zIndex: zIndex };
|
|
670
|
+
if (this.dynamicTabOptions && this.orientation === 'horizontal') {
|
|
671
|
+
renderData.tabWidth = this.tabSize;
|
|
672
|
+
}
|
|
673
|
+
content[i] = this.renderer.renderTab(renderData);
|
|
674
|
+
}
|
|
675
|
+
VirtualDOM.render(content, this.contentNode);
|
|
587
676
|
if (this.scrollBar) {
|
|
588
677
|
this.scrollBar.update();
|
|
589
678
|
}
|
|
@@ -591,6 +680,9 @@ export class ScrollableTabBar extends TabBar<Widget> {
|
|
|
591
680
|
|
|
592
681
|
protected override onResize(msg: Widget.ResizeMessage): void {
|
|
593
682
|
super.onResize(msg);
|
|
683
|
+
if (this.dynamicTabOptions) {
|
|
684
|
+
this.updateTabs();
|
|
685
|
+
}
|
|
594
686
|
if (this.scrollBar) {
|
|
595
687
|
if (this.currentIndex >= 0) {
|
|
596
688
|
this.revealTab(this.currentIndex);
|
|
@@ -680,9 +772,10 @@ export class ToolbarAwareTabBar extends ScrollableTabBar {
|
|
|
680
772
|
protected readonly tabBarToolbarRegistry: TabBarToolbarRegistry,
|
|
681
773
|
protected readonly tabBarToolbarFactory: () => TabBarToolbar,
|
|
682
774
|
protected readonly breadcrumbsRendererFactory: BreadcrumbsRendererFactory,
|
|
683
|
-
|
|
775
|
+
options?: TabBar.IOptions<Widget> & PerfectScrollbar.Options,
|
|
776
|
+
dynamicTabOptions?: ScrollableTabBar.Options
|
|
684
777
|
) {
|
|
685
|
-
super(options);
|
|
778
|
+
super(options, dynamicTabOptions);
|
|
686
779
|
this.breadcrumbsRenderer = this.breadcrumbsRendererFactory();
|
|
687
780
|
this.rewireDOM();
|
|
688
781
|
this.toDispose.push(this.tabBarToolbarRegistry.onDidChange(() => this.update()));
|
|
@@ -756,6 +849,7 @@ export class ToolbarAwareTabBar extends ScrollableTabBar {
|
|
|
756
849
|
}
|
|
757
850
|
const widget = this.currentTitle?.owner ?? undefined;
|
|
758
851
|
this.toolbar.updateTarget(widget);
|
|
852
|
+
this.updateTabs();
|
|
759
853
|
}
|
|
760
854
|
|
|
761
855
|
override handleEvent(event: Event): void {
|
|
@@ -859,7 +953,7 @@ export class SideTabBar extends ScrollableTabBar {
|
|
|
859
953
|
|
|
860
954
|
protected override onAfterAttach(msg: Message): void {
|
|
861
955
|
super.onAfterAttach(msg);
|
|
862
|
-
this.
|
|
956
|
+
this.updateTabs();
|
|
863
957
|
this.node.addEventListener('p-dragenter', this);
|
|
864
958
|
this.node.addEventListener('p-dragover', this);
|
|
865
959
|
this.node.addEventListener('p-dragleave', this);
|
|
@@ -875,7 +969,7 @@ export class SideTabBar extends ScrollableTabBar {
|
|
|
875
969
|
}
|
|
876
970
|
|
|
877
971
|
protected override onUpdateRequest(msg: Message): void {
|
|
878
|
-
this.
|
|
972
|
+
this.updateTabs();
|
|
879
973
|
if (this.scrollBar) {
|
|
880
974
|
this.scrollBar.update();
|
|
881
975
|
}
|
|
@@ -885,7 +979,7 @@ export class SideTabBar extends ScrollableTabBar {
|
|
|
885
979
|
* Render the tab bar in the _hidden content node_ (see `hiddenContentNode` for explanation),
|
|
886
980
|
* then gather size information for labels and render it again in the proper content node.
|
|
887
981
|
*/
|
|
888
|
-
protected
|
|
982
|
+
protected override updateTabs(): void {
|
|
889
983
|
if (this.isAttached) {
|
|
890
984
|
// Render into the invisible node
|
|
891
985
|
this.renderTabs(this.hiddenContentNode);
|
|
@@ -410,3 +410,28 @@
|
|
|
410
410
|
flex-flow: row nowrap;
|
|
411
411
|
min-width: 100%;
|
|
412
412
|
}
|
|
413
|
+
|
|
414
|
+
.p-TabBar-tab .theia-tab-icon-label {
|
|
415
|
+
flex: 1;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
.p-TabBar[data-orientation='horizontal'] .p-TabBar-tab.p-mod-closable:hover .theia-tab-icon-label,
|
|
419
|
+
.p-TabBar[data-orientation='horizontal'] .p-TabBar-tab.p-mod-current .theia-tab-icon-label {
|
|
420
|
+
overflow: hidden;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
.theia-horizontal-tabBar-hover-div {
|
|
424
|
+
margin: 0px 4px;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
.theia-horizontal-tabBar-hover-title {
|
|
428
|
+
font-weight: bolder;
|
|
429
|
+
font-size: medium;
|
|
430
|
+
margin: 0px 0px;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
.theia-horizontal-tabBar-hover-caption {
|
|
434
|
+
font-size: small;
|
|
435
|
+
margin: 0px 0px;
|
|
436
|
+
margin-top: 4px;
|
|
437
|
+
}
|
|
@@ -47,7 +47,7 @@ export function enableJSDOM(): () => void {
|
|
|
47
47
|
|
|
48
48
|
const toCleanup: string[] = [];
|
|
49
49
|
Object.getOwnPropertyNames((dom.window as any)).forEach(property => {
|
|
50
|
-
if (
|
|
50
|
+
if (!(property in global)) {
|
|
51
51
|
(global as any)[property] = (dom.window as any)[property];
|
|
52
52
|
toCleanup.push(property);
|
|
53
53
|
}
|
|
@@ -202,12 +202,12 @@ export namespace Iterators {
|
|
|
202
202
|
* Generator for depth first, pre-order tree traversal iteration.
|
|
203
203
|
*/
|
|
204
204
|
export function* depthFirst<T>(root: T, children: (node: T) => T[] | undefined, include: (node: T) => boolean = () => true): IterableIterator<T> {
|
|
205
|
-
|
|
205
|
+
let stack: T[] = [];
|
|
206
206
|
stack.push(root);
|
|
207
207
|
while (stack.length > 0) {
|
|
208
208
|
const top = stack.pop()!;
|
|
209
209
|
yield top;
|
|
210
|
-
stack.
|
|
210
|
+
stack = stack.concat((children(top) || []).filter(include).reverse());
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
213
|
|
|
@@ -215,12 +215,12 @@ export namespace Iterators {
|
|
|
215
215
|
* Generator for breadth first tree traversal iteration.
|
|
216
216
|
*/
|
|
217
217
|
export function* breadthFirst<T>(root: T, children: (node: T) => T[] | undefined, include: (node: T) => boolean = () => true): IterableIterator<T> {
|
|
218
|
-
|
|
218
|
+
let queue: T[] = [];
|
|
219
219
|
queue.push(root);
|
|
220
220
|
while (queue.length > 0) {
|
|
221
221
|
const head = queue.shift()!;
|
|
222
222
|
yield head;
|
|
223
|
-
queue.
|
|
223
|
+
queue = queue.concat((children(head) || []).filter(include));
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
|
|
17
17
|
import { expect } from 'chai';
|
|
18
18
|
import { MockTreeModel } from './test/mock-tree-model';
|
|
19
|
-
import { TreeSelectionState } from './tree-selection-state';
|
|
20
19
|
import { createTreeTestContainer } from './test/tree-test-container';
|
|
21
|
-
import { SelectableTreeNode, TreeSelection } from './tree-selection';
|
|
22
20
|
import { TreeModel } from './tree-model';
|
|
21
|
+
import { SelectableTreeNode, TreeSelection } from './tree-selection';
|
|
22
|
+
import { TreeSelectionState } from './tree-selection-state';
|
|
23
23
|
|
|
24
24
|
namespace TreeSelectionState {
|
|
25
25
|
|
|
@@ -34,6 +34,16 @@ namespace TreeSelectionState {
|
|
|
34
34
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
const LARGE_FLAT_MOCK_ROOT = (length = 250000) => {
|
|
38
|
+
const children = Array.from({ length }, (_, idx) => ({ 'id': (idx + 1).toString() }));
|
|
39
|
+
return MockTreeModel.Node.toTreeNode({
|
|
40
|
+
'id': 'ROOT',
|
|
41
|
+
'children': [
|
|
42
|
+
...children
|
|
43
|
+
]
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
|
|
37
47
|
describe('tree-selection-state', () => {
|
|
38
48
|
|
|
39
49
|
const model = createTreeModel();
|
|
@@ -391,6 +401,23 @@ describe('tree-selection-state', () => {
|
|
|
391
401
|
});
|
|
392
402
|
});
|
|
393
403
|
|
|
404
|
+
it('should be able to handle range selection on large tree', () => {
|
|
405
|
+
model.root = LARGE_FLAT_MOCK_ROOT();
|
|
406
|
+
expect(model.selectedNodes).to.be.empty;
|
|
407
|
+
|
|
408
|
+
const start = 10;
|
|
409
|
+
const end = 20;
|
|
410
|
+
newState()
|
|
411
|
+
.nextState('toggle', start.toString(), {
|
|
412
|
+
focus: start.toString(),
|
|
413
|
+
selection: [start.toString()]
|
|
414
|
+
})
|
|
415
|
+
.nextState('range', end.toString(), {
|
|
416
|
+
focus: start.toString(),
|
|
417
|
+
selection: Array.from({ length: end - start + 1 }, (_, idx) => (start + idx).toString())
|
|
418
|
+
});
|
|
419
|
+
});
|
|
420
|
+
|
|
394
421
|
function newState(): TreeSelectionState.Assert {
|
|
395
422
|
return nextState(new TreeSelectionState(model));
|
|
396
423
|
}
|
|
@@ -39,22 +39,12 @@ export type FormatType = string | number | boolean | undefined;
|
|
|
39
39
|
|
|
40
40
|
export namespace Localization {
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
let replacement = match;
|
|
49
|
-
if (typeof arg === 'string') {
|
|
50
|
-
replacement = arg;
|
|
51
|
-
} else if (typeof arg === 'number' || typeof arg === 'boolean' || !arg) {
|
|
52
|
-
replacement = String(arg);
|
|
53
|
-
}
|
|
54
|
-
return replacement;
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
return result;
|
|
42
|
+
const formatRegexp = /{([^}]+)}/g;
|
|
43
|
+
|
|
44
|
+
export function format(message: string, args: FormatType[]): string;
|
|
45
|
+
export function format(message: string, args: Record<string | number, FormatType>): string;
|
|
46
|
+
export function format(message: string, args: Record<string | number, FormatType> | FormatType[]): string {
|
|
47
|
+
return message.replace(formatRegexp, (match, group) => (args[group] ?? match) as string);
|
|
58
48
|
}
|
|
59
49
|
|
|
60
50
|
export function localize(localization: Localization | undefined, key: string, defaultValue: string, ...args: FormatType[]): string {
|
package/src/common/nls.ts
CHANGED
|
@@ -20,6 +20,8 @@ export namespace nls {
|
|
|
20
20
|
|
|
21
21
|
export let localization: Localization | undefined;
|
|
22
22
|
|
|
23
|
+
export const defaultLocale = 'en';
|
|
24
|
+
|
|
23
25
|
export const localeId = 'localeId';
|
|
24
26
|
|
|
25
27
|
export const locale = typeof window === 'object' && window && window.localStorage.getItem(localeId) || undefined;
|
|
@@ -57,7 +59,7 @@ export namespace nls {
|
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
export function isSelectedLocale(id: string): boolean {
|
|
60
|
-
if (locale === undefined && id ===
|
|
62
|
+
if (locale === undefined && id === defaultLocale) {
|
|
61
63
|
return true;
|
|
62
64
|
}
|
|
63
65
|
return locale === id;
|
|
@@ -67,6 +67,7 @@ export interface QuickPickSeparator {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
export type QuickPickItemOrSeparator = QuickPickItem | QuickPickSeparator;
|
|
70
|
+
export type QuickPickInput<T = QuickPickItem> = T | QuickPickSeparator;
|
|
70
71
|
|
|
71
72
|
export namespace QuickPickItem {
|
|
72
73
|
export function is(item: QuickPickSeparator | QuickPickItem): item is QuickPickItem {
|
|
@@ -278,7 +279,7 @@ export interface QuickInputService {
|
|
|
278
279
|
open(filter: string): void;
|
|
279
280
|
createInputBox(): InputBox;
|
|
280
281
|
input(options?: InputOptions, token?: CancellationToken): Promise<string | undefined>;
|
|
281
|
-
pick<T extends QuickPickItem, O extends PickOptions<T>>(picks: Promise<T[]> | T[], options?: O, token?: CancellationToken):
|
|
282
|
+
pick<T extends QuickPickItem, O extends PickOptions<T>>(picks: Promise<QuickPickInput<T>[]> | QuickPickInput<T>[], options?: O, token?: CancellationToken):
|
|
282
283
|
Promise<(O extends { canPickMany: true } ? T[] : T) | undefined>;
|
|
283
284
|
showQuickPick<T extends QuickPickItem>(items: Array<T | QuickPickSeparator>, options?: QuickPickOptions<T>): Promise<T | undefined>;
|
|
284
285
|
hide(): void;
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
17
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
18
|
-
import { clipboard } from 'electron';
|
|
19
18
|
import { injectable } from 'inversify';
|
|
20
19
|
import { ClipboardService } from '../browser/clipboard-service';
|
|
21
20
|
|
|
@@ -23,11 +22,11 @@ import { ClipboardService } from '../browser/clipboard-service';
|
|
|
23
22
|
export class ElectronClipboardService implements ClipboardService {
|
|
24
23
|
|
|
25
24
|
readText(): string {
|
|
26
|
-
return
|
|
25
|
+
return window.electronTheiaCore.readClipboard();
|
|
27
26
|
}
|
|
28
27
|
|
|
29
28
|
writeText(value: string): void {
|
|
30
|
-
|
|
29
|
+
window.electronTheiaCore.writeClipboard(value);
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
}
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import { ipcRenderer } from '@theia/electron/shared/electron';
|
|
18
17
|
import { postConstruct, injectable } from 'inversify';
|
|
19
18
|
import { KeyboardLayoutChangeNotifier, NativeKeyboardLayout } from '../../common/keyboard/keyboard-layout-provider';
|
|
20
19
|
import { Emitter, Event } from '../../common/event';
|
|
@@ -34,7 +33,7 @@ export class ElectronKeyboardLayoutChangeNotifier implements KeyboardLayoutChang
|
|
|
34
33
|
|
|
35
34
|
@postConstruct()
|
|
36
35
|
protected initialize(): void {
|
|
37
|
-
|
|
36
|
+
window.electronTheiaCore.onKeyboardLayoutChanged((newLayout: NativeKeyboardLayout) => this.nativeLayoutChanged.fire(newLayout));
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
}
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
|
|
17
17
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
18
18
|
|
|
19
|
-
import * as electron from '../../../electron-shared/electron';
|
|
20
19
|
import { inject, injectable, postConstruct } from 'inversify';
|
|
21
20
|
import {
|
|
22
21
|
ContextMenuRenderer, RenderContextMenuOptions, ContextMenuAccess, FrontendApplicationContribution, CommonCommands, coordinateFromAnchor, PreferenceService
|
|
@@ -25,12 +24,11 @@ import { ElectronMainMenuFactory } from './electron-main-menu-factory';
|
|
|
25
24
|
import { ContextMenuContext } from '../../browser/menu/context-menu-context';
|
|
26
25
|
import { MenuPath, MenuContribution, MenuModelRegistry } from '../../common';
|
|
27
26
|
import { BrowserContextMenuRenderer } from '../../browser/menu/browser-context-menu-renderer';
|
|
28
|
-
import { RequestTitleBarStyle, TitleBarStyleAtStartup } from '../../electron-common/messaging/electron-messages';
|
|
29
27
|
|
|
30
28
|
export class ElectronContextMenuAccess extends ContextMenuAccess {
|
|
31
|
-
constructor(readonly
|
|
29
|
+
constructor(readonly menuHandle: Promise<number>) {
|
|
32
30
|
super({
|
|
33
|
-
dispose: () =>
|
|
31
|
+
dispose: () => menuHandle.then(handle => window.electronTheiaCore.closePopup(handle))
|
|
34
32
|
});
|
|
35
33
|
}
|
|
36
34
|
}
|
|
@@ -93,10 +91,7 @@ export class ElectronContextMenuRenderer extends BrowserContextMenuRenderer {
|
|
|
93
91
|
|
|
94
92
|
@postConstruct()
|
|
95
93
|
protected async init(): Promise<void> {
|
|
96
|
-
|
|
97
|
-
this.useNativeStyle = style === 'native';
|
|
98
|
-
});
|
|
99
|
-
electron.ipcRenderer.send(RequestTitleBarStyle);
|
|
94
|
+
this.useNativeStyle = await window.electronTheiaCore.getTitleBarStyleAtStartup() === 'native';
|
|
100
95
|
}
|
|
101
96
|
|
|
102
97
|
protected override doRender(options: RenderContextMenuOptions): ContextMenuAccess {
|
|
@@ -104,17 +99,15 @@ export class ElectronContextMenuRenderer extends BrowserContextMenuRenderer {
|
|
|
104
99
|
const { menuPath, anchor, args, onHide, context, contextKeyService } = options;
|
|
105
100
|
const menu = this.electronMenuFactory.createElectronContextMenu(menuPath, args, context, contextKeyService);
|
|
106
101
|
const { x, y } = coordinateFromAnchor(anchor);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
102
|
+
|
|
103
|
+
const menuHandle = window.electronTheiaCore.popup(menu, x, y, () => {
|
|
104
|
+
if (onHide) {
|
|
105
|
+
onHide();
|
|
106
|
+
}
|
|
107
|
+
});
|
|
112
108
|
// native context menu stops the event loop, so there is no keyboard events
|
|
113
109
|
this.context.resetAltPressed();
|
|
114
|
-
|
|
115
|
-
menu.once('menu-will-close', () => onHide());
|
|
116
|
-
}
|
|
117
|
-
return new ElectronContextMenuAccess(menu);
|
|
110
|
+
return new ElectronContextMenuAccess(menuHandle);
|
|
118
111
|
} else {
|
|
119
112
|
return super.doRender(options);
|
|
120
113
|
}
|