Hold the footer's panels to the row's inline end where nothing anchors them
Where nothing anchors a panel, the footer row is its containing block and every panel opens flush with the row's inline end, under the menus, whichever menu it belongs to. The test only held the panel inside the row, so a panel at the row's inline start, under nothing it belongs to, passed: with the row's panels moved to inset-inline-start: 0, TestTheFootersMenusOpenOnScreen stayed green. It now asserts the panel's inline end is the row's (its padding box's, the edge inset-inline-end measures from), in both no-anchor legs, with anchor.js and with scripts off, LTR with the widest left-to-right labels and RTL with Arabic's, and in the class spelling as well as the attribute one. The anchored leg is unchanged: there each panel is anchored to its own summary, as the spec has it. Already passing against the footer's CSS, as it should be. The named mutation, the row's panels at inset-inline-start: 0, turns it red in 32 places: both no-anchor legs, both sizes, both directions, both spellings, both menus.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 file changed,
+22
−8
check/footer_browser_test.go+22 −8
Intent
diff --git a/check/footer_browser_test.go b/check/footer_browser_test.go| index d3ab8d3..3608ced 100644 |
| --- a/check/footer_browser_test.go |
| +++ b/check/footer_browser_test.go |
| @@ -240,8 +240,11 @@ func labelled(t *testing.T, doc, lang, dir, language, scheme string) string { |
| // the box that holds it, and in the row Language is not at the end: |
| // hung from its own <details>, its panel, at least 176px wide, runs |
| // past the opposite edge at 320. So the row holds every panel, under |
| -// it and inside it, with anchor.js running and with no script at all, |
| -// and the page grows to hold the panel so it can be scrolled to. |
| +// it and flush with its inline end, whichever menu it belongs to, with |
| +// anchor.js running and with no script at all, in both spellings, and |
| +// the page grows to hold the panel so it can be scrolled to. A panel |
| +// at the row's inline start would be inside the row and on the screen |
| +// too, and under nothing it belongs to. |
| func TestTheFootersMenusOpenOnScreen(t *testing.T) { |
| doc := columnDoc(t) |
| noAnchor := strings.ReplaceAll(string(fiesta.TokensCSS()), "@supports (position-area: block-end) and (position-try-fallbacks: flip-block)", "@supports (position-area: rastrillo-no-such-value)") |
| @@ -264,7 +267,7 @@ func TestTheFootersMenusOpenOnScreen(t *testing.T) { |
| {"no anchor positioning, no scripts", false, false}, |
| } { |
| t.Run(leg.name, func(t *testing.T) { |
| - pages := map[string]string{"/ltr": ltr, "/rtl": rtl} |
| + pages := map[string]string{"/ltr": ltr, "/rtl": rtl, "/ltr-class": classSpelling(t, ltr), "/rtl-class": classSpelling(t, rtl)} |
| if !leg.anchor { |
| for path, page := range pages { |
| pages[path] = strings.Replace(page, `href="tokens.css"`, `href="tokens-noanchor.css"`, 1) |
| @@ -290,17 +293,20 @@ func TestTheFootersMenusOpenOnScreen(t *testing.T) { |
| mustRun(t, ctx, emulation.SetScriptExecutionDisabled(true)) |
| } |
| for _, size := range [][2]int64{{390, 640}, {320, 568}} { |
| - for _, path := range []string{"/ltr", "/rtl"} { |
| + for _, path := range []string{"/ltr", "/rtl", "/ltr-class", "/rtl-class"} { |
| for _, menu := range []string{"rst-locale", "rst-scheme"} { |
| where := fmt.Sprintf("%s at %dx%d, %s", path, size[0], size[1], menu) |
| - details := "[rst-page-foot] > [" + menu + "]" |
| + details, panel := "[rst-page-foot] > ["+menu+"]", "[rst-dropdown-menu]" |
| + if strings.HasSuffix(path, "-class") { |
| + details, panel = ".rst-page__foot > ."+menu, ".rst-dropdown__menu" |
| + } |
| mustRun(t, ctx, chromedp.EmulateViewport(size[0], size[1]), chromedp.Navigate(rig.Origin+path), chromedp.WaitVisible(details, chromedp.ByQuery)) |
| var flips bool |
| at(t, ctx, `JSON.stringify(document.documentElement.hasAttribute("data-rst-flip-menus"))`, &flips) |
| if want := !leg.anchor && leg.scripts; flips != want { |
| t.Fatalf("%s: <html> data-rst-flip-menus is %v, want %v; anchor.js is not doing what this leg needs", where, flips, want) |
| } |
| - RequireAnchorPositioning(t, ctx, where, details+" > [rst-dropdown-menu]", leg.anchor) |
| + RequireAnchorPositioning(t, ctx, where, details+" > "+panel, leg.anchor) |
| mustRun(t, ctx, chromedp.Evaluate(`window.scrollTo(0, document.documentElement.scrollHeight)`, nil), |
| chromedp.Click(details+" > summary", chromedp.ByQuery)) |
| if leg.scripts { |
| @@ -312,10 +318,15 @@ func TestTheFootersMenusOpenOnScreen(t *testing.T) { |
| Open bool |
| L, R, T, B, FL, FR, FB, VW float64 |
| VH, SY, SH float64 |
| + PanelEnd, RowEnd float64 |
| } |
| - at(t, ctx, `(() => { const d = document.querySelector(`+jsStr(details)+`), p = d.querySelector(":scope > [rst-dropdown-menu]").getBoundingClientRect(), f = d.parentElement.getBoundingClientRect(); |
| + // The row's inline end is its padding box's, the |
| + // edge an absolute panel's inset-inline-end |
| + // measures from: the right in LTR, the left in RTL. |
| + at(t, ctx, `(() => { const d = document.querySelector(`+jsStr(details)+`), p = d.querySelector(":scope > `+panel+`").getBoundingClientRect(), row = d.parentElement, f = row.getBoundingClientRect(), cs = getComputedStyle(row), rtl = cs.direction === "rtl"; |
| return JSON.stringify({Open: d.open, L: p.left, R: p.right, T: p.top, B: p.bottom, FL: f.left, FR: f.right, FB: f.bottom, |
| - VW: document.documentElement.clientWidth, VH: innerHeight, SY: scrollY, SH: document.documentElement.scrollHeight}); })()`, &g) |
| + VW: document.documentElement.clientWidth, VH: innerHeight, SY: scrollY, SH: document.documentElement.scrollHeight, |
| + PanelEnd: rtl ? p.left : p.right, RowEnd: rtl ? f.left + parseFloat(cs.borderLeftWidth) : f.right - parseFloat(cs.borderRightWidth)}); })()`, &g) |
| if !g.Open { |
| t.Fatalf("%s: the menu did not open; this leg proves nothing", where) |
| } |
| @@ -331,6 +342,9 @@ func TestTheFootersMenusOpenOnScreen(t *testing.T) { |
| if g.L < g.FL-0.5 || g.R > g.FR+0.5 { |
| t.Errorf("%s: the panel spans %.1f to %.1f and the footer %.1f to %.1f; the row must hold its panel", where, g.L, g.R, g.FL, g.FR) |
| } |
| + if math.Abs(g.PanelEnd-g.RowEnd) > 0.5 { |
| + t.Errorf("%s: the panel's inline end is at %.1f and the row's at %.1f; without anchoring every panel opens flush with the row's inline end", where, g.PanelEnd, g.RowEnd) |
| + } |
| if g.T < g.FB-0.5 { |
| t.Errorf("%s: the panel starts at %.1f, above the footer's foot at %.1f; it must open under the row", where, g.T, g.FB) |
| } |