Repository navigation
fix(php-transformer): keep the source panel box on a projected modal dialog - #2744
Merged
Merged
Conversation
…dialog A captured phone menu panel is held twice: the capture's hidden wired copy keeps the panel's id, and the captured state becomes the native dialog under a generated id. On a Wix phone menu that lost two things: - Author rules that name the panel by id (its left offset, width and the --bg-overlay-color its background layer paints with) reached only the hidden copy. The dialog now carries the held id as its editor anchor class, and the author stylesheet projector keeps those id selectors live through that class, as it already does for document variant ids. - The dialog kept the user agent's box geometry (1em padding, a border, auto margins, insets and size caps), which the source div never had. A modal whose source panel positions itself (position fixed or absolute from its own rules) is now marked placement "source", and the block stylesheet resets that geometry under zero-specificity rules so the source rules place it. Canvas paint stays as the backdrop for the panel's own layers. Refs #2726 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ellenbauer
force-pushed
the
fix/projected-dialog-source-box
branch
from
October 13, 2026 16:42
94083dc to
85ee265
Compare
chubes4
marked this pull request as ready for review
October 13, 2026 22:45
# Conflicts: # php-transformer/tools/capture-evidence-equivalence/README.md
# Conflicts: # php-transformer/tools/capture-evidence-equivalence/README.md
This was referenced Oct 14, 2026
ellenbauer
added a commit
that referenced
this pull request
Oct 14, 2026
…#2783) * fix(php-transformer): open a projected modal in its source open state Review of #2744 found that a projected captured modal could still open invisible or keep the browser's dialog box: - Id rules never matched the dialog during analysis. Its id is generated and the source panel id rides on its editor anchor class, so placement "source" missed a panel positioned only by id rules. The selector matcher and both candidate indexes now treat an element carrying an id's editor anchor class as that id's holder. - A rest rule that hides the panel (by id or by class) made the dialog hidden content and the dialog block was dropped. A captured dialog's own rest state no longer counts as hidden; the block owns its closed state. - Without a captured ancestor state, the rest rule won on the open dialog (`#panel{display:none;transform:translateX(-100%)}` against `body.nav-open #panel{display:block;transform:none}`). For each hiding or offsetting property that a state rule on the same panel reverses, the dialog now carries the state value inline. The block stylesheet's important closed-state rule still closes it. Refs #2726 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(php-transformer): trust only agreeing or recorded state rules for a modal's open values Review of c0b3e89: - The last state rule in source order won: `.dark-theme #panel{opacity:.5}` after `body.nav-open #panel{opacity:1}` gave the dialog `opacity:.5`, and `.no-js #panel{display:block}` replaced `display:flex`. When the capture recorded an opened ancestor class, only state rules naming it are trusted; otherwise every state rule must agree on a property, or nothing is carried. - A centring `translate(-50%,-50%)` counted as a rest offset, so `.no-js #panel{transform:none}` un-centred a modal that was fine on trunk. Only a translation of a full panel (100%) or viewport (100vw, 100vh) or more now counts as moving the panel out of view. - A dialog none of whose triggers can ever show (no viewport shows the trigger or an ancestor) is dropped again instead of surviving as an orphaned closed dialog. Refs #2726 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.
Refs #2726
What was wrong
With #2719 and #2720, the Dunbar Oaks (Wix) phone menu opens, but the panel is white instead of the source's beige and its column sits about 14px right of the source. Both come from the projected dialog's own box, not from the navigation.
The menu panel
#MENU_AS_CONTAINERis held twice in the compiled page. The capture's hidden wired copy (#dla-dialog-0 > #MENU_AS_CONTAINER) keeps the panel's id. The captured open state becomes the native<dialog>under a generated id (blocks-engine-dialog-<hash>), because the id is already taken. Two things follow:#MENU_AS_CONTAINER{left:calc(50% - 160px);width:320px;--bg-overlay-color:rgb(var(--color_32))}. The background layer inside paints with.LNYVZi{background-color:var(--bg-overlay-color)}. Class rules on the panel already reach the dialog (the projector binds both elements), but these id rules reach only the hidden copy. The dialog had no offset and no paint variable.div, so it never had the user agent's dialog box: 1em padding, a 3px solid border, Canvas (white) paint, auto margins, insets and size caps. On the dialog these pushed the content 13px in and drew a white, black-framed box. The block stylesheet already resets that box for in-place dropdowns, but not for modals.What changed
CapturedDialogProjector: when another element still holds the captured root's id, the dialog carries it as its editor anchor class (blocks-engine-editor-anchor-MENU_AS_CONTAINER). The capture's own panel envelope (data-blocks-engine-capture-dialog-panel) does not count, because its id is the wiring key.ScopedAnchorSelectorProjection::identities(): an id that a source element carries as its editor anchor class is projected as:is(#id,.blocks-engine-editor-anchor-id). This is the mechanism already used to keep id selectors live across document variant id suffixes. The specificity shims are unchanged, so the rule keeps its source weight.CapturedDialogConverter: a modal whose own author rules position it (position:fixedorabsolute) getsplacement: "source". The cascade is resolved through the compilation'sStyleResolver.CapturedDialogBlockGenerator::where(dialog:not([data-blocks-engine-presentation])[data-blocks-engine-placement="source"])resetsinset, size caps, margin, padding, border, background and color. It has zero specificity, so every source rule still wins. Modals that do not position themselves keep the user agent box, which is their only placement.These are two causes in one PR because neither alone puts the column where the source has it: the offset needs both the id rule (
left,width) and the box reset.Tests
tests/unit/captured-dialog-source-panel-box.php, 5 assertions (projector, compiled CSS, block placement, stylesheet). On trunk, 4 fail; all pass here.capture-evidence-equivalence: the 12 native dialog cases are re-recorded and noted in its README. Only the emittedstyle.csstext and the hashes derived from it change (7a7af898also gains one style-rule cache hit). Checked by replaying each case on trunk and on this branch and diffing the normalized output.End to end
Studio imports of the Dunbar Oaks capture with v0.38.1 (the last base that reads these captures), iPhone user agent at 375. Quality gate passed on both.
rgb(233, 220, 211)as in the source.composer test(memory_limit -1) passed.🤖 Generated with Claude Code