(aCode, bCode)
| 319 | // Helper to render tab content |
| 320 | // Simple line-level LCS diff renderer between two code strings |
| 321 | function renderCodeDiff(aCode, bCode) { |
| 322 | const a = (aCode || '').split('\n'); |
| 323 | const b = (bCode || '').split('\n'); |
| 324 | const m = a.length, n = b.length; |
| 325 | // build LCS table |
| 326 | const dp = Array.from({length: m+1}, () => new Array(n+1).fill(0)); |
| 327 | for (let ii = m-1; ii >= 0; --ii) { |
| 328 | for (let jj = n-1; jj >= 0; --jj) { |
| 329 | if (a[ii] === b[jj]) dp[ii][jj] = dp[ii+1][jj+1] + 1; |
| 330 | else dp[ii][jj] = Math.max(dp[ii+1][jj], dp[ii][jj+1]); |
| 331 | } |
| 332 | } |
| 333 | // backtrack |
| 334 | let i = 0, j = 0; |
| 335 | const parts = []; |
| 336 | while (i < m && j < n) { |
| 337 | if (a[i] === b[j]) { |
| 338 | parts.push({type: 'eq', line: a[i]}); |
| 339 | i++; j++; |
| 340 | } else if (dp[i+1][j] >= dp[i][j+1]) { |
| 341 | parts.push({type: 'del', line: a[i]}); |
| 342 | i++; |
| 343 | } else { |
| 344 | parts.push({type: 'ins', line: b[j]}); |
| 345 | j++; |
| 346 | } |
| 347 | } |
| 348 | while (i < m) { parts.push({type: 'del', line: a[i++]}); } |
| 349 | while (j < n) { parts.push({type: 'ins', line: b[j++]}); } |
| 350 | |
| 351 | // Render HTML with inline styles |
| 352 | const htmlLines = parts.map(function(p) { |
| 353 | if (p.type === 'eq') return '<div style="white-space:pre-wrap;">' + escapeHtml(p.line) + '</div>'; |
| 354 | if (p.type === 'del') return '<div style="background:#fff0f0;color:#8b1a1a;padding:0.08em 0.3em;border-left:3px solid #f26;white-space:pre-wrap;">- ' + escapeHtml(p.line) + '</div>'; |
| 355 | return '<div style="background:#f2fff2;color:#116611;padding:0.08em 0.3em;border-left:3px solid #2a8;white-space:pre-wrap;">+ ' + escapeHtml(p.line) + '</div>'; |
| 356 | }); |
| 357 | return '<div style="font-family: \'Fira Mono\', monospace; font-size:0.95em; line-height:1.35;">' + |
| 358 | '<div style="margin-bottom:0.4em;color:#666;">Showing diff between program and its parent (parent id: ' + (parentNodeForDiff ? parentNodeForDiff.id : 'N/A') + ')</div>' + |
| 359 | htmlLines.join('') + '</div>'; |
| 360 | } |
| 361 | |
| 362 | // small helper to escape HTML |
| 363 | function escapeHtml(s) { |
no test coverage detected