A wrapped line starts where it should, not one space in - #726
Merged
Conversation
comrak writes a newline behind every `<br>`, and a browser drops that newline only while it is still at the start of the line. The soft-line anchor #541 added is an `inline-block` — a box — and it was inserted between the break and that newline, which made the newline a space BETWEEN two boxes instead of one at the start of a line. So every source line but the first of a paragraph spanning three lines or more opened with an indent nobody typed. The anchor now goes behind the whitespace rather than in front of it. Its position on screen — the only thing `previewAnchor` reads it for — is the same either way.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
A paragraph of three or more source lines rendered every line but its first with a leading space in the preview. The Markdown has no such space. Reported by @PathGao with a screenshot of a plain CJK document, where the indent is unmistakable because every line starts at a different place from the one above it.
No issue filed for it.
Mechanism
Not the block patcher (#632), which was the first suspect — this predates it.
render.hardbreaksmakes comrak end every source line with<br />followed by a newline, and that newline is collapsible whitespace. A browser drops it, but only under one condition: it has to still be at the start of the line. CSS Text 3 removes a sequence of collapsible spaces at the beginning of a line; it does not remove one that follows a box.processSoftLineAnchors(#541) inserts a<span class="source-line-anchor">beside each<br>so a soft line break has something with anoffsetTopfor split-view scroll sync to resolve to. That span isdisplay: inline-block— being a box is the whole point of it, since a<br>generates none — and it was inserted withinsertBefore(anchor, br.nextSibling), which lands it in front of comrak's newline. The newline was then a space between two boxes, which is drawn.Measured in Chromium, three paragraphs identical but for where the anchor sits, x of the first glyph on the second line:
The anchor now goes behind the leading whitespace: the text node is split so the newline stays on the break's side of it.
previewAnchorreads onlyoffsetTopoff the anchor, and that is the same on either side of a zero-width space.Scope
The
<br>is still untouched, for the reason the existing comment gives. Nothing about which blocks qualify for anchors (LINE_ANCHOR_MIN_SPAN) changed, so short paragraphs — which never had the defect, having no anchors — render exactly as before.splitTextwould have been the obvious way to split the text node; the render-protocol DOM the tests drive doesn't implement it, so the split is done withcreateTextNode+insertBefore, the two APIs that module already restricts itself to.Tests
the newline behind a break stays in front of the anchorin scripts/scrollSyncBlockMapping.test.ts, beside the anchors' other tests. It walks the anchors of a four-line paragraph and asserts each one's previous sibling is whitespace and the node before that is the<br>.Revert the fix and keep the test: it goes red (
an anchor sits behind the whitespace, not in front of it). The other 30 tests in that file stay green either way, which is the point — they pin where the anchors are in the source, and nothing about that changed.Verification
Not verified: the pixel behaviour was measured in Chromium, not in the WKWebView the macOS app actually renders in. The rule involved is plain CSS whitespace collapsing rather than anything engine-specific, but I did not put the built app in front of it and count pixels.