Skip to content

Commit

Permalink
webview id attached to notebook editor
Browse files Browse the repository at this point in the history
  • Loading branch information
rebornix committed May 18, 2020
1 parent a14736c commit 55ac452
Show file tree
Hide file tree
Showing 13 changed files with 122 additions and 106 deletions.
94 changes: 50 additions & 44 deletions src/vs/workbench/api/browser/mainThreadNotebook.ts
Expand Up @@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/

import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { MainContext, MainThreadNotebookShape, NotebookExtensionDescription, IExtHostContext, ExtHostNotebookShape, ExtHostContext, INotebookDocumentsAndEditorsDelta } from '../common/extHost.protocol';
import { MainContext, MainThreadNotebookShape, NotebookExtensionDescription, IExtHostContext, ExtHostNotebookShape, ExtHostContext, INotebookDocumentsAndEditorsDelta, INotebookModelAddedData } from '../common/extHost.protocol';
import { Disposable, IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
import { URI, UriComponents } from 'vs/base/common/uri';
import { INotebookService, IMainNotebookController } from 'vs/workbench/contrib/notebook/common/notebookService';
Expand All @@ -17,7 +17,6 @@ import { CancellationToken } from 'vs/base/common/cancellation';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { IRelativePattern } from 'vs/base/common/glob';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { generateUuid } from 'vs/base/common/uuid';

export class MainThreadNotebookDocument extends Disposable {
private _textModel: NotebookTextModel;
Expand All @@ -30,11 +29,10 @@ export class MainThreadNotebookDocument extends Disposable {
private readonly _proxy: ExtHostNotebookShape,
public handle: number,
public viewType: string,
public uri: URI,
public webviewId: string,
public uri: URI
) {
super();
this._textModel = new NotebookTextModel(handle, viewType, uri, webviewId);
this._textModel = new NotebookTextModel(handle, viewType, uri);
this._register(this._textModel.onDidModelChange(e => {
this._proxy.$acceptModelChanged(this.uri, e);
}));
Expand Down Expand Up @@ -189,6 +187,12 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
}));
}

async addNotebookDocument(data: INotebookModelAddedData) {
this._proxy.$acceptDocumentAndEditorsDelta({
addedDocuments: [data]
});
}

