mirror of
https://github.com/Microsoft/vscode
synced 2024-09-13 13:46:13 +00:00
aux window - try to mitigate custom editor claim across windows (#207992)
This commit is contained in:
parent
e1ce54ff03
commit
568fe88e69
|
@ -346,6 +346,8 @@ class MainThreadCustomEditorModel extends ResourceWorkingCopy implements ICustom
|
|||
// this seed.
|
||||
readonly typeId = NO_TYPE_ID;
|
||||
|
||||
readonly isTextBased = false;
|
||||
|
||||
public static async create(
|
||||
instantiationService: IInstantiationService,
|
||||
proxy: extHostProtocol.ExtHostCustomEditorsShape,
|
||||
|
|
|
@ -3,25 +3,31 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { getWindow } from 'vs/base/browser/dom';
|
||||
import { CodeWindow } from 'vs/base/browser/window';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { IMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { IReference } from 'vs/base/common/lifecycle';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { basename } from 'vs/base/common/path';
|
||||
import { dirname, isEqual } from 'vs/base/common/resources';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { assertIsDefined } from 'vs/base/common/types';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { IResourceEditorInput } from 'vs/platform/editor/common/editor';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
|
||||
import { EditorInputCapabilities, GroupIdentifier, IMoveResult, IRevertOptions, ISaveOptions, IUntypedEditorInput, Verbosity } from 'vs/workbench/common/editor';
|
||||
import { EditorInputCapabilities, GroupIdentifier, IMoveResult, IRevertOptions, ISaveOptions, IUntypedEditorInput, Verbosity, createEditorOpenError } from 'vs/workbench/common/editor';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
import { ICustomEditorModel, ICustomEditorService } from 'vs/workbench/contrib/customEditor/common/customEditor';
|
||||
import { IOverlayWebview, IWebviewService } from 'vs/workbench/contrib/webview/browser/webview';
|
||||
import { IWebviewWorkbenchService, LazilyResolvedWebviewEditorInput } from 'vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
|
||||
import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
|
||||
|
||||
|
@ -83,7 +89,8 @@ export class CustomEditorInput extends LazilyResolvedWebviewEditorInput {
|
|||
@IFileDialogService private readonly fileDialogService: IFileDialogService,
|
||||
@IUndoRedoService private readonly undoRedoService: IUndoRedoService,
|
||||
@IFileService private readonly fileService: IFileService,
|
||||
@IFilesConfigurationService private readonly filesConfigurationService: IFilesConfigurationService
|
||||
@IFilesConfigurationService private readonly filesConfigurationService: IFilesConfigurationService,
|
||||
@IEditorGroupsService private readonly editorGroupsService: IEditorGroupsService
|
||||
) {
|
||||
super({ providedId: init.viewType, viewType: init.viewType, name: '' }, webview, webviewWorkbenchService);
|
||||
this._editorResource = init.resource;
|
||||
|
@ -388,4 +395,25 @@ export class CustomEditorInput extends LazilyResolvedWebviewEditorInput {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
public override claim(claimant: unknown, targetWindow: CodeWindow, scopedContextKeyService: IContextKeyService | undefined): void {
|
||||
if (this.isModified() && this._modelRef?.object.isTextBased === false && !this.backupId) {
|
||||
const webviewContainerWindow = getWindow(this.webview.container);
|
||||
if (webviewContainerWindow.vscodeWindowId !== targetWindow.vscodeWindowId) {
|
||||
|
||||
// The custom editor is modified, not backed by a file and without a backup.
|
||||
// We have to assume that the modified state is enclosed into the webview
|
||||
// managed by an extension. As such, we cannot just `claim()` the webview
|
||||
// into another window because that means, we potentally loose the modified
|
||||
// state and thus trigger data loss.
|
||||
// To mitigate this, we refuse to `claim` in this case and also make sure the
|
||||
// editor is still opened in the window it was originally opened in.
|
||||
|
||||
this.editorGroupsService.getPart(webviewContainerWindow).activeGroup.openEditor(this, { preserveFocus: true });
|
||||
|
||||
throw createEditorOpenError(localize('editorUnsupportedInAuxWindow', "Save the editor first before opening in this window."), [], { forceMessage: true, forceSeverity: Severity.Warning });
|
||||
}
|
||||
}
|
||||
return super.claim(claimant, targetWindow, scopedContextKeyService);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ export interface ICustomEditorModel extends IDisposable {
|
|||
readonly viewType: string;
|
||||
readonly resource: URI;
|
||||
readonly backupId: string | undefined;
|
||||
readonly isTextBased: boolean;
|
||||
|
||||
isReadonly(): boolean | IMarkdownString;
|
||||
readonly onDidChangeReadonly: Event<void>;
|
||||
|
|
|
@ -28,6 +28,8 @@ export class CustomTextEditorModel extends Disposable implements ICustomEditorMo
|
|||
});
|
||||
}
|
||||
|
||||
readonly isTextBased = true;
|
||||
|
||||
private readonly _textFileModel: ITextFileEditorModel | undefined;
|
||||
|
||||
private readonly _onDidChangeOrphaned = this._register(new Emitter<void>());
|
||||
|
|
|
@ -169,7 +169,7 @@ export class WebviewEditor extends EditorPane {
|
|||
}
|
||||
|
||||
private claimWebview(input: WebviewInput): void {
|
||||
input.webview.claim(this, this.window, this.scopedContextKeyService);
|
||||
input.claim(this, this.window, this.scopedContextKeyService);
|
||||
|
||||
if (this._element) {
|
||||
this._element.setAttribute('aria-flowto', input.webview.container.id);
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CodeWindow } from 'vs/base/browser/window';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { EditorInputCapabilities, GroupIdentifier, IUntypedEditorInput, Verbosity } from 'vs/workbench/common/editor';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
import { IOverlayWebview } from 'vs/workbench/contrib/webview/browser/webview';
|
||||
|
@ -131,4 +133,8 @@ export class WebviewInput extends EditorInput {
|
|||
other._webview = this._webview;
|
||||
return other;
|
||||
}
|
||||
|
||||
public claim(claimant: unknown, targetWindow: CodeWindow, scopedContextKeyService: IContextKeyService | undefined): void {
|
||||
return this._webview.claim(claimant, targetWindow, scopedContextKeyService);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue