Skip to content

fix(php-transformer): carry menu chrome presentation core cannot save - #1606

Merged
chubes4 merged 4 commits into
trunkfrom
fix/menu-chrome-presentation
Sep 8, 2026
Merged

fix(php-transformer): carry menu chrome presentation core cannot save#1606
chubes4 merged 4 commits into
trunkfrom
fix/menu-chrome-presentation

Conversation

@gmovr

@gmovr gmovr commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Fixes #1605.

Problem

Two menu surfaces are rebuilt by core rather than emitted from the source, so the source element that carried the author classes stops existing and the author rule is left addressing nothing. Both look correct in the editor, which reads the separate editor-static-state projection, and drop to the destination theme's defaults on the front end — which is why this survived four import runs unnoticed.

1. core/navigation-link stores its label as a block attribute. The label markup never reaches the block tree, so SourceBlockAttributeProjector never merges the projected marker classes into a className. AuthorStylesheetProjector has already rewritten the label's author rule onto those markers, so the rewritten rule matches nothing:

frontend  :where(.blocks-engine-semantic-<hash>-3):not(…){color:#FF99FE;font-family:montserrat;font-size:14px}
emitted   <!-- wp:navigation-link {"label":"<span class=\"Item__label\">About</span>", …} /-->

2. core/details renders <summary> with no attributes. BlockFactory emits a hardcoded <summary> and DetailsPattern carries only the summary's inner HTML, so a disclosure toggle's own classes are dropped outright. On a hamburger site that toggle is the entire visible navigation affordance.

Approach

LabelsSourceDom::innerHtmlWithProjectedMarkers() stamps the projected markers while serializing markup destined for a block attribute. Markers are stamped on the serialization clone, never on the source DOM, so later selector matching still sees the authored classes. It falls back to the transformer's own serializer whenever no marker had to be carried, so rich-text lowering is unaffected.

Toggles — resolve the toggle's box once, register it under a marker the details block carries, and restate it from engine-support CSS as .wp-block-details.<marker>>summary{…}, following the existing navigation-link-icon projection.

Delivered as CSS rather than markup by necessity: core/details declares summary as {"type":"rich-text","source":"rich-text","selector":"summary"} and saves a bare <summary>, so attributes there would diverge from core's save shape and invalidate the block. The emitted <summary> stays attribute-free, and the test asserts that.

The label's type rides along on the same rule because it is inheritable and its own rules lost the same ancestor. Position and margin stay out — the details block core lays out already holds the slot.

Verification — two live sources

Imported through WordPress Studio PR Automattic/studio#3952 52755397 + Data Liberation Agent PR Automattic/data-liberation-agent#119 16f32f4 + Static Site Importer 881768a, on WordPress 7.1. Computed styles measured with Playwright, before and after on the same build.

Horizontal menuhttps://www.wix.com/sgtemplates/e-ramirez

menu label before after source
color rgb(0, 0, 0) rgb(255, 153, 254) rgb(255, 153, 254)
font-family Arial montserrat montserrat
font-size 10px 14px 14px
letter-spacing normal 0.7px 0.7px
page height 5143px 4917px 4917px

Overlay togglehttps://www.wix.com/sgtemplates/sophja-j-pierce

"Menu" toggle before after source
background transparent rgb(26, 26, 26) rgb(26, 26, 26)
border-radius 0px 50px 50px
label color rgb(0, 0, 0) rgb(239, 254, 139) rgb(239, 254, 139)
label font Arial 10px madefor-text 18px madefor-text 18px
label box 25×11 48×23 48×23
toggle width 50px 107px 107px
toggle height 25px 25px 40px

Re-importing the first source on the final build confirms no regression: labels and page height unchanged and still exact.

Editor: 0 block-validation warnings and 0 core/html fallback blocks on both sources, before and after.

Known gaps, deliberately not in this PR

  • Toggle height 25px vs 40px. The source resolves height:100% on the toggle; the <details> box core lays out does not fill its parent, so the pill is flatter than the source. Paint, radius, width and type are exact.
  • The overlay panel's link typography stays unstyled on the second source (56px syne links render at Arial 10px). Different mechanism: the rewritten rule addresses markers -58/-59/-60 while the labels that render carry -53-56, i.e. the rule was projected onto source elements that never reach the output. That sits in the responsive-counterpart area, whose most recent change on Data Liberation Agent Preserve source button controls semantically #119 is a revert of "Preserve responsive counterpart provenance", so it wants a decision there rather than a patch here.

Note for #1482

This adds one more marker vocabulary (blocks-engine-disclosure-summary-*) to the surface #1482 wants to consolidate. It deliberately follows the existing navigation-link-icon projection rather than introducing a new mechanism, but it is additional surface for that refactor to absorb.

Validation

  • composer test:canonical — 150 tests pass (149 before, plus the new one).
  • composer test:parity — 300 fixtures pass.
  • New tests/unit/menu-chrome-presentation-carry.php fails on trunk for both surfaces (2 of 5 assertions) and passes on this branch.
  • php -l clean on every changed file.

AI Assistance

Claude Opus 5 via Claude Code was used to diagnose both failures, reduce each to a minimal reproduction, implement the change, and run verification against two live sources. gmovr remains responsible for the submitted changes.

🤖 Generated with Claude Code

https://claude.ai/code/session_016W6gpfFTSwSok5vMvLnd5L

gmovr and others added 4 commits September 8, 2026 10:38
A navigation label is inlined into the core/navigation-link `label`
attribute, so it never reaches the block tree and SourceBlockAttributeProjector
never stamps its projected marker classes. The author rules for the label were
already rewritten onto those markers, so the rewritten rule matched nothing and
menu labels rendered at user-agent defaults on the front end while looking
correct in the editor, which reads the separate editor-static-state projection.

Carry the markers on the serialization clone so the rewritten rules match.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016W6gpfFTSwSok5vMvLnd5L
…not save

core/details renders `<summary>` with no attributes, so a source toggle's own
classes are dropped and every author rule addressing them is left with nothing
to match. An overlay menu button loses its paint, its radius and its label
type, and drops to the destination theme's defaults.

Resolve the toggle's box once and restate it on a marker the details block
carries, following the navigation link icon projection. The label's type rides
along because it is inheritable and its own rules lost the same ancestor.

Delivered as CSS, not markup: attributes on <summary> would diverge from core's
save shape and invalidate the block.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016W6gpfFTSwSok5vMvLnd5L
core renders <summary> with no box, and the static-disclosure stylesheet only
makes it inline-block, so a toggle sized by the source collapses to fit its
label. Carry the box the source resolved on the toggle alongside its paint.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016W6gpfFTSwSok5vMvLnd5L
Fails on trunk for both surfaces: the navigation label carries no marker the
frontend stylesheet addresses, and the disclosure toggle emits no summary rule.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016W6gpfFTSwSok5vMvLnd5L
@chubes4
chubes4 merged commit e454c99 into trunk Sep 8, 2026
10 checks passed
@chubes4
chubes4 deleted the fix/menu-chrome-presentation branch September 8, 2026 12:06
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.

Menu chrome core rebuilds loses its source presentation

2 participants