Repository navigation
Fold a captured mobile menu dialog into the navigation it repeats - #2705
Merged
Merged
Conversation
…tion beside non-menu controls Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…igation it repeats A header can draw its menu twice: a row of dropdown items for wide screens and a hamburger that opens a panel with the same items for narrow screens. When the capture records that panel as a dialog, the importer kept a plain button for the hamburger and a custom Dialog block for the panel, beside a core/navigation that had no hamburger of its own. When every entry in the dialog is an item the row already has, the row's navigation now takes it over: overlayMenu is mobile, the hamburger and the dialog are dropped, a hamburger wrapper that only repeats row controls is dropped, and dialog entries the row shows outside its items go into the overlay. The row is shown again below the source breakpoint with the repeated controls hidden. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…come first The shell search takes the first block of a level as the header only when it holds the navigation. Pages that start with empty decoration groups skipped that check and settled on the navigation block alone, so they stopped sharing the header part with pages that did not. Skip empty decoration groups ahead of the header. This showed up once a folded menu dialog no longer sat beside the header's contents and kept the search one level deeper on every page. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
# Conflicts: # php-transformer/composer.json # php-transformer/src/HtmlToBlocks/Patterns/NavigationPattern.php # php-transformer/src/HtmlToBlocks/Support/NavigationToggleSuppressor.php # php-transformer/src/WordPressSitePlan/ShellExtraction.php # php-transformer/tests/unit/navigation-menu-row-beside-controls.php
chubes4
marked this pull request as ready for review
October 13, 2026 23:48
Contributor
|
Retargeted to
The PR's own tests, the shared-shell contracts, the vocabulary contract and capture-evidence equivalence all pass locally. Equivalence needed no re-recording. Merge and test by Claude (Opus) via OpenCode on behalf of @chubes4. |
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.
This PR is stacked on #2691. Its base is that branch. Please retarget to
trunkafter #2691 merges. Only the last two commits belong to this PR. It was also built and checked together with #2694 (shared header part), because the header sharing it touches only matters there.What was wrong
Some headers draw their menu twice. One copy is a row of items for wide screens. The other is a hamburger that opens a panel with the same items for narrow screens.
When the capture records that panel as a dialog, the importer turned it into two separate things:
core/buttonThe row next to them stayed a
core/navigationwith no hamburger of its own. On a phone, the Dialog panel held the four top-level labels as buttons that opened nothing. The links under them were not in the panel at all.What changed
When a captured menu dialog only repeats a row whose items open dropdown panels, the row's navigation now takes it over. Each entry in the dialog must match an item the row already has: a link by label and href, or an accordion button by label. At least one entry must match a dropdown item. If anything in the dialog is not in the row, nothing changes.
When that holds:
overlayMenu: "mobile". Core draws the hamburger, the close button and the responsive container.core/buttonsblock. They are hidden at the wide layout. The row's own copy is hidden at the narrow layout.If the row cannot hand its whole menu to one navigation (for example its items are split by a control), the dialog is kept as it was captured.
The same change had a side effect. A dialog next to the header used to stop the shell search one level too deep, so it found the same header on every page. With the dialog gone, pages that start with empty decoration blocks found a different, smaller block as their header. Those pages stopped sharing the header part (6 of 14 on the test site). The search now skips empty decoration groups ahead of the header.
The changes are in
NavigationPattern::menuRowBesideControls(the fold), a newCapturedMenuDialogFold(what counts as a copy), andShellExtraction::collectNestedChrome(the empty groups).How I tested it
New checks:
tests/unit/navigation-menu-dialog-fold.phpuses made-up markup (two dropdown items, a link, a switcher, a call to action, a hamburger and a captured dialog). It fails on Keep a menu row as navigation when it also holds a language switcher #2691 (7 of 19 checks) and passes with the change. It also checks three cases that must not fold: a dialog with an entry the row lacks, a row split by a control, and a hamburger wrapper with its own content.tests/contract/shared-menu-with-folded-dialog.phpcompiles three made-up pages, two with empty decoration blocks ahead of the header. It expects one header part, one navigation entity, and no copy of the menu in page content. It fails without theShellExtractionchange.Both are added to
test:canonical. The fullcomposer test:canonicalpasses (no PHP memory limit).phpcsandphpstanare clean.I also imported a real capture (a 14-page orthodontics site made with Data Liberation Agent) with a paired Static Site Importer package, with #2691, #2692 to #2697 and #2694 merged in. Home page:
core/buttonin the header partcore/navigationblocks in the header partoverlayMenu: mobile)wp_navigationentitiesBrowser checks at 390px: a real mouse click and a touch tap both open the overlay. The close button, Escape, and following a link (a top-level link and a child link) all work. The page does not scroll sideways at any width tried. In the block editor the header part has one
core/navigation, no hamburger button and no Dialog block. The navigation entity holds 4 submenus, 21 links and the call-to-action buttons block.The paired package was built with a small stand-in for
homeboy(it runsnpm run buildand zips the runtime files). It has no lint or review step.What is not fixed
🤖 Generated with Claude Code