提交 f53b0ebf 编写于 作者: R rebornix

json editor

上级 6bbdfe03
...@@ -476,8 +476,8 @@ const embeddedEditorBackground = 'walkThrough.embeddedEditorBackground'; ...@@ -476,8 +476,8 @@ const embeddedEditorBackground = 'walkThrough.embeddedEditorBackground';
registerThemingParticipant((theme, collector) => { registerThemingParticipant((theme, collector) => {
const color = getExtraColor(theme, embeddedEditorBackground, { dark: 'rgba(0, 0, 0, .4)', extra_dark: 'rgba(200, 235, 255, .064)', light: '#f4f4f4', hc: null }); const color = getExtraColor(theme, embeddedEditorBackground, { dark: 'rgba(0, 0, 0, .4)', extra_dark: 'rgba(200, 235, 255, .064)', light: '#f4f4f4', hc: null });
if (color) { if (color) {
collector.addRule(`.monaco-workbench .part.editor > .content .notebook-editor .monaco-editor-background, collector.addRule(`.monaco-workbench .part.editor > .content .notebook-editor .cell .monaco-editor-background,
.monaco-workbench .part.editor > .content .notebook-editor .margin-view-overlays { background: ${color}; }`); .monaco-workbench .part.editor > .content .notebook-editor .cell .margin-view-overlays { background: ${color}; }`);
} }
const link = theme.getColor(textLinkForeground); const link = theme.getColor(textLinkForeground);
if (link) { if (link) {
......
...@@ -17,11 +17,12 @@ import { getZoomLevel } from 'vs/base/browser/browser'; ...@@ -17,11 +17,12 @@ import { getZoomLevel } from 'vs/base/browser/browser';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { Action } from 'vs/base/common/actions'; import { Action } from 'vs/base/common/actions';
import { DisposableStore } from 'vs/base/common/lifecycle'; import { DisposableStore } from 'vs/base/common/lifecycle';
import { IWebviewService } from 'vs/workbench/contrib/webview/browser/webview';
import { NotebookHandler, CellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/renderers/interfaces'; import { NotebookHandler, CellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/renderers/interfaces';
import { StatefullMarkdownCell } from 'vs/workbench/contrib/notebook/browser/renderers/markdownCell'; import { StatefullMarkdownCell } from 'vs/workbench/contrib/notebook/browser/renderers/markdownCell';
import { CellViewModel } from './cellViewModel'; import { CellViewModel } from './cellViewModel';
import { CodeCell } from 'vs/workbench/contrib/notebook/browser/renderers/codeCell'; import { CodeCell } from 'vs/workbench/contrib/notebook/browser/renderers/codeCell';
import { IModelService } from 'vs/editor/common/services/modelService';
import { IModeService } from 'vs/editor/common/services/modeService';
export class NotebookCellListDelegate implements IListVirtualDelegate<CellViewModel> { export class NotebookCellListDelegate implements IListVirtualDelegate<CellViewModel> {
private _lineHeight: number; private _lineHeight: number;
...@@ -268,7 +269,8 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende ...@@ -268,7 +269,8 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
@IConfigurationService configurationService: IConfigurationService, @IConfigurationService configurationService: IConfigurationService,
@IInstantiationService private readonly instantiationService: IInstantiationService, @IInstantiationService private readonly instantiationService: IInstantiationService,
@IThemeService private readonly themeService: IThemeService, @IThemeService private readonly themeService: IThemeService,
@IWebviewService private readonly webviewService: IWebviewService @IModelService private readonly modelService: IModelService,
@IModeService private readonly modeService: IModeService
) { ) {
super(handler, contextMenuService, configurationService, 'python'); super(handler, contextMenuService, configurationService, 'python');
} }
...@@ -329,7 +331,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende ...@@ -329,7 +331,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
this.showContextMenu(listIndex, element, e.posx, top + height); this.showContextMenu(listIndex, element, e.posx, top + height);
})); }));
elementDisposable?.add(new CodeCell(this.handler, element, templateData, this.themeService, this.webviewService, height)); elementDisposable?.add(new CodeCell(this.handler, element, templateData, this.themeService, this.instantiationService, this.modelService, this.modeService, height));
} }
disposeTemplate(templateData: CellRenderTemplate): void { disposeTemplate(templateData: CellRenderTemplate): void {
......
...@@ -9,7 +9,9 @@ import { CellRenderTemplate, NotebookHandler, CELL_MARGIN } from 'vs/workbench/c ...@@ -9,7 +9,9 @@ import { CellRenderTemplate, NotebookHandler, CELL_MARGIN } from 'vs/workbench/c
import { getResizesObserver } from 'vs/workbench/contrib/notebook/browser/renderers/sizeObserver'; import { getResizesObserver } from 'vs/workbench/contrib/notebook/browser/renderers/sizeObserver';
import { MimeTypeRenderer } from 'vs/workbench/contrib/notebook/browser/renderers/outputRenderer'; import { MimeTypeRenderer } from 'vs/workbench/contrib/notebook/browser/renderers/outputRenderer';
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IWebviewService } from 'vs/workbench/contrib/webview/browser/webview'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IModelService } from 'vs/editor/common/services/modelService';
import { IModeService } from 'vs/editor/common/services/modeService';
export class CodeCell extends Disposable { export class CodeCell extends Disposable {
constructor( constructor(
...@@ -17,7 +19,9 @@ export class CodeCell extends Disposable { ...@@ -17,7 +19,9 @@ export class CodeCell extends Disposable {
viewCell: CellViewModel, viewCell: CellViewModel,
templateData: CellRenderTemplate, templateData: CellRenderTemplate,
themeService: IThemeService, themeService: IThemeService,
webviewService: IWebviewService, instantiationService: IInstantiationService,
modelService: IModelService,
modeService: IModeService,
height: number | undefined height: number | undefined
) { ) {
super(); super();
...@@ -96,10 +100,11 @@ export class CodeCell extends Disposable { ...@@ -96,10 +100,11 @@ export class CodeCell extends Disposable {
if (viewCell.outputs.length > 0) { if (viewCell.outputs.length > 0) {
let hasDynamicHeight = true; let hasDynamicHeight = true;
for (let i = 0; i < viewCell.outputs.length; i++) { for (let i = 0; i < viewCell.outputs.length; i++) {
let result = MimeTypeRenderer.render(viewCell.outputs[i], themeService, webviewService); let outputItemDiv = document.createElement('div');
let result = MimeTypeRenderer.render(viewCell.outputs[i], outputItemDiv, themeService, instantiationService, modelService, modeService, handler);
templateData.outputContainer?.appendChild(outputItemDiv);
if (result) { if (result) {
hasDynamicHeight = hasDynamicHeight || result?.hasDynamicHeight; hasDynamicHeight = hasDynamicHeight || result?.hasDynamicHeight;
templateData.outputContainer?.appendChild(result.element);
if (result.shadowContent) { if (result.shadowContent) {
hasDynamicHeight = false; hasDynamicHeight = false;
handler.createContentWidget(viewCell, i, result.shadowContent, totalHeight + 8); handler.createContentWidget(viewCell, i, result.shadowContent, totalHeight + 8);
...@@ -125,7 +130,6 @@ export class CodeCell extends Disposable { ...@@ -125,7 +130,6 @@ export class CodeCell extends Disposable {
elementSizeObserver.dispose(); elementSizeObserver.dispose();
} }
}); });
// const elementSizeObserver = new ElementSizeObserver();
elementSizeObserver.startObserving(); elementSizeObserver.startObserving();
if (!hasDynamicHeight && clientHeight !== 0) { if (!hasDynamicHeight && clientHeight !== 0) {
viewCell.dynamicHeight = totalHeight + 32 + clientHeight; viewCell.dynamicHeight = totalHeight + 32 + clientHeight;
...@@ -140,10 +144,11 @@ export class CodeCell extends Disposable { ...@@ -140,10 +144,11 @@ export class CodeCell extends Disposable {
if (viewCell.outputs.length > 0) { if (viewCell.outputs.length > 0) {
let hasDynamicHeight = true; let hasDynamicHeight = true;
for (let i = 0; i < viewCell.outputs.length; i++) { for (let i = 0; i < viewCell.outputs.length; i++) {
let result = MimeTypeRenderer.render(viewCell.outputs[i], themeService, webviewService); let outputItemDiv = document.createElement('div');
let result = MimeTypeRenderer.render(viewCell.outputs[i], outputItemDiv, themeService, instantiationService, modelService, modeService, handler);
templateData.outputContainer?.appendChild(outputItemDiv);
if (result) { if (result) {
hasDynamicHeight = hasDynamicHeight || result?.hasDynamicHeight; hasDynamicHeight = hasDynamicHeight || result?.hasDynamicHeight;
templateData.outputContainer?.appendChild(result.element);
if (result.shadowContent) { if (result.shadowContent) {
hasDynamicHeight = false; hasDynamicHeight = false;
handler.createContentWidget(viewCell, i, result.shadowContent, totalHeight + 8); handler.createContentWidget(viewCell, i, result.shadowContent, totalHeight + 8);
......
...@@ -7,11 +7,16 @@ import * as DOM from 'vs/base/browser/dom'; ...@@ -7,11 +7,16 @@ import * as DOM from 'vs/base/browser/dom';
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
import { RGBA, Color } from 'vs/base/common/color'; import { RGBA, Color } from 'vs/base/common/color';
import { ansiColorIdentifiers } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; import { ansiColorIdentifiers } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry';
import { IWebviewService } from 'vs/workbench/contrib/webview/browser/webview';
import { isArray } from 'vs/base/common/types'; import { isArray } from 'vs/base/common/types';
import { IOutput } from 'vs/editor/common/modes'; import { IOutput } from 'vs/editor/common/modes';
import * as marked from 'vs/base/common/marked/marked'; import * as marked from 'vs/base/common/marked/marked';
import { NotebookHandler } from 'vs/workbench/contrib/notebook/browser/renderers/interfaces'; import { NotebookHandler } from 'vs/workbench/contrib/notebook/browser/renderers/interfaces';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
import { IModelService } from 'vs/editor/common/services/modelService';
import { URI } from 'vs/base/common/uri';
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
import { IModeService } from 'vs/editor/common/services/modeService';
export function registerMineTypeRenderer(types: string[], renderer: IMimeRenderer) { export function registerMineTypeRenderer(types: string[], renderer: IMimeRenderer) {
types.forEach(type => { types.forEach(type => {
...@@ -20,14 +25,12 @@ export function registerMineTypeRenderer(types: string[], renderer: IMimeRendere ...@@ -20,14 +25,12 @@ export function registerMineTypeRenderer(types: string[], renderer: IMimeRendere
} }
export interface IRenderOutput { export interface IRenderOutput {
element: HTMLElement;
whitespaceElement?: HTMLElement;
shadowContent?: string; shadowContent?: string;
hasDynamicHeight: boolean; hasDynamicHeight: boolean;
} }
interface IMimeRenderer { interface IMimeRenderer {
render(output: IOutput, themeService: IThemeService, webviewService: IWebviewService, notebookHandler?: NotebookHandler): IRenderOutput; render(output: IOutput, container: HTMLElement, themeService: IThemeService, instantiationService: IInstantiationService, modelService: IModelService, modeService: IModeService, notebookHandler?: NotebookHandler): IRenderOutput;
} }
export class MimeTypeRenderer { export class MimeTypeRenderer {
...@@ -42,23 +45,24 @@ export class MimeTypeRenderer { ...@@ -42,23 +45,24 @@ export class MimeTypeRenderer {
return this._renderers.get(type); return this._renderers.get(type);
} }
static render(output: IOutput, themeService: IThemeService, webviewService: IWebviewService, notebookHandler?: NotebookHandler): IRenderOutput | null { static render(output: IOutput, container: HTMLElement, themeService: IThemeService, instantiationService: IInstantiationService, modelService: IModelService, modeService: IModeService, notebookHandler: NotebookHandler): IRenderOutput | null {
return MimeTypeRenderer.instance.getRenderer(output.output_type)?.render(output, themeService, webviewService, notebookHandler) ?? null; return MimeTypeRenderer.instance.getRenderer(output.output_type)?.render(output, container, themeService, instantiationService, modelService, modeService, notebookHandler) ?? null;
} }
} }
registerMineTypeRenderer(['stream'], { registerMineTypeRenderer(['stream'], {
render: ( render: (
output: IOutput, output: IOutput,
container: HTMLElement,
themeService: IThemeService, themeService: IThemeService,
webviewService: IWebviewService instantiationService: IInstantiationService,
modelService: IModelService,
modeService: IModeService
) => { ) => {
const outputNode = document.createElement('div');
const contentNode = document.createElement('p'); const contentNode = document.createElement('p');
contentNode.innerText = output.text; contentNode.innerText = output.text;
outputNode.appendChild(contentNode); container.appendChild(contentNode);
return { return {
element: outputNode,
hasDynamicHeight: false hasDynamicHeight: false
}; };
} }
...@@ -67,10 +71,12 @@ registerMineTypeRenderer(['stream'], { ...@@ -67,10 +71,12 @@ registerMineTypeRenderer(['stream'], {
registerMineTypeRenderer(['error'], { registerMineTypeRenderer(['error'], {
render: ( render: (
output: IOutput, output: IOutput,
container: HTMLElement,
themeService: IThemeService, themeService: IThemeService,
webviewService: IWebviewService instantiationService: IInstantiationService,
modelService: IModelService,
modeService: IModeService
) => { ) => {
const outputNode = document.createElement('div');
const traceback = document.createElement('pre'); const traceback = document.createElement('pre');
DOM.addClasses(traceback, 'traceback'); DOM.addClasses(traceback, 'traceback');
if (output.traceback) { if (output.traceback) {
...@@ -78,9 +84,8 @@ registerMineTypeRenderer(['error'], { ...@@ -78,9 +84,8 @@ registerMineTypeRenderer(['error'], {
traceback.appendChild(handleANSIOutput(output.traceback[j], themeService)); traceback.appendChild(handleANSIOutput(output.traceback[j], themeService));
} }
} }
outputNode.appendChild(traceback); container.appendChild(traceback);
return { return {
element: outputNode,
hasDynamicHeight: false hasDynamicHeight: false
}; };
} }
...@@ -104,20 +109,49 @@ registerMineTypeRenderer(['error'], { ...@@ -104,20 +109,49 @@ registerMineTypeRenderer(['error'], {
class RichDisplayRenderer implements IMimeRenderer { class RichDisplayRenderer implements IMimeRenderer {
private _mdRenderer: marked.Renderer = new marked.Renderer({ gfm: true });; private _mdRenderer: marked.Renderer = new marked.Renderer({ gfm: true });;
render(output: any, themeService: IThemeService, webviewService: IWebviewService, notebookHandler: NotebookHandler): IRenderOutput { render(output: any, container: HTMLElement, themeService: IThemeService, instantiationService: IInstantiationService, modelService: IModelService, modeService: IModeService, notebookHandler: NotebookHandler): IRenderOutput {
const display = document.createElement('div');
const outputNode = document.createElement('div');
let hasDynamicHeight = false; let hasDynamicHeight = false;
DOM.addClasses(display, 'display');
if (output.data) { if (output.data) {
if (output.data['application/javascript']) { if (output.data['application/json']) {
let data = output.data['application/json'];
let str = JSON.stringify(data, null, '\t');
const editor = instantiationService.createInstance(CodeEditorWidget, container, {
...getJSONSimpleEditorOptions(),
dimension: {
width: 0,
height: 0
}
}, {
isSimpleWidget: true
});
let mode = modeService.create('json');
let resource = URI.parse(`notebook-output-${Date.now()}.json`);
const textModel = modelService.createModel(str, mode, resource, false);
editor.setModel(textModel);
let width = notebookHandler.getListDimension()!.width;
let fontInfo = notebookHandler.getFontInfo();
let height = Math.min(textModel.getLineCount(), 16) * (fontInfo?.lineHeight || 18);
editor.layout({
height,
width
});
container.style.height = `${height + 16}px`;
return {
hasDynamicHeight: true
};
} else if (output.data['application/javascript']) {
let data = output.data['application/javascript']; let data = output.data['application/javascript'];
let str = isArray(data) ? data.join('') : data; let str = isArray(data) ? data.join('') : data;
let scriptVal = `<script type="application/javascript">${str}</script>`; let scriptVal = `<script type="application/javascript">${str}</script>`;
hasDynamicHeight = false; hasDynamicHeight = false;
return { return {
element: outputNode,
shadowContent: scriptVal, shadowContent: scriptVal,
hasDynamicHeight hasDynamicHeight
}; };
...@@ -126,7 +160,6 @@ class RichDisplayRenderer implements IMimeRenderer { ...@@ -126,7 +160,6 @@ class RichDisplayRenderer implements IMimeRenderer {
let str = isArray(data) ? data.join('') : data; let str = isArray(data) ? data.join('') : data;
hasDynamicHeight = false; hasDynamicHeight = false;
return { return {
element: outputNode,
shadowContent: str, shadowContent: str,
hasDynamicHeight hasDynamicHeight
}; };
...@@ -135,7 +168,6 @@ class RichDisplayRenderer implements IMimeRenderer { ...@@ -135,7 +168,6 @@ class RichDisplayRenderer implements IMimeRenderer {
let str = isArray(data) ? data.join('') : data; let str = isArray(data) ? data.join('') : data;
hasDynamicHeight = false; hasDynamicHeight = false;
return { return {
element: outputNode,
shadowContent: str, shadowContent: str,
hasDynamicHeight hasDynamicHeight
}; };
...@@ -144,31 +176,34 @@ class RichDisplayRenderer implements IMimeRenderer { ...@@ -144,31 +176,34 @@ class RichDisplayRenderer implements IMimeRenderer {
const str = isArray(data) ? data.join('') : data; const str = isArray(data) ? data.join('') : data;
const mdOutput = document.createElement('div'); const mdOutput = document.createElement('div');
mdOutput.innerHTML = marked(str, { renderer: this._mdRenderer }); mdOutput.innerHTML = marked(str, { renderer: this._mdRenderer });
outputNode.appendChild(mdOutput); container.appendChild(mdOutput);
hasDynamicHeight = true; hasDynamicHeight = true;
} else if (output.data['image/png']) { } else if (output.data['image/png']) {
const image = document.createElement('img'); const image = document.createElement('img');
image.src = `data:image/png;base64,${output.data['image/png']}`; image.src = `data:image/png;base64,${output.data['image/png']}`;
const display = document.createElement('div');
DOM.addClasses(display, 'display');
display.appendChild(image); display.appendChild(image);
outputNode.appendChild(display); container.appendChild(display);
hasDynamicHeight = true; hasDynamicHeight = true;
} else if (output.data['image/jpeg']) { } else if (output.data['image/jpeg']) {
const image = document.createElement('img'); const image = document.createElement('img');
image.src = `data:image/jpeg;base64,${output.data['image/jpeg']}`; image.src = `data:image/jpeg;base64,${output.data['image/jpeg']}`;
const display = document.createElement('div');
DOM.addClasses(display, 'display');
display.appendChild(image); display.appendChild(image);
outputNode.appendChild(display); container.appendChild(display);
hasDynamicHeight = true; hasDynamicHeight = true;
} else if (output.data['text/plain']) { } else if (output.data['text/plain']) {
let data = output.data['text/plain']; let data = output.data['text/plain'];
let str = isArray(data) ? data.join('') : data; let str = isArray(data) ? data.join('') : data;
const contentNode = document.createElement('p'); const contentNode = document.createElement('p');
contentNode.innerText = str; contentNode.innerText = str;
outputNode.appendChild(contentNode); container.appendChild(contentNode);
} }
} }
return { return {
element: outputNode,
hasDynamicHeight hasDynamicHeight
}; };
} }
...@@ -523,3 +558,25 @@ export function calcANSI8bitColor(colorNumber: number): RGBA | undefined { ...@@ -523,3 +558,25 @@ export function calcANSI8bitColor(colorNumber: number): RGBA | undefined {
return undefined; return undefined;
} }
} }
export function getJSONSimpleEditorOptions(): IEditorOptions {
return {
wordWrap: 'on',
overviewRulerLanes: 0,
glyphMargin: false,
selectOnLineNumbers: false,
hideCursorInOverviewRuler: true,
selectionHighlight: false,
lineDecorationsWidth: 0,
overviewRulerBorder: false,
scrollBeyondLastLine: false,
renderLineHighlight: 'none',
minimap: {
enabled: false
},
lineNumbers: 'off',
scrollbar: {
alwaysConsumeMouseWheel: false
}
};
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册