Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
- [plugin] Introduce `DebugSession#workspaceFolder` [#11090](https://github.com/eclipse-theia/theia/pull/11090) - Contributed on behalf of STMicroelectronics
- [console] fixed issue in Debug console where console history was not being trimmed in accordance with the maximum commands limit [#10598](https://github.com/eclipse-theia/theia/pull/10598)

<a name="breaking_changes_1.26.0">[Breaking Changes:](#breaking_changes_1.26.0)</a>

- [callhierarchy] `paths.ts` and `glob.ts` moved to `core/src/common`; `language-selector.ts` moved to `editor/src/common`. Any imports will need to be updated.

## v1.25.0 - 4/28/2022

[1.25.0 Milestone](https://github.com/eclipse-theia/theia/milestone/35)
Expand Down
14 changes: 12 additions & 2 deletions examples/api-tests/src/preferences.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,21 @@ describe('Preferences', function () {
}

async function deleteAllValues() {
return setValueTo(undefined);
}

/**
* @param {any} value - A JSON value to write to the workspace preference file.
*/
async function setValueTo(value) {
const reference = await modelService.createModelReference(uri);
if (reference.object.dirty) {
await reference.object.revert();
}
/** @type {import ('@theia/preferences/lib/browser/folder-preference-provider').FolderPreferenceProvider} */
const provider = Array.from(folderPreferences['providers'].values()).find(candidate => candidate.getConfigUri().isEqual(uri));
assert.isDefined(provider);
await provider['doSetPreference']('', [], undefined);
await provider['doSetPreference']('', [], value);
reference.dispose();
}

Expand All @@ -92,7 +99,10 @@ describe('Preferences', function () {
if (!fileExistsBeforehand) {
await fileService.delete(uri, { fromUserGesture: false }).catch(() => { });
} else {
await fileService.write(uri, contentBeforehand);
let content = '';
try { content = JSON.parse(contentBeforehand); } catch { }
// Use the preference service because its promise is guaranteed to resolve after the file change is complete.
await setValueTo(content);
}
});

Expand Down
16 changes: 10 additions & 6 deletions examples/api-tests/src/typescript.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ describe('TypeScript', function () {
const contextKeyService = container.get(ContextKeyService);
const commands = container.get(CommandRegistry);
const openerService = container.get(OpenerService);
/** @type {KeybindingRegistry} */
const keybindings = container.get(KeybindingRegistry);
/** @type {import('@theia/core/lib/browser/preferences/preference-service').PreferenceService} */
const preferences = container.get(PreferenceService);
Expand Down Expand Up @@ -108,20 +109,21 @@ describe('TypeScript', function () {
/**
* @param {() => Promise<unknown> | unknown} condition
* @param {number | undefined} [timeout]
* @param {string | undefined} [message]
* @returns {Promise<void>}
*/
function waitForAnimation(condition, timeout) {
const success = new Promise(async (resolve, dispose) => {
toTearDown.push({ dispose });
function waitForAnimation(condition, timeout, message) {
const success = new Promise(async (resolve, reject) => {
toTearDown.push({ dispose: () => reject(message ?? 'Test terminated before resolution.') });
do {
await animationFrame();
} while (!condition());
resolve();
});
if (timeout !== undefined) {
const timedOut = new Promise((_, fail) => {
const toClear = setTimeout(() => fail(new Error('Wait for animation timed out.')), timeout);
toTearDown.push({ dispose: () => (fail(new Error('Wait for animation timed out.')), clearTimeout(toClear)) });
const toClear = setTimeout(() => fail(new Error(message ?? 'Wait for animation timed out.')), timeout);
toTearDown.push({ dispose: () => (fail(new Error(message ?? 'Wait for animation timed out.')), clearTimeout(toClear)) });
});
return Promise.race([success, timedOut]);
}
Expand Down Expand Up @@ -277,6 +279,7 @@ describe('TypeScript', function () {
const from = 'an editor' + (preview ? ' preview' : '');
it('within ' + from, async function () {
const editor = await openEditor(demoFileUri, preview);
editor.getControl().revealLine(24);
// const demoInstance = new Demo|Class('demo');
editor.getControl().setPosition({ lineNumber: 24, column: 30 });
assert.equal(editor.getControl().getModel().getWordAtPosition(editor.getControl().getPosition()).word, 'DemoClass');
Expand All @@ -299,6 +302,7 @@ describe('TypeScript', function () {
await editorManager.open(definitionFileUri, { mode: 'open' });

const editor = await openEditor(demoFileUri, preview);
editor.getControl().revealLine(32);
// const bar: Defined|Interface = { coolField: [] };
editor.getControl().setPosition({ lineNumber: 32, column: 19 });
assert.equal(editor.getControl().getModel().getWordAtPosition(editor.getControl().getPosition()).word, 'DefinedInterface');
Expand All @@ -319,6 +323,7 @@ describe('TypeScript', function () {

it(`from ${from} to an editor preview`, async function () {
const editor = await openEditor(demoFileUri);
editor.getControl().revealLine(32);
// const bar: Defined|Interface = { coolField: [] };
editor.getControl().setPosition({ lineNumber: 32, column: 19 });
assert.equal(editor.getControl().getModel().getWordAtPosition(editor.getControl().getPosition()).word, 'DefinedInterface');
Expand Down Expand Up @@ -729,5 +734,4 @@ SPAN {
assert.equal(getResultText(), expectedMessage);
});
}

});
2 changes: 1 addition & 1 deletion examples/api-tests/src/undo-redo-selectAll.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ describe('Undo, Redo and Select All', function () {
let originalValue = undefined;
before(async () => {
originalValue = preferenceService.inspect('files.autoSave').globalValue;
await preferenceService.set('files.autoSave', false, PreferenceScope.User);
await preferenceService.set('files.autoSave', 'off', PreferenceScope.User);
shell.leftPanelHandler.collapse();
});

Expand Down
23 changes: 9 additions & 14 deletions examples/playwright/src/theia-notification-indicator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,26 @@

import { TheiaStatusIndicator } from './theia-status-indicator';

const NOTIFICATION_ICON = 'codicon-bell';
const NOTIFICATION_DOT_ICON = 'codicon-bell-dot';
const NOTIFICATION_ICONS = [NOTIFICATION_ICON, NOTIFICATION_DOT_ICON];

export class TheiaNotificationIndicator extends TheiaStatusIndicator {

protected get title(): string {
return 'Notification';
}

override async isVisible(): Promise<boolean> {
return super.isVisible(NOTIFICATION_ICONS, this.title);
}
id = 'theia-notification-center';

async hasNotifications(): Promise<boolean> {
return super.isVisible(NOTIFICATION_DOT_ICON, this.title);
const container = await this.getElementHandle();
const bellWithDot = await container.$(`.${NOTIFICATION_DOT_ICON}`);
return Boolean(bellWithDot?.isVisible());
}

override async waitForVisible(expectNotifications = false): Promise<void> {
await super.waitForVisibleByIcon(expectNotifications ? NOTIFICATION_DOT_ICON : NOTIFICATION_ICON);
await super.waitForVisible();
if (expectNotifications && !(await this.hasNotifications())) {
throw new Error('No notifications when notifications expected.');
}
}

async toggleOverlay(): Promise<void> {
const hasNotifications = await this.hasNotifications();
const element = await this.getElementHandleByIcon(hasNotifications ? NOTIFICATION_DOT_ICON : NOTIFICATION_ICON, this.title);
const element = await this.getElementHandle();
if (element) {
await element.click();
}
Expand Down
11 changes: 2 additions & 9 deletions examples/playwright/src/theia-problem-indicator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,8 @@
import { ElementHandle } from '@playwright/test';
import { TheiaStatusIndicator } from './theia-status-indicator';

const PROBLEM_ICON = 'codicon-error';

export class TheiaProblemIndicator extends TheiaStatusIndicator {

override async isVisible(): Promise<boolean> {
const handle = await super.getElementHandleByIcon(PROBLEM_ICON);
return !!handle && handle.isVisible();
}
id = 'problem-marker-status';

async numberOfProblems(): Promise<number> {
const spans = await this.getSpans();
Expand All @@ -37,8 +31,7 @@ export class TheiaProblemIndicator extends TheiaStatusIndicator {
}

protected async getSpans(): Promise<ElementHandle[] | undefined> {
const handle = await super.getElementHandleByIcon(PROBLEM_ICON);
const handle = await this.getElementHandle();
return handle?.$$('span');
}

}
59 changes: 15 additions & 44 deletions examples/playwright/src/theia-status-indicator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,60 +17,31 @@
import { ElementHandle } from '@playwright/test';
import { TheiaPageObject } from './theia-page-object';

export class TheiaStatusIndicator extends TheiaPageObject {
export abstract class TheiaStatusIndicator extends TheiaPageObject {
protected abstract id: string;

protected elementSpanSelector = '#theia-statusBar .element span';
protected statusBarElementSelector = '#theia-statusBar div.element';

protected async getElementHandle(): Promise<ElementHandle<SVGElement | HTMLElement> | null> {
return this.page.$(this.elementSpanSelector);
protected getSelectorForId(id: string): string {
return `${this.statusBarElementSelector}#status-bar-${id}`;
}

async waitForVisible(): Promise<void> {
await this.page.waitForSelector(this.elementSpanSelector);
async waitForVisible(waitForDetached = false): Promise<void> {
await this.page.waitForSelector(this.getSelectorForId(this.id), waitForDetached ? { state: 'detached' } : {});
}

protected getSelectorByTitle(title: string): string {
return `.element[title="${title}"]`;
}

async getElementHandleByTitle(title: string): Promise<ElementHandle<SVGElement | HTMLElement> | null> {
// Fetch element via title in case status elements exist without a dedicated Codicon icon
return this.page.$(this.getSelectorByTitle(title));
}

protected getSelectorByIcon(icon: string): string {
return `${this.elementSpanSelector}.codicon.${icon}`;
}

async getElementHandleByIcon(iconClass: string | string[], titleContain = ''): Promise<ElementHandle<SVGElement | HTMLElement> | null> {
const icons = Array.isArray(iconClass) ? iconClass : [iconClass];
for (const icon of icons) {
const span = await this.page.$(this.getSelectorByIcon(icon));
if (span) {
const parent = await span.$('..');
if (titleContain === '') {
return parent;
} else {
const parentTitle = await parent?.getAttribute('title');
if (parentTitle?.includes(titleContain)) { return parent; }
}
}
async getElementHandle(): Promise<ElementHandle<SVGElement | HTMLElement>> {
const element = await this.page.$(this.getSelectorForId(this.id));
if (element) {
return element;
}
throw new Error('Cannot find indicator');
}

async waitForVisibleByTitle(title: string, waitForDetached = false): Promise<void> {
await this.page.waitForSelector(this.getSelectorByTitle(title), waitForDetached ? { state: 'detached' } : {});
}

async waitForVisibleByIcon(icon: string, waitForDetached = false): Promise<void> {
await this.page.waitForSelector(this.getSelectorByIcon(icon), waitForDetached ? { state: 'detached' } : {});
throw new Error('Could not find status bar element with ID ' + this.id);
}

async isVisible(icon: string | string[], titleContain = ''): Promise<boolean> {
async isVisible(): Promise<boolean> {
try {
const element = await this.getElementHandleByIcon(icon, titleContain);
return !!element && element.isVisible();
const element = await this.getElementHandle();
return element.isVisible();
} catch (err) {
return false;
}
Expand Down
6 changes: 1 addition & 5 deletions examples/playwright/src/theia-toggle-bottom-indicator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@

import { TheiaStatusIndicator } from './theia-status-indicator';

const TOGGLE_BOTTOM_ICON = 'codicon-window';

export class TheiaToggleBottomIndicator extends TheiaStatusIndicator {
override async isVisible(): Promise<boolean> {
return super.isVisible(TOGGLE_BOTTOM_ICON);
}
id = 'bottom-panel-toggle';
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { CancellationToken } from '@theia/core';
import URI from '@theia/core/lib/common/uri';
import { ContributionProvider, Disposable, Emitter, Event } from '@theia/core/lib/common';
import { CallHierarchyItem, CallHierarchyIncomingCall, CallHierarchyOutgoingCall } from './callhierarchy';
import { LanguageSelector, score } from '../common/language-selector';
import { LanguageSelector, score } from '@theia/editor/lib/common/language-selector';

export const CallHierarchyService = Symbol('CallHierarchyService');

Expand Down
1 change: 0 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"@phosphor/signaling": "1",
"@phosphor/virtualdom": "1",
"@phosphor/widgets": "1",
"@primer/octicons-react": "^9.0.0",
"@theia/application-package": "1.25.0",
"@types/body-parser": "^1.16.4",
"@types/cookie": "^0.3.3",
Expand Down
11 changes: 10 additions & 1 deletion packages/core/src/browser/common-frontend-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1608,7 +1608,7 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
{
id: 'statusBarItem.warningBackground', defaults: {
dark: Color.darken('warningBackground', 0.4),
light: Color.darken('warningBackground', 0.4),
light: Color.darken('warningBackground', 0.4),
hc: undefined
}, description: 'Status bar warning items background color. Warning items stand out from other status bar entries to indicate warning conditions. The status bar is shown in the bottom of the window.'
},
Expand Down Expand Up @@ -2227,6 +2227,15 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
hc: Color.lighten('activityBar.foreground', 0.1),
}, description: 'Foreground color of active toolbar item',
},
{
id: 'editorHoverWidgetInternalBorder',
defaults: {
dark: Color.transparent('editorHoverWidget.border', 0.5),
light: Color.transparent('editorHoverWidget.border', 0.5),
hc: Color.transparent('editorHoverWidget.border', 0.5),
},
description: 'The border between subelements of a hover widget'
}
);
}
}
11 changes: 7 additions & 4 deletions packages/core/src/browser/frontend-application-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ import {
SidebarMenuWidget, SidebarTopMenuWidgetFactory,
SplitPositionHandler, DockPanelRendererFactory, ApplicationShellLayoutMigration, ApplicationShellLayoutMigrationError, SidebarBottomMenuWidgetFactory
} from './shell';
import { StatusBar, StatusBarImpl } from './status-bar/status-bar';
import { LabelParser } from './label-parser';
import { LabelProvider, LabelProviderContribution, DefaultUriLabelProviderContribution } from './label-provider';
import { PreferenceService } from './preferences';
Expand Down Expand Up @@ -123,12 +122,14 @@ import { bindFrontendStopwatch, bindBackendStopwatch } from './performance';
import { SaveResourceService } from './save-resource-service';
import { UserWorkingDirectoryProvider } from './user-working-directory-provider';
import { TheiaDockPanel } from './shell/theia-dock-panel';
import { bindStatusBar } from './status-bar';
import { MarkdownRenderer, MarkdownRendererFactory, MarkdownRendererImpl } from './markdown-rendering/markdown-renderer';

export { bindResourceProvider, bindMessageService, bindPreferenceService };

ColorApplicationContribution.initBackground();

export const frontendApplicationModule = new ContainerModule((bind, unbind, isBound, rebind) => {
export const frontendApplicationModule = new ContainerModule((bind, _unbind, _isBound, _rebind) => {
bind(NoneIconTheme).toSelf().inSingletonScope();
bind(LabelProviderContribution).toService(NoneIconTheme);
bind(IconThemeService).toSelf().inSingletonScope();
Expand Down Expand Up @@ -272,15 +273,17 @@ export const frontendApplicationModule = new ContainerModule((bind, unbind, isBo
return quickPickService;
});

bind(MarkdownRenderer).to(MarkdownRendererImpl).inSingletonScope();
bind(MarkdownRendererFactory).toFactory(({ container }) => () => container.get(MarkdownRenderer));

bindContributionProvider(bind, QuickAccessContribution);
bind(QuickInputFrontendContribution).toSelf().inSingletonScope();
bind(FrontendApplicationContribution).toService(QuickInputFrontendContribution);

bind(LocalStorageService).toSelf().inSingletonScope();
bind(StorageService).toService(LocalStorageService);

bind(StatusBarImpl).toSelf().inSingletonScope();
bind(StatusBar).toService(StatusBarImpl);
bindStatusBar(bind);
bind(LabelParser).toSelf().inSingletonScope();

bindContributionProvider(bind, LabelProviderContribution);
Expand Down
9 changes: 6 additions & 3 deletions packages/core/src/browser/keybinding.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import { KeyboardLayoutService } from './keyboard/keyboard-layout-service';
import { CommandRegistry, CommandService, CommandContribution, Command } from '../common/command';
import { LabelParser } from './label-parser';
import { MockLogger } from '../common/test/mock-logger';
import { StatusBar, StatusBarImpl } from './status-bar/status-bar';
import { FrontendApplicationStateService } from './frontend-application-state';
import { ContextKeyService, ContextKeyServiceDummyImpl } from './context-key-service';
import { CorePreferences } from './core-preferences';
Expand All @@ -39,6 +38,8 @@ import { Emitter, Event } from '../common/event';
import { bindPreferenceService } from './frontend-application-bindings';
import { FrontendApplicationConfigProvider } from './frontend-application-config-provider';
import { ApplicationProps } from '@theia/application-package/lib/';
import { bindStatusBar } from './status-bar';
import { MarkdownRenderer, MarkdownRendererFactory, MarkdownRendererImpl } from './markdown-rendering/markdown-renderer';

disableJSDOM();

Expand Down Expand Up @@ -83,8 +84,10 @@ before(async () => {
}
});

bind(StatusBarImpl).toSelf().inSingletonScope();
bind(StatusBar).toService(StatusBarImpl);
bindStatusBar(bind);
bind(MarkdownRendererImpl).toSelf().inSingletonScope();
bind(MarkdownRenderer).toService(MarkdownRendererImpl);
bind(MarkdownRendererFactory).toFactory(({ container }) => container.get(MarkdownRenderer));
bind(CommandService).toService(CommandRegistry);
bind(LabelParser).toSelf().inSingletonScope();
bind(ContextKeyService).to(ContextKeyServiceDummyImpl).inSingletonScope();
Expand Down
Loading