mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-26 03:29:00 +01:00
fixes #6644
This commit is contained in:
@@ -5,21 +5,10 @@
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { sequence } from 'vs/base/common/async';
|
||||
import { EditorModel, EditorInput } from 'vs/workbench/common/editor';
|
||||
import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel';
|
||||
import { IModel } from 'vs/editor/common/editorCommon';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export interface IResourceEditorContentProvider {
|
||||
provideTextContent(resource: URI): TPromise<IModel>;
|
||||
}
|
||||
import { ITextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService';
|
||||
|
||||
/**
|
||||
* A read-only text editor input whos contents are made of the provided resource that points to an existing
|
||||
@@ -27,92 +16,6 @@ export interface IResourceEditorContentProvider {
|
||||
*/
|
||||
export class ResourceEditorInput extends EditorInput {
|
||||
|
||||
// --- registry logic
|
||||
// todo@joh,ben this should maybe be a service that is in charge of loading/resolving a uri from a scheme
|
||||
|
||||
private static loadingModels: { [uri: string]: TPromise<IModel> } = Object.create(null);
|
||||
private static registry: { [scheme: string]: IResourceEditorContentProvider[] } = Object.create(null);
|
||||
|
||||
public static registerResourceContentProvider(scheme: string, provider: IResourceEditorContentProvider): IDisposable {
|
||||
let array = ResourceEditorInput.registry[scheme];
|
||||
if (!array) {
|
||||
array = [provider];
|
||||
ResourceEditorInput.registry[scheme] = array;
|
||||
} else {
|
||||
array.unshift(provider);
|
||||
}
|
||||
|
||||
return {
|
||||
dispose() {
|
||||
let array = ResourceEditorInput.registry[scheme];
|
||||
let idx = array.indexOf(provider);
|
||||
if (idx >= 0) {
|
||||
array.splice(idx, 1);
|
||||
if (array.length === 0) {
|
||||
delete ResourceEditorInput.registry[scheme];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static getOrCreateModel(modelService: IModelService, resource: URI): TPromise<IModel> {
|
||||
const model = modelService.getModel(resource);
|
||||
if (model) {
|
||||
return TPromise.as(model);
|
||||
}
|
||||
|
||||
let loadingModel = ResourceEditorInput.loadingModels[resource.toString()];
|
||||
if (!loadingModel) {
|
||||
|
||||
// make sure we have a provider this scheme
|
||||
// the resource uses
|
||||
const array = ResourceEditorInput.registry[resource.scheme];
|
||||
if (!array) {
|
||||
return TPromise.wrapError(`No model with uri '${resource}' nor a resolver for the scheme '${resource.scheme}'.`);
|
||||
}
|
||||
|
||||
// load the model-content from the provider and cache
|
||||
// the loading such that we don't create the same model
|
||||
// twice
|
||||
ResourceEditorInput.loadingModels[resource.toString()] = loadingModel = new TPromise<IModel>((resolve, reject) => {
|
||||
let result: IModel;
|
||||
let lastError: any;
|
||||
|
||||
sequence(array.map(provider => {
|
||||
return () => {
|
||||
if (!result) {
|
||||
const contentPromise = provider.provideTextContent(resource);
|
||||
if (!contentPromise) {
|
||||
return TPromise.wrapError<any>(`No resolver for the scheme '${resource.scheme}' found.`);
|
||||
}
|
||||
|
||||
return contentPromise.then(value => {
|
||||
result = value;
|
||||
}, err => {
|
||||
lastError = err;
|
||||
});
|
||||
}
|
||||
};
|
||||
})).then(() => {
|
||||
if (!result && lastError) {
|
||||
reject(lastError);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
}, reject);
|
||||
|
||||
}, function () {
|
||||
// no cancellation when caching promises
|
||||
});
|
||||
|
||||
// remove the cached promise 'cos the model is now known to the model service (see above)
|
||||
loadingModel.then(() => delete ResourceEditorInput.loadingModels[resource.toString()], () => delete ResourceEditorInput.loadingModels[resource.toString()]);
|
||||
}
|
||||
|
||||
return loadingModel;
|
||||
}
|
||||
|
||||
public static ID: string = 'workbench.editors.resourceEditorInput';
|
||||
|
||||
protected cachedModel: ResourceEditorModel;
|
||||
@@ -125,8 +28,7 @@ export class ResourceEditorInput extends EditorInput {
|
||||
name: string,
|
||||
description: string,
|
||||
resource: URI,
|
||||
@IModelService protected modelService: IModelService,
|
||||
@IInstantiationService protected instantiationService: IInstantiationService
|
||||
@ITextModelResolverService private textModelResolverService: ITextModelResolverService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -169,20 +71,16 @@ export class ResourceEditorInput extends EditorInput {
|
||||
}
|
||||
|
||||
// Otherwise Create Model and handle dispose event
|
||||
return ResourceEditorInput.getOrCreateModel(this.modelService, this.resource).then(() => {
|
||||
let model = this.instantiationService.createInstance(ResourceEditorModel, this.resource);
|
||||
return this.textModelResolverService.resolve(this.resource).then((model: ResourceEditorModel) => {
|
||||
this.cachedModel = model;
|
||||
|
||||
const unbind = model.onDispose(() => {
|
||||
this.cachedModel = null; // make sure we do not dispose model again
|
||||
unbind.dispose();
|
||||
this.dispose();
|
||||
});
|
||||
|
||||
// Load it
|
||||
return model.load().then((resolvedModel: ResourceEditorModel) => {
|
||||
this.cachedModel = resolvedModel;
|
||||
|
||||
return this.cachedModel;
|
||||
});
|
||||
return this.cachedModel;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user