Fix #194 r2: align line-number gutter in both wrap modes
QA FAIL of PR #179 (verified on palette-dev 2026-09-10) found two defects:
1) Row accounting: splitLines() joined .codeline blocks with '\n' text
nodes. Since dee062d made .codeline display:block, each interleaved
newline text node rendered as its own extra visual row in the code
column under pre-wrap, but renumber() counted only .codeline span
heights, so the gutter had one fewer row per line break and numbers
drifted off alignment on wrapped lines. Fix: join('') so blocks are
adjacent with no phantom newline rows; blank source lines become
empty blocks given a line box via .codeline:empty::before (ZWJ) in
app.css so they still count as one row.
2) Inline gutter spans: .gutline spans were appended with no separators
and .code .gutter .gutline { display: block } did not exist on the
deployed build, so all numbers landed on one row. That rule is
present in origin/dev (merged via #183); kept unchanged and verified
by rendering in a local build.
Wrap OFF path unchanged: gutter still gets '1\n2\n3\n4' text and the
horizontal-scroll gutter behavior is untouched (no CSS changes to
scrolling; only a :empty line-box rule). CSP unchanged: no inline
styles/handlers, static JS only.
This commit is contained in:
@@ -301,6 +301,9 @@ html[data-wrap] .float { overflow-x: hidden; }
|
|||||||
.codeline { display: block; }
|
.codeline { display: block; }
|
||||||
/* #167 rev: gutter number spans must stack one per visual row (wrap on) */
|
/* #167 rev: gutter number spans must stack one per visual row (wrap on) */
|
||||||
.code .gutter .gutline { display: block; }
|
.code .gutter .gutline { display: block; }
|
||||||
|
/* #194: codeline blocks are adjacent (no '\n' text between them), so an
|
||||||
|
empty block (blank source line) needs its own line box to stay one row */
|
||||||
|
.codeline:empty::before { content: "\200B"; }
|
||||||
/* syntax highlight tokens (#1) */
|
/* syntax highlight tokens (#1) */
|
||||||
.tok-kw { color: #c792ea; }
|
.tok-kw { color: #c792ea; }
|
||||||
.tok-str { color: #a5e075; }
|
.tok-str { color: #a5e075; }
|
||||||
|
|||||||
@@ -13,7 +13,13 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Wrap each logical line (split on newline; spans never contain newlines
|
// Wrap each logical line (split on newline; spans never contain newlines
|
||||||
// because HighlightCode highlights per line) in a .codeline block.
|
// because HighlightCode highlights per line) in a .codeline block. The
|
||||||
|
// blocks must be adjacent with NO newline text between them (#194):
|
||||||
|
// .codeline is display:block, and under pre-wrap each interleaved '\n'
|
||||||
|
// text node renders as an extra phantom row in the code column that
|
||||||
|
// renumber() does not count, drifting the gutter off alignment on
|
||||||
|
// wrapped lines. Blank lines become empty blocks; .codeline:empty keeps
|
||||||
|
// them one row tall (see app.css).
|
||||||
function splitLines() {
|
function splitLines() {
|
||||||
var html = body.innerHTML;
|
var html = body.innerHTML;
|
||||||
var parts = html.split('\n');
|
var parts = html.split('\n');
|
||||||
@@ -21,7 +27,7 @@
|
|||||||
for (var i = 0; i < parts.length; i++) {
|
for (var i = 0; i < parts.length; i++) {
|
||||||
out.push('<span class="codeline">' + parts[i] + '</span>');
|
out.push('<span class="codeline">' + parts[i] + '</span>');
|
||||||
}
|
}
|
||||||
body.innerHTML = out.join('\n');
|
body.innerHTML = out.join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
function renumber() {
|
function renumber() {
|
||||||
|
|||||||
Reference in New Issue
Block a user