oxc/website/playground/traverseJson.js
IWANABETHATGUY 0a9c548332
feat(playground): bidirectional inspect ast node (#1619)
1. Before we implement inspect the source code via the related AST node.

2. This pull request implemented the reverse process, you can inspect
the related ast node by clicking the source code, also it would scroll
the corresponding ast node into the viewport after you click source
code.
2023-12-04 00:18:54 +08:00

56 lines
1.3 KiB
JavaScript

let typeFilter = ["JsonText", "Object", "Property", "Array"];
/**
* @param {import('@lezer/common').SyntaxNode} node
* @returns {import('@lezer/common').SyntaxNode}
*
* */
export function findMostInnerNodeForPosition(node, offset, source) {
if (!typeFilter.includes(node.name)) {
return;
}
let targetNode;
if (node.name === "Object") {
let span = getSpanOfNode(node, source);
if (Object.keys(span).length > 0) {
let { start, end } = span;
if (start <= offset && end >= offset) {
targetNode = node;
} else {
return targetNode;
}
}
}
let curChild = node.firstChild;
while (curChild) {
let node = findMostInnerNodeForPosition(curChild, offset, source);
if (node?.from) {
targetNode = node;
}
curChild = curChild.nextSibling;
}
return targetNode;
}
/**
* @param {import('@lezer/common').SyntaxNode} node
* @param {string} source
* */
function getSpanOfNode(node, source) {
let span = {};
let child = node.firstChild;
while (child) {
if (child.name === "Property" && child.firstChild.name === "PropertyName") {
let { from, to } = child.firstChild;
let name = source.slice(from + 1, to - 1);
if (["start", "end"].includes(name)) {
let value = child.firstChild.nextSibling;
if (value) {
span[name] = +source.slice(value.from, value.to);
}
}
}
child = child.nextSibling;
}
return span;
}