提交 c59da6a4 编写于 作者: C Christof Marti

Acquire models in input

上级 8ef8adb3
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import URI from 'vs/base/common/uri';
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
import { ITextModelResolverService } from 'vs/editor/common/services/resolverService';
export class WalkThroughInput extends ResourceEditorInput {
// just a marker class
constructor(
name: string,
description: string,
resource: URI,
public readonly onReady: (container: HTMLElement) => void,
@ITextModelResolverService textModelResolverService: ITextModelResolverService
) {
super(name, description, resource, textModelResolverService);
}
getResource(): URI {
return this.resource;
}
}
...@@ -11,7 +11,7 @@ import { Action } from 'vs/base/common/actions'; ...@@ -11,7 +11,7 @@ import { Action } from 'vs/base/common/actions';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import URI from 'vs/base/common/uri'; import URI from 'vs/base/common/uri';
import { WalkThroughInput } from 'vs/workbench/parts/walkThrough/common/walkThroughInput'; import { WalkThroughInput } from 'vs/workbench/parts/walkThrough/node/walkThroughInput';
import { WALK_THROUGH_SCHEME } from 'vs/workbench/parts/walkThrough/electron-browser/walkThroughContentProvider'; import { WALK_THROUGH_SCHEME } from 'vs/workbench/parts/walkThrough/electron-browser/walkThroughContentProvider';
export class EditorWalkThroughAction extends Action { export class EditorWalkThroughAction extends Action {
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
'use strict'; 'use strict';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { WalkThroughInput } from 'vs/workbench/parts/walkThrough/common/walkThroughInput'; import { WalkThroughInput } from 'vs/workbench/parts/walkThrough/node/walkThroughInput';
import { WalkThroughPart } from 'vs/workbench/parts/walkThrough/electron-browser/walkThroughPart'; import { WalkThroughPart } from 'vs/workbench/parts/walkThrough/electron-browser/walkThroughPart';
import { WalkThroughContentProvider } from 'vs/workbench/parts/walkThrough/electron-browser/walkThroughContentProvider'; import { WalkThroughContentProvider } from 'vs/workbench/parts/walkThrough/electron-browser/walkThroughContentProvider';
import { EditorWalkThroughAction } from 'vs/workbench/parts/walkThrough/electron-browser/editor/editorWalkThrough'; import { EditorWalkThroughAction } from 'vs/workbench/parts/walkThrough/electron-browser/editor/editorWalkThrough';
......
...@@ -12,26 +12,22 @@ import * as strings from 'vs/base/common/strings'; ...@@ -12,26 +12,22 @@ import * as strings from 'vs/base/common/strings';
import URI from 'vs/base/common/uri'; import URI from 'vs/base/common/uri';
import { TPromise } from 'vs/base/common/winjs.base'; import { TPromise } from 'vs/base/common/winjs.base';
import { DefaultConfig } from 'vs/editor/common/config/defaultConfig'; import { DefaultConfig } from 'vs/editor/common/config/defaultConfig';
import { IEditorOptions, IModel } from 'vs/editor/common/editorCommon'; import { IEditorOptions } from 'vs/editor/common/editorCommon';
import { $, Dimension, Builder } from 'vs/base/browser/builder'; import { $, Dimension, Builder } from 'vs/base/browser/builder';
import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { EditorOptions } from 'vs/workbench/common/editor'; import { EditorOptions } from 'vs/workbench/common/editor';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { WalkThroughInput } from 'vs/workbench/parts/walkThrough/common/walkThroughInput'; import { WalkThroughInput } from 'vs/workbench/parts/walkThrough/node/walkThroughInput';
import { IThemeService } from 'vs/workbench/services/themes/common/themeService'; import { IThemeService } from 'vs/workbench/services/themes/common/themeService';
import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IOpenerService } from 'vs/platform/opener/common/opener';
import { marked } from 'vs/base/common/marked/marked'; import { marked } from 'vs/base/common/marked/marked';
import { IModeService } from 'vs/editor/common/services/modeService'; import { IModeService } from 'vs/editor/common/services/modeService';
import { IFileService } from 'vs/platform/files/common/files'; import { IFileService } from 'vs/platform/files/common/files';
import { IModelService } from 'vs/editor/common/services/modelService'; import { IModelService } from 'vs/editor/common/services/modelService';
import * as uuid from 'vs/base/common/uuid';
import { CodeEditor } from 'vs/editor/browser/codeEditor'; import { CodeEditor } from 'vs/editor/browser/codeEditor';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import * as path from 'path'; import * as path from 'path';
import { tmpdir } from 'os';
import { mkdirp } from 'vs/base/node/extfs';
import { IMode } from 'vs/editor/common/modes';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
...@@ -116,15 +112,12 @@ export class WalkThroughPart extends BaseEditor { ...@@ -116,15 +112,12 @@ export class WalkThroughPart extends BaseEditor {
this.contentDisposables = dispose(this.contentDisposables); this.contentDisposables = dispose(this.contentDisposables);
this.content.innerHTML = ''; this.content.innerHTML = '';
const folderName = path.join(tmpdir(), 'vscode-walk-through', uuid.generateUuid());
const folder = new TPromise<string>((c, e) => mkdirp(folderName, null, err => err ? e(err) : c(folderName)));
return super.setInput(input, options) return super.setInput(input, options)
.then(() => { .then(() => {
return input.resolve(true); return input.resolve(true);
}) })
.then(model => { .then(model => {
const content = model.textEditorModel.getLinesContent().join('\n'); const content = model.main.textEditorModel.getLinesContent().join('\n');
if (strings.endsWith(input.getResource().path, '.html')) { if (strings.endsWith(input.getResource().path, '.html')) {
this.content.innerHTML = content; this.content.innerHTML = content;
this.decorateContent(); this.decorateContent();
...@@ -135,19 +128,10 @@ export class WalkThroughPart extends BaseEditor { ...@@ -135,19 +128,10 @@ export class WalkThroughPart extends BaseEditor {
return; return;
} }
const files: TPromise<any>[] = []; let i = 0;
const codes: { id: string; model: IModel }[] = [];
const renderer = new marked.Renderer(); const renderer = new marked.Renderer();
renderer.code = (code, lang) => { renderer.code = (code, lang) => {
const id = `code-${uuid.generateUuid()}`; const id = path.basename(model.snippets[i++].textEditorModel.uri.fsPath);
const mode = this.getModeForLanguage(lang);
const resource = URI.file(path.join(folderName, `${id}.${lang}`));
const model = this.modelService.createModel(code, mode, resource);
codes.push({ id, model });
// E.g., the TypeScript service needs files on disk.
files.push(folder.then(() => this.fileService.createFile(resource, code)));
return `<div id=${id} class="walkThroughEditorContainer" ></div>`; return `<div id=${id} class="walkThroughEditorContainer" ></div>`;
}; };
this.content.classList.add('walkThroughContent'); // only for markdown files this.content.classList.add('walkThroughContent'); // only for markdown files
...@@ -155,56 +139,37 @@ export class WalkThroughPart extends BaseEditor { ...@@ -155,56 +139,37 @@ export class WalkThroughPart extends BaseEditor {
this.content.innerHTML = marked(markdown, { renderer }); this.content.innerHTML = marked(markdown, { renderer });
// TODO: also create jsconfig.json and tsconfig.json // TODO: also create jsconfig.json and tsconfig.json
return TPromise.join(files).then(() => { model.snippets.forEach(snippet => {
codes.forEach(({ id, model }) => { const model = snippet.textEditorModel;
const div = this.content.querySelector(`#${id}`) as HTMLElement; const id = path.basename(model.uri.fsPath);
const div = this.content.querySelector(`#${id.replace(/\./g, '\\.')}`) as HTMLElement;
var options: IEditorOptions = {
scrollBeyondLastLine: false, var options: IEditorOptions = {
scrollbar: DefaultConfig.editor.scrollbar, scrollBeyondLastLine: false,
overviewRulerLanes: 3, scrollbar: DefaultConfig.editor.scrollbar,
fixedOverflowWidgets: true, overviewRulerLanes: 3,
lineNumbersMinChars: 1, fixedOverflowWidgets: true,
theme: this.themeService.getColorTheme().id, lineNumbersMinChars: 1,
}; theme: this.themeService.getColorTheme().id,
};
const editor = this.instantiationService.createInstance(CodeEditor, div, options);
editor.setModel(model); const editor = this.instantiationService.createInstance(CodeEditor, div, options);
this.contentDisposables.push(editor); editor.setModel(model);
this.contentDisposables.push(editor);
const lineHeight = editor.getConfiguration().lineHeight;
const height = model.getLineCount() * lineHeight; const lineHeight = editor.getConfiguration().lineHeight;
div.style.height = height + 'px'; const height = model.getLineCount() * lineHeight;
div.style.height = height + 'px';
this.contentDisposables.push(this.themeService.onDidColorThemeChange(theme => editor.updateOptions({ theme: theme.id })));
this.contentDisposables.push(this.themeService.onDidColorThemeChange(theme => editor.updateOptions({ theme: theme.id })));
editor.layout();
}); editor.layout();
if (input.onReady) {
input.onReady(this.content);
}
this.scrollbar.scanDomNode();
}); });
}); if (input.onReady) {
} input.onReady(this.content);
private getModeForLanguage(lang: string): TPromise<IMode> {
return new TPromise(c => {
const that = this;
function tryGetMode() {
const modeId = that.modeService.getModeIdForLanguageName(lang);
const mode = modeId && that.modeService.getOrCreateMode(modeId);
if (mode) {
c(mode);
} else {
const subscription = that.modeService.onDidAddModes(() => {
subscription.dispose();
tryGetMode();
});
} }
} this.scrollbar.scanDomNode();
tryGetMode(); });
});
} }
private expandMacros(input: string) { private expandMacros(input: string) {
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as strings from 'vs/base/common/strings';
import { TPromise } from 'vs/base/common/winjs.base';
import { EditorInput, EditorModel, ITextEditorModel } from 'vs/workbench/common/editor';
import URI from 'vs/base/common/uri';
import { IReference } from 'vs/base/common/lifecycle';
import { telemetryURIDescriptor } from 'vs/platform/telemetry/common/telemetryUtils';
import { ITextModelResolverService } from 'vs/editor/common/services/resolverService';
import { IFileService } from 'vs/platform/files/common/files';
import * as uuid from 'vs/base/common/uuid';
import * as path from 'path';
import { tmpdir } from 'os';
import { mkdirp } from 'vs/base/node/extfs';
import { marked } from 'vs/base/common/marked/marked';
export class WalkThroughModel extends EditorModel {
constructor(
private mainRef: IReference<ITextEditorModel>,
private snippetRefs: IReference<ITextEditorModel>[]
) {
super();
}
get main() {
return this.mainRef.object;
}
get snippets() {
return this.snippetRefs.map(snippet => snippet.object);
}
dispose() {
this.snippetRefs.forEach(ref => ref.dispose());
this.mainRef.dispose();
super.dispose();
}
}
export class WalkThroughInput extends EditorInput {
static ID: string = 'workbench.editors.walkThroughInput';
private promise: TPromise<WalkThroughModel>;
private resource: URI;
private name: string;
private description: string;
constructor(
name: string,
description: string,
resource: URI,
public readonly onReady: (container: HTMLElement) => void,
@IFileService private fileService: IFileService,
@ITextModelResolverService private textModelResolverService: ITextModelResolverService
) {
super();
this.name = name;
this.description = description;
this.resource = resource;
}
getResource(): URI {
return this.resource;
}
getTypeId(): string {
return WalkThroughInput.ID;
}
getName(): string {
return this.name;
}
getDescription(): string {
return this.description;
}
getTelemetryDescriptor(): { [key: string]: any; } {
const descriptor = super.getTelemetryDescriptor();
descriptor['resource'] = telemetryURIDescriptor(this.resource);
return descriptor;
}
resolve(refresh?: boolean): TPromise<WalkThroughModel> {
if (!this.promise) {
this.promise = this.textModelResolverService.createModelReference(this.resource)
.then(ref => {
if (strings.endsWith(this.getResource().path, '.html')) {
return new WalkThroughModel(ref, []);
}
const folderName = path.join(tmpdir(), 'vscode-walk-through', uuid.generateUuid());
const folder = new TPromise<string>((c, e) => mkdirp(folderName, null, err => err ? e(err) : c(folderName)));
const snippets: TPromise<IReference<ITextEditorModel>>[] = [];
const renderer = new marked.Renderer();
renderer.code = (code, lang) => {
const id = `code-${uuid.generateUuid()}`;
const resource = URI.file(path.join(folderName, `${id}.${lang}`));
// E.g., the TypeScript service needs files on disk.
snippets.push(folder.then(() => this.fileService.createFile(resource, code))
.then(() => this.textModelResolverService.createModelReference(resource)));
return '';
};
const markdown = ref.object.textEditorModel.getLinesContent().join('\n');
marked(markdown, { renderer });
return TPromise.join(snippets)
.then(refs => new WalkThroughModel(ref, refs));
});
}
return this.promise;
// TODO: replicate above?
// return this.promise.then(ref => {
// const model = ref.object;
// if (!(model instanceof ResourceEditorModel)) {
// ref.dispose();
// this.promise = null;
// return TPromise.wrapError(`Unexpected model for ResourceInput: ${this.resource}`); // TODO@Ben eventually also files should be supported, but we guard due to the dangerous dispose of the model in dispose()
// }
// // TODO@Joao this should never happen
// model.onDispose(() => this.dispose());
// return model;
// });
}
matches(otherInput: any): boolean {
if (super.matches(otherInput) === true) {
return true;
}
if (otherInput instanceof WalkThroughInput) {
let otherResourceEditorInput = <WalkThroughInput>otherInput;
// Compare by properties
return otherResourceEditorInput.resource.toString() === this.resource.toString();
}
return false;
}
dispose(): void {
if (this.promise) {
this.promise.then(model => model.dispose());
this.promise = null;
}
super.dispose();
}
}
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
import 'vs/css!./welcomePage'; import 'vs/css!./welcomePage';
import URI from 'vs/base/common/uri'; import URI from 'vs/base/common/uri';
import * as path from 'path'; import * as path from 'path';
import { WalkThroughInput } from 'vs/workbench/parts/walkThrough/common/walkThroughInput'; import { WalkThroughInput } from 'vs/workbench/parts/walkThrough/node/walkThroughInput';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IPartService } from 'vs/workbench/services/part/common/partService'; import { IPartService } from 'vs/workbench/services/part/common/partService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册