Map cellspacing / cellpadding attributes as presentational hints#503
Map cellspacing / cellpadding attributes as presentational hints#503mitsuru wants to merge 1 commit into
Conversation
…al hints
Per HTML5 §14.3 (rendering: tables) these attributes map to:
- `<table cellspacing="N">` → `border-spacing: Npx`
- `<table cellpadding="N">` → `padding: Npx` on descendant `<td>` / `<th>`
Blitz's presentational-hint synthesizer already covers `align`, `width`,
`height`, `bgcolor`, `hidden` on the relevant elements but not these two,
so tests that rely on `cellspacing="0"` / `cellpadding="0"` to zero out
the UA defaults (`table { border-spacing: 2px }` at `default.css` L314,
`td { padding: 1px }` at L546) render with the UA values still applied.
For `cellspacing`, push `PropertyDeclaration::BorderSpacing` when the
attribute appears on `<table>`. For `cellpadding`, walk up from each
`<td>` / `<th>` to the first ancestor `<table>` and, if it has a
`cellpadding` attribute, push `Padding{Top,Right,Bottom,Left}` on the
cell. The walk-up mirrors Chrome/Firefox's UA-sheet descendant selector
(`table[cellpadding] td, table[cellpadding] th { padding: attr(cellpadding px) }`),
which Stylo doesn't currently expose to embedders.
WPT css/css-tables (339 tests, 205 run): 64 → 67 PASS on `main@1127951`
(v0.3.0-beta.1) with this patch applied:
- colspan-001.html FAIL → PASS (5/5 subtests)
- colspan-002.html FAIL → PASS (5/5 subtests)
- colspan-003.html FAIL → PASS (5/5 subtests)
Claude-Session: https://claude.ai/code/session_01YHhheUghdrjENLNdfiMUV9
nicoburns
left a comment
There was a problem hiding this comment.
The cellspacing makes sense to me.
I don't like the tree walking in the cellpadding implementation. I think we should avoid that if at all possible.
Chrome and Firefox express this via a UA-sheet descendant selector; Stylo doesn't expose that surface to embedders
This assertion seems suspicious to me:
- Stylo does expose UA stylesheets. And we already have one in Blitz (
default.css) - Firefox uses Stylo! So if it didn't expose it, I'm not sure how Firefox would do this
|
@nicoburns The strongest evidence is Servo itself. Servo caches the parsed if let Some(cellpadding) = self
.downcast::<HTMLTableCellElement>()
.and_then(|this| this.get_table())
.and_then(|table| table.get_cellpadding())
{
let cellpadding = NonNegative(specified::LengthPercentage::Length(
specified::NoCalcLength::from_px(cellpadding as f32),
));
push(PropertyDeclaration::PaddingTop(cellpadding.clone()));
push(PropertyDeclaration::PaddingLeft(cellpadding.clone()));
push(PropertyDeclaration::PaddingBottom(cellpadding.clone()));
push(PropertyDeclaration::PaddingRight(cellpadding));
}That's structurally identical to this PR — walk up from the cell to the This convergence is CSS-driven: Spike A — CSS custom-property inheritance Spike B — cached walk-up (matches Servo) Both pass the same 67 WPT I lean toward B: it's the smaller change, matches Servo's design |
Summary
Implements the mapping defined in the HTML Rendering spec's Tables
section for
the legacy
cellspacingandcellpaddingtable attributes as CSSpresentational hints, so that
<table cellspacing="0">/<table cellpadding="0">actually zero out the UA sheet'sborder-spacing: 2pxand
td { padding: 1px }defaults. Without this, any WPT (or real page) thatrelies on the boilerplate
cellspacing="0" cellpadding="0"to reach a cleanstarting geometry renders with UA padding still applied.
Approach
<table>→ pushPropertyDeclaration::BorderSpacingfrom the element's own attribute iteration (same shape as the existing
align/width/height/bgcolor/hiddenhints).<table>but the effect is ondescendant
<td>/<th>cells. Chrome and Firefox express this via a UA-sheetdescendant selector; Stylo doesn't expose that surface to embedders, so we
walk up from each cell to the first ancestor
<table>and read itscellpaddingattribute at presentational-hint time.Both attributes are parsed per the spec's rules for parsing non-negative
integers
(approximated with
str::parse::<u32>), matching Blink/Gecko'sParseHTMLNonNegativeIntegersemantics for the common case. A stricter,whitespace-trimming HTML-integer parser could be shared across
colspan/rowspan/ new hints in a follow-up.Verification
WPT
css/css-tables(339 tests, 205 run) onmain@11279518:Specifically fixes:
colspan-001.html— FAIL → PASS (5/5 subtests)colspan-002.html— FAIL → PASS (5/5 subtests)colspan-003.html— FAIL → PASS (5/5 subtests)No regressions in the suite.
Follow-ups (out of scope)
parse_html_non_negative_integerhelper (would also tightencolspan/rowspaninlayout/table.rs, currently.parse().ok()without whitespace trimming or
+prefix handling).<table border>,<img hspace>/<vspace>,<hr size>,<body/iframe marginwidth/height>.