editors - cleanup editor descriptors and 💄
This commit is contained in:
parent
dee37c6e76
commit
59f5bbaf25
17 changed files with 192 additions and 182 deletions
|
@ -32,7 +32,9 @@ class MenuActions extends Disposable {
|
|||
private readonly contextKeyService: IContextKeyService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.menu = this._register(menuService.createMenu(menuId, contextKeyService));
|
||||
|
||||
this._register(this.menu.onDidChange(() => this.updateActions()));
|
||||
this.updateActions();
|
||||
}
|
||||
|
@ -48,6 +50,7 @@ class MenuActions extends Disposable {
|
|||
|
||||
private updateSubmenus(actions: readonly IAction[], submenus: { [id: number]: IMenu }): IDisposable {
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
for (const action of actions) {
|
||||
if (action instanceof SubmenuItemAction && !submenus[action.item.submenu.id]) {
|
||||
const menu = submenus[action.item.submenu.id] = disposables.add(this.menuService.createMenu(action.item.submenu, this.contextKeyService));
|
||||
|
@ -55,6 +58,7 @@ class MenuActions extends Disposable {
|
|||
disposables.add(this.updateSubmenus(action.actions, submenus));
|
||||
}
|
||||
}
|
||||
|
||||
return disposables;
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +79,9 @@ export class CompositeMenuActions extends Disposable {
|
|||
@IMenuService private readonly menuService: IMenuService,
|
||||
) {
|
||||
super();
|
||||
|
||||
this.menuActions = this._register(new MenuActions(menuId, this.options, menuService, contextKeyService));
|
||||
|
||||
this._register(this.menuActions.onDidChange(() => this._onDidChange.fire()));
|
||||
}
|
||||
|
||||
|
@ -89,11 +95,13 @@ export class CompositeMenuActions extends Disposable {
|
|||
|
||||
getContextMenuActions(): IAction[] {
|
||||
const actions: IAction[] = [];
|
||||
|
||||
if (this.contextMenuId) {
|
||||
const menu = this.menuService.createMenu(this.contextMenuId, this.contextKeyService);
|
||||
this.contextMenuActionsDisposable.value = createAndFillInActionBarActions(menu, this.options, { primary: [], secondary: actions });
|
||||
menu.dispose();
|
||||
}
|
||||
|
||||
return actions;
|
||||
}
|
||||
}
|
|
@ -118,10 +118,6 @@ export abstract class Composite extends Component implements IComposite {
|
|||
this.parent = parent;
|
||||
}
|
||||
|
||||
override updateStyles(): void {
|
||||
super.updateStyles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the container this composite is being build in.
|
||||
*/
|
||||
|
@ -158,6 +154,13 @@ export abstract class Composite extends Component implements IComposite {
|
|||
*/
|
||||
abstract layout(dimension: Dimension): void;
|
||||
|
||||
/**
|
||||
* Update the styles of the contents of this composite.
|
||||
*/
|
||||
override updateStyles(): void {
|
||||
super.updateStyles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of actions to show in the action bar of the composite.
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { localize } from 'vs/nls';
|
||||
import { EditorInput, EditorResourceAccessor, IEditorInput, EditorExtensions, SideBySideEditor } from 'vs/workbench/common/editor';
|
||||
import { EditorInput, EditorResourceAccessor, IEditorInput, EditorExtensions, SideBySideEditor, IEditorDescriptor as ICommonEditorDescriptor } from 'vs/workbench/common/editor';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
|
||||
|
@ -20,22 +20,7 @@ import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsSe
|
|||
|
||||
//#region Editors Registry
|
||||
|
||||
export interface IEditorDescriptor {
|
||||
|
||||
/**
|
||||
* The unique identifier of the editor
|
||||
*/
|
||||
getId(): string;
|
||||
|
||||
/**
|
||||
* The display name of the editor
|
||||
*/
|
||||
getName(): string;
|
||||
|
||||
instantiate(instantiationService: IInstantiationService): EditorPane;
|
||||
|
||||
describes(obj: unknown): boolean;
|
||||
}
|
||||
export interface IEditorDescriptor extends ICommonEditorDescriptor<EditorPane> { }
|
||||
|
||||
export interface IEditorRegistry {
|
||||
|
||||
|
@ -48,22 +33,12 @@ export interface IEditorRegistry {
|
|||
* @param inputDescriptors A set of constructor functions that return an instance of EditorInput for which the
|
||||
* registered editor should be used for.
|
||||
*/
|
||||
registerEditor(descriptor: IEditorDescriptor, inputDescriptors: readonly SyncDescriptor<EditorInput>[]): IDisposable;
|
||||
registerEditor(editorDescriptor: IEditorDescriptor, inputDescriptors: readonly SyncDescriptor<EditorInput>[]): IDisposable;
|
||||
|
||||
/**
|
||||
* Returns the editor descriptor for the given input or `undefined` if none.
|
||||
*/
|
||||
getEditor(input: EditorInput): IEditorDescriptor | undefined;
|
||||
|
||||
/**
|
||||
* Returns the editor descriptor for the given identifier or `undefined` if none.
|
||||
*/
|
||||
getEditorById(editorId: string): IEditorDescriptor | undefined;
|
||||
|
||||
/**
|
||||
* Returns an array of registered editors known to the platform.
|
||||
*/
|
||||
getEditors(): readonly IEditorDescriptor[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -74,36 +49,28 @@ export class EditorDescriptor implements IEditorDescriptor {
|
|||
|
||||
static create<Services extends BrandedService[]>(
|
||||
ctor: { new(...services: Services): EditorPane },
|
||||
id: string,
|
||||
typeId: string,
|
||||
name: string
|
||||
): EditorDescriptor {
|
||||
return new EditorDescriptor(ctor as IConstructorSignature0<EditorPane>, id, name);
|
||||
return new EditorDescriptor(ctor as IConstructorSignature0<EditorPane>, typeId, name);
|
||||
}
|
||||
|
||||
constructor(
|
||||
private constructor(
|
||||
private readonly ctor: IConstructorSignature0<EditorPane>,
|
||||
private readonly id: string,
|
||||
private readonly name: string
|
||||
readonly typeId: string,
|
||||
readonly name: string
|
||||
) { }
|
||||
|
||||
instantiate(instantiationService: IInstantiationService): EditorPane {
|
||||
return instantiationService.createInstance(this.ctor);
|
||||
}
|
||||
|
||||
getId(): string {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
describes(obj: unknown): boolean {
|
||||
return obj instanceof EditorPane && obj.getId() === this.id;
|
||||
describes(editorPane: EditorPane): boolean {
|
||||
return editorPane.getId() === this.typeId;
|
||||
}
|
||||
}
|
||||
|
||||
class EditorRegistry implements IEditorRegistry {
|
||||
export class EditorRegistry implements IEditorRegistry {
|
||||
|
||||
private readonly editors: EditorDescriptor[] = [];
|
||||
private readonly mapEditorToInputs = new Map<EditorDescriptor, readonly SyncDescriptor<EditorInput>[]>();
|
||||
|
@ -120,58 +87,53 @@ class EditorRegistry implements IEditorRegistry {
|
|||
}
|
||||
|
||||
getEditor(input: EditorInput): EditorDescriptor | undefined {
|
||||
const findEditorDescriptors = (input: EditorInput, byInstanceOf?: boolean): EditorDescriptor[] => {
|
||||
const matchingDescriptors: EditorDescriptor[] = [];
|
||||
const descriptors = this.findEditorDescriptors(input);
|
||||
|
||||
for (const editor of this.editors) {
|
||||
const inputDescriptors = this.mapEditorToInputs.get(editor) || [];
|
||||
for (const inputDescriptor of inputDescriptors) {
|
||||
const inputClass = inputDescriptor.ctor;
|
||||
if (descriptors.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Direct check on constructor type (ignores prototype chain)
|
||||
if (!byInstanceOf && input.constructor === inputClass) {
|
||||
matchingDescriptors.push(editor);
|
||||
break;
|
||||
}
|
||||
|
||||
// Normal instanceof check
|
||||
else if (byInstanceOf && input instanceof inputClass) {
|
||||
matchingDescriptors.push(editor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no descriptors found, continue search using instanceof and prototype chain
|
||||
if (!byInstanceOf && matchingDescriptors.length === 0) {
|
||||
return findEditorDescriptors(input, true);
|
||||
}
|
||||
|
||||
if (byInstanceOf) {
|
||||
return matchingDescriptors;
|
||||
}
|
||||
|
||||
return matchingDescriptors;
|
||||
};
|
||||
|
||||
const descriptors = findEditorDescriptors(input);
|
||||
if (descriptors.length > 0) {
|
||||
|
||||
// Ask the input for its preferred Editor
|
||||
const preferredEditorId = input.getPreferredEditorId(descriptors.map(descriptor => descriptor.getId()));
|
||||
if (preferredEditorId) {
|
||||
return this.getEditorById(preferredEditorId);
|
||||
}
|
||||
|
||||
// Otherwise, first come first serve
|
||||
if (descriptors.length === 1) {
|
||||
return descriptors[0];
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return input.prefersEditor(descriptors);
|
||||
}
|
||||
|
||||
getEditorById(editorId: string): EditorDescriptor | undefined {
|
||||
return this.editors.find(editor => editor.getId() === editorId);
|
||||
private findEditorDescriptors(input: EditorInput, byInstanceOf?: boolean): EditorDescriptor[] {
|
||||
const matchingDescriptors: EditorDescriptor[] = [];
|
||||
|
||||
for (const editor of this.editors) {
|
||||
const inputDescriptors = this.mapEditorToInputs.get(editor) || [];
|
||||
for (const inputDescriptor of inputDescriptors) {
|
||||
const inputClass = inputDescriptor.ctor;
|
||||
|
||||
// Direct check on constructor type (ignores prototype chain)
|
||||
if (!byInstanceOf && input.constructor === inputClass) {
|
||||
matchingDescriptors.push(editor);
|
||||
break;
|
||||
}
|
||||
|
||||
// Normal instanceof check
|
||||
else if (byInstanceOf && input instanceof inputClass) {
|
||||
matchingDescriptors.push(editor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no descriptors found, continue search using instanceof and prototype chain
|
||||
if (!byInstanceOf && matchingDescriptors.length === 0) {
|
||||
return this.findEditorDescriptors(input, true);
|
||||
}
|
||||
|
||||
return matchingDescriptors;
|
||||
}
|
||||
|
||||
//#region Used for tests only
|
||||
|
||||
getEditorByType(typeId: string): EditorDescriptor | undefined {
|
||||
return this.editors.find(editor => editor.typeId === typeId);
|
||||
}
|
||||
|
||||
getEditors(): readonly EditorDescriptor[] {
|
||||
|
@ -189,6 +151,8 @@ class EditorRegistry implements IEditorRegistry {
|
|||
|
||||
return inputClasses;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
||||
|
||||
Registry.add(EditorExtensions.Editors, new EditorRegistry());
|
||||
|
@ -255,7 +219,6 @@ export function whenEditorClosed(accessor: ServicesAccessor, resources: URI[]):
|
|||
|
||||
//#endregion
|
||||
|
||||
|
||||
//#region ARIA
|
||||
|
||||
export function computeEditorAriaLabel(input: IEditorInput, index: number | undefined, group: IEditorGroup | undefined, groupCount: number): string {
|
||||
|
|
|
@ -10,7 +10,7 @@ import { IConstructorSignature0, BrandedService, IInstantiationService } from 'v
|
|||
import { assertIsDefined } from 'vs/base/common/types';
|
||||
import { PaneComposite } from 'vs/workbench/browser/panecomposite';
|
||||
import { IAction, Separator } from 'vs/base/common/actions';
|
||||
import { CompositeMenuActions } from 'vs/workbench/browser/menuActions';
|
||||
import { CompositeMenuActions } from 'vs/workbench/browser/actions';
|
||||
import { MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
|
|
|
@ -143,7 +143,6 @@ export class EditorControl extends Disposable {
|
|||
if (!editorPane.getContainer()) {
|
||||
const editorPaneContainer = document.createElement('div');
|
||||
editorPaneContainer.classList.add('editor-instance');
|
||||
editorPaneContainer.setAttribute('data-editor-id', descriptor.getId());
|
||||
|
||||
editorPane.create(editorPaneContainer);
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditorPan
|
|||
return this.instantiationService.createInstance(DiffEditorWidget, parent, configuration, {});
|
||||
}
|
||||
|
||||
override async setInput(input: DiffEditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {//
|
||||
override async setInput(input: DiffEditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
|
||||
|
||||
// Dispose previous diff navigator
|
||||
this.diffNavigatorDisposables.clear();
|
||||
|
|
|
@ -40,7 +40,7 @@ import { ScrollbarVisibility } from 'vs/base/common/scrollable';
|
|||
import { URI } from 'vs/base/common/uri';
|
||||
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { CompositeMenuActions } from 'vs/workbench/browser/menuActions';
|
||||
import { CompositeMenuActions } from 'vs/workbench/browser/actions';
|
||||
|
||||
export interface IViewPaneOptions extends IPaneOptions {
|
||||
id: string;
|
||||
|
|
|
@ -35,7 +35,7 @@ import { RunOnceScheduler } from 'vs/base/common/async';
|
|||
import { KeyMod, KeyCode, KeyChord } from 'vs/base/common/keyCodes';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { ViewPane } from 'vs/workbench/browser/parts/views/viewPane';
|
||||
import { CompositeMenuActions } from 'vs/workbench/browser/menuActions';
|
||||
import { CompositeMenuActions } from 'vs/workbench/browser/actions';
|
||||
import { createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||
import { IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { ScrollEvent } from 'vs/base/common/scrollable';
|
||||
|
|
|
@ -183,7 +183,7 @@ class BrowserMain extends Disposable {
|
|||
serviceCollection.set(IFileService, fileService);
|
||||
await this.registerFileSystemProviders(environmentService, fileService, remoteAgentService, logService, logsPath);
|
||||
|
||||
// IURIIdentityService
|
||||
// URI Identity
|
||||
const uriIdentityService = new UriIdentityService(fileService);
|
||||
serviceCollection.set(IUriIdentityService, uriIdentityService);
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { setFullscreen } from 'vs/base/browser/browser';
|
||||
import { addDisposableListener, addDisposableThrottledListener, detectFullscreen, EventHelper, EventType, windowOpenNoOpenerWithSuccess, windowOpenNoOpener } from 'vs/base/browser/dom';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { DomEmitter } from 'vs/base/browser/event';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
|
@ -89,8 +89,8 @@ export class BrowserWindow extends Disposable {
|
|||
// when shutdown has happened to not show the dialog e.g.
|
||||
// when navigation takes a longer time.
|
||||
Event.toPromise(Event.any(
|
||||
Event.once(domEvent(document.body, EventType.KEY_DOWN, true)),
|
||||
Event.once(domEvent(document.body, EventType.MOUSE_DOWN, true))
|
||||
Event.once(new DomEmitter(document.body, EventType.KEY_DOWN, true).event),
|
||||
Event.once(new DomEmitter(document.body, EventType.MOUSE_DOWN, true).event)
|
||||
)).then(async () => {
|
||||
|
||||
// Delay the dialog in case the user interacted
|
||||
|
|
|
@ -68,6 +68,31 @@ export const TEXT_DIFF_EDITOR_ID = 'workbench.editors.textDiffEditor';
|
|||
*/
|
||||
export const BINARY_DIFF_EDITOR_ID = 'workbench.editors.binaryResourceDiffEditor';
|
||||
|
||||
export interface IEditorDescriptor<T extends IEditorPane> {
|
||||
|
||||
/**
|
||||
* The unique type identifier of the editor. All instances
|
||||
* of the same `IEditorPane` should have the same type
|
||||
* identifier.
|
||||
*/
|
||||
readonly typeId: string;
|
||||
|
||||
/**
|
||||
* The display name of the editor.
|
||||
*/
|
||||
readonly name: string;
|
||||
|
||||
/**
|
||||
* Instantiates the editor pane using the provided services.
|
||||
*/
|
||||
instantiate(instantiationService: IInstantiationService): T;
|
||||
|
||||
/**
|
||||
* Whether the descriptor is for the provided editor pane.
|
||||
*/
|
||||
describes(editorPane: T): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* The editor pane is the container for workbench editors.
|
||||
*/
|
||||
|
@ -414,7 +439,7 @@ export interface IEditorInput extends IDisposable {
|
|||
readonly onDidChangeLabel: Event<void>;
|
||||
|
||||
/**
|
||||
* Unique type identifier for this inpput. Every editor input of the
|
||||
* Unique type identifier for this input. Every editor input of the
|
||||
* same class should share the same type identifier. The type identifier
|
||||
* is used for example for serialising/deserialising editor inputs
|
||||
* via the serialisers of the `IEditorInputFactoryRegistry`.
|
||||
|
@ -586,14 +611,6 @@ export abstract class EditorInput extends Disposable implements IEditorInput {
|
|||
return this.getTitle(Verbosity.SHORT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred editor for this input. A list of candidate editors is passed in that whee registered
|
||||
* for the input. This allows subclasses to decide late which editor to use for the input on a case by case basis.
|
||||
*/
|
||||
getPreferredEditorId(candidates: string[]): string | undefined {
|
||||
return firstOrDefault(candidates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a descriptor suitable for telemetry events.
|
||||
*
|
||||
|
@ -642,6 +659,17 @@ export abstract class EditorInput extends Disposable implements IEditorInput {
|
|||
return this === otherInput;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a input was registered onto multiple editors, this method
|
||||
* will be asked to return the preferred one to use.
|
||||
*
|
||||
* @param editors a list of editor descriptors that are candidates
|
||||
* for the editor input to open in.
|
||||
*/
|
||||
prefersEditor<T extends IEditorDescriptor<IEditorPane>>(editors: T[]): T | undefined {
|
||||
return firstOrDefault(editors);
|
||||
}
|
||||
|
||||
isDisposed(): boolean {
|
||||
return this.disposed;
|
||||
}
|
||||
|
@ -828,6 +856,12 @@ export class SideBySideEditorInput extends EditorInput {
|
|||
return this.description;
|
||||
}
|
||||
|
||||
override getTelemetryDescriptor(): { [key: string]: unknown } {
|
||||
const descriptor = this.primary.getTelemetryDescriptor();
|
||||
|
||||
return Object.assign(descriptor, super.getTelemetryDescriptor());
|
||||
}
|
||||
|
||||
override isDirty(): boolean {
|
||||
return this.primary.isDirty();
|
||||
}
|
||||
|
@ -848,12 +882,6 @@ export class SideBySideEditorInput extends EditorInput {
|
|||
return this.primary.revert(group, options);
|
||||
}
|
||||
|
||||
override getTelemetryDescriptor(): { [key: string]: unknown } {
|
||||
const descriptor = this.primary.getTelemetryDescriptor();
|
||||
|
||||
return Object.assign(descriptor, super.getTelemetryDescriptor());
|
||||
}
|
||||
|
||||
override matches(otherInput: unknown): boolean {
|
||||
if (otherInput === this) {
|
||||
return true;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { EditorModel, EditorInput, SideBySideEditorInput, TEXT_DIFF_EDITOR_ID, BINARY_DIFF_EDITOR_ID, Verbosity } from 'vs/workbench/common/editor';
|
||||
import { EditorModel, EditorInput, SideBySideEditorInput, TEXT_DIFF_EDITOR_ID, BINARY_DIFF_EDITOR_ID, Verbosity, IEditorDescriptor, IEditorPane } from 'vs/workbench/common/editor';
|
||||
import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel';
|
||||
import { DiffEditorModel } from 'vs/workbench/common/editor/diffEditorModel';
|
||||
import { TextDiffEditorModel } from 'vs/workbench/common/editor/textDiffEditorModel';
|
||||
|
@ -104,8 +104,12 @@ export class DiffEditorInput extends SideBySideEditorInput {
|
|||
return this.cachedModel;
|
||||
}
|
||||
|
||||
override getPreferredEditorId(candidates: string[]): string {
|
||||
return this.forceOpenAsBinary ? BINARY_DIFF_EDITOR_ID : TEXT_DIFF_EDITOR_ID;
|
||||
override prefersEditor<T extends IEditorDescriptor<IEditorPane>>(editors: T[]): T | undefined {
|
||||
if (this.forceOpenAsBinary) {
|
||||
return editors.find(editor => editor.typeId === BINARY_DIFF_EDITOR_ID);
|
||||
}
|
||||
|
||||
return editors.find(editor => editor.typeId === TEXT_DIFF_EDITOR_ID);
|
||||
}
|
||||
|
||||
private async createModel(): Promise<DiffEditorModel> {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IFileEditorInput, Verbosity, GroupIdentifier, IMoveResult, isTextEditorPane, EditorInputCapabilities } from 'vs/workbench/common/editor';
|
||||
import { IFileEditorInput, Verbosity, GroupIdentifier, IMoveResult, isTextEditorPane, EditorInputCapabilities, IEditorDescriptor, IEditorPane } from 'vs/workbench/common/editor';
|
||||
import { AbstractTextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput';
|
||||
import { BinaryEditorModel } from 'vs/workbench/common/editor/binaryEditorModel';
|
||||
import { FileOperationError, FileOperationResult, FileSystemProviderCapabilities, IFileService } from 'vs/platform/files/common/files';
|
||||
|
@ -264,8 +264,12 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements
|
|||
return super.isSaving();
|
||||
}
|
||||
|
||||
override getPreferredEditorId(candidates: string[]): string {
|
||||
return this.forceOpenAs === ForceOpenAs.Binary ? BINARY_FILE_EDITOR_ID : TEXT_FILE_EDITOR_ID;
|
||||
override prefersEditor<T extends IEditorDescriptor<IEditorPane>>(editors: T[]): T | undefined {
|
||||
if (this.forceOpenAs === ForceOpenAs.Binary) {
|
||||
return editors.find(editor => editor.typeId === BINARY_FILE_EDITOR_ID);
|
||||
}
|
||||
|
||||
return editors.find(editor => editor.typeId === TEXT_FILE_EDITOR_ID);
|
||||
}
|
||||
|
||||
override resolve(): Promise<ITextFileEditorModel | BinaryEditorModel> {
|
||||
|
|
|
@ -221,7 +221,7 @@ export class OutputEditor extends AbstractTextResourceEditor {
|
|||
return channel ? nls.localize('outputViewWithInputAriaLabel', "{0}, Output panel", channel.label) : nls.localize('outputViewAriaLabel', "Output panel");
|
||||
}
|
||||
|
||||
override async setInput(input: TextResourceEditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {//
|
||||
override async setInput(input: TextResourceEditorInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
|
||||
const focus = !(options && options.preserveFocus);
|
||||
if (input.matches(this.input)) {
|
||||
return;
|
||||
|
|
|
@ -151,7 +151,7 @@ export class PreferencesEditor extends EditorPane {
|
|||
this.preferencesRenderers.editFocusedPreference();
|
||||
}
|
||||
|
||||
override setInput(input: PreferencesEditorInput, options: SettingsEditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {//
|
||||
override setInput(input: PreferencesEditorInput, options: SettingsEditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
|
||||
this.defaultSettingsEditorContextKey.set(true);
|
||||
this.defaultSettingsJSONEditorContextKey.set(true);
|
||||
if (options && options.query) {
|
||||
|
|
|
@ -208,7 +208,7 @@ export abstract class SharedDesktopMain extends Disposable {
|
|||
await result;
|
||||
}
|
||||
|
||||
// Uri Identity
|
||||
// URI Identity
|
||||
const uriIdentityService = new UriIdentityService(fileService);
|
||||
serviceCollection.set(IUriIdentityService, uriIdentityService);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import * as assert from 'assert';
|
||||
import { EditorPane, EditorMemento } from 'vs/workbench/browser/parts/editor/editorPane';
|
||||
import { WorkspaceTrustRequiredEditor } from 'vs/workbench/browser/parts/editor/workspaceTrustRequiredEditor';
|
||||
import { EditorInput, EditorOptions, IEditorInputSerializer, IEditorInputFactoryRegistry, EditorExtensions, EditorInputCapabilities } from 'vs/workbench/common/editor';
|
||||
import { EditorInput, EditorOptions, IEditorInputSerializer, IEditorInputFactoryRegistry, EditorExtensions, EditorInputCapabilities, IEditorDescriptor, IEditorPane } from 'vs/workbench/common/editor';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
|
@ -16,7 +16,7 @@ import { workbenchInstantiationService, TestEditorGroupView, TestEditorGroupsSer
|
|||
import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput';
|
||||
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IEditorRegistry, EditorDescriptor } from 'vs/workbench/browser/editor';
|
||||
import { EditorDescriptor, EditorRegistry } from 'vs/workbench/browser/editor';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IEditorModel } from 'vs/platform/editor/common/editor';
|
||||
import { DisposableStore, dispose } from 'vs/base/common/lifecycle';
|
||||
|
@ -30,8 +30,8 @@ import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/w
|
|||
|
||||
const NullThemeService = new TestThemeService();
|
||||
|
||||
let EditorRegistry: IEditorRegistry = Registry.as(EditorExtensions.Editors);
|
||||
let EditorInputRegistry: IEditorInputFactoryRegistry = Registry.as(EditorExtensions.EditorInputFactories);
|
||||
const editorRegistry: EditorRegistry = Registry.as(EditorExtensions.Editors);
|
||||
const editorInputRegistry: IEditorInputFactoryRegistry = Registry.as(EditorExtensions.EditorInputFactories);
|
||||
|
||||
class TestEditor extends EditorPane {
|
||||
|
||||
|
@ -75,8 +75,8 @@ class TestInput extends EditorInput {
|
|||
|
||||
readonly resource = undefined;
|
||||
|
||||
override getPreferredEditorId(ids: string[]) {
|
||||
return ids[1];
|
||||
override prefersEditor<T extends IEditorDescriptor<IEditorPane>>(editors: T[]): T | undefined {
|
||||
return editors[1];
|
||||
}
|
||||
|
||||
override get typeId(): string {
|
||||
|
@ -105,85 +105,85 @@ class TestResourceEditorInput extends TextResourceEditorInput { }
|
|||
suite('Workbench EditorPane', () => {
|
||||
|
||||
test('EditorPane API', async () => {
|
||||
let e = new TestEditor(NullTelemetryService);
|
||||
let input = new OtherTestInput();
|
||||
let options = new EditorOptions();
|
||||
const editor = new TestEditor(NullTelemetryService);
|
||||
const input = new OtherTestInput();
|
||||
const options = new EditorOptions();
|
||||
|
||||
assert(!e.isVisible());
|
||||
assert(!e.input);
|
||||
assert(!editor.isVisible());
|
||||
assert(!editor.input);
|
||||
|
||||
await e.setInput(input, options, Object.create(null), CancellationToken.None);
|
||||
assert.strictEqual(<any>input, e.input);
|
||||
await editor.setInput(input, options, Object.create(null), CancellationToken.None);
|
||||
assert.strictEqual(<any>input, editor.input);
|
||||
const group = new TestEditorGroupView(1);
|
||||
e.setVisible(true, group);
|
||||
assert(e.isVisible());
|
||||
assert.strictEqual(e.group, group);
|
||||
editor.setVisible(true, group);
|
||||
assert(editor.isVisible());
|
||||
assert.strictEqual(editor.group, group);
|
||||
input.onWillDispose(() => {
|
||||
assert(false);
|
||||
});
|
||||
e.dispose();
|
||||
e.clearInput();
|
||||
e.setVisible(false, group);
|
||||
assert(!e.isVisible());
|
||||
assert(!e.input);
|
||||
assert(!e.getControl());
|
||||
editor.dispose();
|
||||
editor.clearInput();
|
||||
editor.setVisible(false, group);
|
||||
assert(!editor.isVisible());
|
||||
assert(!editor.input);
|
||||
assert(!editor.getControl());
|
||||
});
|
||||
|
||||
test('EditorDescriptor', () => {
|
||||
let d = EditorDescriptor.create(TestEditor, 'id', 'name');
|
||||
assert.strictEqual(d.getId(), 'id');
|
||||
assert.strictEqual(d.getName(), 'name');
|
||||
const editorDescriptor = EditorDescriptor.create(TestEditor, 'id', 'name');
|
||||
assert.strictEqual(editorDescriptor.typeId, 'id');
|
||||
assert.strictEqual(editorDescriptor.name, 'name');
|
||||
});
|
||||
|
||||
test('Editor Registration', function () {
|
||||
let d1 = EditorDescriptor.create(TestEditor, 'id1', 'name');
|
||||
let d2 = EditorDescriptor.create(OtherTestEditor, 'id2', 'name');
|
||||
const editorDescriptor1 = EditorDescriptor.create(TestEditor, 'id1', 'name');
|
||||
const editorDescriptor2 = EditorDescriptor.create(OtherTestEditor, 'id2', 'name');
|
||||
|
||||
let oldEditorsCnt = EditorRegistry.getEditors().length;
|
||||
let oldInputCnt = (<any>EditorRegistry).getEditorInputs().length;
|
||||
const oldEditorsCnt = editorRegistry.getEditors().length;
|
||||
const oldInputCnt = editorRegistry.getEditorInputs().length;
|
||||
|
||||
const dispose1 = EditorRegistry.registerEditor(d1, [new SyncDescriptor(TestInput)]);
|
||||
const dispose2 = EditorRegistry.registerEditor(d2, [new SyncDescriptor(TestInput), new SyncDescriptor(OtherTestInput)]);
|
||||
const dispose1 = editorRegistry.registerEditor(editorDescriptor1, [new SyncDescriptor(TestInput)]);
|
||||
const dispose2 = editorRegistry.registerEditor(editorDescriptor2, [new SyncDescriptor(TestInput), new SyncDescriptor(OtherTestInput)]);
|
||||
|
||||
assert.strictEqual(EditorRegistry.getEditors().length, oldEditorsCnt + 2);
|
||||
assert.strictEqual((<any>EditorRegistry).getEditorInputs().length, oldInputCnt + 3);
|
||||
assert.strictEqual(editorRegistry.getEditors().length, oldEditorsCnt + 2);
|
||||
assert.strictEqual(editorRegistry.getEditorInputs().length, oldInputCnt + 3);
|
||||
|
||||
assert.strictEqual(EditorRegistry.getEditor(new TestInput()), d2);
|
||||
assert.strictEqual(EditorRegistry.getEditor(new OtherTestInput()), d2);
|
||||
assert.strictEqual(editorRegistry.getEditor(new TestInput()), editorDescriptor2);
|
||||
assert.strictEqual(editorRegistry.getEditor(new OtherTestInput()), editorDescriptor2);
|
||||
|
||||
assert.strictEqual(EditorRegistry.getEditorById('id1'), d1);
|
||||
assert.strictEqual(EditorRegistry.getEditorById('id2'), d2);
|
||||
assert(!EditorRegistry.getEditorById('id3'));
|
||||
assert.strictEqual(editorRegistry.getEditorByType('id1'), editorDescriptor1);
|
||||
assert.strictEqual(editorRegistry.getEditorByType('id2'), editorDescriptor2);
|
||||
assert(!editorRegistry.getEditorByType('id3'));
|
||||
|
||||
dispose([dispose1, dispose2]);
|
||||
});
|
||||
|
||||
test('Editor Lookup favors specific class over superclass (match on specific class)', function () {
|
||||
let d1 = EditorDescriptor.create(TestEditor, 'id1', 'name');
|
||||
const d1 = EditorDescriptor.create(TestEditor, 'id1', 'name');
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
disposables.add(registerTestResourceEditor());
|
||||
disposables.add(EditorRegistry.registerEditor(d1, [new SyncDescriptor(TestResourceEditorInput)]));
|
||||
disposables.add(editorRegistry.registerEditor(d1, [new SyncDescriptor(TestResourceEditorInput)]));
|
||||
|
||||
let inst = workbenchInstantiationService();
|
||||
const inst = workbenchInstantiationService();
|
||||
|
||||
const editor = EditorRegistry.getEditor(inst.createInstance(TestResourceEditorInput, URI.file('/fake'), 'fake', '', undefined))!.instantiate(inst);
|
||||
const editor = editorRegistry.getEditor(inst.createInstance(TestResourceEditorInput, URI.file('/fake'), 'fake', '', undefined))!.instantiate(inst);
|
||||
assert.strictEqual(editor.getId(), 'testEditor');
|
||||
|
||||
const otherEditor = EditorRegistry.getEditor(inst.createInstance(TextResourceEditorInput, URI.file('/fake'), 'fake', '', undefined))!.instantiate(inst);
|
||||
const otherEditor = editorRegistry.getEditor(inst.createInstance(TextResourceEditorInput, URI.file('/fake'), 'fake', '', undefined))!.instantiate(inst);
|
||||
assert.strictEqual(otherEditor.getId(), 'workbench.editors.textResourceEditor');
|
||||
|
||||
disposables.dispose();
|
||||
});
|
||||
|
||||
test('Editor Lookup favors specific class over superclass (match on super class)', function () {
|
||||
let inst = workbenchInstantiationService();
|
||||
const inst = workbenchInstantiationService();
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
disposables.add(registerTestResourceEditor());
|
||||
const editor = EditorRegistry.getEditor(inst.createInstance(TestResourceEditorInput, URI.file('/fake'), 'fake', '', undefined))!.instantiate(inst);
|
||||
const editor = editorRegistry.getEditor(inst.createInstance(TestResourceEditorInput, URI.file('/fake'), 'fake', '', undefined))!.instantiate(inst);
|
||||
|
||||
assert.strictEqual('workbench.editors.textResourceEditor', editor.getId());
|
||||
|
||||
|
@ -192,17 +192,17 @@ suite('Workbench EditorPane', () => {
|
|||
|
||||
test('Editor Input Serializer', function () {
|
||||
const testInput = new TestEditorInput(URI.file('/fake'), 'testTypeId');
|
||||
workbenchInstantiationService().invokeFunction(accessor => EditorInputRegistry.start(accessor));
|
||||
const disposable = EditorInputRegistry.registerEditorInputSerializer(testInput.typeId, TestInputSerializer);
|
||||
workbenchInstantiationService().invokeFunction(accessor => editorInputRegistry.start(accessor));
|
||||
const disposable = editorInputRegistry.registerEditorInputSerializer(testInput.typeId, TestInputSerializer);
|
||||
|
||||
let factory = EditorInputRegistry.getEditorInputSerializer('testTypeId');
|
||||
let factory = editorInputRegistry.getEditorInputSerializer('testTypeId');
|
||||
assert(factory);
|
||||
|
||||
factory = EditorInputRegistry.getEditorInputSerializer(testInput);
|
||||
factory = editorInputRegistry.getEditorInputSerializer(testInput);
|
||||
assert(factory);
|
||||
|
||||
// throws when registering serializer for same type
|
||||
assert.throws(() => EditorInputRegistry.registerEditorInputSerializer(testInput.typeId, TestInputSerializer));
|
||||
assert.throws(() => editorInputRegistry.registerEditorInputSerializer(testInput.typeId, TestInputSerializer));
|
||||
|
||||
disposable.dispose();
|
||||
});
|
||||
|
@ -283,7 +283,7 @@ suite('Workbench EditorPane', () => {
|
|||
interface TestViewState { line: number; }
|
||||
|
||||
const rawMemento = Object.create(null);
|
||||
let memento = new EditorMemento<TestViewState>('id', 'key', rawMemento, 3, editorGroupService);
|
||||
const memento = new EditorMemento<TestViewState>('id', 'key', rawMemento, 3, editorGroupService);
|
||||
|
||||
memento.saveEditorState(testGroup0, URI.file('/some/folder/file-1.txt'), { line: 1 });
|
||||
memento.saveEditorState(testGroup0, URI.file('/some/folder/file-2.txt'), { line: 2 });
|
||||
|
@ -326,7 +326,7 @@ suite('Workbench EditorPane', () => {
|
|||
}
|
||||
|
||||
const rawMemento = Object.create(null);
|
||||
let memento = new EditorMemento<TestViewState>('id', 'key', rawMemento, 3, new TestEditorGroupsService());
|
||||
const memento = new EditorMemento<TestViewState>('id', 'key', rawMemento, 3, new TestEditorGroupsService());
|
||||
|
||||
const testInputA = new TestEditorInput(URI.file('/A'));
|
||||
|
||||
|
@ -364,7 +364,7 @@ suite('Workbench EditorPane', () => {
|
|||
}
|
||||
|
||||
const rawMemento = Object.create(null);
|
||||
let memento = new EditorMemento<TestViewState>('id', 'key', rawMemento, 3, new TestEditorGroupsService());
|
||||
const memento = new EditorMemento<TestViewState>('id', 'key', rawMemento, 3, new TestEditorGroupsService());
|
||||
|
||||
const testInputA = new TestEditorInput(URI.file('/A'));
|
||||
|
||||
|
@ -401,6 +401,7 @@ suite('Workbench EditorPane', () => {
|
|||
});
|
||||
|
||||
test('WorkspaceTrustRequiredEditor', async function () {
|
||||
|
||||
class TrustRequiredTestEditor extends EditorPane {
|
||||
constructor(@ITelemetryService telemetryService: ITelemetryService) {
|
||||
super('TestEditor', NullTelemetryService, NullThemeService, new TestStorageService());
|
||||
|
@ -443,8 +444,8 @@ suite('Workbench EditorPane', () => {
|
|||
|
||||
const group = editorPart.activeGroup;
|
||||
|
||||
let editorDescriptor = EditorDescriptor.create(TrustRequiredTestEditor, 'id1', 'name');
|
||||
disposables.add(EditorRegistry.registerEditor(editorDescriptor, [new SyncDescriptor(TrustRequiredTestInput)]));
|
||||
const editorDescriptor = EditorDescriptor.create(TrustRequiredTestEditor, 'id1', 'name');
|
||||
disposables.add(editorRegistry.registerEditor(editorDescriptor, [new SyncDescriptor(TrustRequiredTestInput)]));
|
||||
|
||||
const testInput = new TrustRequiredTestInput();
|
||||
|
||||
|
|
Loading…
Reference in a new issue