diff --git a/src/vs/workbench/contrib/webview/browser/dynamicWebviewEditorOverlay.ts b/src/vs/workbench/contrib/webview/browser/dynamicWebviewEditorOverlay.ts index 70ad3167bd10ca76e4d318363f179831a7076f5c..2b251b0a95962bdd44a42d78e9b0c6708675276e 100644 --- a/src/vs/workbench/contrib/webview/browser/dynamicWebviewEditorOverlay.ts +++ b/src/vs/workbench/contrib/webview/browser/dynamicWebviewEditorOverlay.ts @@ -8,14 +8,16 @@ import { memoize } from 'vs/base/common/decorators'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, DisposableStore, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; -import { IWebviewService, Webview, WebviewContentOptions, WebviewOverlay, WebviewElement, WebviewOptions, WebviewExtensionDescription } from 'vs/workbench/contrib/webview/browser/webview'; +import { IWebviewService, Webview, WebviewContentOptions, WebviewOverlay, WebviewElement, WebviewOptions, WebviewExtensionDescription, KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE } from 'vs/workbench/contrib/webview/browser/webview'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { Dimension } from 'vs/base/browser/dom'; +import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; /** * Webview editor overlay that creates and destroys the underlying webview as needed. */ export class DynamicWebviewEditorOverlay extends Disposable implements WebviewOverlay { + private readonly _onDidWheel = this._register(new Emitter()); public readonly onDidWheel = this._onDidWheel.event; @@ -33,18 +35,24 @@ export class DynamicWebviewEditorOverlay extends Disposable implements WebviewOv private _owner: any = undefined; + private readonly _scopedContextKeyService = this._register(new MutableDisposable()); + private _findWidgetVisible: IContextKey; + public constructor( private readonly id: string, initialOptions: WebviewOptions, initialContentOptions: WebviewContentOptions, + @IContextKeyService private readonly _contextKeyService: IContextKeyService, @IWorkbenchLayoutService private readonly _layoutService: IWorkbenchLayoutService, - @IWebviewService private readonly _webviewService: IWebviewService + @IWebviewService private readonly _webviewService: IWebviewService, ) { super(); this._options = initialOptions; this._contentOptions = initialContentOptions; + this._findWidgetVisible = KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE.bindTo(_contextKeyService); + this._register(toDisposable(() => this.container.remove())); } @@ -101,7 +109,10 @@ export class DynamicWebviewEditorOverlay extends Disposable implements WebviewOv if (this._options.tryRestoreScrollPosition) { webview.initialScrollProgress = this._initialScrollProgress; } + webview.mountTo(this.container); + this._scopedContextKeyService.value = this._contextKeyService.createScoped(this.container); + this._findWidgetVisible = KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE.bindTo(this._scopedContextKeyService.value); // Forward events from inner webview to outer listeners this._webviewEvents.clear(); @@ -188,11 +199,22 @@ export class DynamicWebviewEditorOverlay extends Disposable implements WebviewOv focus(): void { this.withWebview(webview => webview.focus()); } reload(): void { this.withWebview(webview => webview.reload()); } - showFind(): void { this.withWebview(webview => webview.showFind()); } - hideFind(): void { this.withWebview(webview => webview.hideFind()); } - runFindAction(previous: boolean): void { this.withWebview(webview => webview.runFindAction(previous)); } selectAll(): void { this.withWebview(webview => webview.selectAll()); } + showFind() { + if (this._webview.value) { + this._webview.value.showFind(); + this._findWidgetVisible.set(true); + } + } + + hideFind() { + this._findWidgetVisible.reset(); + this._webview.value?.hideFind(); + } + + runFindAction(previous: boolean): void { this.withWebview(webview => webview.runFindAction(previous)); } + public getInnerWebview() { return this._webview.value; } diff --git a/src/vs/workbench/contrib/webview/browser/webview.ts b/src/vs/workbench/contrib/webview/browser/webview.ts index 455a7eb31a6a26ae2b02c31da5578377efa39095..d9fa87f548a8f336217f0e98fb6e916bfb3a7fca 100644 --- a/src/vs/workbench/contrib/webview/browser/webview.ts +++ b/src/vs/workbench/contrib/webview/browser/webview.ts @@ -101,10 +101,16 @@ export interface Webview extends IDisposable { windowDidDragEnd(): void; } +/** + * Basic webview rendered in the dom + */ export interface WebviewElement extends Webview { mountTo(parent: HTMLElement): void; } +/** + * Dynamically created webview drawn over another element. + */ export interface WebviewOverlay extends Webview { readonly container: HTMLElement; options: WebviewOptions; diff --git a/src/vs/workbench/contrib/webview/browser/webviewCommands.ts b/src/vs/workbench/contrib/webview/browser/webviewCommands.ts index bbe0fb5fb3c20f76b766c01e0b47347cde588765..820506611fe0c4f32957e22ed5d596c5c80716d4 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewCommands.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewCommands.ts @@ -8,12 +8,12 @@ import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import * as nls from 'vs/nls'; import { Action2 } from 'vs/platform/actions/common/actions'; import { ContextKeyExpr, ContextKeyExpression } from 'vs/platform/contextkey/common/contextkey'; +import { InputFocusedContextKey } from 'vs/platform/contextkey/common/contextkeys'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; -import { KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_FOCUSED, KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE } from 'vs/workbench/contrib/webview/browser/webview'; +import { KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_FOCUSED, KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE, Webview } from 'vs/workbench/contrib/webview/browser/webview'; import { WebviewEditor } from 'vs/workbench/contrib/webview/browser/webviewEditor'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { InputFocusedContextKey } from 'vs/platform/contextkey/common/contextkeys'; export class ShowWebViewEditorFindWidgetAction extends Action2 { public static readonly ID = 'editor.action.webvieweditor.showFind'; @@ -74,7 +74,7 @@ export class WebViewEditorFindNextCommand extends Action2 { } public run(accessor: ServicesAccessor): void { - getActiveWebviewEditor(accessor)?.find(false); + getActiveWebviewEditor(accessor)?.runFindAction(false); } } @@ -95,7 +95,7 @@ export class WebViewEditorFindPreviousCommand extends Action2 { } public run(accessor: ServicesAccessor): void { - getActiveWebviewEditor(accessor)?.find(true); + getActiveWebviewEditor(accessor)?.runFindAction(true); } } @@ -135,7 +135,7 @@ export class ReloadWebviewAction extends Action { public run(): Promise { for (const webview of this.getVisibleWebviews()) { - webview.reload(); + webview.webview?.reload(); } return Promise.resolve(true); } @@ -147,8 +147,8 @@ export class ReloadWebviewAction extends Action { } } -export function getActiveWebviewEditor(accessor: ServicesAccessor): WebviewEditor | undefined { +export function getActiveWebviewEditor(accessor: ServicesAccessor): Webview | undefined { const editorService = accessor.get(IEditorService); const activeEditorPane = editorService.activeEditorPane as WebviewEditor | undefined; - return activeEditorPane?.isWebviewEditor ? activeEditorPane : undefined; + return activeEditorPane?.isWebviewEditor ? activeEditorPane.webview : undefined; } diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditor.ts b/src/vs/workbench/contrib/webview/browser/webviewEditor.ts index b1783cacfb40ebf4786a47682c2c381c489a656b..b442aad86ae86325ba7f9458192a3d18ddd3d8e9 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewEditor.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewEditor.ts @@ -8,14 +8,13 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { Emitter, Event } from 'vs/base/common/event'; import { DisposableStore, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { isWeb } from 'vs/base/common/platform'; -import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart'; import { EditorInput, EditorOptions } from 'vs/workbench/common/editor'; -import { KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE, WebviewOverlay } from 'vs/workbench/contrib/webview/browser/webview'; +import { WebviewOverlay } from 'vs/workbench/contrib/webview/browser/webview'; import { WebviewInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput'; import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -25,8 +24,6 @@ export class WebviewEditor extends BaseEditor { public static readonly ID = 'WebviewEditor'; - private readonly _scopedContextKeyService = this._register(new MutableDisposable()); - private _findWidgetVisible: IContextKey; private _editorFrame?: HTMLElement; private _content?: HTMLElement; private _dimension?: DOM.Dimension; @@ -41,14 +38,11 @@ export class WebviewEditor extends BaseEditor { @ITelemetryService telemetryService: ITelemetryService, @IThemeService themeService: IThemeService, @IStorageService storageService: IStorageService, - @IContextKeyService private readonly _contextKeyService: IContextKeyService, @IEditorService private readonly _editorService: IEditorService, @IEditorGroupsService private readonly _editorGroupsService: IEditorGroupsService, @IHostService private readonly _hostService: IHostService, ) { super(WebviewEditor.ID, telemetryService, themeService, storageService); - - this._findWidgetVisible = KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE.bindTo(_contextKeyService); } public get isWebviewEditor() { @@ -70,30 +64,6 @@ export class WebviewEditor extends BaseEditor { super.dispose(); } - public showFind() { - if (this.webview) { - this.webview.showFind(); - this._findWidgetVisible.set(true); - } - } - - public hideFind() { - this._findWidgetVisible.reset(); - this.webview?.hideFind(); - } - - public find(previous: boolean) { - this.webview?.runFindAction(previous); - } - - public selectAll() { - this.webview?.selectAll(); - } - - public reload() { - this.webview?.reload(); - } - public layout(dimension: DOM.Dimension): void { this._dimension = dimension; if (this.webview) { @@ -169,11 +139,6 @@ export class WebviewEditor extends BaseEditor { private claimWebview(input: WebviewInput): void { input.webview.claim(this); - if (input.webview.options.enableFindWidget) { - this._scopedContextKeyService.value = this._contextKeyService.createScoped(input.webview.container); - this._findWidgetVisible = KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE.bindTo(this._scopedContextKeyService.value); - } - if (this._content) { this._content.setAttribute('aria-flowto', input.webview.container.id); } diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts index f13fe1eb6eae4011e818a5873e496e686bb7abde..2e4115a3e1a3cc1256cce52728c836df24660c7e 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts @@ -146,7 +146,7 @@ export class RedoWebviewEditorCommand extends Action2 { } function getActiveWebviewBasedWebview(accessor: ServicesAccessor): ElectronWebviewBasedWebview | undefined { - const webview = getActiveWebviewEditor(accessor)?.webview; + const webview = getActiveWebviewEditor(accessor); if (!webview) { return undefined; }