Skip to content

Commit

Permalink
Support using theme icons in webview iconPath
Browse files Browse the repository at this point in the history
Fixes #90616

Enables using theme icons in the webview.iconPath

This fixes the problem in a very ugly way by inlining all the codicon css classes. We should look into a proper fix
  • Loading branch information
mjbvz committed Mar 5, 2020
1 parent 3474ea7 commit 4803dd2
Show file tree
Hide file tree
Showing 7 changed files with 469 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/vs/vscode.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6430,7 +6430,7 @@ declare module 'vscode' {
/**
* Icon for the panel shown in UI.
*/
iconPath?: Uri | { light: Uri; dark: Uri };
iconPath?: Uri | { light: Uri; dark: Uri } | ThemeIcon;

/**
* Webview belonging to the panel.
Expand Down
21 changes: 15 additions & 6 deletions src/vs/workbench/api/browser/mainThreadWebview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
import { onUnexpectedError } from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable, DisposableStore, IDisposable, IReference, dispose } from 'vs/base/common/lifecycle';
import { Disposable, DisposableStore, dispose, IDisposable, IReference } from 'vs/base/common/lifecycle';
import { Schemas } from 'vs/base/common/network';
import { basename } from 'vs/base/common/path';
import { isWeb } from 'vs/base/common/platform';
Expand All @@ -21,6 +21,7 @@ import { ILabelService } from 'vs/platform/label/common/label';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IProductService } from 'vs/platform/product/common/productService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
import * as extHostProtocol from 'vs/workbench/api/common/extHost.protocol';
import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } from 'vs/workbench/api/common/shared/editor';
import { IEditorInput, IRevertOptions, ISaveOptions } from 'vs/workbench/common/editor';
Expand Down Expand Up @@ -196,7 +197,7 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
webview.setName(value);
}

public $setIconPath(handle: extHostProtocol.WebviewPanelHandle, value: { light: UriComponents, dark: UriComponents; } | undefined): void {
public $setIconPath(handle: extHostProtocol.WebviewPanelHandle, value: { light: UriComponents, dark: UriComponents; } | extHostProtocol.ThemeIconDto | undefined): void {
const webview = this.getWebviewInput(handle);
webview.iconPath = reviveWebviewIcon(value);
}
Expand Down Expand Up @@ -505,11 +506,19 @@ function reviveWebviewOptions(options: modes.IWebviewOptions): WebviewInputOptio
}

function reviveWebviewIcon(
value: { light: UriComponents, dark: UriComponents; } | undefined
value: extHostProtocol.WebviewUriIconDto | extHostProtocol.ThemeIconDto | undefined
): WebviewIcons | undefined {
return value
? { light: URI.revive(value.light), dark: URI.revive(value.dark) }
: undefined;
if (!value) {
return undefined;
}
if ((value as extHostProtocol.ThemeIconDto).id) {
return value as ThemeIcon;
}

return {
light: URI.revive((value as extHostProtocol.WebviewUriIconDto).light),
dark: URI.revive((value as extHostProtocol.WebviewUriIconDto).dark),
};
}

namespace HotExitState {
Expand Down
15 changes: 12 additions & 3 deletions src/vs/workbench/api/common/extHost.protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ export interface TransferQuickPickItems extends quickInput.IQuickPickItem {

export interface TransferQuickInputButton {
handle: number;
iconPath: { dark: URI; light?: URI; } | { id: string; };
iconPath: { dark: URI; light?: URI; } | ThemeIconDto;
tooltip?: string;
}

Expand Down Expand Up @@ -573,12 +573,17 @@ export interface WebviewExtensionDescription {
readonly location: UriComponents;
}

export interface WebviewUriIconDto {
readonly light: UriComponents;
readonly dark: UriComponents;
}

export interface MainThreadWebviewsShape extends IDisposable {
$createWebviewPanel(extension: WebviewExtensionDescription, handle: WebviewPanelHandle, viewType: string, title: string, showOptions: WebviewPanelShowOptions, options: modes.IWebviewPanelOptions & modes.IWebviewOptions): void;
$disposeWebview(handle: WebviewPanelHandle): void;
$reveal(handle: WebviewPanelHandle, showOptions: WebviewPanelShowOptions): void;
$setTitle(handle: WebviewPanelHandle, value: string): void;
$setIconPath(handle: WebviewPanelHandle, value: { light: UriComponents, dark: UriComponents; } | undefined): void;
$setIconPath(handle: WebviewPanelHandle, value: WebviewUriIconDto | ThemeIconDto | undefined): void;

$setHtml(handle: WebviewPanelHandle, value: string): void;
$setOptions(handle: WebviewPanelHandle, options: modes.IWebviewOptions): void;
Expand Down Expand Up @@ -1102,7 +1107,7 @@ export interface IWorkspaceEditEntryMetadataDto {
needsConfirmation: boolean;
label: string;
description?: string;
iconPath?: { id: string } | UriComponents | { light: UriComponents, dark: UriComponents };
iconPath?: ThemeIconDto | UriComponents | { light: UriComponents, dark: UriComponents };
}

export interface IWorkspaceFileEditDto {
Expand Down Expand Up @@ -1288,6 +1293,10 @@ export interface ITerminalDimensionsDto {
rows: number;
}

export interface ThemeIconDto {
readonly id: string;
}

export interface ExtHostTerminalServiceShape {
$acceptTerminalClosed(id: number, exitCode: number | undefined): void;
$acceptTerminalOpened(id: number, name: string, shellLaunchConfig: IShellLaunchConfigDto): void;
Expand Down
4 changes: 2 additions & 2 deletions src/vs/workbench/api/common/extHostWebview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview';
import type * as vscode from 'vscode';
import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShape, WebviewExtensionDescription, WebviewPanelHandle, WebviewPanelViewStateData } from './extHost.protocol';
import { Disposable as VSCodeDisposable } from './extHostTypes';
import { Disposable as VSCodeDisposable, ThemeIcon } from './extHostTypes';

type IconPath = URI | { light: URI, dark: URI };
type IconPath = URI | { readonly light: URI; readonly dark: URI } | ThemeIcon;

export class ExtHostWebview implements vscode.Webview {
private _html: string = '';
Expand Down
7 changes: 4 additions & 3 deletions src/vs/workbench/contrib/webview/browser/webview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/

import { Dimension } from 'vs/base/browser/dom';
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
import { Event } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
Expand All @@ -12,7 +13,7 @@ import * as nls from 'vs/nls';
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';

/**
* Set when the find widget in a webview is visible.
Expand All @@ -25,10 +26,10 @@ export const webviewHasOwnEditFunctionsContext = new RawContextKey<boolean>(webv

export const IWebviewService = createDecorator<IWebviewService>('webviewService');

export interface WebviewIcons {
export type WebviewIcons = ThemeIcon | {
readonly light: URI;
readonly dark: URI;
}
};

/**
* Handles the creation of webview elements.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IEditorInputFactory } from 'vs/workbench/common/editor';
import { WebviewInput } from './webviewEditorInput';
import { IWebviewWorkbenchService, WebviewInputOptions } from './webviewWorkbenchService';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
import { WebviewIcons } from 'vs/workbench/contrib/webview/browser/webview';

interface SerializedIconPath {
light: string | UriComponents;
dark: string | UriComponents;
}
type SerializedIconPath = ThemeIcon | {
readonly light: string | UriComponents;
readonly dark: string | UriComponents;
};

interface SerializedWebview {
readonly id?: string;
Expand Down Expand Up @@ -84,17 +86,23 @@ export class WebviewEditorInputFactory implements IEditorInputFactory {
extensionLocation: input.extension ? input.extension.location : undefined,
extensionId: input.extension && input.extension.id ? input.extension.id.value : undefined,
state: input.webview.state,
iconPath: input.iconPath ? { light: input.iconPath.light, dark: input.iconPath.dark, } : undefined,
iconPath: input.iconPath
? ThemeIcon.isThemeIcon(input.iconPath) ? input.iconPath : { light: input.iconPath.light, dark: input.iconPath.dark, }
: undefined,
group: input.group
};
}
}

function reviveIconPath(data: SerializedIconPath | undefined) {
function reviveIconPath(data: SerializedIconPath | undefined): WebviewIcons | undefined {
if (!data) {
return undefined;
}

if (ThemeIcon.isThemeIcon(data)) {
return data;
}

const light = reviveUri(data.light);
const dark = reviveUri(data.dark);
return light && dark ? { light, dark } : undefined;
Expand Down
Loading

0 comments on commit 4803dd2

Please sign in to comment.