mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-08 07:44:33 +01:00
Notebook ipywidgets output
This commit is contained in:
@@ -9,12 +9,28 @@
|
||||
|
||||
const withDefaults = require('../shared.webpack.config');
|
||||
|
||||
module.exports = withDefaults({
|
||||
context: __dirname,
|
||||
resolve: {
|
||||
mainFields: ['module', 'main']
|
||||
},
|
||||
entry: {
|
||||
extension: './src/extension.ts',
|
||||
module.exports = [
|
||||
withDefaults({
|
||||
context: __dirname,
|
||||
resolve: {
|
||||
mainFields: ['module', 'main']
|
||||
},
|
||||
entry: {
|
||||
extension: './src/extension.ts',
|
||||
}
|
||||
}),
|
||||
{
|
||||
mode: 'development',
|
||||
entry: './output/ipywidgets.js',
|
||||
output: {
|
||||
filename: 'ipywidgets.js',
|
||||
publicPath: 'dist/'
|
||||
},
|
||||
target: 'web',
|
||||
module: {
|
||||
rules: [
|
||||
{ test: /\.css$/, loader: "style-loader!css-loader" }
|
||||
]
|
||||
},
|
||||
}
|
||||
});
|
||||
]
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
var WidgetManager = require("./manager").WidgetManager;
|
||||
require('@jupyter-widgets/controls/css/widgets.css');
|
||||
|
||||
var widgetarea = document.getElementsByClassName("widgetarea")[0];
|
||||
manager = new WidgetManager(widgetarea);
|
||||
window.manager = manager;
|
||||
|
||||
manager.renderTag = () => {
|
||||
let tags = widgetarea.querySelectorAll('script[type="application/vnd.jupyter.widget-state+json"]');
|
||||
if (tags.length) {
|
||||
let state = JSON.parse(tags[0].innerHTML);
|
||||
window.manager.set_state(state).then(function (models) {
|
||||
window.models = models;
|
||||
}).then(function () {
|
||||
let tags = widgetarea.querySelectorAll('script[type="application/vnd.jupyter.widget-view+json"]');
|
||||
for (let i = 0; i != tags.length; ++i) {
|
||||
let viewtag = tags[i];
|
||||
let widgetViewObject = JSON.parse(viewtag.innerHTML);
|
||||
let model_id = widgetViewObject.model_id;
|
||||
|
||||
let model = window.models.filter((item) => {
|
||||
return item.model_id == model_id;
|
||||
})[0];
|
||||
if (model !== undefined) {
|
||||
let widgetTag = document.createElement('div');
|
||||
widgetTag.className = 'widget-subarea';
|
||||
viewtag.parentElement.insertBefore(widgetTag, viewtag);
|
||||
viewtag.parentElement.removeChild(viewtag);
|
||||
manager.display_model(undefined, model, { el: widgetTag });
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
manager.renderTag();
|
||||
@@ -0,0 +1,64 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
var base = require('@jupyter-widgets/base');
|
||||
var controls = require('@jupyter-widgets/controls');
|
||||
var LuminoWidget = require('@lumino/widgets').Widget;
|
||||
|
||||
class WidgetManager extends base.ManagerBase {
|
||||
constructor(el) {
|
||||
super();
|
||||
this.el = el;
|
||||
}
|
||||
|
||||
loadClass(className, moduleName, moduleVersion) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
if (moduleName === '@jupyter-widgets/controls') {
|
||||
resolve(controls);
|
||||
} else if (moduleName === '@jupyter-widgets/base') {
|
||||
resolve(base)
|
||||
} else {
|
||||
var fallback = function(err) {
|
||||
let failedId = err.requireModules && err.requireModules[0];
|
||||
if (failedId) {
|
||||
console.log(`Falling back to unpkg.com for ${moduleName}@${moduleVersion}`);
|
||||
window.require([`https://unpkg.com/${moduleName}@${moduleVersion}/dist/index.js`], resolve, reject);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
window.require([`${moduleName}.js`], resolve, fallback);
|
||||
}
|
||||
}).then(function(module) {
|
||||
if (module[className]) {
|
||||
return module[className];
|
||||
} else {
|
||||
return Promise.reject(`Class ${className} not found in module ${moduleName}@${moduleVersion}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
display_view(msg, view, options) {
|
||||
var that = this;
|
||||
return Promise.resolve(view).then(function(view) {
|
||||
let el = options.el || that.el;
|
||||
LuminoWidget.attach(view.pWidget, el);
|
||||
view.on('remove', function() {
|
||||
console.log('View removed', view);
|
||||
});
|
||||
return view;
|
||||
});
|
||||
};
|
||||
|
||||
_get_comm_info() {
|
||||
return Promise.resolve({});
|
||||
};
|
||||
|
||||
_create_comm() {
|
||||
return Promise.reject('no comms available');
|
||||
}
|
||||
}
|
||||
|
||||
exports.WidgetManager = WidgetManager;
|
||||
@@ -14,7 +14,7 @@
|
||||
"engines": {
|
||||
"vscode": "^1.40.0"
|
||||
},
|
||||
"main": "./out/extension",
|
||||
"main": "./dist/extension",
|
||||
"categories": [
|
||||
"Other"
|
||||
],
|
||||
@@ -39,8 +39,16 @@
|
||||
"watch": "tsc -watch -p ./"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jupyter-widgets/base": "^2.0.2",
|
||||
"@jupyter-widgets/controls": "^1.5.3",
|
||||
"@lumino/widgets": "^1.3.0",
|
||||
"typescript": "^3.6.4",
|
||||
"vscode-extension-telemetry": "0.1.1",
|
||||
"vscode-nls": "^4.0.0",
|
||||
"typescript": "^3.6.4"
|
||||
"vscode-nls": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"webpack-cli": "^3.3.10",
|
||||
"css-loader": "^3.4.1",
|
||||
"style-loader": "^1.1.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,6 @@ import { NotebookProvider } from './notebookProvider';
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
console.log(context.extensionPath);
|
||||
|
||||
context.subscriptions.push(vscode.window.registerNotebookProvider('jupyter', new NotebookProvider()));
|
||||
context.subscriptions.push(vscode.window.registerNotebookProvider('jupyter', new NotebookProvider(context.extensionPath)));
|
||||
}
|
||||
|
||||
|
||||
@@ -4,18 +4,29 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as path from 'path';
|
||||
|
||||
export class Cell implements vscode.ICell {
|
||||
public outputs: any[] = [];
|
||||
public outputs: vscode.IOutput[] = [];
|
||||
|
||||
constructor(
|
||||
public source: string[],
|
||||
public cell_type: 'markdown' | 'code',
|
||||
private _outputs: any[]
|
||||
private _outputs: vscode.IOutput[]
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
containHTML() {
|
||||
return this._outputs && this._outputs.some(output => {
|
||||
if (output.output_type === 'display_data' && output.data['text/html']) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
fillInOutputs() {
|
||||
this.outputs = this._outputs;
|
||||
}
|
||||
@@ -35,7 +46,7 @@ export class NotebookProvider implements vscode.NotebookProvider {
|
||||
onDidChangeNotebook: vscode.Event<{ resource: vscode.Uri; notebook: vscode.INotebook; }> = this._onDidChangeNotebook.event;
|
||||
private _notebooks: Map<string, JupyterNotebook> = new Map();
|
||||
|
||||
constructor() {
|
||||
constructor(private _extensionPath: string) {
|
||||
}
|
||||
|
||||
async resolveNotebook(resource: vscode.Uri): Promise<vscode.INotebook | undefined> {
|
||||
@@ -68,7 +79,35 @@ export class NotebookProvider implements vscode.NotebookProvider {
|
||||
async executeNotebook(resource: vscode.Uri): Promise<void> {
|
||||
if (this._notebooks.has(resource.fsPath)) {
|
||||
let notebook = this._notebooks.get(resource.fsPath);
|
||||
notebook!.cells.forEach(cell => cell.fillInOutputs());
|
||||
let preloadScript = false;
|
||||
notebook!.cells.forEach(cell => {
|
||||
if (!preloadScript) {
|
||||
let containHTML = cell.containHTML();
|
||||
if (containHTML) {
|
||||
preloadScript = true;
|
||||
cell.fillInOutputs();
|
||||
const scriptPathOnDisk = vscode.Uri.file(
|
||||
path.join(this._extensionPath, 'dist', 'ipywidgets.js')
|
||||
);
|
||||
|
||||
let scriptUri = scriptPathOnDisk.with({ scheme: 'vscode-resource' });
|
||||
cell.outputs.unshift(
|
||||
{
|
||||
'output_type': 'display_data',
|
||||
'data': {
|
||||
'text/html': [
|
||||
`<script src="${scriptUri}"></script>\n`,
|
||||
]
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
cell.fillInOutputs();
|
||||
}
|
||||
} else {
|
||||
cell.fillInOutputs();
|
||||
}
|
||||
});
|
||||
this._onDidChangeNotebook.fire({ resource, notebook: notebook! });
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -560,9 +560,9 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
}
|
||||
|
||||
this.rowsContainer.style.left = `-${renderLeft}px`;
|
||||
console.log('------');
|
||||
const date = new Date();
|
||||
console.log('list view render top change, old ', this.rowsContainer.style.top, ' new ', `-${renderTop}` + ' - ' + date.getMinutes() + ':' + date.getSeconds() + ':' + date.getMilliseconds());
|
||||
// console.log('------');
|
||||
// const date = new Date();
|
||||
// console.log('list view render top change, old ', this.rowsContainer.style.top, ' new ', `-${renderTop}` + ' - ' + date.getMinutes() + ':' + date.getSeconds() + ':' + date.getMilliseconds());
|
||||
this.rowsContainer.style.top = `-${renderTop}px`;
|
||||
|
||||
if (this.horizontalScrolling) {
|
||||
|
||||
Vendored
+2
-6
@@ -1302,14 +1302,10 @@ declare module 'vscode' {
|
||||
|
||||
export interface IDisplayOutput {
|
||||
output_type: 'display_data';
|
||||
data: { string: string };
|
||||
data: { [key: string]: any };
|
||||
}
|
||||
|
||||
export interface IGenericOutput {
|
||||
output_type: string;
|
||||
}
|
||||
|
||||
export type IOutput = IStreamOutput | any;
|
||||
export type IOutput = IStreamOutput | IErrorOutput | IDisplayOutput;
|
||||
|
||||
export interface ICell {
|
||||
source: string[];
|
||||
|
||||
@@ -85,7 +85,7 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
|
||||
$registerNotebookProvider(extension: NotebookExtensionDescription, viewType: string): void {
|
||||
let controller = new MainThreadNotebookController(this);
|
||||
this._notebookProviders.set(viewType, controller);
|
||||
this._notebookService.registerNotebookController(viewType, controller);
|
||||
this._notebookService.registerNotebookController(viewType, extension, controller);
|
||||
}
|
||||
|
||||
$unregisterNotebookProvider(viewType: string): void {
|
||||
|
||||
@@ -185,7 +185,7 @@ export interface NotebookHandler {
|
||||
editNotebookCell(cell: ViewCell): void;
|
||||
saveNotebookCell(cell: ViewCell): void;
|
||||
layoutElement(cell: ViewCell, height: number): void;
|
||||
createContentWidget(cell: ViewCell, shadowContent: string, offset: number): void;
|
||||
createContentWidget(cell: ViewCell, index: number, shadowContent: string, offset: number): void;
|
||||
disposeViewCell(cell: ViewCell): void;
|
||||
triggerWheel(event: IMouseWheelEvent): void;
|
||||
}
|
||||
@@ -581,7 +581,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
|
||||
templateData.outputContainer?.appendChild(result.element);
|
||||
if (result.shadowContent) {
|
||||
hasDynamicHeight = false;
|
||||
this.handler.createContentWidget(element, result.shadowContent, totalHeight + 8);
|
||||
this.handler.createContentWidget(element, i, result.shadowContent, totalHeight + 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -634,7 +634,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
|
||||
templateData.outputContainer?.appendChild(result.element);
|
||||
if (result.shadowContent) {
|
||||
hasDynamicHeight = false;
|
||||
this.handler.createContentWidget(element, result.shadowContent, totalHeight + 8);
|
||||
this.handler.createContentWidget(element, i, result.shadowContent, totalHeight + 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { IWebviewService, WebviewElement } from 'vs/workbench/contrib/webview/br
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import * as UUID from 'vs/base/common/uuid';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { INotebookService } from 'vs/workbench/contrib/notebook/browser/notebookService';
|
||||
|
||||
|
||||
export interface IDimentionMessage {
|
||||
@@ -61,8 +62,9 @@ export class BackLayerWebView extends Disposable {
|
||||
public element: HTMLElement;
|
||||
public webview: WebviewElement;
|
||||
public mapping: Map<string, { cell: ViewCell, offset: number, top: number }> = new Map();
|
||||
public outputMapping: Map<string, boolean> = new Map();
|
||||
|
||||
constructor(public webviewService: IWebviewService, public notebookHandler: NotebookHandler) {
|
||||
constructor(public webviewService: IWebviewService, public notebookService: INotebookService, public notebookHandler: NotebookHandler) {
|
||||
super();
|
||||
this.element = document.createElement('div');
|
||||
this.element.style.width = 'calc(100% - 36px)';
|
||||
@@ -70,19 +72,44 @@ export class BackLayerWebView extends Disposable {
|
||||
this.element.style.position = 'absolute';
|
||||
this.element.style.margin = '0px 0 0px 24px';
|
||||
|
||||
|
||||
let content = /* html */`
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
</head>
|
||||
<body style="overflow: hidden;">
|
||||
<div id='container' style="position: absolute;width:100%;"></div>
|
||||
<div id='container' class="widgetarea" style="position: absolute;width:100%;"></div>
|
||||
<script>
|
||||
(function () {
|
||||
// eslint-disable-next-line no-undef
|
||||
const vscode = acquireVsCodeApi();
|
||||
console.log('a');
|
||||
|
||||
const preservedScriptAttributes = {
|
||||
type: true,
|
||||
src: true,
|
||||
nonce: true,
|
||||
noModule: true,
|
||||
async: true
|
||||
};
|
||||
|
||||
// derived from https://github.com/jquery/jquery/blob/d0ce00cdfa680f1f0c38460bc51ea14079ae8b07/src/core/DOMEval.js
|
||||
const domEval = (container) => {
|
||||
var arr = Array.from(container.getElementsByTagName('script'));
|
||||
for (let n = 0; n < arr.length; n++) {
|
||||
let node = arr[n];
|
||||
let scriptTag = document.createElement('script');
|
||||
scriptTag.text = node.innerText;
|
||||
for (let key in preservedScriptAttributes ) {
|
||||
const val = node[key] || node.getAttribute && node.getAttribute(key);
|
||||
if (val) {
|
||||
scriptTag.setAttribute(key, val);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: should script with src not be removed?
|
||||
container.appendChild(scriptTag).parentNode.removeChild(scriptTag);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('message', event => {
|
||||
let id = event.data.id;
|
||||
@@ -90,30 +117,39 @@ export class BackLayerWebView extends Disposable {
|
||||
switch (event.data.type) {
|
||||
case 'html':
|
||||
{
|
||||
let content = event.data.content;
|
||||
let newElement = document.createElement('div');
|
||||
newElement.style.position = 'absolute';
|
||||
newElement.style.top = event.data.top + 'px';
|
||||
newElement.id = id;
|
||||
document.getElementById('container').appendChild(newElement);
|
||||
newElement.innerHTML = content;
|
||||
var arr = newElement.getElementsByTagName('script');
|
||||
for (let n = 0; n < arr.length; n++) {
|
||||
eval(arr[n].innerHTML); //run script inside div
|
||||
let cellOutputContainer = document.getElementById(id);
|
||||
if (!cellOutputContainer) {
|
||||
let newElement = document.createElement('div');
|
||||
newElement.style.position = 'absolute';
|
||||
newElement.style.top = event.data.top + 'px';
|
||||
newElement.id = id;
|
||||
document.getElementById('container').appendChild(newElement);
|
||||
cellOutputContainer = newElement;
|
||||
}
|
||||
vscode.postMessage({
|
||||
type: 'dimension',
|
||||
id: id,
|
||||
data: {
|
||||
height: newElement.clientHeight
|
||||
}
|
||||
});
|
||||
|
||||
let outputNode = document.createElement('div');
|
||||
let content = event.data.content;
|
||||
outputNode.innerHTML = content;
|
||||
cellOutputContainer.appendChild(outputNode);
|
||||
|
||||
// eval
|
||||
domEval(outputNode);
|
||||
|
||||
setTimeout(() => {
|
||||
vscode.postMessage({
|
||||
type: 'dimension',
|
||||
id: id,
|
||||
data: {
|
||||
height: cellOutputContainer.clientHeight
|
||||
}
|
||||
});
|
||||
}, 200);
|
||||
}
|
||||
break;
|
||||
case 'view-scroll':
|
||||
{
|
||||
const date = new Date();
|
||||
console.log('----- will scroll ---- ', date.getMinutes() + ':' + date.getSeconds() + ':' + date.getMilliseconds());
|
||||
// console.log('----- will scroll ---- ', date.getMinutes() + ':' + date.getSeconds() + ':' + date.getMilliseconds());
|
||||
|
||||
document.getElementById('container').style.top = event.data.top + 'px';
|
||||
for (let i = 0; i < event.data.widgets.length; i++) {
|
||||
@@ -159,9 +195,9 @@ export class BackLayerWebView extends Disposable {
|
||||
this.notebookHandler.layoutElement(cell, totalHeight + 32 + height);
|
||||
}
|
||||
} else if (data.type === 'scroll-ack') {
|
||||
const date = new Date();
|
||||
const top = data.data.top;
|
||||
console.log('ack top ', top, ' version: ', data.version, ' - ', date.getMinutes() + ':' + date.getSeconds() + ':' + date.getMilliseconds());
|
||||
// const date = new Date();
|
||||
// const top = data.data.top;
|
||||
// console.log('ack top ', top, ' version: ', data.version, ' - ', date.getMinutes() + ':' + date.getSeconds() + ':' + date.getMilliseconds());
|
||||
}
|
||||
}));
|
||||
}
|
||||
@@ -170,7 +206,8 @@ export class BackLayerWebView extends Disposable {
|
||||
const webview = webviewService.createWebview('' + UUID.generateUuid(), {
|
||||
enableFindWidget: false,
|
||||
}, {
|
||||
allowScripts: true
|
||||
allowScripts: true,
|
||||
localResourceRoots: this.notebookService.getNotebookProviderResourceRoots()
|
||||
});
|
||||
webview.html = content;
|
||||
return webview;
|
||||
|
||||
@@ -24,6 +24,7 @@ import { IWebviewService } from 'vs/workbench/contrib/webview/browser/webview';
|
||||
import { BackLayerWebView } from 'vs/workbench/contrib/notebook/browser/contentWidget';
|
||||
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { INotebookService } from 'vs/workbench/contrib/notebook/browser/notebookService';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
@@ -46,7 +47,8 @@ export class NotebookEditor extends BaseEditor implements NotebookHandler {
|
||||
@IModelService private readonly modelService: IModelService,
|
||||
@IModeService private readonly modeService: IModeService,
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IWebviewService private webviewService: IWebviewService
|
||||
@IWebviewService private webviewService: IWebviewService,
|
||||
@INotebookService private notebookService: INotebookService
|
||||
) {
|
||||
super(NotebookEditor.ID, telemetryService, themeService, storageService);
|
||||
}
|
||||
@@ -116,7 +118,7 @@ export class NotebookEditor extends BaseEditor implements NotebookHandler {
|
||||
}
|
||||
);
|
||||
|
||||
this.webview = new BackLayerWebView(this.webviewService, this);
|
||||
this.webview = new BackLayerWebView(this.webviewService, this.notebookService, this);
|
||||
this.list.view.rowsContainer.appendChild(this.webview.element);
|
||||
this._register(this.list);
|
||||
}
|
||||
@@ -125,7 +127,7 @@ export class NotebookEditor extends BaseEditor implements NotebookHandler {
|
||||
this.list?.triggerScrollFromMouseWheelEvent(event);
|
||||
}
|
||||
|
||||
createContentWidget(cell: ViewCell, shadowContent: string, offset: number) {
|
||||
createContentWidget(cell: ViewCell, outputIndex: number, shadowContent: string, offset: number) {
|
||||
if (!this.webview) {
|
||||
return;
|
||||
}
|
||||
@@ -134,6 +136,12 @@ export class NotebookEditor extends BaseEditor implements NotebookHandler {
|
||||
let index = this.model!.getNotebook().cells.indexOf(cell.cell);
|
||||
let top = this.list?.getElementTop(index) || 0;
|
||||
this.webview!.createContentWidget(cell, offset, shadowContent, top + offset);
|
||||
this.webview!.outputMapping.set(cell.id + `-${outputIndex}`, true);
|
||||
} else if (!this.webview!.outputMapping.has(cell.id + `-${outputIndex}`)) {
|
||||
let index = this.model!.getNotebook().cells.indexOf(cell.cell);
|
||||
let top = this.list?.getElementTop(index) || 0;
|
||||
this.webview!.outputMapping.set(cell.id + `-${outputIndex}`, true);
|
||||
this.webview!.createContentWidget(cell, offset, shadowContent, top + offset);
|
||||
} else {
|
||||
let index = this.model!.getNotebook().cells.indexOf(cell.cell);
|
||||
let top = this.list?.getElementTop(index) || 0;
|
||||
@@ -185,9 +193,8 @@ export class NotebookEditor extends BaseEditor implements NotebookHandler {
|
||||
if (this.webview) {
|
||||
this.webview?.clearContentWidgets();
|
||||
} else {
|
||||
this.webview = new BackLayerWebView(this.webviewService, this);
|
||||
this.webview = new BackLayerWebView(this.webviewService, this.notebookService, this);
|
||||
this.list?.view.rowsContainer.insertAdjacentElement('afterbegin', this.webview!.element);
|
||||
|
||||
}
|
||||
|
||||
this.model = model;
|
||||
|
||||
@@ -9,6 +9,7 @@ import { INotebook } from 'vs/editor/common/modes';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { notebookExtensionPoint } from 'vs/workbench/contrib/notebook/browser/extensionPoint';
|
||||
import { NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookProvider';
|
||||
import { NotebookExtensionDescription } from 'vs/workbench/api/common/extHost.protocol';
|
||||
|
||||
export const INotebookService = createDecorator<INotebookService>('notebookService');
|
||||
|
||||
@@ -20,11 +21,12 @@ export interface IMainNotebookController {
|
||||
|
||||
export interface INotebookService {
|
||||
_serviceBrand: undefined;
|
||||
registerNotebookController(viewType: string, controller: IMainNotebookController): void;
|
||||
registerNotebookController(viewType: string, extensionData: NotebookExtensionDescription, controller: IMainNotebookController): void;
|
||||
unregisterNotebookProvider(viewType: string): void;
|
||||
resolveNotebook(viewType: string, uri: URI): Promise<INotebook | undefined>;
|
||||
executeNotebook(viewType: string, uri: URI): Promise<void>;
|
||||
getContributedNotebook(resource: URI): readonly NotebookProviderInfo[];
|
||||
getNotebookProviderResourceRoots(): URI[];
|
||||
}
|
||||
|
||||
export class NotebookInfoStore {
|
||||
@@ -55,7 +57,7 @@ export class NotebookInfoStore {
|
||||
|
||||
export class NotebookService extends Disposable implements INotebookService {
|
||||
_serviceBrand: undefined;
|
||||
private readonly _notebookProviders = new Map<string, IMainNotebookController>();
|
||||
private readonly _notebookProviders = new Map<string, { controller: IMainNotebookController, extensionData: NotebookExtensionDescription }>();
|
||||
public notebookProviderInfoStore: NotebookInfoStore = new NotebookInfoStore();
|
||||
|
||||
constructor() {
|
||||
@@ -78,8 +80,8 @@ export class NotebookService extends Disposable implements INotebookService {
|
||||
|
||||
}
|
||||
|
||||
registerNotebookController(viewType: string, controller: IMainNotebookController) {
|
||||
this._notebookProviders.set(viewType, controller);
|
||||
registerNotebookController(viewType: string, extensionData: NotebookExtensionDescription, controller: IMainNotebookController) {
|
||||
this._notebookProviders.set(viewType, { extensionData, controller });
|
||||
}
|
||||
|
||||
unregisterNotebookProvider(viewType: string): void {
|
||||
@@ -90,7 +92,7 @@ export class NotebookService extends Disposable implements INotebookService {
|
||||
let provider = this._notebookProviders.get(viewType);
|
||||
|
||||
if (provider) {
|
||||
return provider.resolveNotebook(viewType, uri);
|
||||
return provider.controller.resolveNotebook(viewType, uri);
|
||||
}
|
||||
|
||||
return Promise.resolve(undefined);
|
||||
@@ -100,7 +102,7 @@ export class NotebookService extends Disposable implements INotebookService {
|
||||
let provider = this._notebookProviders.get(viewType);
|
||||
|
||||
if (provider) {
|
||||
return provider.executeNotebook(viewType, uri);
|
||||
return provider.controller.executeNotebook(viewType, uri);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -109,4 +111,13 @@ export class NotebookService extends Disposable implements INotebookService {
|
||||
public getContributedNotebook(resource: URI): readonly NotebookProviderInfo[] {
|
||||
return this.notebookProviderInfoStore.getContributedNotebook(resource);
|
||||
}
|
||||
|
||||
public getNotebookProviderResourceRoots(): URI[] {
|
||||
let ret: URI[] = [];
|
||||
this._notebookProviders.forEach(val => {
|
||||
ret.push(URI.revive(val.extensionData.location));
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user