@making-sense/antlr-editor
Version:
ANTLR Typescript editor
210 lines • 9.24 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const react_2 = __importDefault(require("@monaco-editor/react"));
const Monaco = __importStar(require("monaco-editor/esm/vs/editor/editor.api"));
const monaco = __importStar(require("monaco-editor"));
const react_3 = require("@monaco-editor/react");
const ParserFacade_1 = require("./utils/ParserFacade");
const providers_1 = require("./utils/providers");
const variables_1 = require("./utils/variables");
const EditorFooter_1 = __importDefault(require("./EditorFooter"));
react_3.loader.config({
monaco
});
const Editor = ({ script, setScript, onListErrors, customFetcher, variables, variablesInputURLs, tools, height = "50vh", width = "100%", theme = "vs-dark", options, shortcuts, FooterComponent }) => {
const editorRef = (0, react_1.useRef)(null);
const monacoRef = (0, react_1.useRef)(null);
const [ready, setReady] = (0, react_1.useState)(false);
const [vars, setVars] = (0, react_1.useState)((0, variables_1.buildVariables)(variables));
const [cursor, setCursor] = (0, react_1.useState)({
line: 1,
column: 1,
selectionLength: 0
});
const onMount = (editor, mon, t) => {
editorRef.current = editor;
monacoRef.current = mon;
let parseContentTO;
let contentChangeTO;
parseContent(t, script);
editor.onDidChangeModelContent(() => {
if (parseContentTO)
clearTimeout(parseContentTO);
parseContentTO = setTimeout(() => {
parseContent(t, script);
}, 0);
if (!contentChangeTO) {
if (setScript) {
contentChangeTO = setTimeout(() => {
setScript(editor.getValue());
contentChangeTO = undefined;
}, 200);
}
}
});
editor.onDidChangeCursorPosition(e => {
setCursor(prev => ({
...prev,
line: e.position.lineNumber,
column: e.position.column
}));
});
editor.onDidChangeCursorSelection(e => {
const selection = e.selection;
const length = editor?.getModel()?.getValueInRange(selection).length;
setCursor(prev => ({
...prev,
selectionLength: length || 0
}));
});
if (shortcuts) {
Object.entries(shortcuts).forEach(([comboString, action]) => {
comboString.split(",").forEach(combo => {
const keys = combo.trim().toLowerCase().split("+");
let keyCode = null;
let keyMod = 0;
keys.forEach(k => {
if (k === "ctrl")
keyMod |= monaco.KeyMod.CtrlCmd;
else if (k === "meta")
keyMod |= monaco.KeyMod.CtrlCmd;
else if (k === "shift")
keyMod |= monaco.KeyMod.Shift;
else if (k === "alt")
keyMod |= monaco.KeyMod.Alt;
else {
const upper = k.length === 1 ? k.toUpperCase() : k;
if (`Key${upper}` in monaco.KeyCode) {
keyCode = monaco.KeyCode[`Key${upper}`];
}
else if (upper in monaco.KeyCode) {
keyCode = monaco.KeyCode[upper];
}
else {
keyCode = null;
}
}
});
if (keyCode !== null) {
editor.addCommand(keyMod | keyCode, e => {
e?.preventDefault?.();
action();
});
}
});
});
}
editor.onKeyDown(e => {
const isMac = /Mac/.test(navigator.userAgent);
const metaPressed = e.metaKey;
const ctrlPressed = e.ctrlKey;
if ((isMac && metaPressed && e.code === "Enter") ||
(!isMac && ctrlPressed && e.code === "Enter")) {
e.preventDefault();
e.stopPropagation();
shortcuts["ctrl+enter, meta+enter"]?.();
}
});
};
const parseContent = (0, react_1.useCallback)((t, str) => {
const editor = editorRef.current;
const monacoErrors = (0, ParserFacade_1.validate)(t)(editor?.getValue() || str).map(error => {
return {
startLineNumber: error.startLine,
startColumn: error.startCol,
endLineNumber: error.endLine,
endColumn: error.endCol,
message: error.message,
severity: Monaco.MarkerSeverity.Error
};
});
const model = editor?.getModel();
if (model)
monacoRef.current?.editor.setModelMarkers(model, "owner", monacoErrors);
if (onListErrors) {
onListErrors(monacoErrors.map(error => {
return {
line: error.startLineNumber,
column: error.startColumn,
message: error.message
};
}));
}
}, [onListErrors]);
(0, react_1.useEffect)(() => {
if (!Array.isArray(variablesInputURLs) || variablesInputURLs.length === 0)
setReady(true);
const f = customFetcher || fetch;
if (variablesInputURLs && variablesInputURLs.length > 0 && !ready) {
Promise.all(variablesInputURLs.map(v => f(v)))
.then(res => Promise.all(res.map(r => r.json())).then(res => {
const uniqueVars = (0, variables_1.buildUniqueVariables)(res);
setVars(v => [...v, ...uniqueVars]);
setReady(true);
}))
.catch(() => {
setReady(true);
});
}
}, [variablesInputURLs]);
(0, react_1.useEffect)(() => {
parseContent(tools);
}, [tools.initialRule]);
const isDark = theme.includes("dark");
if (!ready)
return null;
const bannerHeight = 22;
return ((0, jsx_runtime_1.jsxs)("div", { style: { position: "relative", height, width }, children: [(0, jsx_runtime_1.jsx)("div", { style: { height: `calc(100% - ${bannerHeight}px)` }, children: (0, jsx_runtime_1.jsx)(react_2.default, { value: script, height: "100%", width: "100%", onMount: (e, m) => {
parseContent(tools, script);
onMount(e, m, tools);
(0, providers_1.getEditorWillMount)(tools)({
variables: vars,
editor: e
})(m);
}, onChange: () => {
parseContent(tools);
}, theme: theme, language: tools.id, options: options }) }), (0, jsx_runtime_1.jsx)("div", { style: {
position: "absolute",
height: bannerHeight,
width: "100%",
bottom: 0,
left: 0,
gap: "12px",
padding: "4px 8px",
background: isDark ? "#1e1e1e" : "#f3f3f3",
color: isDark ? "#ccc" : "#333",
borderTop: `1px solid ${isDark ? "#333" : "#ccc"}`,
zIndex: 10,
boxSizing: "border-box"
}, children: (0, jsx_runtime_1.jsx)(EditorFooter_1.default, { cursor: cursor, FooterComponent: FooterComponent }) })] }));
};
exports.default = Editor;
//# sourceMappingURL=Editor.js.map