Skip to content

Commit c47a8e9

Browse files
authored
Merge pull request #7712 from roc-lang/html-security-fix
Html security fix, fix simple-http-server nix
2 parents bdb5fea + d127c69 commit c47a8e9

File tree

5 files changed

+107
-42
lines changed

5 files changed

+107
-42
lines changed

devtools/smart_diff_utrace.html

+63-31
Original file line numberDiff line numberDiff line change
@@ -161,62 +161,89 @@ <h1>Text Comparison Tool</h1>
161161
function processTrace(trace, otherTrace, resultId) {
162162
const lines = trace.trim().split('\n');
163163
const otherLines = otherTrace.trim().split('\n');
164-
let contentHtml = '';
165-
let lineNumbersHtml = '';
166-
let indentLevel = 0;
167-
let blockStartLine = -1;
164+
const container = document.createElement('div');
165+
const lineNumbersDiv = document.createElement('div');
166+
const contentAreaDiv = document.createElement('div');
168167

168+
lineNumbersDiv.className = 'line-numbers';
169+
contentAreaDiv.className = 'content-area';
170+
container.appendChild(lineNumbersDiv);
171+
container.appendChild(contentAreaDiv);
172+
169173
// Generate line numbers
170174
for (let i = 1; i <= lines.length; i++) {
171-
lineNumbersHtml += `${i}\n`;
175+
const lineNum = document.createElement('div');
176+
lineNum.textContent = i;
177+
lineNumbersDiv.appendChild(lineNum);
172178
}
173-
179+
180+
let indentLevel = 0;
181+
let currentBlock = contentAreaDiv;
182+
174183
for (let i = 0; i < lines.length; i++) {
175184
const line = lines[i].trim();
176185
const shouldHighlight = !otherLines.some(otherLine => otherLine.trim() === line);
177186
const highlightClass = shouldHighlight ? 'highlight' : '';
178-
179187
const isBlockStart = line.endsWith('{') && i < lines.length - 1;
180-
188+
181189
if (isBlockStart) {
182-
blockStartLine = i;
183-
const functionName = line;
184-
contentHtml += `<div class="function-block" style="margin-left: ${indentLevel * 20}px">
185-
<div class="function-header ${highlightClass}">
186-
<span class="toggle-btn">▼</span>
187-
<span class="function-name">${functionName}</span>
188-
</div>
189-
<div class="function-content">`;
190+
const functionBlock = document.createElement('div');
191+
const header = document.createElement('div');
192+
const toggleBtn = document.createElement('span');
193+
const functionName = document.createElement('span');
194+
const content = document.createElement('div');
195+
196+
functionBlock.className = 'function-block';
197+
functionBlock.style.marginLeft = `${indentLevel * 20}px`;
198+
header.className = `function-header ${highlightClass}`;
199+
toggleBtn.className = 'toggle-btn';
200+
toggleBtn.textContent = '▼';
201+
functionName.className = 'function-name';
202+
functionName.textContent = line;
203+
content.className = 'function-content';
204+
205+
header.appendChild(toggleBtn);
206+
header.appendChild(functionName);
207+
functionBlock.appendChild(header);
208+
functionBlock.appendChild(content);
209+
currentBlock.appendChild(functionBlock);
210+
190211
indentLevel++;
212+
currentBlock = content;
191213
} else if (line.includes('}')) {
192214
if (indentLevel > 0) {
193215
indentLevel--;
194-
contentHtml += `</div><span class="function-end ${highlightClass}">${line}</span></div>`;
216+
const endSpan = document.createElement('span');
217+
endSpan.className = `function-end ${highlightClass}`;
218+
endSpan.textContent = line;
219+
currentBlock.appendChild(endSpan);
220+
currentBlock = currentBlock.parentElement.parentElement; // Move up to parent block
195221
} else {
196-
contentHtml += `<div class="line ${highlightClass}">${line}</div>`;
222+
const lineDiv = document.createElement('div');
223+
lineDiv.className = `line ${highlightClass}`;
224+
lineDiv.textContent = line;
225+
currentBlock.appendChild(lineDiv);
197226
}
198227
} else {
199-
const isLastLineBlock = line.endsWith('{') && i === lines.length - 1;
200-
if (isLastLineBlock) {
201-
contentHtml += `<div class="line ${highlightClass}">${line}</div>`;
202-
} else {
203-
contentHtml += `<div class="line ${highlightClass}">${line}</div>`;
204-
}
228+
const lineDiv = document.createElement('div');
229+
lineDiv.className = `line ${highlightClass}`;
230+
lineDiv.textContent = line;
231+
currentBlock.appendChild(lineDiv);
205232
}
206233
}
207-
208-
return `<div class="line-numbers">${lineNumbersHtml}</div><div class="content-area">${contentHtml}</div>`;
234+
235+
return container;
209236
}
210237

