mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 13:59:08 +00:00
made {} block foldable
Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com>
This commit is contained in:
parent
71e68f9725
commit
ae26f9392a
1 changed files with 172 additions and 91 deletions
|
@ -1,70 +1,133 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>uftrace Diff Tool</title>
|
<meta charset="UTF-8">
|
||||||
|
<title>Function Trace Diff Tool</title>
|
||||||
<style>
|
<style>
|
||||||
/* This uftrace diff tool ignores differences in `{`,`}` and `;`.*/
|
|
||||||
/* CSS styles */
|
|
||||||
body {
|
body {
|
||||||
font-family: Arial, sans-serif;
|
font-family: monospace;
|
||||||
margin: 20px;
|
padding: 20px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
#input-area, #result-area {
|
#input-area {
|
||||||
display: flex;
|
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#input-area textarea {
|
#input-area textarea {
|
||||||
width: 50%;
|
width: 100%;
|
||||||
height: 200px;
|
height: 150px;
|
||||||
margin: 5px;
|
margin-bottom: 10px;
|
||||||
|
font-family: monospace;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
font-family: monospace;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Targeting only direct child divs */
|
button {
|
||||||
#result-area > div {
|
padding: 8px 16px;
|
||||||
width: 50%;
|
background-color: #4CAF50;
|
||||||
margin: 5px;
|
color: white;
|
||||||
border: 1px solid #ccc;
|
border: none;
|
||||||
/* Quadrupled the height from 300px to 1200px */
|
border-radius: 4px;
|
||||||
height: 1200px;
|
cursor: pointer;
|
||||||
overflow-y: scroll;
|
margin-bottom: 20px;
|
||||||
white-space: pre-wrap;
|
|
||||||
font-family: monospace;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Styles for each line in the results */
|
button:hover {
|
||||||
#result1 div, #result2 div {
|
background-color: #45a049;
|
||||||
padding: 2px 5px;
|
}
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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 {
|
.highlight {
|
||||||
background-color: yellow;
|
background-color: #fff3b0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#compare-btn {
|
|
||||||
display: block;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 10px 20px;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Text Comparison Tool</h1>
|
<h1>Text Comparison Tool</h1>
|
||||||
|
|
||||||
<div id="input-area">
|
<div id="input-area">
|
||||||
<textarea id="text1" placeholder="Enter Text 1"></textarea>
|
<textarea id="input1" placeholder="Enter first trace..."></textarea>
|
||||||
<textarea id="text2" placeholder="Enter Text 2"></textarea>
|
<textarea id="input2" placeholder="Enter second trace..."></textarea>
|
||||||
|
<button onclick="compareTraces()">Compare</button>
|
||||||
</div>
|
</div>
|
||||||
<button id="compare-btn">Compare</button>
|
|
||||||
|
|
||||||
<div id="result-area">
|
<div id="result-area">
|
||||||
<div id="result1"></div>
|
<div id="result1"></div>
|
||||||
|
@ -72,63 +135,81 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.getElementById('compare-btn').addEventListener('click', function() {
|
function processTrace(trace, otherTrace, resultId) {
|
||||||
// Get text from textareas
|
const lines = trace.trim().split('\n');
|
||||||
let text1 = document.getElementById('text1').value;
|
const otherLines = otherTrace.trim().split('\n');
|
||||||
let text2 = document.getElementById('text2').value;
|
let html = '';
|
||||||
|
let indentLevel = 0;
|
||||||
|
let blockStartLine = -1;
|
||||||
|
|
||||||
// Function to process lines: remove { }, ; then trim
|
for (let i = 0; i < lines.length; i++) {
|
||||||
function processLine(line) {
|
const line = lines[i].trim();
|
||||||
return line.replace(/[{};]/g, '').trim();
|
const shouldHighlight = !otherLines.some(otherLine => otherLine.trim() === line);
|
||||||
|
const highlightClass = shouldHighlight ? 'highlight' : '';
|
||||||
|
|
||||||
|
// Check if this line is the start of a block that has content
|
||||||
|
const isBlockStart = line.endsWith('{') && i < lines.length - 1;
|
||||||
|
|
||||||
|
if (isBlockStart) {
|
||||||
|
blockStartLine = i;
|
||||||
|
// Start of a function block with content
|
||||||
|
const functionName = line;
|
||||||
|
html += `<div class="function-block" style="margin-left: ${indentLevel * 20}px">
|
||||||
|
<div class="function-header ${highlightClass}">
|
||||||
|
<span class="toggle-btn">▼</span>
|
||||||
|
<span class="function-name">${functionName}</span>
|
||||||
|
</div>
|
||||||
|
<div class="function-content">`;
|
||||||
|
indentLevel++;
|
||||||
|
} else if (line.includes('}')) {
|
||||||
|
// End of a block
|
||||||
|
if (indentLevel > 0) {
|
||||||
|
indentLevel--;
|
||||||
|
html += `</div><span class="function-end ${highlightClass}">${line}</span></div>`;
|
||||||
|
} else {
|
||||||
|
html += `<div class="line ${highlightClass}">${line}</div>`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Regular line or a line ending with { at the end of input
|
||||||
|
const isLastLineBlock = line.endsWith('{') && i === lines.length - 1;
|
||||||
|
if (isLastLineBlock) {
|
||||||
|
html += `<div class="line ${highlightClass}">${line}</div>`;
|
||||||
|
} else {
|
||||||
|
html += `<div class="line ${highlightClass}">${line}</div>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split texts into lines and process them
|
return html;
|
||||||
let rawLines1 = text1.split(/\r?\n/);
|
|
||||||
let rawLines2 = text2.split(/\r?\n/);
|
|
||||||
|
|
||||||
let lines1 = rawLines1.map(processLine);
|
|
||||||
let lines2 = rawLines2.map(processLine);
|
|
||||||
|
|
||||||
// Find common lines
|
|
||||||
let set1 = new Set(lines1);
|
|
||||||
let set2 = new Set(lines2);
|
|
||||||
let commonLines = new Set([...set1].filter(line => line && set2.has(line)));
|
|
||||||
|
|
||||||
// Display texts with highlighting
|
|
||||||
let result1 = document.getElementById('result1');
|
|
||||||
let result2 = document.getElementById('result2');
|
|
||||||
|
|
||||||
result1.innerHTML = '';
|
|
||||||
result2.innerHTML = '';
|
|
||||||
|
|
||||||
// Display lines for Text 1
|
|
||||||
for (let i = 0; i < rawLines1.length; i++) {
|
|
||||||
let originalLine = rawLines1[i];
|
|
||||||
let processedLine = lines1[i];
|
|
||||||
|
|
||||||
let div = document.createElement('div');
|
|
||||||
div.textContent = originalLine;
|
|
||||||
|
|
||||||
if (!commonLines.has(processedLine)) {
|
|
||||||
div.classList.add('highlight');
|
|
||||||
}
|
|
||||||
result1.appendChild(div);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display lines for Text 2
|
function initializeCollapsible(containerId) {
|
||||||
for (let i = 0; i < rawLines2.length; i++) {
|
const container = document.getElementById(containerId);
|
||||||
let originalLine = rawLines2[i];
|
const functionBlocks = container.querySelectorAll('.function-block');
|
||||||
let processedLine = lines2[i];
|
|
||||||
|
|
||||||
let div = document.createElement('div');
|
functionBlocks.forEach(block => {
|
||||||
div.textContent = originalLine;
|
const header = block.querySelector('.function-header');
|
||||||
|
const toggleBtn = block.querySelector('.toggle-btn');
|
||||||
|
|
||||||
if (!commonLines.has(processedLine)) {
|
header.addEventListener('click', (e) => {
|
||||||
div.classList.add('highlight');
|
block.classList.toggle('collapsed');
|
||||||
}
|
toggleBtn.textContent = block.classList.contains('collapsed') ? '▶' : '▼';
|
||||||
result2.appendChild(div);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function compareTraces() {
|
||||||
|
const trace1 = document.getElementById('input1').value;
|
||||||
|
const trace2 = document.getElementById('input2').value;
|
||||||
|
|
||||||
|
document.getElementById('result1').innerHTML = processTrace(trace1, trace2, 'result1');
|
||||||
|
document.getElementById('result2').innerHTML = processTrace(trace2, trace1, 'result2');
|
||||||
|
|
||||||
|
initializeCollapsible('result1');
|
||||||
|
initializeCollapsible('result2');
|
||||||
|
}
|
||||||
|
|
||||||
|
compareTraces();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue