Skip to content
Open
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
21 changes: 17 additions & 4 deletions src/vs/workbench/contrib/webview/browser/overlayWebview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,12 @@ export class OverlayWebview extends Disposable implements IOverlayWebview {
this._windowId = targetWindow.vscodeWindowId;
this._show(targetWindow);

if (this._anchorState) {
// Only re-apply a still-connected anchor. Unhide happens in `_updateVisibility`
// once a connected anchor is bound (see https://github.com/microsoft/vscode/issues/323890).
if (this._anchorState?.anchorElement.isConnected) {
this.overlayLayout.setAnchorElement(this._anchorState.anchorElement, { clippingContainer: this._anchorState.clippingContainer });
}
this._updateVisibility();

if (oldOwner !== owner) {
const contextKeyService = (scopedContextKeyService || this._baseContextKeyService);
Expand Down Expand Up @@ -200,6 +203,18 @@ export class OverlayWebview extends Disposable implements IOverlayWebview {
this._anchorState = { anchorElement, clippingContainer };
// Force the overlay layout to be created if it doesn't exist
this.overlayLayout.setAnchorElement(anchorElement, { clippingContainer });
this._updateVisibility();
}

private _updateVisibility(): void {
if (!this._overlayLayout) {
return;
}

// Keep retained iframes hidden until a connected CSS anchor is bound so they
// do not briefly paint at the browser default size (~300×150).
const shouldShow = !!this._owner && !!this._anchorState?.anchorElement.isConnected;
this._overlayLayout.content.style.visibility = shouldShow ? 'visible' : 'hidden';
}

private _show(targetWindow: CodeWindow) {
Expand Down Expand Up @@ -274,9 +289,7 @@ export class OverlayWebview extends Disposable implements IOverlayWebview {
this._shouldShowFindWidgetOnRestore = false;
}

if (this._overlayLayout) {
this._overlayLayout.content.style.visibility = 'visible';
}
// Visibility is updated only after a connected CSS anchor has been bound (#323890).
}

public setHtml(html: string) {
Expand Down
14 changes: 9 additions & 5 deletions src/vs/workbench/contrib/webviewPanel/browser/webviewEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,18 +161,22 @@ export class WebviewEditor extends EditorPane {
}

private claimWebview(input: WebviewInput): void {
// Check if this editor is inside a modal editor
const modalEditorContainer = this._editorGroupsService.activeModalEditorPart?.modalElement;
const isModal = isHTMLElement(modalEditorContainer) && this._element && modalEditorContainer.contains(this._element);
this._clippingContainer = isModal ? undefined : this._workbenchLayoutService.getContainer(this.window, Parts.EDITOR_PART);

// Bind the CSS anchor before claim when the editor element is already connected
// so retained webviews size correctly on first paint (#323890).
this.setWebviewAnchorElement(input.webview);

input.claim(this, this.window, this.scopedContextKeyService);

if (this._element) {
this._element.setAttribute('aria-flowto', input.webview.container.id);
DOM.setParentFlowTo(input.webview.container, this._element);
}

// Check if this editor is inside a modal editor
const modalEditorContainer = this._editorGroupsService.activeModalEditorPart?.modalElement;
const isModal = isHTMLElement(modalEditorContainer) && this._element && modalEditorContainer.contains(this._element);
this._clippingContainer = isModal ? undefined : this._workbenchLayoutService.getContainer(this.window, Parts.EDITOR_PART);

this._webviewVisibleDisposables.clear();

// Webviews are not part of the normal editor dom, so we have to register our own drag and drop handler on them.
Expand Down