211238
function initializeCollapsible(containerId) {
212239
const container = document.getElementById(containerId);
213240
const functionBlocks = container.querySelectorAll('.function-block');
214-
241+
215242
functionBlocks.forEach(block => {
216243
const header = block.querySelector('.function-header');
217244
const toggleBtn = block.querySelector('.toggle-btn');
218-
219-
header.addEventListener('click', (e) => {
245+
246+
header.addEventListener('click', () => {
220247
block.classList.toggle('collapsed');
221248
toggleBtn.textContent = block.classList.contains('collapsed') ? '▶' : '▼';
222249
});
@@ -227,8 +254,13 @@ <h1>Text Comparison Tool</h1>
227254
const trace1 = document.getElementById('input1').value;
228255
const trace2 = document.getElementById('input2').value;
229256

230-
document.getElementById('result1').innerHTML = processTrace(trace1, trace2, 'result1');
231-
document.getElementById('result2').innerHTML = processTrace(trace2, trace1, 'result2');
257+
const result1 = document.getElementById('result1');
258+
const result2 = document.getElementById('result2');
259+
result1.innerHTML = ''; // Clear previous content
260+
result2.innerHTML = ''; // Clear previous content
261+
262+
result1.appendChild(processTrace(trace1, trace2, 'result1'));
263+
result2.appendChild(processTrace(trace2, trace1, 'result2'));
232264

233265
initializeCollapsible('result1');
234266
initializeCollapsible('result2');

flake.nix

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797

9898
zls # zig language server
9999
watchexec
100+
simple-http-server # to view the website locally
100101
]);
101102

102103
aliases = ''

nix/simple-http-server.nix

+19-2
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,33 @@
1-
{ rustPlatform, fetchFromGitHub }:
1+
{
2+
lib,
3+
stdenv,
4+
rustPlatform,
5+
fetchFromGitHub,
6+
pkg-config,
7+
openssl,
8+
darwin,
9+
}:
210

3-
rustPlatform.buildRustPackage {
11+
rustPlatform.buildRustPackage rec {
412
pname = "simple-http-server";
513
version = "0.1.0"; # adjust version as needed
614

715
src = fetchFromGitHub {
816
owner = "Anton-4";
917
repo = "simple-http-server";
1018
rev = "f3089e5736a1e8abdb69ba9e7618fe5e518a2df0";
19+
sha256 = "sha256-Vcckv75hmJV7F9mqPtM3piSIZg9MvKI/oU7/tv4viy4=";
1120
};
1221

1322
cargoLock = {
1423
lockFile = "${src}/Cargo.lock";
1524
};
25+
26+
nativeBuildInputs = [ pkg-config ];
27+
28+
buildInputs =
29+
[ openssl ]
30+
++ lib.optionals stdenv.hostPlatform.isDarwin [
31+
darwin.apple_sdk.frameworks.Security
32+
];
1633
}

www/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ bash ./www/build-dev-local.sh
2020

2121
Open http://0.0.0.0:8080 in your browser.
2222

23+
If you want to build the repl as well, check out crates/repl_wasm/README.md.
24+
2325
## After you've made a change locally
2426

2527
In the terminal where the web server is running:

www/public/site.js

+22-9
Original file line numberDiff line numberDiff line change
@@ -351,18 +351,31 @@ function createHistoryEntry(inputText) {
351351
const historyIndex = repl.inputHistory.length;
352352
repl.inputHistory.push(inputText);
353353

354-
const firstLinePrefix = '<span class="input-line-prefix">» </span>';
355-
const otherLinePrefix = '<br><span class="input-line-prefix">… </span>';
356-
const inputLines = inputText.split("\n");
357-
if (inputLines[inputLines.length - 1] === "") {
358-
inputLines.pop();
359-
}
360-
const inputWithPrefixes = firstLinePrefix + inputLines.join(otherLinePrefix);
361-
362354
const inputElem = document.createElement("div");
363-
inputElem.innerHTML = inputWithPrefixes;
364355
inputElem.classList.add("input");
365356

357+
const inputLines = inputText.split("\n").filter(line => line !== ""); // Remove empty last line if present
358+
359+
inputLines.forEach((line, index) => {
360+
if (index > 0) {
361+
// Add line break for subsequent lines
362+
inputElem.appendChild(document.createElement("br"));
363+
const prefixSpan = document.createElement("span");
364+
prefixSpan.className = "input-line-prefix";
365+
prefixSpan.textContent = "… ";
366+
inputElem.appendChild(prefixSpan);
367+
} else {
368+
// First line prefix
369+
const prefixSpan = document.createElement("span");
370+
prefixSpan.className = "input-line-prefix";
371+
prefixSpan.textContent = "» ";
372+
inputElem.appendChild(prefixSpan);
373+
}
374+
375+
// Add the line text as plain text
376+
inputElem.appendChild(document.createTextNode(line));
377+
});
378+
366379
const historyItem = document.createElement("div");
367380
historyItem.appendChild(inputElem);
368381
historyItem.classList.add("history-item");

0 commit comments

Comments
 (0)