Release v0.4.0: dev -> main #251
@@ -28,9 +28,11 @@
|
|||||||
body.innerHTML = out.join('');
|
body.innerHTML = out.join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
// One .gutline block per visual row. Numbers are placed at the gutter row
|
// One .gutline block per visual row. The gutter must reproduce the code
|
||||||
// whose top matches their .codeline's top; filler rows pad the gaps so
|
// column's REAL rendered rows: each number goes on the visual row whose top
|
||||||
// alignment is driven by measured geometry, not by uniform row counts.
|
// matches its .codeline's top (a line wrapping to N rows gets its number on
|
||||||
|
// the FIRST of those rows), and filler rows pad the gaps. Geometry is
|
||||||
|
// measured, not derived from span counts or heights.
|
||||||
function renumber() {
|
function renumber() {
|
||||||
var lines = body.querySelectorAll('.codeline');
|
var lines = body.querySelectorAll('.codeline');
|
||||||
if (!wrapOn() || !lines.length) {
|
if (!wrapOn() || !lines.length) {
|
||||||
@@ -42,11 +44,8 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Measure each logical line's geometry. Reading all rects first avoids
|
// Read all rects first: batching layout reads before the writes below
|
||||||
// interleaved layout reads/writes. A line's number goes on the visual row
|
// avoids interleaved read/write reflows.
|
||||||
// whose top matches the line's top; the gutter is sized to cover the
|
|
||||||
// deepest row any line STARTS on (a trailing empty logical line renders
|
|
||||||
// with zero height but still needs its number row).
|
|
||||||
var bodyTop = body.getBoundingClientRect().top;
|
var bodyTop = body.getBoundingClientRect().top;
|
||||||
var lh = parseFloat(getComputedStyle(body).lineHeight) || 1;
|
var lh = parseFloat(getComputedStyle(body).lineHeight) || 1;
|
||||||
var rowIdx = [];
|
var rowIdx = [];
|
||||||
@@ -76,15 +75,16 @@
|
|||||||
// settle a hair under N * line-height after the gutter is rebuilt; a
|
// settle a hair under N * line-height after the gutter is rebuilt; a
|
||||||
// gutter pass that changes the code column width reflows it. Verify the
|
// gutter pass that changes the code column width reflows it. Verify the
|
||||||
// placement one frame later and re-run if any line's row moved (#167).
|
// placement one frame later and re-run if any line's row moved (#167).
|
||||||
var placed = {};
|
var placed = [];
|
||||||
for (var q = 0; q < tops.length; q++) placed[q] = Math.round((tops[q] - bodyTop) / lh);
|
for (var p = 0; p < rowIdx.length; p++) placed.push(rowIdx[p]);
|
||||||
requestAnimationFrame(function () {
|
requestAnimationFrame(function () {
|
||||||
var moved = false;
|
var moved = false;
|
||||||
|
var bodyTop2 = body.getBoundingClientRect().top;
|
||||||
|
var lh2 = parseFloat(getComputedStyle(body).lineHeight) || lh;
|
||||||
var tops2 = [];
|
var tops2 = [];
|
||||||
for (var q2 = 0; q2 < lines.length; q2++) tops2.push(lines[q2].getBoundingClientRect().top);
|
for (var q2 = 0; q2 < lines.length; q2++) tops2.push(lines[q2].getBoundingClientRect().top);
|
||||||
var bodyTop2 = body.getBoundingClientRect().top;
|
|
||||||
for (var q3 = 0; q3 < tops2.length; q3++) {
|
for (var q3 = 0; q3 < tops2.length; q3++) {
|
||||||
if (Math.round((tops2[q3] - bodyTop2) / lh) !== placed[q3]) { moved = true; break; }
|
if (Math.round((tops2[q3] - bodyTop2) / lh2) !== placed[q3]) { moved = true; break; }
|
||||||
}
|
}
|
||||||
if (moved) renumber();
|
if (moved) renumber();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user