made {} block foldable

Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com>
This commit is contained in:
Anton-4 2024-10-23 16:43:14 +02:00 committed by GitHub
parent 71e68f9725
commit ae26f9392a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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' : '';
// Split texts into lines and process them // Check if this line is the start of a block that has content
let rawLines1 = text1.split(/\r?\n/); const isBlockStart = line.endsWith('{') && i < lines.length - 1;
let rawLines2 = text2.split(/\r?\n/);
let lines1 = rawLines1.map(processLine); if (isBlockStart) {
let lines2 = rawLines2.map(processLine); blockStartLine = i;
// Start of a function block with content
// Find common lines const functionName = line;
let set1 = new Set(lines1); html += `<div class="function-block" style="margin-left: ${indentLevel * 20}px">
let set2 = new Set(lines2); <div class="function-header ${highlightClass}">
let commonLines = new Set([...set1].filter(line => line && set2.has(line))); <span class="toggle-btn"></span>
<span class="function-name">${functionName}</span>
// Display texts with highlighting </div>
let result1 = document.getElementById('result1'); <div class="function-content">`;
let result2 = document.getElementById('result2'); indentLevel++;
} else if (line.includes('}')) {
result1.innerHTML = ''; // End of a block
result2.innerHTML = ''; if (indentLevel > 0) {
indentLevel--;
// Display lines for Text 1 html += `</div><span class="function-end ${highlightClass}">${line}</span></div>`;
for (let i = 0; i < rawLines1.length; i++) { } else {
let originalLine = rawLines1[i]; html += `<div class="line ${highlightClass}">${line}</div>`;
let processedLine = lines1[i]; }
} else {
let div = document.createElement('div'); // Regular line or a line ending with { at the end of input
div.textContent = originalLine; const isLastLineBlock = line.endsWith('{') && i === lines.length - 1;
if (isLastLineBlock) {
if (!commonLines.has(processedLine)) { html += `<div class="line ${highlightClass}">${line}</div>`;
div.classList.add('highlight'); } else {
html += `<div class="line ${highlightClass}">${line}</div>`;
}
} }
result1.appendChild(div);
} }
// Display lines for Text 2 return html;
for (let i = 0; i < rawLines2.length; i++) { }
let originalLine = rawLines2[i];
let processedLine = lines2[i];
let div = document.createElement('div'); function initializeCollapsible(containerId) {
div.textContent = originalLine; const container = document.getElementById(containerId);
const functionBlocks = container.querySelectorAll('.function-block');
if (!commonLines.has(processedLine)) { functionBlocks.forEach(block => {
div.classList.add('highlight'); const header = block.querySelector('.function-header');
} const toggleBtn = block.querySelector('.toggle-btn');
result2.appendChild(div);
} header.addEventListener('click', (e) => {
}); block.classList.toggle('collapsed');
toggleBtn.textContent = block.classList.contains('collapsed') ? '▶' : '▼';
});
});
}
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>