提交 f53b0ebf 编写于 作者: R rebornix

json editor

上级 6bbdfe03
......@@ -476,8 +476,8 @@ const embeddedEditorBackground = 'walkThrough.embeddedEditorBackground';
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 });
if (color) {
collector.addRule(`.monaco-workbench .part.editor > .content .notebook-editor .monaco-editor-background,
.monaco-workbench .part.editor > .content .notebook-editor .margin-view-overlays { background: ${color}; }`);
collector.addRule(`.monaco-workbench .part.editor > .content .notebook-editor .cell .monaco-editor-background,
.monaco-workbench .part.editor > .content .notebook-editor .cell .margin-view-overlays { background: ${color}; }`);
}
const link = theme.getColor(textLinkForeground);
if (link) {
......
......@@ -17,11 +17,12 @@ import { getZoomLevel } from 'vs/base/browser/browser';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { Action } from 'vs/base/common/actions';
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 { StatefullMarkdownCell } from 'vs/workbench/contrib/notebook/browser/renderers/markdownCell';
import { CellViewModel } from './cellViewModel';
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> {
private _lineHeight: number;
......@@ -268,7 +269,8 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
@IConfigurationService configurationService: IConfigurationService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@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');
}
......@@ -329,7 +331,7 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
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 {
......
......@@ -9,7 +9,9 @@ import { CellRenderTemplate, NotebookHandler, CELL_MARGIN } from 'vs/workbench/c
import { getResizesObserver } from 'vs/workbench/contrib/notebook/browser/renderers/sizeObserver';
import { MimeTypeRenderer } from 'vs/workbench/contrib/notebook/browser/renderers/outputRenderer';
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 {
constructor(
......@@ -17,7 +19,9 @@ export class CodeCell extends Disposable {
viewCell: CellViewModel,
templateData: CellRenderTemplate,
themeService: IThemeService,
webviewService: IWebviewService,
instantiationService: IInstantiationService,
modelService: IModelService,
modeService: IModeService,
height: number | undefined
) {
super();
......@@ -96,10 +100,11 @@ export class CodeCell extends Disposable {
if (viewCell.outputs.length > 0) {
let hasDynamicHeight = true;
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) {
hasDynamicHeight = hasDynamicHeight || result?.hasDynamicHeight;
templateData.outputContainer?.appendChild(result.element);
if (result.shadowContent) {
hasDynamicHeight = false;
handler.createContentWidget(viewCell, i, result.shadowContent, totalHeight + 8);
......@@ -125,7 +130,6 @@ export class CodeCell extends Disposable {
elementSizeObserver.dispose();
}
});
// const elementSizeObserver = new ElementSizeObserver();
elementSizeObserver.startObserving();
if (!hasDynamicHeight && clientHeight !== 0) {
viewCell.dynamicHeight = totalHeight + 32 + clientHeight;
......@@ -140,10 +144,11 @@ export class CodeCell extends Disposable {
if (viewCell.outputs.length > 0) {
let hasDynamicHeight = true;
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) {
hasDynamicHeight = hasDynamicHeight || result?.hasDynamicHeight;
templateData.outputContainer?.appendChild(result.element);
if (result.shadowContent) {
hasDynamicHeight = false;
handler.createContentWidget(viewCell, i, result.shadowContent, totalHeight + 8);
......
......@@ -7,11 +7,16 @@ import * as DOM from 'vs/base/browser/dom';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { RGBA, Color } from 'vs/base/common/color';
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 { IOutput } from 'vs/editor/common/modes';
import * as marked from 'vs/base/common/marked/marked';
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) {
types.forEach(type => {
......@@ -20,14 +25,12 @@ export function registerMineTypeRenderer(types: string[], renderer: IMimeRendere
}
export interface IRenderOutput {
element: HTMLElement;
whitespaceElement?: HTMLElement;
shadowContent?: string;
hasDynamicHeight: boolean;
}
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 {
......@@ -42,23 +45,24 @@ export class MimeTypeRenderer {
return this._renderers.get(type);
}
static render(output: IOutput, themeService: IThemeService, webviewService: IWebviewService, notebookHandler?: NotebookHandler): IRenderOutput | null {
return MimeTypeRenderer.instance.getRenderer(output.output_type)?.render(output, themeService, webviewService, notebookHandler) ?? 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, container, themeService, instantiationService, modelService, modeService, notebookHandler) ?? null;
}
}
registerMineTypeRenderer(['stream'], {
render: (
output: IOutput,
container: HTMLElement,
themeService: IThemeService,
webviewService: IWebviewService
instantiationService: IInstantiationService,
modelService: IModelService,
modeService: IModeService
) => {
const outputNode = document.createElement('div');
const contentNode = document.createElement('p');
contentNode.innerText = output.text;
outputNode.appendChild(contentNode);
container.appendChild(contentNode);
return {
element: outputNode,
hasDynamicHeight: false
};
}
......@@ -67,10 +71,12 @@ registerMineTypeRenderer(['stream'], {
registerMineTypeRenderer(['error'], {
render: (
output: IOutput,
container: HTMLElement,
themeService: IThemeService,
webviewService: IWebviewService
instantiationService: IInstantiationService,
modelService: IModelService,
modeService: IModeService
) => {
const outputNode = document.createElement('div');
const traceback = document.createElement('pre');
DOM.addClasses(traceback, 'traceback');
if (output.traceback) {
......@@ -78,9 +84,8 @@ registerMineTypeRenderer(['error'], {
traceback.appendChild(handleANSIOutput(output.traceback[j], themeService));
}
}
outputNode.appendChild(traceback);
container.appendChild(traceback);
return {
element: outputNode,
hasDynamicHeight: false
};
}
......@@ -104,20 +109,49 @@ registerMineTypeRenderer(['error'], {
class RichDisplayRenderer implements IMimeRenderer {
private _mdRenderer: marked.Renderer = new marked.Renderer({ gfm: true });;
render(output: any, themeService: IThemeService, webviewService: IWebviewService, notebookHandler: NotebookHandler): IRenderOutput {
const display = document.createElement('div');
const outputNode = document.createElement('div');
render(output: any, container: HTMLElement, themeService: IThemeService, instantiationService: IInstantiationService, modelService: IModelService, modeService: IModeService, notebookHandler: NotebookHandler): IRenderOutput {
let hasDynamicHeight = false;
DOM.addClasses(display, 'display');
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 str = isArray(data) ? data.join('') : data;
let scriptVal = `<script type="application/javascript">${str}</script>`;
hasDynamicHeight = false;
return {
element: outputNode,
shadowContent: scriptVal,
hasDynamicHeight
};
......@@ -126,7 +160,6 @@ class RichDisplayRenderer implements IMimeRenderer {
let str = isArray(data) ? data.join('') : data;
hasDynamicHeight = false;
return {
element: outputNode,
shadowContent: str,
hasDynamicHeight
};
......@@ -135,7 +168,6 @@ class RichDisplayRenderer implements IMimeRenderer {
let str = isArray(data) ? data.join('') : data;
hasDynamicHeight = false;
return {
element: outputNode,
shadowContent: str,
hasDynamicHeight
};
......@@ -144,31 +176,34 @@ class RichDisplayRenderer implements IMimeRenderer {
const str = isArray(data) ? data.join('') : data;
const mdOutput = document.createElement('div');
mdOutput.innerHTML = marked(str, { renderer: this._mdRenderer });
outputNode.appendChild(mdOutput);
container.appendChild(mdOutput);
hasDynamicHeight = true;
} else if (output.data['image/png']) {
const image = document.createElement('img');
image.src = `data:image/png;base64,${output.data['image/png']}`;
const display = document.createElement('div');
DOM.addClasses(display, 'display');
display.appendChild(image);
outputNode.appendChild(display);
container.appendChild(display);
hasDynamicHeight = true;
} else if (output.data['image/jpeg']) {
const image = document.createElement('img');
image.src = `data:image/jpeg;base64,${output.data['image/jpeg']}`;
const display = document.createElement('div');
DOM.addClasses(display, 'display');
display.appendChild(image);
outputNode.appendChild(display);
container.appendChild(display);
hasDynamicHeight = true;
} else if (output.data['text/plain']) {
let data = output.data['text/plain'];
let str = isArray(data) ? data.join('') : data;
const contentNode = document.createElement('p');
contentNode.innerText = str;
outputNode.appendChild(contentNode);
container.appendChild(contentNode);
}
}
return {
element: outputNode,
hasDynamicHeight
};
}
......@@ -523,3 +558,25 @@ export function calcANSI8bitColor(colorNumber: number): RGBA | 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.
先完成此消息的编辑!
想要评论请 注册