private _addNotebookEditor(e: IEditor) {
this._toDisposeOnEditorRemove.set(e.getId(), combinedDisposable(
e.onDidChangeModel(() => this._updateState()),
Expand Down Expand Up @@ -335,7 +339,7 @@ export class MainThreadNotebookController implements IMainNotebookController {
) {
}

async createNotebook(viewType: string, uri: URI, backup: INotebookTextModelBackup | undefined, forceReload: boolean): Promise<NotebookTextModel | undefined> {
async createNotebook(viewType: string, uri: URI, backup: INotebookTextModelBackup | undefined, forceReload: boolean, editorId?: string): Promise<NotebookTextModel | undefined> {
let mainthreadNotebook = this._mapping.get(URI.from(uri).toString());

if (mainthreadNotebook) {
Expand All @@ -355,7 +359,7 @@ export class MainThreadNotebookController implements IMainNotebookController {
return mainthreadNotebook.textModel;
}

let document = new MainThreadNotebookDocument(this._proxy, MainThreadNotebookController.documentHandle++, viewType, uri, generateUuid());
let document = new MainThreadNotebookDocument(this._proxy, MainThreadNotebookController.documentHandle++, viewType, uri);
this._mapping.set(document.uri.toString(), document);

if (backup) {
Expand All @@ -367,28 +371,29 @@ export class MainThreadNotebookController implements IMainNotebookController {
{
editType: CellEditType.Insert,
index: 0,
cells: backup.cells
cells: backup.cells || []
}
]);

await this._proxy.$acceptDocumentAndEditorsDelta({
addedDocuments: [{
viewType: document.viewType,
handle: document.handle,
webviewId: document.webviewId,
uri: document.uri,
metadata: document.textModel.metadata,
versionId: document.textModel.versionId,
cells: document.textModel.cells.map(cell => ({
handle: cell.handle,
uri: cell.uri,
source: cell.textBuffer.getLinesContent(),
language: cell.language,
cellKind: cell.cellKind,
outputs: cell.outputs,
metadata: cell.metadata
}))
}]
this._mainThreadNotebook.addNotebookDocument({
viewType: document.viewType,
handle: document.handle,
uri: document.uri,
metadata: document.textModel.metadata,
versionId: document.textModel.versionId,
cells: document.textModel.cells.map(cell => ({
handle: cell.handle,
uri: cell.uri,
source: cell.textBuffer.getLinesContent(),
language: cell.language,
cellKind: cell.cellKind,
outputs: cell.outputs,
metadata: cell.metadata
})),
attachedEditor: editorId ? {
id: editorId,
selections: document.textModel.selections
} : undefined
});

return document.textModel;
Expand All @@ -410,24 +415,25 @@ export class MainThreadNotebookController implements IMainNotebookController {
document.textModel.insertTemplateCell(mainCell);
}

await this._proxy.$acceptDocumentAndEditorsDelta({
addedDocuments: [{
viewType: document.viewType,
handle: document.handle,
webviewId: document.webviewId,
uri: document.uri,
metadata: document.textModel.metadata,
versionId: document.textModel.versionId,
cells: document.textModel.cells.map(cell => ({
handle: cell.handle,
uri: cell.uri,
source: cell.textBuffer.getLinesContent(),
language: cell.language,
cellKind: cell.cellKind,
outputs: cell.outputs,
metadata: cell.metadata
}))
}]
await this._mainThreadNotebook.addNotebookDocument({
viewType: document.viewType,
handle: document.handle,
uri: document.uri,
metadata: document.textModel.metadata,
versionId: document.textModel.versionId,
cells: document.textModel.cells.map(cell => ({
handle: cell.handle,
uri: cell.uri,
source: cell.textBuffer.getLinesContent(),
language: cell.language,
cellKind: cell.cellKind,
outputs: cell.outputs,
metadata: cell.metadata
})),
attachedEditor: editorId ? {
id: editorId,
selections: document.textModel.selections
} : undefined
});

this._proxy.$acceptEditorPropertiesChanged(uri, { selections: null, metadata: document.textModel.metadata });
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/api/common/extHost.protocol.ts
Expand Up @@ -1546,11 +1546,11 @@ export interface INotebookEditorPropertiesChangeData {
export interface INotebookModelAddedData {
uri: UriComponents;
handle: number;
webviewId: string;
versionId: number;
cells: IMainCellDto[],
viewType: string;
metadata?: NotebookDocumentMetadata;
attachedEditor?: { id: string; selections: number[]; }
}

export interface INotebookEditorAddData {
Expand Down
75 changes: 43 additions & 32 deletions src/vs/workbench/api/common/extHostNotebook.ts
Expand Up @@ -219,8 +219,6 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
return this._versionId;
}

webviewId: string = '';

constructor(
private readonly _proxy: MainThreadNotebookShape,
private _documentsAndEditors: ExtHostDocumentsAndEditors,
Expand Down Expand Up @@ -501,7 +499,6 @@ export class ExtHostNotebookEditor extends Disposable implements vscode.Notebook
public uri: URI,
private _proxy: MainThreadNotebookShape,
private _onDidReceiveMessage: Emitter<any>,
public _webviewId: string,
private _webviewInitData: WebviewInitData,
public document: ExtHostNotebookDocument,
private _documentsAndEditors: ExtHostDocumentsAndEditors
Expand Down Expand Up @@ -591,7 +588,7 @@ export class ExtHostNotebookEditor extends Disposable implements vscode.Notebook
}

asWebviewUri(localResource: vscode.Uri): vscode.Uri {
return asWebviewUri(this._webviewInitData, this._webviewId, localResource);
return asWebviewUri(this._webviewInitData, this.id, localResource);
}
}

Expand Down Expand Up @@ -997,7 +994,38 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
}
}

private _createExtHostEditor(document: ExtHostNotebookDocument, editorId: string, selections: number[]) {
const onDidReceiveMessage = new Emitter<any>();
const revivedUri = document.uri;

let editor = new ExtHostNotebookEditor(
document.viewType,
editorId,
revivedUri,
this._proxy,
onDidReceiveMessage,
this._webviewInitData,
document,
this._documentsAndEditors
);

const cells = editor.document.cells;

if (selections.length) {
const firstCell = selections[0];
editor.selection = cells.find(cell => cell.handle === firstCell);
} else {
editor.selection = undefined;
}

this._editors.get(editorId)?.editor.dispose();

this._editors.set(editorId, { editor, onDidReceiveMessage });
}

async $acceptDocumentAndEditorsDelta(delta: INotebookDocumentsAndEditorsDelta) {
let editorChanged = false;

if (delta.removedDocuments) {
delta.removedDocuments.forEach((uri) => {
let document = this._documents.get(URI.revive(uri).toString());
Expand Down Expand Up @@ -1045,49 +1073,32 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
]
});

document.webviewId = modelData.webviewId;
this._documents.set(revivedUriStr, document);

// create editor if populated
if (modelData.attachedEditor) {
this._createExtHostEditor(document, modelData.attachedEditor.id, modelData.attachedEditor.selections);
editorChanged = true;
}
}

const document = this._documents.get(revivedUriStr)!;
this._onDidOpenNotebookDocument.fire(document);
});
}

let editorChanged = false;

if (delta.addedEditors) {
delta.addedEditors.forEach(editorModelData => {
if (this._editors.has(editorModelData.id)) {
return;
}

const revivedUri = URI.revive(editorModelData.documentUri);
const document = this._documents.get(revivedUri.toString());

if (document) {
const onDidReceiveMessage = new Emitter<any>();

let editor = new ExtHostNotebookEditor(
document.viewType,
editorModelData.id,
revivedUri,
this._proxy,
onDidReceiveMessage,
document.webviewId,
this._webviewInitData,
document,
this._documentsAndEditors
);

const cells = editor.document.cells;

if (editorModelData.selections.length) {
const firstCell = editorModelData.selections[0];
editor.selection = cells.find(cell => cell.handle === firstCell);
} else {
editor.selection = undefined;
}

this._createExtHostEditor(document, editorModelData.id, editorModelData.selections);
editorChanged = true;

this._editors.set(editorModelData.id, { editor, onDidReceiveMessage });
}
});
}
Expand Down
5 changes: 3 additions & 2 deletions src/vs/workbench/contrib/notebook/browser/notebookEditor.ts
Expand Up @@ -139,8 +139,6 @@ export class NotebookEditor extends BaseEditor {
});


const model = await input.resolve();
const viewState = this.loadTextEditorViewState(input);
const existingEditorWidgetForInput = NotebookRegistry.getNotebookEditorWidget(input);
if (existingEditorWidgetForInput) {
// hide current widget
Expand All @@ -161,6 +159,9 @@ export class NotebookEditor extends BaseEditor {
this._widget.layout(this.dimension, this._rootElement);
}

const model = await input.resolve(this._widget!.getId());
const viewState = this.loadTextEditorViewState(input);

this._widget.setModel(model.notebook, viewState, options);
}

Expand Down
Expand Up @@ -129,12 +129,12 @@ export class NotebookEditorInput extends EditorInput {
return;
}

async resolve(): Promise<NotebookEditorModel> {
async resolve(editorId?: string): Promise<NotebookEditorModel> {
if (!await this.notebookService.canResolve(this.viewType!)) {
throw new Error(`Cannot open notebook of type '${this.viewType}'`);
}

this.textModel = await this.notebookService.modelManager.resolve(this.resource, this.viewType!);
this.textModel = await this.notebookService.modelManager.resolve(this.resource, this.viewType!, editorId);

this._register(this.textModel.onDidChangeDirty(() => {
this._onDidChangeDirty.fire();
Expand Down
Expand Up @@ -471,7 +471,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
}

private async attachModel(textModel: NotebookTextModel, viewState: INotebookEditorViewState | undefined) {
this.createWebview(textModel.webviewId);
this.createWebview(this.getId());
await this.webview!.waitForInitialization();

this.eventDispatcher = new NotebookEventDispatcher();
Expand Down
Expand Up @@ -265,13 +265,13 @@ export class NotebookService extends Disposable implements INotebookService, ICu
return;
}

async createNotebookFromBackup(viewType: string, uri: URI, metadata: NotebookDocumentMetadata, languages: string[], cells: ICellDto2[]): Promise<NotebookTextModel | undefined> {
async createNotebookFromBackup(viewType: string, uri: URI, metadata: NotebookDocumentMetadata, languages: string[], cells: ICellDto2[], editorId?: string): Promise<NotebookTextModel | undefined> {
const provider = this._notebookProviders.get(viewType);
if (!provider) {
return undefined;
}

const notebookModel = await provider.controller.createNotebook(viewType, uri, { metadata, languages, cells }, false);
const notebookModel = await provider.controller.createNotebook(viewType, uri, { metadata, languages, cells }, false, editorId);
if (!notebookModel) {
return undefined;
}
Expand All @@ -286,15 +286,15 @@ export class NotebookService extends Disposable implements INotebookService, ICu
return modelData.model;
}

async resolveNotebook(viewType: string, uri: URI, forceReload: boolean): Promise<NotebookTextModel | undefined> {
async resolveNotebook(viewType: string, uri: URI, forceReload: boolean, editorId?: string): Promise<NotebookTextModel | undefined> {
const provider = this._notebookProviders.get(viewType);
if (!provider) {
return undefined;
}

let notebookModel: NotebookTextModel | undefined;

notebookModel = await provider.controller.createNotebook(viewType, uri, undefined, forceReload);
notebookModel = await provider.controller.createNotebook(viewType, uri, undefined, forceReload, editorId);

// new notebook model created
const modelId = MODEL_ID(uri);
Expand Down
Expand Up @@ -104,8 +104,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
constructor(
public handle: number,
public viewType: string,
public uri: URI,
public webviewId: string
public uri: URI
) {
super();
this.cells = [];
Expand Down

0 comments on commit 55ac452

Please sign in to comment.