Files
Automata/packages/editor-ui/src/components/CodeNodeEditor/utils.ts

56 lines
1.3 KiB
TypeScript

import type * as esprima from 'esprima-next';
import type { Completion } from '@codemirror/autocomplete';
import type { Node } from 'estree';
import type { RangeNode } from './types';
import { sanitizeHtml } from '@/utils/htmlUtils';
export function walk<T extends RangeNode>(
node: Node | esprima.Program,
test: (node: Node) => boolean,
found: Node[] = [],
) {
// @ts-ignore
if (test(node)) found.push(node);
for (const key in node) {
if (!(key in node)) continue;
// @ts-ignore
const child = node[key];
if (child === null || typeof child !== 'object') continue;
if (Array.isArray(child)) {
child.forEach((node) => walk(node, test, found));
} else {
walk(child, test, found);
}
}
return found as T[];
}
export const escape = (str: string) =>
str
.replace('$', '\\$')
.replace('(', '\\(')
.replace(')', '\\)')
.replace('[', '\\[')
.replace(']', '\\]');
export const toVariableOption = (label: string) => ({ label, type: 'variable' });
export const addVarType = (option: Completion) => ({ ...option, type: 'variable' });
export const addInfoRenderer = (option: Completion): Completion => {
const { info } = option;
if (typeof info === 'string') {
option.info = () => {
const wrapper = document.createElement('span');
wrapper.innerHTML = sanitizeHtml(info);
return wrapper;
};
}
return option;
};