profoundjs
Version:
Profound.js Framework and Server
197 lines (178 loc) • 6.25 kB
JavaScript
// Cloned from vlog.js
// TODO: remove some unused stuff later
let stepSpan, fileDropdown, codeContainer, PJSCodeButton, diffButton, currentStep, currentStepNumber, stepListDiv;
// eslint-disable-next-line no-unused-vars
function init() {
stepSpan = document.querySelector("span.step");
fileDropdown = document.querySelector("select.file-dropdown");
codeContainer = document.querySelector("div.code-container");
PJSCodeButton = document.querySelector("button.PJS-code-button");
diffButton = document.querySelector("button.diff-button");
stepListDiv = document.querySelector("div.step-list");
fileDropdown.onchange = function() {
const entry = vlog[fileDropdown.value];
loadCode(entry.lines, entry.map);
};
PJSCodeButton.onclick = showPJSCodeButtonClick;
diffButton.onclick = showDiff;
loadFiles();
const max = vlog.log.length;
changeStep(max);
}
// This is cloned from vlog.js. "Step" is actually a program name for rpglog.
function changeStep(stepNumber) {
stepListDiv.style.display = "none";
let text = "";
if (typeof stepNumber !== "number") stepNumber = Number(this.value);
text = "Program";
stepSpan.innerText = text;
const step = vlog.log[stepNumber - 1];
if (!step) return;
currentStep = step;
currentStepNumber = stepNumber;
setFile(step.file);
const PJSCodeView = (PJSCodeButton.innerText !== "Show PJS Code");
// Remove old current-line
let curLine = codeContainer.querySelector("pre.current-line"); // get old current line
if (curLine) {
let contentEl = curLine.querySelector(".jscode");
if (!contentEl) contentEl = curLine;
curLine.classList.remove("current-line");
const lineNumberStr = contentEl.innerHTML.split(":")[0] + ": ";
let lines;
if (PJSCodeView) lines = vlog[fileDropdown.value].PJSlines;
else lines = vlog[fileDropdown.value].RPGlines;
const lineNumber = Number(lineNumberStr.trim().split(":")[0]);
const line = lines[lineNumber - 1].split("pjs.logToRpglog(")[0];
contentEl.innerHTML = lineNumberStr + hiLine(line);
}
// Set new current-line
curLine = codeContainer.querySelector(`pre:nth-child(${step.lineNum})`);
if (curLine) {
let contentEl = curLine.querySelector(".jscode");
if (!contentEl) contentEl = curLine;
const lineNumberStr = contentEl.innerHTML.split(":")[0] + ": ";
// const line = step.line;
if (!PJSCodeView) contentEl.innerHTML = lineNumberStr + hiLine(step.line);
curLine.classList.add("current-line");
setTimeout(function() {
curLine.scrollIntoView({
behavior: "smooth",
block: "center"
});
}, 0);
}
}
function hiLine(line) {
return "<code>" + hljs.highlight(line, { language: "JavaScript" }).value + "</code>";
}
function loadFiles() {
for (file in vlog) {
if (file === "log") continue;
fileDropdown.options.add(new Option(file));
}
// Load last file
fileDropdown.value = file;
const entry = vlog[file];
loadCode(entry.lines, entry.map);
}
function setFile(file) {
if (fileDropdown.value === file) return;
fileDropdown.value = file;
const entry = vlog[file];
loadCode(entry.lines, entry.map);
}
function showPJSCodeButtonClick() {
const entry = vlog[fileDropdown.value];
if (!entry) return;
if (PJSCodeButton.innerText === "Show PJS Code") {
loadCode(entry.PJSlines, entry.map, true);
}
else {
loadCode(entry.RPGlines, entry.map);
}
if (currentStep && currentStep.file === fileDropdown.value) {
changeStep(currentStepNumber);
}
codeContainer.classList.add("hljs");
}
function loadCode(lines, map, PJScode) {
codeContainer.innerHTML = "";
if (!lines) return;
const lineNumWidth = String(lines.length).length;
for (let i = 0; i < lines.length; i++) {
let line = lines[i];
if (PJScode) line = line.split("pjs.logToRpglog(")[0];
const pre = document.createElement("pre");
const lineNumber = i + 1;
const lineNumberStr = (" " + lineNumber).substr(-lineNumWidth) + ": ";
let html = lineNumberStr + hiLine(line);
if (map) {
let prevMapEntry = map[i - 1];
if (!prevMapEntry) prevMapEntry = {};
const mapEntry = map[i];
let rpgLine = "";
if (mapEntry && mapEntry.lineNum && prevMapEntry.lineNum !== mapEntry.lineNum) {
const rpgLineNumberStr = (" " + mapEntry.lineNum).substr(-6) + ": ";
rpgLine = rpgLineNumberStr + mapEntry.code;
}
html = `
<div class="jscode">${html}</div>
<div class="rpgcode">${rpgLine}</div>
`;
}
pre.innerHTML = html;
codeContainer.appendChild(pre);
}
if (PJScode) {
PJSCodeButton.innerText = "Show RPG Code";
}
else {
PJSCodeButton.innerText = "Show PJS Code";
}
}
function showDiff() {
const entry = vlog[fileDropdown.value];
if (!entry) return;
const config = { outputFormat: "side-by-side" };
const diffData = Diff2Html.html(Diff2Html.parse(entry.diff), config);
codeContainer.innerHTML = diffData;
codeContainer.classList.remove("hljs");
}
// eslint-disable-next-line no-unused-vars
function hideCoverage() {
const lineEls = codeContainer.children;
for (let i = 0; i < lineEls.length; i++) {
const el = lineEls[i];
el.classList.remove("covered");
el.onmouseover = function() {};
}
}
// eslint-disable-next-line no-unused-vars
function setupMouseOver(el) {
el.onmouseover = function(e) {
const steps = el.steps;
let html = "";
steps.forEach(step => {
const line = step.line;
const parts = line.split("//");
html += `<a href="JavaScript:changeStep(${step.stepNumber}); hideCoverage();">
Step ${step.stepNumber}
</a>
-
<span class="step-details">
//${parts[parts.length - 1]}
</span>
<br/>`;
});
stepListDiv.innerHTML = html;
stepListDiv.style.left = e.clientX + 5 + "px";
stepListDiv.style.top = e.clientY - 5 + "px";
stepListDiv.style.display = "";
};
el.onmouseout = stepListDiv.onmouseout = function(e) {
const toElement = e.toElement || e.relatedTarget;
if (toElement === stepListDiv || stepListDiv.contains(toElement)) return;
stepListDiv.style.display = "none";
};
}