Adds diff visualizer.
This commit is contained in:
@@ -46,6 +46,11 @@
|
||||
"name": "Monaco Text Visualizer",
|
||||
"preferredVisualizationId": "monaco-text"
|
||||
},
|
||||
{
|
||||
"dataSrc": "{\r\n \"kind\": { \"text\": true },\r\n \"text\": \"class Test {\\n}\",\r\n \"otherText\": \"class test {\\n}\",\r\n \"fileName\": \"foo.ts\"\r\n}",
|
||||
"name": "Monaco Text Diff Visualizer",
|
||||
"preferredVisualizationId": "monaco-text"
|
||||
},
|
||||
{
|
||||
"dataSrc": "{\r\n \"kind\": { \"text\": true },\r\n \"text\": \"class Test {\\n}\",\r\n \"fileName\": \"foo.ts\"\r\n}",
|
||||
"name": "Simple Text Visualizer",
|
||||
|
||||
@@ -3,6 +3,7 @@ export * from "./graph";
|
||||
export * from "./grid-visualizer";
|
||||
export * from "./image-visualizer";
|
||||
export * from "./monaco-text-visualizer";
|
||||
export * from "./monaco-text-diff-visualizer";
|
||||
export * from "./perspective-table-visualizer";
|
||||
export * from "./plotly-visualizer";
|
||||
export * from "./simple-text-visualizer";
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
import * as React from "react";
|
||||
import { observer, disposeOnUnmount } from "mobx-react";
|
||||
import { observable, autorun } from "mobx";
|
||||
import * as monacoTypes from "monaco-editor";
|
||||
import { Theme } from "@hediet/visualization-core";
|
||||
import { getLoadedMonaco } from "@hediet/monaco-editor-react";
|
||||
|
||||
export function getLanguageId(fileName: string): string {
|
||||
const l = getLoadedMonaco().languages.getLanguages();
|
||||
const result = l.find(l => {
|
||||
if (l.filenamePatterns) {
|
||||
for (const p of l.filenamePatterns) {
|
||||
if (new RegExp(p).test(fileName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (l.extensions) {
|
||||
for (const p of l.extensions) {
|
||||
if (fileName.endsWith(p)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (result) {
|
||||
return result.id;
|
||||
}
|
||||
return "text";
|
||||
}
|
||||
|
||||
@observer
|
||||
export class MonacoEditor extends React.Component<{
|
||||
originalText: string;
|
||||
modifiedText: string;
|
||||
languageId: string;
|
||||
theme: Theme;
|
||||
}> {
|
||||
@observable private editor:
|
||||
| monacoTypes.editor.IStandaloneDiffEditor
|
||||
| undefined;
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.editor) {
|
||||
this.editor.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private originalModel:
|
||||
| monacoTypes.editor.ITextModel
|
||||
| undefined = undefined;
|
||||
private modifiedModel:
|
||||
| monacoTypes.editor.ITextModel
|
||||
| undefined = undefined;
|
||||
|
||||
@disposeOnUnmount
|
||||
private _updateText = autorun(() => {
|
||||
if (this.editor) {
|
||||
const originalModel = getLoadedMonaco().editor.createModel(
|
||||
this.props.originalText,
|
||||
this.props.languageId,
|
||||
undefined
|
||||
);
|
||||
const modifiedModel = getLoadedMonaco().editor.createModel(
|
||||
this.props.modifiedText,
|
||||
this.props.languageId,
|
||||
undefined
|
||||
);
|
||||
|
||||
this.editor.setModel({
|
||||
original: originalModel,
|
||||
modified: modifiedModel,
|
||||
});
|
||||
|
||||
if (this.originalModel) {
|
||||
this.originalModel.dispose();
|
||||
}
|
||||
this.originalModel = originalModel;
|
||||
|
||||
if (this.modifiedModel) {
|
||||
this.modifiedModel.dispose();
|
||||
}
|
||||
this.modifiedModel = modifiedModel;
|
||||
}
|
||||
});
|
||||
|
||||
private readonly setEditorDiv = (editorDiv: HTMLDivElement) => {
|
||||
if (!editorDiv) {
|
||||
return;
|
||||
}
|
||||
this.editor = getLoadedMonaco().editor.createDiffEditor(editorDiv, {
|
||||
automaticLayout: true,
|
||||
scrollBeyondLastLine: false,
|
||||
minimap: { enabled: false },
|
||||
fixedOverflowWidgets: true,
|
||||
readOnly: true,
|
||||
theme: this.props.theme.kind === "dark" ? "vs-dark" : "vs",
|
||||
});
|
||||
if (this.originalModel && this.modifiedModel) {
|
||||
this.editor.setModel({
|
||||
original: this.originalModel!,
|
||||
modified: this.modifiedModel!,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="component-monaco-editor">
|
||||
<div className="part-editor" ref={this.setEditorDiv} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import {
|
||||
sOpenObject,
|
||||
sLiteral,
|
||||
sString,
|
||||
sOptionalProp,
|
||||
sProp,
|
||||
} from "@hediet/semantic-json";
|
||||
import * as React from "react";
|
||||
import {
|
||||
getLanguageId,
|
||||
MonacoEditor as MonacoDiffEditor,
|
||||
} from "./MonacoEditor";
|
||||
import {
|
||||
createVisualizer,
|
||||
ReactVisualization,
|
||||
globalVisualizationFactory,
|
||||
} from "@hediet/visualization-core";
|
||||
import { visualizationNs } from "../../consts";
|
||||
|
||||
export const monacoTextDiffVisualizer = createVisualizer({
|
||||
id: "monaco-text-diff",
|
||||
name: "Text Diff",
|
||||
serializer: sOpenObject({
|
||||
kind: sOpenObject({
|
||||
text: sLiteral(true),
|
||||
}),
|
||||
text: sProp(sString(), { description: "The text to show" }),
|
||||
otherText: sProp(sString(), {
|
||||
description: "The text to compare against",
|
||||
}),
|
||||
fileName: sOptionalProp(sString(), {
|
||||
description:
|
||||
"An optional filename that might be used for chosing a syntax highlighter",
|
||||
}),
|
||||
}).defineAs(visualizationNs("MonacoTextDiffVisualizationData")),
|
||||
getVisualization: (data, self) =>
|
||||
new ReactVisualization(self, { priority: 500 }, theme => {
|
||||
let id = "text";
|
||||
if (data.fileName) {
|
||||
id = getLanguageId(data.fileName);
|
||||
}
|
||||
return (
|
||||
<MonacoDiffEditor
|
||||
originalText={data.otherText}
|
||||
modifiedText={data.text}
|
||||
languageId={id}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
}),
|
||||
});
|
||||
|
||||
globalVisualizationFactory.addVisualizer(monacoTextDiffVisualizer);
|
||||
@@ -0,0 +1,22 @@
|
||||
.component-monaco-editor {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-width: 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
padding: 2px;
|
||||
border: 0.5px solid gray;
|
||||
|
||||
.part-editor {
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
flex: 1;
|
||||
|
||||
.current-line {
|
||||
border: none !important;
|
||||
}
|
||||
.selectionHighlight {
|
||||
background: transparent !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user