Skip to content

Commit b52ad5b

Browse files
authored
Merge branch 'master' into gh-10684
2 parents 7e5f258 + 1819ebf commit b52ad5b

File tree

23 files changed

+207
-85
lines changed

23 files changed

+207
-85
lines changed

CHANGELOG.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,13 @@
1010

1111
- [core] Move code for untitled resources into `core` from `plugin-ext` and allow users to open untitled editors with `New File` command. [#10868](https://github.com/eclipse-theia/theia/pull/10868)
1212
- [plugin] added support for `SnippetString.appendChoice` [#10969](https://github.com/eclipse-theia/theia/pull/10969) - Contributed on behalf of STMicroelectronics
13+
- [plugin] added support for `AccessibilityInformation` [#10961](https://github.com/eclipse-theia/theia/pull/10961) - Contributed on behalf of STMicroelectronics
1314
- [core] Heavily refactored the core messaging API. Replaced `vscode-ws-jsonrpc` with a custom RPC protocol that is better suited for handling binary data and enables message tunneling.
1415
This impacts all main concepts of the messaging API. The API no longer exposes a `Connection` object and uses a generic `Channel` implementation instead.
1516
* `MessagingService`: No longer offers the `listen` and `forward` method. Use `wsChannel`instead. [#11011](https://github.com/eclipse-theia/theia/pull/11011) - Contributed on behalf of STMicroelectronics.
1617

17-
1818
<a name="breaking_changes_1.25.0">[Breaking Changes:](#breaking_changes_1.25.0)</a>
1919

20-
2120
## v1.24.0 - 3/31/2022
2221

2322
[1.24.0 Milestone](https://github.com/eclipse-theia/theia/milestone/32)

packages/core/src/browser/common-frontend-contribution.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,10 +1474,6 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
14741474
},
14751475
{
14761476
id: 'tab.activeBorderTop',
1477-
defaults: {
1478-
dark: 'focusBorder',
1479-
light: 'focusBorder'
1480-
},
14811477
description: 'Border to the top of an active tab. Tabs are the containers for editors in the editor area. Multiple tabs can be opened in one editor group. There can be multiple editor groups.'
14821478
},
14831479
{
@@ -1488,6 +1484,10 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
14881484
},
14891485
{
14901486
id: 'tab.hoverBackground',
1487+
defaults: {
1488+
dark: 'tab.inactiveBackground',
1489+
light: 'tab.inactiveBackground'
1490+
},
14911491
description: 'Tab background color when hovering. Tabs are the containers for editors in the editor area. Multiple tabs can be opened in one editor group. There can be multiple editor groups.'
14921492
},
14931493
{

packages/core/src/browser/shell/application-shell.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,7 @@ export class ApplicationShell extends Widget {
690690
this.collapseBottomPanel();
691691
}
692692
const widgets = toArray(this.bottomPanel.widgets());
693+
this.bottomPanel.markActiveTabBar(widgets[0]?.title);
693694
if (bottomPanel.pinned && bottomPanel.pinned.length === widgets.length) {
694695
widgets.forEach((a, i) => {
695696
if (bottomPanel.pinned![i]) {
@@ -706,6 +707,9 @@ export class ApplicationShell extends Widget {
706707
this.mainPanel.restoreLayout(mainPanel);
707708
this.registerWithFocusTracker(mainPanel.main);
708709
const widgets = toArray(this.mainPanel.widgets());
710+
// We don't store information about the last active tabbar
711+
// So we simply mark the first as being active
712+
this.mainPanel.markActiveTabBar(widgets[0]?.title);
709713
if (mainPanelPinned && mainPanelPinned.length === widgets.length) {
710714
widgets.forEach((a, i) => {
711715
if (mainPanelPinned[i]) {
@@ -1418,6 +1422,10 @@ export class ApplicationShell extends Widget {
14181422
alignment: StatusBarAlignment.RIGHT,
14191423
tooltip: 'Toggle Bottom Panel',
14201424
command: 'core.toggle.bottom.panel',
1425+
accessibilityInformation: {
1426+
label: 'Toggle Bottom Panel',
1427+
role: 'button'
1428+
},
14211429
priority: -1000
14221430
};
14231431
this.statusBar.setElement(BOTTOM_PANEL_TOGGLE_ID, element);

packages/core/src/browser/shell/theia-dock-panel.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { inject } from 'inversify';
2424
import { Emitter, environment } from '../../common';
2525

2626
export const MAXIMIZED_CLASS = 'theia-maximized';
27+
export const ACTIVE_TABBAR_CLASS = 'theia-tabBar-active';
2728
const VISIBLE_MENU_MAXIMIZED_CLASS = 'theia-visible-menu-maximized';
2829

2930
export const MAIN_AREA_ID = 'theia-main-content-panel';
@@ -106,6 +107,7 @@ export class TheiaDockPanel extends DockPanel {
106107
markAsCurrent(title: Title<Widget> | undefined): void {
107108
this.toDisposeOnMarkAsCurrent.dispose();
108109
this._currentTitle = title;
110+
this.markActiveTabBar(title);
109111
if (title) {
110112
const resetCurrent = () => this.markAsCurrent(undefined);
111113
title.owner.disposed.connect(resetCurrent);
@@ -115,17 +117,31 @@ export class TheiaDockPanel extends DockPanel {
115117
}
116118
}
117119

120+
markActiveTabBar(title?: Title<Widget>): void {
121+
const tabBars = toArray(this.tabBars());
122+
tabBars.forEach(tabBar => tabBar.removeClass(ACTIVE_TABBAR_CLASS));
123+
const activeTabBar = title && this.findTabBar(title);
124+
if (activeTabBar) {
125+
activeTabBar.addClass(ACTIVE_TABBAR_CLASS);
126+
} else if (tabBars.length > 0) {
127+
// At least one tabbar needs to be active
128+
tabBars[0].addClass(ACTIVE_TABBAR_CLASS);
129+
}
130+
}
131+
118132
override addWidget(widget: Widget, options?: DockPanel.IAddOptions): void {
119133
if (this.mode === 'single-document' && widget.parent === this) {
120134
return;
121135
}
122136
super.addWidget(widget, options);
123137
this.widgetAdded.emit(widget);
138+
this.markActiveTabBar(widget.title);
124139
}
125140

126141
override activateWidget(widget: Widget): void {
127142
super.activateWidget(widget);
128143
this.widgetActivated.emit(widget);
144+
this.markActiveTabBar(widget.title);
129145
}
130146

131147
protected override onChildRemoved(msg: Widget.ChildMessage): void {

packages/core/src/browser/status-bar/status-bar.tsx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { ReactWidget } from '../widgets/react-widget';
2222
import { FrontendApplicationStateService } from '../frontend-application-state';
2323
import { LabelParser, LabelIcon } from '../label-parser';
2424
import { PreferenceService } from '../preferences';
25+
import { AccessibilityInformation } from '../../common/accessibility';
2526

2627
export interface StatusBarEntry {
2728
/**
@@ -44,20 +45,14 @@ export interface StatusBarEntry {
4445
// eslint-disable-next-line @typescript-eslint/no-explicit-any
4546
arguments?: any[];
4647
priority?: number;
48+
accessibilityInformation?: AccessibilityInformation;
4749
onclick?: (e: MouseEvent) => void;
4850
}
4951

5052
export enum StatusBarAlignment {
5153
LEFT, RIGHT
5254
}
5355

54-
export interface StatusBarEntryAttributes {
55-
className?: string;
56-
title?: string;
57-
style?: object;
58-
onClick?: (e: MouseEvent) => void;
59-
}
60-
6156
export const STATUSBAR_WIDGET_FACTORY_ID = 'statusBar';
6257

6358
export const StatusBar = Symbol('StatusBar');
@@ -169,15 +164,15 @@ export class StatusBarImpl extends ReactWidget implements StatusBar {
169164
};
170165
}
171166

172-
protected createAttributes(entry: StatusBarEntry): StatusBarEntryAttributes {
173-
const attrs: StatusBarEntryAttributes = {};
167+
protected createAttributes(entry: StatusBarEntry): React.Attributes & React.HTMLAttributes<HTMLElement> {
168+
const attrs: React.Attributes & React.HTMLAttributes<HTMLElement> = {};
174169

175170
if (entry.command) {
176171
attrs.onClick = this.onclick(entry);
177172
attrs.className = 'element hasCommand';
178173
} else if (entry.onclick) {
179174
attrs.onClick = e => {
180-
if (entry.onclick) {
175+
if (entry.onclick && e instanceof MouseEvent) {
181176
entry.onclick(e);
182177
}
183178
};
@@ -189,15 +184,20 @@ export class StatusBarImpl extends ReactWidget implements StatusBar {
189184
if (entry.tooltip) {
190185
attrs.title = entry.tooltip;
191186
}
187+
if (entry.className) {
188+
attrs.className += ' ' + entry.className;
189+
}
190+
if (entry.accessibilityInformation) {
191+
attrs['aria-label'] = entry.accessibilityInformation.label;
192+
attrs.role = entry.accessibilityInformation.role;
193+
} else {
194+
attrs['aria-label'] = [entry.text, entry.tooltip].join(', ');
195+
}
192196

193197
attrs.style = {
194198
color: entry.color || this.color
195199
};
196200

197-
if (entry.className) {
198-
attrs.className += ' ' + entry.className;
199-
}
200-
201201
return attrs;
202202
}
203203

packages/core/src/browser/style/sidepanel.css

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,11 @@
9090
border-top-color: transparent;
9191
}
9292

93-
.p-TabBar.theia-app-left .p-TabBar-tab.p-mod-current.theia-mod-active {
94-
border-left: var(--theia-panel-border-width) solid var(--theia-focusBorder);
95-
}
96-
9793
.p-TabBar.theia-app-right .p-TabBar-tab.p-mod-current {
9894
border-right: var(--theia-panel-border-width) solid var(--theia-activityBar-activeBorder);
9995
border-top-color: transparent;
10096
}
10197

102-
.p-TabBar.theia-app-right .p-TabBar-tab.p-mod-current.theia-mod-active {
103-
border-right: var(--theia-panel-border-width) solid var(--theia-focusBorder);
104-
}
105-
10698
.p-TabBar.theia-app-sides .p-TabBar-tabLabel,
10799
.p-TabBar.theia-app-sides .p-TabBar-tabCloseIcon {
108100
display: none;
@@ -285,16 +277,19 @@
285277

286278
#theia-bottom-content-panel .p-TabBar-tab:not(.p-mod-current) {
287279
color: var(--theia-panelTitle-inactiveForeground);
288-
border-top: var(--theia-border-width) solid var(--theia-panel-background);
289280
}
290281

291282
#theia-bottom-content-panel .p-TabBar-tab.p-mod-current {
292283
color: var(--theia-panelTitle-activeForeground);
293-
border-top: var(--theia-border-width) solid var(--theia-panelTitle-activeBorder);
284+
box-shadow: 0 var(--theia-border-width) 0 var(--theia-panelTitle-activeBorder) inset;
285+
}
286+
287+
#theia-bottom-content-panel .p-TabBar:not(.theia-tabBar-active) .p-TabBar-tab .theia-tab-icon-label {
288+
color: var(--theia-tab-unfocusedInactiveForeground);
294289
}
295290

296-
#theia-bottom-content-panel .p-TabBar-tab.p-mod-current.theia-mod-active {
297-
border-top-color: var(--theia-focusBorder);
291+
#theia-bottom-content-panel .p-TabBar:not(.theia-tabBar-active) .p-TabBar-tab.p-mod-current .theia-tab-icon-label {
292+
color: var(--theia-tab-unfocusedActiveForeground);
298293
}
299294

300295
/*-----------------------------------------------------------------------------

packages/core/src/browser/style/tabs.css

Lines changed: 14 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -80,65 +80,34 @@
8080

8181
#theia-main-content-panel .p-TabBar .p-TabBar-tab {
8282
border-right: 1px solid var(--theia-tab-border);
83+
background: var(--theia-tab-inactiveBackground);
84+
color: var(--theia-tab-inactiveForeground);
8385
}
8486

85-
#theia-main-content-panel .p-TabBar .p-TabBar-tab:hover.theia-mod-active {
86-
background: var(--theia-tab-hoverBackground) !important;
87-
box-shadow: var(--theia-tab-hoverBorder) 0 -1px inset !important;
88-
}
89-
90-
#theia-main-content-panel .p-TabBar .p-TabBar-tab:hover:not(.theia-mod-active) {
91-
background: var(--theia-tab-unfocusedHoverBackground) !important;
92-
box-shadow: var(--theia-tab-unfocusedHoverBorder) 0 -1px inset !important;
87+
#theia-main-content-panel .p-TabBar .p-TabBar-tab:hover {
88+
background: var(--theia-tab-hoverBackground);
89+
box-shadow: 0 1px 0 var(--theia-tab-hoverBorder) inset;
9390
}
9491

95-
/* active tab in an active group */
96-
body.theia-editor-highlightModifiedTabs
97-
#theia-main-content-panel .p-TabBar .p-TabBar-tab.p-mod-current.theia-mod-active.theia-mod-dirty {
98-
border-top: 1px solid var(--theia-tab-activeModifiedBorder);
92+
#theia-main-content-panel .p-TabBar:not(.theia-tabBar-active) .p-TabBar-tab:hover {
93+
background: var(--theia-tab-unfocusedHoverBackground);
94+
box-shadow: 0 1px 0 var(--theia-tab-unfocusedHoverBorder) inset;
9995
}
10096

101-
#theia-main-content-panel .p-TabBar .p-TabBar-tab.p-mod-current.theia-mod-active {
97+
#theia-main-content-panel .p-TabBar .p-TabBar-tab.p-mod-current {
10298
background: var(--theia-tab-activeBackground);
10399
color: var(--theia-tab-activeForeground);
104-
border-top: 1px solid var(--theia-tab-activeBorderTop);
105-
border-bottom: 1px solid var(--theia-tab-activeBorder);
106-
}
107-
108-
/* inactive tab in an active group */
109-
body.theia-editor-highlightModifiedTabs
110-
#theia-main-content-panel .p-TabBar .p-TabBar-tab:not(.p-mod-current).theia-mod-active.theia-mod-dirty {
111-
border-top: 1px solid var(--theia-tab-inactiveModifiedBorder);
112-
}
113-
114-
#theia-main-content-panel .p-TabBar .p-TabBar-tab:not(.p-mod-current).theia-mod-active {
115-
background: var(--theia-tab-inactiveBackground);
116-
color: var(--theia-tab-inactiveForeground);
100+
box-shadow: 0 1px 0 var(--theia-tab-activeBorderTop) inset, 0 -1px 0 var(--theia-tab-activeBorder) inset;
117101
}
118102

119-
/* active tab in an unfocused group */
120-
body.theia-editor-highlightModifiedTabs
121-
#theia-main-content-panel .p-TabBar .p-TabBar-tab.p-mod-current:not(.theia-mod-active).theia-mod-dirty {
122-
border-top: 1px solid var(--theia-tab-unfocusedActiveModifiedBorder);
103+
#theia-main-content-panel .p-TabBar:not(.theia-tabBar-active) .p-TabBar-tab {
104+
color: var(--theia-tab-unfocusedInactiveForeground);
123105
}
124106

125-
#theia-main-content-panel .p-TabBar .p-TabBar-tab.p-mod-current:not(.theia-mod-active) {
107+
#theia-main-content-panel .p-TabBar:not(.theia-tabBar-active) .p-TabBar-tab.p-mod-current {
126108
background: var(--theia-tab-unfocusedActiveBackground);
127109
color: var(--theia-tab-unfocusedActiveForeground);
128-
border-top: 1px solid var(--theia-tab-unfocusedActiveBorderTop);
129-
border-bottom: 1px solid var(--theia-tab-unfocusedActiveBorder);
130-
}
131-
132-
/* inactive tab in an unfocused group */
133-
body.theia-editor-highlightModifiedTabs
134-
#theia-main-content-panel .p-TabBar .p-TabBar-tab:not(.p-mod-current):not(.theia-mod-active).theia-mod-dirty {
135-
border-top: 1px solid var(--theia-tab-unfocusedInactiveModifiedBorder);
136-
}
137-
138-
#theia-main-content-panel .p-TabBar .p-TabBar-tab:not(.p-mod-current):not(.theia-mod-active) {
139-
background: var(--theia-tab-inactiveBackground);
140-
color: var(--theia-tab-inactiveForeground);
141-
border-top: 1px solid var(--theia-tab-inactiveBackground);
110+
box-shadow: 0 1px 0 var(--theia-tab-unfocusedActiveBorderTop) inset, 0 -1px 0 var(--theia-tab-unfocusedActiveBorder) inset;
142111
}
143112

144113
.p-TabBar.theia-app-centers {
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// *****************************************************************************
2+
// Copyright (C) 2022 STMicroelectronics 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 WITH Classpath-exception-2.0
15+
// *****************************************************************************
16+
17+
/**
18+
* Accessibility information which controls screen reader behavior.
19+
*/
20+
export interface AccessibilityInformation {
21+
/**
22+
* Label to be read out by a screen reader once the item has focus.
23+
*/
24+
readonly label: string;
25+
26+
/**
27+
* Role of the widget which defines how a screen reader interacts with it.
28+
* The role should be set in special cases when for example a tree-like element behaves like a checkbox.
29+
* If role is not specified the editor will pick the appropriate role automatically.
30+
* More about aria roles can be found here https://w3c.github.io/aria/#widget_roles
31+
*/
32+
readonly role?: string;
33+
}

packages/core/src/common/quick-pick-service.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ export interface QuickPick<T extends QuickPickItemOrSeparator> extends QuickInpu
201201
canSelectMany: boolean;
202202
matchOnDescription: boolean;
203203
matchOnDetail: boolean;
204+
keepScrollPosition: boolean;
204205
readonly onDidAccept: Event<{ inBackground: boolean } | undefined>;
205206
readonly onDidChangeValue: Event<string>;
206207
readonly onDidTriggerButton: Event<QuickInputButton>;
@@ -261,6 +262,7 @@ export interface QuickPickOptions<T extends QuickPickItemOrSeparator> {
261262
matchOnDetail?: boolean;
262263
matchOnLabel?: boolean;
263264
sortByLabel?: boolean;
265+
keepScrollPosition?: boolean;
264266
autoFocusOnList?: boolean;
265267
ignoreFocusOut?: boolean;
266268
valueSelection?: Readonly<[number, number]>;

packages/git/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"dugite-extra": "0.1.15",
1818
"find-git-exec": "^0.0.4",
1919
"find-git-repositories": "^0.1.1",
20-
"moment": "2.24.0",
20+
"moment": "2.29.2",
2121
"octicons": "^7.1.0",
2222
"p-queue": "^2.4.2",
2323
"ts-md5": "^1.2.2"

0 commit comments

Comments
 (0)