more fixes for #9794
This commit is contained in:
parent
77d8f8b5f4
commit
176f350454
|
@ -242,10 +242,6 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupService
|
|||
const active = (group.count === 0) || !options || !options.inactive;
|
||||
group.openEditor(input, { active, pinned, index: options && options.index });
|
||||
|
||||
// indicate to the UI that an editor is about to open. we need to update the title because it could be that
|
||||
// the input is already opened but the title has changed and the UI should reflect that
|
||||
this.sideBySideControl.updateTitle({ group, editor: input });
|
||||
|
||||
// Return early if the editor is to be open inactive and there are other editors in this group to show
|
||||
if (!active) {
|
||||
return TPromise.as<BaseEditor>(null);
|
||||
|
|
|
@ -122,11 +122,13 @@ export interface IEditorInputFactory {
|
|||
export abstract class EditorInput implements IEditorInput {
|
||||
private _onDispose: Emitter<void>;
|
||||
protected _onDidChangeDirty: Emitter<void>;
|
||||
protected _onDidChangeLabel: Emitter<void>;
|
||||
|
||||
private disposed: boolean;
|
||||
|
||||
constructor() {
|
||||
this._onDidChangeDirty = new Emitter<void>();
|
||||
this._onDidChangeLabel = new Emitter<void>();
|
||||
this._onDispose = new Emitter<void>();
|
||||
|
||||
this.disposed = false;
|
||||
|
@ -139,6 +141,13 @@ export abstract class EditorInput implements IEditorInput {
|
|||
return this._onDidChangeDirty.event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when the label this input changes.
|
||||
*/
|
||||
public get onDidChangeLabel(): Event<void> {
|
||||
return this._onDidChangeLabel.event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when the model gets disposed.
|
||||
*/
|
||||
|
@ -247,6 +256,7 @@ export abstract class EditorInput implements IEditorInput {
|
|||
this._onDispose.fire();
|
||||
|
||||
this._onDidChangeDirty.dispose();
|
||||
this._onDidChangeLabel.dispose();
|
||||
this._onDispose.dispose();
|
||||
}
|
||||
|
||||
|
@ -749,6 +759,7 @@ export function getResource(input: IEditorInput): URI {
|
|||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
return getUntitledOrFileResource(input, true);
|
||||
}
|
||||
|
||||
|
@ -827,6 +838,7 @@ export interface IEditorGroup {
|
|||
previewEditor: IEditorInput;
|
||||
|
||||
getEditor(index: number): IEditorInput;
|
||||
getEditor(resource: URI): IEditorInput;
|
||||
indexOf(editor: IEditorInput): number;
|
||||
|
||||
contains(editor: IEditorInput): boolean;
|
||||
|
|
|
@ -60,8 +60,9 @@ export class DiffEditorInput extends BaseDiffEditorInput {
|
|||
}
|
||||
}));
|
||||
|
||||
// When the modified model gets dirty, re-emit this to the outside
|
||||
// Reemit some events from the modified side to the outside
|
||||
this._toUnbind.push(this.modifiedInput.onDidChangeDirty(() => this._onDidChangeDirty.fire()));
|
||||
this._toUnbind.push(this.modifiedInput.onDidChangeLabel(() => this._onDidChangeLabel.fire()));
|
||||
}
|
||||
|
||||
public get toUnbind() {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
'use strict';
|
||||
|
||||
import Event, {Emitter, once} from 'vs/base/common/event';
|
||||
import {IEditorRegistry, Extensions, EditorInput, getUntitledOrFileResource, IEditorStacksModel, IEditorGroup, IEditorIdentifier, IGroupEvent, GroupIdentifier, IStacksModelChangeEvent, IWorkbenchEditorConfiguration, EditorOpenPositioning} from 'vs/workbench/common/editor';
|
||||
import {IEditorRegistry, Extensions, EditorInput, getResource, IEditorStacksModel, IEditorGroup, IEditorIdentifier, IGroupEvent, GroupIdentifier, IStacksModelChangeEvent, IWorkbenchEditorConfiguration, EditorOpenPositioning} from 'vs/workbench/common/editor';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import {IStorageService, StorageScope} from 'vs/platform/storage/common/storage';
|
||||
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
|
||||
|
@ -17,9 +17,6 @@ import {Registry} from 'vs/platform/platform';
|
|||
import {Position, Direction} from 'vs/platform/editor/common/editor';
|
||||
import {DiffEditorInput} from 'vs/workbench/common/editor/diffEditorInput';
|
||||
|
||||
// TODO@Ben currently only files and untitled editors are tracked with their resources in the stacks model
|
||||
// Once the resource is a base concept of all editor inputs, every resource should be tracked for any editor
|
||||
|
||||
export interface GroupEvent extends IGroupEvent {
|
||||
editor: EditorInput;
|
||||
}
|
||||
|
@ -69,6 +66,7 @@ export class EditorGroup implements IEditorGroup {
|
|||
private _onEditorClosed: Emitter<GroupEvent>;
|
||||
private _onEditorDisposed: Emitter<EditorInput>;
|
||||
private _onEditorDirty: Emitter<EditorInput>;
|
||||
private _onEditorLabelChange: Emitter<EditorInput>;
|
||||
private _onEditorMoved: Emitter<EditorInput>;
|
||||
private _onEditorPinned: Emitter<EditorInput>;
|
||||
private _onEditorUnpinned: Emitter<EditorInput>;
|
||||
|
@ -93,13 +91,14 @@ export class EditorGroup implements IEditorGroup {
|
|||
this._onEditorClosed = new Emitter<GroupEvent>();
|
||||
this._onEditorDisposed = new Emitter<EditorInput>();
|
||||
this._onEditorDirty = new Emitter<EditorInput>();
|
||||
this._onEditorLabelChange = new Emitter<EditorInput>();
|
||||
this._onEditorMoved = new Emitter<EditorInput>();
|
||||
this._onEditorPinned = new Emitter<EditorInput>();
|
||||
this._onEditorUnpinned = new Emitter<EditorInput>();
|
||||
this._onEditorStateChanged = new Emitter<EditorInput>();
|
||||
this._onEditorsStructureChanged = new Emitter<EditorInput>();
|
||||
|
||||
this.toDispose.push(this._onEditorActivated, this._onEditorOpened, this._onEditorClosed, this._onEditorDisposed, this._onEditorDirty, this._onEditorMoved, this._onEditorPinned, this._onEditorUnpinned, this._onEditorStateChanged, this._onEditorsStructureChanged);
|
||||
this.toDispose.push(this._onEditorActivated, this._onEditorOpened, this._onEditorClosed, this._onEditorDisposed, this._onEditorDirty, this._onEditorLabelChange, this._onEditorMoved, this._onEditorPinned, this._onEditorUnpinned, this._onEditorStateChanged, this._onEditorsStructureChanged);
|
||||
|
||||
if (typeof arg1 === 'object') {
|
||||
this.deserialize(arg1);
|
||||
|
@ -154,6 +153,10 @@ export class EditorGroup implements IEditorGroup {
|
|||
return this._onEditorDirty.event;
|
||||
}
|
||||
|
||||
public get onEditorLabelChange(): Event<EditorInput> {
|
||||
return this._onEditorLabelChange.event;
|
||||
}
|
||||
|
||||
public get onEditorMoved(): Event<EditorInput> {
|
||||
return this._onEditorMoved.event;
|
||||
}
|
||||
|
@ -178,8 +181,27 @@ export class EditorGroup implements IEditorGroup {
|
|||
return mru ? this.mru.slice(0) : this.editors.slice(0);
|
||||
}
|
||||
|
||||
public getEditor(index: number): EditorInput {
|
||||
return this.editors[index];
|
||||
public getEditor(index: number): EditorInput;
|
||||
public getEditor(resource: URI): EditorInput;
|
||||
public getEditor(arg1: any): EditorInput {
|
||||
if (typeof arg1 === 'number') {
|
||||
return this.editors[arg1];
|
||||
}
|
||||
|
||||
const resource: URI = arg1;
|
||||
if (!this.contains(resource)) {
|
||||
return null; // fast check for resource opened or not
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.editors.length; i++) {
|
||||
const editor = this.editors[i];
|
||||
const editorResource = getResource(editor);
|
||||
if (editorResource && editorResource.toString() === resource.toString()) {
|
||||
return editor;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public get activeEditor(): EditorInput {
|
||||
|
@ -308,6 +330,11 @@ export class EditorGroup implements IEditorGroup {
|
|||
this.fireEvent(this._onEditorDirty, editor, false);
|
||||
}));
|
||||
|
||||
// Re-Emit label changes
|
||||
unbind.push(editor.onDidChangeLabel(() => {
|
||||
this.fireEvent(this._onEditorLabelChange, editor, false);
|
||||
}));
|
||||
|
||||
// Clean up dispose listeners once the editor gets closed
|
||||
unbind.push(this.onEditorClosed(event => {
|
||||
if (event.editor.matches(editor)) {
|
||||
|
@ -514,7 +541,7 @@ export class EditorGroup implements IEditorGroup {
|
|||
}
|
||||
|
||||
private updateResourceMap(editor: EditorInput, remove: boolean): void {
|
||||
const resource = getUntitledOrFileResource(editor, true /* include diff editors */);
|
||||
const resource = getResource(editor);
|
||||
if (resource) {
|
||||
|
||||
// It is possible to have the same resource opened twice (once as normal input and once as diff input)
|
||||
|
@ -663,6 +690,7 @@ export class EditorStacksModel implements IEditorStacksModel {
|
|||
private _onGroupRenamed: Emitter<EditorGroup>;
|
||||
private _onEditorDisposed: Emitter<EditorIdentifier>;
|
||||
private _onEditorDirty: Emitter<EditorIdentifier>;
|
||||
private _onEditorLabelChange: Emitter<EditorIdentifier>;
|
||||
private _onEditorClosed: Emitter<GroupEvent>;
|
||||
private _onModelChanged: Emitter<IStacksModelChangeEvent>;
|
||||
|
||||
|
@ -686,9 +714,10 @@ export class EditorStacksModel implements IEditorStacksModel {
|
|||
this._onModelChanged = new Emitter<IStacksModelChangeEvent>();
|
||||
this._onEditorDisposed = new Emitter<EditorIdentifier>();
|
||||
this._onEditorDirty = new Emitter<EditorIdentifier>();
|
||||
this._onEditorLabelChange = new Emitter<EditorIdentifier>();
|
||||
this._onEditorClosed = new Emitter<GroupEvent>();
|
||||
|
||||
this.toDispose.push(this._onGroupOpened, this._onGroupClosed, this._onGroupActivated, this._onGroupDeactivated, this._onGroupMoved, this._onGroupRenamed, this._onModelChanged, this._onEditorDisposed, this._onEditorDirty, this._onEditorClosed);
|
||||
this.toDispose.push(this._onGroupOpened, this._onGroupClosed, this._onGroupActivated, this._onGroupDeactivated, this._onGroupMoved, this._onGroupRenamed, this._onModelChanged, this._onEditorDisposed, this._onEditorDirty, this._onEditorLabelChange, this._onEditorClosed);
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
@ -733,6 +762,10 @@ export class EditorStacksModel implements IEditorStacksModel {
|
|||
return this._onEditorDirty.event;
|
||||
}
|
||||
|
||||
public get onEditorLabelChange(): Event<EditorIdentifier> {
|
||||
return this._onEditorLabelChange.event;
|
||||
}
|
||||
|
||||
public get onEditorClosed(): Event<GroupEvent> {
|
||||
return this._onEditorClosed.event;
|
||||
}
|
||||
|
@ -1064,6 +1097,7 @@ export class EditorStacksModel implements IEditorStacksModel {
|
|||
}));
|
||||
unbind.push(group.onEditorDisposed(editor => this._onEditorDisposed.fire({ editor, group })));
|
||||
unbind.push(group.onEditorDirty(editor => this._onEditorDirty.fire({ editor, group })));
|
||||
unbind.push(group.onEditorLabelChange(editor => this._onEditorLabelChange.fire({ editor, group })));
|
||||
unbind.push(this.onGroupClosed(g => {
|
||||
if (g === group) {
|
||||
dispose(unbind);
|
||||
|
|
|
@ -143,10 +143,24 @@ export class ResourceEditorInput extends EditorInput {
|
|||
return this.name;
|
||||
}
|
||||
|
||||
public setName(name: string): void {
|
||||
if (this.name !== name) {
|
||||
this.name = name;
|
||||
this._onDidChangeLabel.fire();
|
||||
}
|
||||
}
|
||||
|
||||
public getDescription(): string {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public setDescription(description: string): void {
|
||||
if (this.description !== description) {
|
||||
this.description = description;
|
||||
this._onDidChangeLabel.fire();
|
||||
}
|
||||
}
|
||||
|
||||
public resolve(refresh?: boolean): TPromise<EditorModel> {
|
||||
|
||||
// Use Cached Model
|
||||
|
|
|
@ -16,6 +16,7 @@ import {Registry} from 'vs/platform/platform';
|
|||
import {EditorDescriptor} from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||
import {IEditorRegistry, Extensions as EditorExtensions} from 'vs/workbench/common/editor';
|
||||
import {SyncDescriptor} from 'vs/platform/instantiation/common/descriptors';
|
||||
import {IEditorGroupService} from 'vs/workbench/services/group/common/groupService';
|
||||
|
||||
// --- Register Editor
|
||||
(<IEditorRegistry>Registry.as(EditorExtensions.Editors)).registerEditor(new EditorDescriptor(HtmlPreviewPart.ID,
|
||||
|
@ -28,9 +29,27 @@ import {SyncDescriptor} from 'vs/platform/instantiation/common/descriptors';
|
|||
|
||||
CommandsRegistry.registerCommand('_workbench.previewHtml', function (accessor: ServicesAccessor, resource: URI | string, position?: EditorPosition, label?: string) {
|
||||
|
||||
let uri = resource instanceof URI ? resource : URI.parse(resource);
|
||||
const uri = resource instanceof URI ? resource : URI.parse(resource);
|
||||
label = label || uri.fsPath;
|
||||
let input = accessor.get(IInstantiationService).createInstance(HtmlInput, label, '', uri);
|
||||
|
||||
let input: HtmlInput;
|
||||
|
||||
// Find already opened HTML input if any
|
||||
const stacks = accessor.get(IEditorGroupService).getStacksModel();
|
||||
const targetGroup = stacks.groupAt(position) || stacks.activeGroup;
|
||||
if (targetGroup) {
|
||||
const existingInput = targetGroup.getEditor(uri);
|
||||
if (existingInput instanceof HtmlInput) {
|
||||
input = existingInput;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, create new input and open it
|
||||
if (!input) {
|
||||
input = accessor.get(IInstantiationService).createInstance(HtmlInput, label, '', uri);
|
||||
} else {
|
||||
input.setName(label); // make sure to use passed in label
|
||||
}
|
||||
|
||||
return accessor.get(IWorkbenchEditorService)
|
||||
.openEditor(input, { pinned: true }, position)
|
||||
|
|
|
@ -111,11 +111,15 @@ export abstract class BaseHistoryService {
|
|||
// Propagate to history
|
||||
this.onEditorEvent(activeEditor);
|
||||
|
||||
// Apply listener for dirty changes
|
||||
// Apply listener for dirty and label changes
|
||||
if (activeInput instanceof EditorInput) {
|
||||
this.activeEditorListeners.push(activeInput.onDidChangeDirty(() => {
|
||||
this.updateWindowTitle(activeInput); // Calculate New Window Title when dirty state changes
|
||||
}));
|
||||
|
||||
this.activeEditorListeners.push(activeInput.onDidChangeLabel(() => {
|
||||
this.updateWindowTitle(activeInput); // Calculate New Window Title when label changes
|
||||
}));
|
||||
}
|
||||
|
||||
// Apply listener for selection changes if this is a text editor
|
||||
|
|
|
@ -1483,13 +1483,16 @@ suite('Editor Stacks Model', () => {
|
|||
assert.ok(model.isOpen(input1Resource));
|
||||
assert.ok(group1.contains(input1Resource));
|
||||
assert.equal(model.count(input1Resource), 1);
|
||||
assert.equal(group1.getEditor(input1Resource), input1);
|
||||
|
||||
group2.openEditor(input1);
|
||||
group1.closeEditor(input1);
|
||||
|
||||
assert.ok(model.isOpen(input1Resource));
|
||||
assert.ok(!group1.contains(input1Resource));
|
||||
assert.ok(!group1.getEditor(input1Resource));
|
||||
assert.ok(group2.contains(input1Resource));
|
||||
assert.equal(group2.getEditor(input1Resource), input1);
|
||||
assert.equal(model.count(input1Resource), 1);
|
||||
|
||||
const input1ResourceClone = URI.file('/hello/world.txt');
|
||||
|
@ -1502,6 +1505,7 @@ suite('Editor Stacks Model', () => {
|
|||
|
||||
assert.ok(model.isOpen(input1Resource));
|
||||
assert.ok(group1.contains(input1Resource));
|
||||
assert.equal(group1.getEditor(input1Resource), input1Clone);
|
||||
assert.ok(!group2.contains(input1Resource));
|
||||
|
||||
group1.closeEditor(input1Clone);
|
||||
|
|
Loading…
Reference in a new issue