UNPKG

profoundjs

Version:

Profound.js Framework and Server

211 lines (193 loc) 6.72 kB
let slider, stepSpan, fileDropdown, codeContainer, transformedCodeButton, coverageButton, currentStep, currentStepNumber, stepListDiv; // eslint-disable-next-line no-unused-vars function init() { slider = document.querySelector("input.log-slider"); stepSpan = document.querySelector("span.step"); fileDropdown = document.querySelector("select.file-dropdown"); codeContainer = document.querySelector("div.code-container"); transformedCodeButton = document.querySelector("button.transformed-code-button"); coverageButton = document.querySelector("button.coverage-button"); stepListDiv = document.querySelector("div.step-list"); fileDropdown.onchange = function() { const entry = vlog[fileDropdown.value]; loadCode(entry.lines, entry.map); slider.focus(); }; transformedCodeButton.onclick = showTransformedCodeButtonClick; coverageButton.onclick = showCoverage; loadFiles(); const max = vlog.log.length; slider.max = max; slider.value = max; changeStep(max); slider.oninput = changeStep; slider.focus(); } function changeStep(stepNumber) { stepListDiv.style.display = "none"; let text = ""; if (typeof stepNumber !== "number") stepNumber = Number(this.value); text = "Step " + stepNumber; stepSpan.innerText = text; const step = vlog.log[stepNumber - 1]; if (!step) return; currentStep = step; currentStepNumber = stepNumber; setFile(step.file); const transformedView = (transformedCodeButton.innerText !== "Show Tranformed 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 (transformedView) lines = vlog[fileDropdown.value].transformedLines; else lines = vlog[fileDropdown.value].lines; const lineNumber = Number(lineNumberStr.trim().split(":")[0]); const line = lines[lineNumber - 1].split("pjs.log(")[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 (!transformedView) 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 showTransformedCodeButtonClick() { const entry = vlog[fileDropdown.value]; if (!entry) return; if (transformedCodeButton.innerText === "Show Tranformed Code") { loadCode(entry.transformedLines, entry.map, true); } else { loadCode(entry.lines, entry.map); } if (currentStep && currentStep.file === fileDropdown.value) { changeStep(currentStepNumber); } slider.focus(); } function loadCode(lines, map, transformed) { codeContainer.innerHTML = ""; if (!lines) return; const lineNumWidth = String(lines.length).length; for (let i = 0; i < lines.length; i++) { let line = lines[i]; if (transformed) line = line.split("pjs.log(")[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 (transformed) { transformedCodeButton.innerText = "Show Original Code"; } else { transformedCodeButton.innerText = "Show Tranformed Code"; } } function showCoverage() { const covered = {}; const lineEls = codeContainer.children; const log = vlog.log; for (let i = 0; i < log.length; i++) { const step = log[i]; if (step.file !== fileDropdown.value) continue; if (!covered[step.lineNum - 1]) covered[step.lineNum - 1] = []; step.stepNumber = i + 1; covered[step.lineNum - 1].push(step); } for (let i = 0; i < lineEls.length; i++) { const el = lineEls[i]; if (covered[i]) { el.classList.add("covered"); el.steps = covered[i]; setupMouseOver(el); } } slider.focus(); } // 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() {}; } } 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(); slider.value = ${step.stepNumber}; slider.focus();"> 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"; }; }