Highlighting characters.
This commit is contained in:
parent
676dffa15f
commit
acdc8b8993
@ -14,6 +14,7 @@ function abortableFetch(request, options) {
|
||||
}
|
||||
|
||||
function clearOutput() {
|
||||
clearActiveAstNode();
|
||||
outputElement.innerHTML = "";
|
||||
astTreeElement.innerHTML = "";
|
||||
}
|
||||
@ -34,7 +35,18 @@ function renderSourceBox(response) {
|
||||
|
||||
for (let line of lines) {
|
||||
let wrappedLine = document.createElement("code");
|
||||
wrappedLine.textContent = line ? line : "\n";
|
||||
if (line !== "" && line !== null) {
|
||||
for (let chr of line) {
|
||||
// Please forgive me
|
||||
let wrappedCharacter = document.createElement("span");
|
||||
wrappedCharacter.textContent = chr;
|
||||
wrappedLine.appendChild(wrappedCharacter);
|
||||
}
|
||||
} else {
|
||||
let wrappedCharacter = document.createElement("span");
|
||||
wrappedCharacter.textContent = "\n";
|
||||
wrappedLine.appendChild(wrappedCharacter);
|
||||
}
|
||||
outputElement.appendChild(wrappedLine);
|
||||
}
|
||||
}
|
||||
@ -53,12 +65,46 @@ function renderAstNode(originalSource, depth, astNode) {
|
||||
|
||||
nodeElem.innerText = `${astNode.name}: ${escapedSource}`;
|
||||
nodeElem.style.marginLeft = `${depth * 20}px`;
|
||||
nodeElem.dataset.startLine = astNode.position.start_line;
|
||||
nodeElem.dataset.endLine = astNode.position.end_line;
|
||||
nodeElem.dataset.startCharacter = astNode.position.start_character;
|
||||
nodeElem.dataset.endCharacter = astNode.position.end_character;
|
||||
|
||||
nodeElem.addEventListener("click", () => {
|
||||
setActiveAstNode(nodeElem, originalSource);
|
||||
});
|
||||
|
||||
astTreeElement.appendChild(nodeElem);
|
||||
for (let child of astNode.children) {
|
||||
renderAstNode(originalSource, depth + 1, child);
|
||||
}
|
||||
}
|
||||
|
||||
function clearActiveAstNode() {
|
||||
for (let elem of document.querySelectorAll("#ast-tree .ast_node.highlighted")) {
|
||||
elem.classList.remove("highlighted");
|
||||
}
|
||||
for (let elem of document.querySelectorAll("#parse-output > code.highlighted")) {
|
||||
elem.classList.remove("highlighted");
|
||||
}
|
||||
for (let elem of document.querySelectorAll("#parse-output > code > span")) {
|
||||
elem.classList.remove("highlighted");
|
||||
}
|
||||
}
|
||||
|
||||
function setActiveAstNode(elem, originalSource) {
|
||||
clearActiveAstNode();
|
||||
elem.classList.add("highlighted");
|
||||
let startLine = parseInt(elem.dataset.startLine, 10);
|
||||
let endLine = parseInt(elem.dataset.endLine, 10);
|
||||
let startCharacter = parseInt(elem.dataset.startCharacter, 10);
|
||||
let endCharacter = parseInt(elem.dataset.endCharacter, 10);
|
||||
for (let line = startLine; line < endLine; ++line) {
|
||||
highlightLine("parse-output", line - 1);
|
||||
}
|
||||
highlightCharacters("parse-output", originalSource, startCharacter, endCharacter);
|
||||
}
|
||||
|
||||
inputElement.addEventListener("input", async () => {
|
||||
let orgSource = inputElement.value;
|
||||
if (inFlightRequest != null) {
|
||||
@ -86,12 +132,24 @@ inputElement.addEventListener("input", async () => {
|
||||
|
||||
function highlightLine(htmlName, lineOffset) {
|
||||
const childOffset = lineOffset + 1;
|
||||
const codeLineElement = document.querySelector(`.${htmlName} > code:nth-child(${childOffset})`);
|
||||
const codeLineElement = document.querySelector(`#${htmlName} > code:nth-child(${childOffset})`);
|
||||
codeLineElement?.classList.add("highlighted")
|
||||
}
|
||||
|
||||
function unhighlightLine(htmlName, lineOffset) {
|
||||
const childOffset = lineOffset + 1;
|
||||
const codeLineElement = document.querySelector(`.${htmlName} > code:nth-child(${childOffset})`);
|
||||
codeLineElement?.classList.remove("highlighted")
|
||||
function highlightCharacters(htmlName, originalSource, startCharacter, endCharacter) {
|
||||
let sourceBefore = originalSource.slice(0, startCharacter - 1);
|
||||
let precedingLineBreak = sourceBefore.lastIndexOf("\n");
|
||||
let characterIndexOnLine = precedingLineBreak !== -1 ? startCharacter - precedingLineBreak - 1 : startCharacter;
|
||||
let lineNumber = (sourceBefore.match(/\r?\n/g) || '').length + 1;
|
||||
|
||||
for (let characterIndex = startCharacter; characterIndex < endCharacter; ++characterIndex) {
|
||||
document.querySelector(`#${htmlName} > code:nth-child(${lineNumber}) > span:nth-child(${characterIndexOnLine})`)?.classList.add("highlighted");
|
||||
if (originalSource[characterIndex - 1] == "\n") {
|
||||
++lineNumber;
|
||||
characterIndexOnLine = 1;
|
||||
} else {
|
||||
++characterIndexOnLine;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -47,13 +47,18 @@ h7 {
|
||||
}
|
||||
|
||||
.code_block > code.highlighted {
|
||||
background: #307351ff;
|
||||
/* We aren't using this because we are going to highlight individual characters, but we still need to set the highlighted class on the code elem so the line numbers on the left get highlighted to make empty lines more obvious. */
|
||||
/* background: #307351ff; */
|
||||
}
|
||||
|
||||
.code_block > code.highlighted::before {
|
||||
background: #307351ff;
|
||||
}
|
||||
|
||||
.code_block > code > span.highlighted {
|
||||
background: #307351ff;
|
||||
}
|
||||
|
||||
.output_container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@ -68,8 +73,14 @@ h7 {
|
||||
}
|
||||
|
||||
.ast_node {
|
||||
cursor: pointer;
|
||||
background: #eeeeee;
|
||||
margin-bottom: 5px;
|
||||
border: 1px solid #000000;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.ast_node.highlighted {
|
||||
background: #307351ff;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user