Skip to content

vaev-layout: Preserve and trim inter-inline whitespace.#249

Open
andg-odoo wants to merge 1 commit into
odoo:mainfrom
andg-odoo:andg/vaev-inter-inline-whitespace
Open

vaev-layout: Preserve and trim inter-inline whitespace.#249
andg-odoo wants to merge 1 commit into
odoo:mainfrom
andg-odoo:andg/vaev-inter-inline-whitespace

Conversation

@andg-odoo

Copy link
Copy Markdown
Contributor

When we build text in a block formatting context, _buildText skips any whitespace-only text node outright. However, whitespace between two inline-level boxes is not structural: it collapses to a single preserved space, so dropping the node loses the gap between adjacent spans. Such a node should only be skipped when there is no active inline content on the line (leading or inter-block whitespace).

For example, in Odoo's sale order report the product quantity is rendered as two adjacent spans, <span>5.00</span> and <span>Units</span>. The whitespace between them is dropped, so the line renders as 5.00Units instead of 5.00 Units.

Letting it through on its own would then leak trailing spaces, because the builder implements only the leading half of white-space phase 2 and never trims the end of a line. The collapsed space has to survive long enough to be either emitted or dropped depending on what follows it.

The fix to this is a deferred space: a collapsed space is held on the root inline box and materialized only once a following glyph is appended, so it is dropped at end of line. Anything else that ends the line's run of pending whitespace consumes it the same way, so the space is also dropped before an atomic inline box and across a forced (pre-line) break (this is the trailing half of white-space phase 2).

Ref: https://www.w3.org/TR/css-text-3/#white-space-phase-2

When we build text in a block formatting context, `_buildText` skips
any whitespace-only text node outright. However, whitespace between
two inline-level boxes is not structural: it collapses to a single
preserved space, so dropping the node loses the gap between
`<span>5.00</span>` and `<span>Units</span>` and the line renders as
`5.00Units`. Such a node should only be skipped when there is no active
inline content on the line (leading or inter-block whitespace).

Letting it through on its own would then leak trailing spaces, because
the builder implements only the leading half of white-space phase 2 and
never trims the end of a line. The collapsed space has to survive long
enough to be either emitted or dropped depending on what follows it.

The fix to this is a deferred space: a collapsed space is held on the
root inline box and materialized only once a following glyph is
appended, so it is dropped at end of line. Anything else that ends the
line's run of pending whitespace consumes it the same way, so the space
is also dropped before an atomic inline box and across a forced
(pre-line) break (this is the trailing half of white-space phase 2).

Ref: https://www.w3.org/TR/css-text-3/#white-space-phase-2
@sleepy-monax

Copy link
Copy Markdown
Member

Hi can you add a test to avoid regression

https://github.com/odoo/paper-muncher/blob/main/doc/reftests.md

@ananas-dev

Copy link
Copy Markdown
Member

Hello, thanks for your PR! I have a few nitpicks:

For comments inside the code, we try to stick as closely as possible to the spec by placing raw snippets and links from it directly above the relevant code, rather than writing our own explanations.

Also, it looks like this PR implements cross-inline-box collapsing as defined in white-space phase 1, rather than white-space phase 2, which concerns the rendering of text (zero-advance hanging characters, etc.) and happens post-wrapping, during layout, not box building.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants