mirror of
https://github.com/microsoft/vscode.git
synced 2026-08-09 15:24:28 +01:00
do not keep entire window as property on a class
This commit is contained in:
@@ -513,10 +513,10 @@ export class BackLayerWebView<T extends ICommonCellInfo> extends Themable {
|
||||
return !!this.webview;
|
||||
}
|
||||
|
||||
createWebview(codeWindow: CodeWindow): Promise<void> {
|
||||
createWebview(targetWindow: CodeWindow): Promise<void> {
|
||||
const baseUrl = this.asWebviewUri(this.getNotebookBaseUri(), undefined);
|
||||
const htmlContent = this.generateContent(baseUrl.toString());
|
||||
return this._initialize(htmlContent, codeWindow);
|
||||
return this._initialize(htmlContent, targetWindow);
|
||||
}
|
||||
|
||||
private getNotebookBaseUri() {
|
||||
@@ -551,16 +551,16 @@ export class BackLayerWebView<T extends ICommonCellInfo> extends Themable {
|
||||
];
|
||||
}
|
||||
|
||||
private async _initialize(content: string, codeWindow: CodeWindow): Promise<void> {
|
||||
private async _initialize(content: string, targetWindow: CodeWindow): Promise<void> {
|
||||
if (!getWindow(this.element).document.body.contains(this.element)) {
|
||||
throw new Error('Element is already detached from the DOM tree');
|
||||
}
|
||||
|
||||
this.webview = this._createInset(this.webviewService, content);
|
||||
this.webview.mountTo(this.element, codeWindow);
|
||||
this.webview.mountTo(this.element, targetWindow);
|
||||
this._register(this.webview);
|
||||
|
||||
this._register(new WebviewWindowDragMonitor(codeWindow, () => this.webview));
|
||||
this._register(new WebviewWindowDragMonitor(targetWindow, () => this.webview));
|
||||
|
||||
const initializePromise = new DeferredPromise<void>();
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Dimension } from 'vs/base/browser/dom';
|
||||
import { Dimension, getWindowById } from 'vs/base/browser/dom';
|
||||
import { FastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { CodeWindow } from 'vs/base/browser/window';
|
||||
import { CodeWindow, mainWindow } from 'vs/base/browser/window';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { Disposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
@@ -36,7 +36,9 @@ export class OverlayWebview extends Disposable implements IOverlayWebview {
|
||||
private _options: WebviewOptions;
|
||||
|
||||
private _owner: any = undefined;
|
||||
public _codeWindow: CodeWindow | undefined = undefined;
|
||||
|
||||
private _windowId: number | undefined = undefined;
|
||||
private get window() { return typeof this._windowId === 'number' ? getWindowById(this._windowId)?.window : undefined; }
|
||||
|
||||
private readonly _scopedContextKeyService = this._register(new MutableDisposable<IScopedContextKeyService>());
|
||||
private _findWidgetVisible: IContextKey<boolean> | undefined;
|
||||
@@ -105,21 +107,20 @@ export class OverlayWebview extends Disposable implements IOverlayWebview {
|
||||
|
||||
// Webviews cannot be reparented in the dom as it will destroy their contents.
|
||||
// Mount them to a high level node to avoid this.
|
||||
const layoutContainer = this._codeWindow ? this._layoutService.getContainer(this._codeWindow) : this._layoutService.mainContainer;
|
||||
layoutContainer.appendChild(node);
|
||||
this._layoutService.getContainer(this.window ?? mainWindow).appendChild(node);
|
||||
}
|
||||
|
||||
return this._container.domNode;
|
||||
}
|
||||
|
||||
public claim(owner: any, codeWindow: CodeWindow, scopedContextKeyService: IContextKeyService | undefined) {
|
||||
public claim(owner: any, targetWindow: CodeWindow, scopedContextKeyService: IContextKeyService | undefined) {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const oldOwner = this._owner;
|
||||
|
||||
if (this._codeWindow && this._codeWindow?.vscodeWindowId !== codeWindow.vscodeWindowId) {
|
||||
if (this._windowId !== targetWindow.vscodeWindowId) {
|
||||
// moving to a new window
|
||||
this.release(oldOwner);
|
||||
this._container?.domNode.remove();
|
||||
@@ -127,8 +128,8 @@ export class OverlayWebview extends Disposable implements IOverlayWebview {
|
||||
}
|
||||
|
||||
this._owner = owner;
|
||||
this._codeWindow = codeWindow;
|
||||
this._show(codeWindow);
|
||||
this._windowId = targetWindow.vscodeWindowId;
|
||||
this._show(targetWindow);
|
||||
|
||||
if (oldOwner !== owner) {
|
||||
const contextKeyService = (scopedContextKeyService || this._baseContextKeyService);
|
||||
@@ -195,7 +196,7 @@ export class OverlayWebview extends Disposable implements IOverlayWebview {
|
||||
}
|
||||
}
|
||||
|
||||
private _show(codeWindow: CodeWindow) {
|
||||
private _show(targetWindow: CodeWindow) {
|
||||
if (this._isDisposed) {
|
||||
throw new Error('OverlayWebview is disposed');
|
||||
}
|
||||
@@ -207,7 +208,7 @@ export class OverlayWebview extends Disposable implements IOverlayWebview {
|
||||
title: this._title,
|
||||
options: this._options,
|
||||
contentOptions: this._contentOptions,
|
||||
extension: this.extension
|
||||
extension: this.extension,
|
||||
});
|
||||
this._webview.value = webview;
|
||||
webview.state = this._state;
|
||||
@@ -226,7 +227,7 @@ export class OverlayWebview extends Disposable implements IOverlayWebview {
|
||||
|
||||
this._findWidgetEnabled?.set(!!this.options.enableFindWidget);
|
||||
|
||||
webview.mountTo(this.container, codeWindow);
|
||||
webview.mountTo(this.container, targetWindow);
|
||||
|
||||
// Forward events from inner webview to outer listeners
|
||||
this._webviewEvents.clear();
|
||||
|
||||
@@ -277,7 +277,7 @@ export interface IWebviewElement extends IWebview {
|
||||
*
|
||||
* @param parent Element to append the webview to.
|
||||
*/
|
||||
mountTo(parent: HTMLElement, codeWindow: CodeWindow): void;
|
||||
mountTo(parent: HTMLElement, targetWindow: CodeWindow): void;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -307,7 +307,7 @@ export interface IOverlayWebview extends IWebview {
|
||||
* @param claimant Identifier for the object claiming the webview.
|
||||
* This must match the `claimant` passed to {@link IOverlayWebview.release}.
|
||||
*/
|
||||
claim(claimant: any, codeWindow: CodeWindow, scopedContextKeyService: IContextKeyService | undefined): void;
|
||||
claim(claimant: any, targetWindow: CodeWindow, scopedContextKeyService: IContextKeyService | undefined): void;
|
||||
|
||||
/**
|
||||
* Release ownership of the webview.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { isFirefox } from 'vs/base/browser/browser';
|
||||
import { addDisposableListener, EventType } from 'vs/base/browser/dom';
|
||||
import { addDisposableListener, EventType, getWindowById } from 'vs/base/browser/dom';
|
||||
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { promiseWithResolvers, ThrottledDelayer } from 'vs/base/common/async';
|
||||
import { streamToBuffer, VSBufferReadableStream } from 'vs/base/common/buffer';
|
||||
@@ -88,7 +88,8 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD
|
||||
*/
|
||||
public readonly origin: string;
|
||||
|
||||
private _codeWindow?: CodeWindow;
|
||||
private _windowId: number | undefined = undefined;
|
||||
private get window() { return typeof this._windowId === 'number' ? getWindowById(this._windowId)?.window : undefined; }
|
||||
|
||||
private _encodedWebviewOriginPromise?: Promise<string>;
|
||||
private _encodedWebviewOrigin: string | undefined;
|
||||
@@ -106,11 +107,11 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD
|
||||
return false;
|
||||
}
|
||||
// code window is only available after the webview is mounted.
|
||||
if (!this._codeWindow) {
|
||||
if (!this.window) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this._codeWindow.document.activeElement && this._codeWindow.document.activeElement !== this.element) {
|
||||
if (this.window.document.activeElement && this.window.document.activeElement !== this.element) {
|
||||
// looks like https://github.com/microsoft/vscode/issues/132641
|
||||
// where the focus is actually not in the `<iframe>`
|
||||
return false;
|
||||
@@ -412,7 +413,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD
|
||||
return element;
|
||||
}
|
||||
|
||||
private _initElement(encodedWebviewOrigin: string, extension: WebviewExtensionDescription | undefined, options: WebviewOptions, codeWindow: CodeWindow) {
|
||||
private _initElement(encodedWebviewOrigin: string, extension: WebviewExtensionDescription | undefined, options: WebviewOptions, targetWindow: CodeWindow) {
|
||||
// The extensionId and purpose in the URL are used for filtering in js-debug:
|
||||
const params: { [key: string]: string } = {
|
||||
id: this.id,
|
||||
@@ -421,7 +422,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD
|
||||
extensionId: extension?.id.value ?? '',
|
||||
platform: this.platform,
|
||||
'vscode-resource-base-authority': webviewRootResourceAuthority,
|
||||
parentOrigin: codeWindow.origin,
|
||||
parentOrigin: targetWindow.origin,
|
||||
};
|
||||
|
||||
if (this._options.disableServiceWorker) {
|
||||
@@ -446,19 +447,19 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD
|
||||
this.element!.setAttribute('src', `${this.webviewContentEndpoint(encodedWebviewOrigin)}/${fileName}?${queryString}`);
|
||||
}
|
||||
|
||||
public mountTo(element: HTMLElement, codeWindow: CodeWindow) {
|
||||
public mountTo(element: HTMLElement, targetWindow: CodeWindow) {
|
||||
if (!this.element) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._codeWindow = codeWindow;
|
||||
this._encodedWebviewOriginPromise = parentOriginHash(codeWindow.origin, this.origin).then(id => this._encodedWebviewOrigin = id);
|
||||
this._windowId = targetWindow.vscodeWindowId;
|
||||
this._encodedWebviewOriginPromise = parentOriginHash(targetWindow.origin, this.origin).then(id => this._encodedWebviewOrigin = id);
|
||||
this._encodedWebviewOriginPromise.then(encodedWebviewOrigin => {
|
||||
if (!this._disposed) {
|
||||
this._initElement(encodedWebviewOrigin, this.extension, this._options, codeWindow);
|
||||
this._initElement(encodedWebviewOrigin, this.extension, this._options, targetWindow);
|
||||
}
|
||||
});
|
||||
this._registerMessageHandler(codeWindow);
|
||||
this._registerMessageHandler(targetWindow);
|
||||
|
||||
if (this._webviewFindWidget) {
|
||||
element.appendChild(this._webviewFindWidget.getDomNode());
|
||||
@@ -470,7 +471,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD
|
||||
}));
|
||||
}
|
||||
|
||||
for (const node of [element, codeWindow]) {
|
||||
for (const node of [element, targetWindow]) {
|
||||
this._register(addDisposableListener(node, EventType.DRAG_END, () => {
|
||||
this._stopBlockingIframeDragEvents();
|
||||
}));
|
||||
@@ -481,8 +482,8 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD
|
||||
element.appendChild(this.element);
|
||||
}
|
||||
|
||||
private _registerMessageHandler(codeWindow: CodeWindow) {
|
||||
const subscription = this._register(addDisposableListener(codeWindow, 'message', (e: MessageEvent) => {
|
||||
private _registerMessageHandler(targetWindow: CodeWindow) {
|
||||
const subscription = this._register(addDisposableListener(targetWindow, 'message', (e: MessageEvent) => {
|
||||
if (!this._encodedWebviewOrigin || e?.data?.target !== this.id) {
|
||||
return;
|
||||
}
|
||||
@@ -693,7 +694,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD
|
||||
get: () => this.element,
|
||||
});
|
||||
// And re-dispatch
|
||||
this._codeWindow?.dispatchEvent(emulatedKeyboardEvent);
|
||||
this.window?.dispatchEvent(emulatedKeyboardEvent);
|
||||
}
|
||||
|
||||
windowDidDragStart(): void {
|
||||
@@ -835,7 +836,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._codeWindow?.document.activeElement && this._codeWindow.document.activeElement !== this.element && this._codeWindow.document.activeElement?.tagName !== 'BODY') {
|
||||
if (this.window?.document.activeElement && this.window.document.activeElement !== this.element && this.window.document.activeElement?.tagName !== 'BODY') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@ import { IWebview } from 'vs/workbench/contrib/webview/browser/webview';
|
||||
* event so it can handle editor element drag drop.
|
||||
*/
|
||||
export class WebviewWindowDragMonitor extends Disposable {
|
||||
constructor(codeWindow: CodeWindow, getWebview: () => IWebview | undefined) {
|
||||
constructor(targetWindow: CodeWindow, getWebview: () => IWebview | undefined) {
|
||||
super();
|
||||
|
||||
this._register(DOM.addDisposableListener(codeWindow, DOM.EventType.DRAG_START, () => {
|
||||
this._register(DOM.addDisposableListener(targetWindow, DOM.EventType.DRAG_START, () => {
|
||||
getWebview()?.windowDidDragStart();
|
||||
}));
|
||||
|
||||
@@ -26,8 +26,8 @@ export class WebviewWindowDragMonitor extends Disposable {
|
||||
getWebview()?.windowDidDragEnd();
|
||||
};
|
||||
|
||||
this._register(DOM.addDisposableListener(codeWindow, DOM.EventType.DRAG_END, onDragEnd));
|
||||
this._register(DOM.addDisposableListener(codeWindow, DOM.EventType.MOUSE_MOVE, currentEvent => {
|
||||
this._register(DOM.addDisposableListener(targetWindow, DOM.EventType.DRAG_END, onDragEnd));
|
||||
this._register(DOM.addDisposableListener(targetWindow, DOM.EventType.MOUSE_MOVE, currentEvent => {
|
||||
if (currentEvent.buttons === 0) {
|
||||
onDragEnd();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user