mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 12:18:19 +00:00
272 lines
8.4 KiB
HTML
272 lines
8.4 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Function Trace Diff Tool</title>
|
|
<style>
|
|
body {
|
|
font-family: monospace;
|
|
padding: 20px;
|
|
background-color: #f5f5f5;
|
|
max-width: 2000px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
h1 {
|
|
text-align: center;
|
|
color: #333;
|
|
}
|
|
|
|
#input-area {
|
|
display: flex;
|
|
gap: 20px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
#input-area textarea {
|
|
flex: 1;
|
|
height: 150px;
|
|
margin-bottom: 10px;
|
|
font-family: monospace;
|
|
padding: 10px;
|
|
}
|
|
|
|
button {
|
|
display: block;
|
|
width: 200px;
|
|
margin: 0 auto 20px;
|
|
padding: 8px 16px;
|
|
background-color: #4CAF50;
|
|
color: white;
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
button:hover {
|
|
background-color: #45a049;
|
|
}
|
|
|
|
#result-area {
|
|
display: flex;
|
|
gap: 20px;
|
|
}
|
|
|
|
#result1, #result2 {
|
|
flex: 1;
|
|
background-color: white;
|
|
padding: 5px;
|
|
padding-left: 15px;
|
|
border-radius: 4px;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
white-space: pre;
|
|
overflow-x: auto;
|
|
position: relative;
|
|
}
|
|
|
|
.line-numbers {
|
|
position: absolute;
|
|
left: 0;
|
|
top: 0;
|
|
bottom: 0;
|
|
width: 30px;
|
|
background-color: #f0f0f0;
|
|
border-right: 1px solid #ddd;
|
|
text-align: right;
|
|
padding: 5px 5px 5px 0;
|
|
color: #666;
|
|
user-select: none;
|
|
}
|
|
|
|
.content-area {
|
|
margin-left: 35px;
|
|
}
|
|
|
|
.function-block {
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
margin-left: 0 !important;
|
|
}
|
|
|
|
.function-header {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.function-header:hover {
|
|
background-color: #f0f0f0;
|
|
}
|
|
|
|
.toggle-btn {
|
|
position: absolute;
|
|
left: -10px;
|
|
width: 10px;
|
|
cursor: pointer;
|
|
color: #666;
|
|
user-select: none;
|
|
}
|
|
|
|
.function-name {
|
|
flex-grow: 1;
|
|
}
|
|
|
|
.function-content {
|
|
margin-left: 20px;
|
|
}
|
|
|
|
.line {
|
|
margin-left: 0px;
|
|
}
|
|
|
|
.function-end {
|
|
margin-left: 0;
|
|
color: #666;
|
|
}
|
|
|
|
.collapsed .function-content {
|
|
display: none;
|
|
}
|
|
|
|
.collapsed .function-end {
|
|
display: none;
|
|
}
|
|
|
|
.collapsed .function-header::after {
|
|
content: " ... }";
|
|
color: #666;
|
|
}
|
|
|
|
.highlight {
|
|
background-color: #fff3b0;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>Text Comparison Tool</h1>
|
|
|
|
<div id="input-area">
|
|
<textarea id="input1" placeholder="Enter first trace..."></textarea>
|
|
<textarea id="input2" placeholder="Enter second trace..."></textarea>
|
|
</div>
|
|
<button onclick="compareTraces()">Compare</button>
|
|
|
|
<div id="result-area">
|
|
<div id="result1"></div>
|
|
<div id="result2"></div>
|
|
</div>
|
|
|
|
<script>
|
|
function processTrace(trace, otherTrace, resultId) {
|
|
const lines = trace.trim().split('\n');
|
|
const otherLines = otherTrace.trim().split('\n');
|
|
const container = document.createElement('div');
|
|
const lineNumbersDiv = document.createElement('div');
|
|
const contentAreaDiv = document.createElement('div');
|
|
|
|
lineNumbersDiv.className = 'line-numbers';
|
|
contentAreaDiv.className = 'content-area';
|
|
container.appendChild(lineNumbersDiv);
|
|
container.appendChild(contentAreaDiv);
|
|
|
|
// Generate line numbers
|
|
for (let i = 1; i <= lines.length; i++) {
|
|
const lineNum = document.createElement('div');
|
|
lineNum.textContent = i;
|
|
lineNumbersDiv.appendChild(lineNum);
|
|
}
|
|
|
|
let indentLevel = 0;
|
|
let currentBlock = contentAreaDiv;
|
|
|
|
for (let i = 0; i < lines.length; i++) {
|
|
const line = lines[i].trim();
|
|
const shouldHighlight = !otherLines.some(otherLine => otherLine.trim() === line);
|
|
const highlightClass = shouldHighlight ? 'highlight' : '';
|
|
const isBlockStart = line.endsWith('{') && i < lines.length - 1;
|
|
|
|
if (isBlockStart) {
|
|
const functionBlock = document.createElement('div');
|
|
const header = document.createElement('div');
|
|
const toggleBtn = document.createElement('span');
|
|
const functionName = document.createElement('span');
|
|
const content = document.createElement('div');
|
|
|
|
functionBlock.className = 'function-block';
|
|
functionBlock.style.marginLeft = `${indentLevel * 20}px`;
|
|
header.className = `function-header ${highlightClass}`;
|
|
toggleBtn.className = 'toggle-btn';
|
|
toggleBtn.textContent = '▼';
|
|
functionName.className = 'function-name';
|
|
functionName.textContent = line;
|
|
content.className = 'function-content';
|
|
|
|
header.appendChild(toggleBtn);
|
|
header.appendChild(functionName);
|
|
functionBlock.appendChild(header);
|
|
functionBlock.appendChild(content);
|
|
currentBlock.appendChild(functionBlock);
|
|
|
|
indentLevel++;
|
|
currentBlock = content;
|
|
} else if (line.includes('}')) {
|
|
if (indentLevel > 0) {
|
|
indentLevel--;
|
|
const endSpan = document.createElement('span');
|
|
endSpan.className = `function-end ${highlightClass}`;
|
|
endSpan.textContent = line;
|
|
currentBlock.appendChild(endSpan);
|
|
currentBlock = currentBlock.parentElement.parentElement; // Move up to parent block
|
|
} else {
|
|
const lineDiv = document.createElement('div');
|
|
lineDiv.className = `line ${highlightClass}`;
|
|
lineDiv.textContent = line;
|
|
currentBlock.appendChild(lineDiv);
|
|
}
|
|
} else {
|
|
const lineDiv = document.createElement('div');
|
|
lineDiv.className = `line ${highlightClass}`;
|
|
lineDiv.textContent = line;
|
|
currentBlock.appendChild(lineDiv);
|
|
}
|
|
}
|
|
|
|
return container;
|
|
}
|
|
|
|
function initializeCollapsible(containerId) {
|
|
const container = document.getElementById(containerId);
|
|
const functionBlocks = container.querySelectorAll('.function-block');
|
|
|
|
functionBlocks.forEach(block => {
|
|
const header = block.querySelector('.function-header');
|
|
const toggleBtn = block.querySelector('.toggle-btn');
|
|
|
|
header.addEventListener('click', () => {
|
|
block.classList.toggle('collapsed');
|
|
toggleBtn.textContent = block.classList.contains('collapsed') ? '▶' : '▼';
|
|
});
|
|
});
|
|
}
|
|
|
|
function compareTraces() {
|
|
const trace1 = document.getElementById('input1').value;
|
|
const trace2 = document.getElementById('input2').value;
|
|
|
|
const result1 = document.getElementById('result1');
|
|
const result2 = document.getElementById('result2');
|
|
result1.innerHTML = ''; // Clear previous content
|
|
result2.innerHTML = ''; // Clear previous content
|
|
|
|
result1.appendChild(processTrace(trace1, trace2, 'result1'));
|
|
result2.appendChild(processTrace(trace2, trace1, 'result2'));
|
|
|
|
initializeCollapsible('result1');
|
|
initializeCollapsible('result2');
|
|
}
|
|
|
|
compareTraces();
|
|
</script>
|
|
</body>
|
|
</html>
|