Emit canonical empty save for dynamic nav blocks (fix editor_block_invalid)#340
Merged
Merged
Conversation
…e/navigation family
The navigation family (core/navigation, core/navigation-link,
core/navigation-submenu) are dynamic, server-rendered blocks: supports.html
is false and each registers a render_callback, so their save() returns null.
WordPress stores only the block comment delimiters plus serialized inner
blocks; the <nav>/<ul>/<li> chrome is produced at render time.
BlockFactory was emitting that static <nav><ul> / <li><a><span> chrome into
the stored block. Because save() returns null, wp.blocks.validateBlock re-runs
save() (empty), sees the leftover tags, and flags every navigation block
invalid in the editor ("Expected end of content, instead saw StartTag nav/li").
This was the dominant editor_block_invalid residual surfaced by the offloaded
SSI fixture-matrix gate (navigation/navigation-link were the entire invalid set
in the populated gate artifact; 14 of the cited 21 on 15-saas, 12 of 14 on
38-medical-clinic by direct transform). The label/url/className ride in the
block comment attributes, so the canonical save()-matching shape carries no
inner HTML at all.
- BlockFactory: navigation and navigation-submenu serialize as empty
opening/closing (inner blocks only); navigation-link serializes as the
self-closing block comment. Drop the now-dead anchor/submenu markup helpers.
- BlockValidityValidator: add DYNAMIC_EMPTY_SAVE_BLOCKS + the
dynamic_block_static_markup finding so the fast pure-PHP loop catches any
future regression that emits static markup for these blocks, off the editor
gate. Remove the obsolete static-markup link-text check for the nav family.
- RuntimeDependencyParityReport: recognize block-comment anchor/className as
preserved DOM targets. Anchor and className supports render those onto the
wrapper at runtime, so a first-party script targeting #id/.class keeps working
even though the dynamic block now stores no static id=/class= attributes.
- MaterializationPlanBuilder: read navigation links from the canonical
navigation-link/navigation-submenu block comments (label/url), keeping the
static <nav><a> scan as a fallback for non-converting navs.
- Update parity + contract fixtures to the canonical block-comment shape,
adding not_contains guards proving the editor-invalid static chrome is gone
and a fast-loop case proving clean static <li> markup is now flagged.
Co-Authored-By: Claude Opus 4.8 (1M context) <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.
What
Fixes the editor block-validity residual the offloaded gate surfaced: both content fixtures failed on editor-invalid blocks (15-saas 14, 38-medical 12) — 100% the navigation family.
core/navigation/-link/-submenuare DYNAMIC blocks (supports.html:false,save()returns null), butBlockFactorywas storing static<nav><ul><li><a><span>chrome →wp.blocks.validateBlockre-runs save (empty), sees leftover tags → every nav block invalid (Expectedendofcontent,insteadsawStartTagnav).Fix
BlockFactory.php: nav family emits canonical empty save markup (innernavigation-linkblocks / self-closing comment only); label/url/className ride in the block-comment attrs.BlockValidityValidator.php: addedDYNAMIC_EMPTY_SAVE_BLOCKS+dynamic_block_static_markupfinding so the fast pure-PHP loop catches static-markup-on-dynamic-block regressions off the editor gate.RuntimeDependencyParityReport.php: recognizes block-commentanchor/classNameas preserved DOM targets (rendered at runtime), keeping script-target parity honest now that nav stores no static id/class.MaterializationPlanBuilder.php: reads nav links from the canonicalnavigation-linkcomments (static<nav><a>scan kept as fallback).Verification
composer test+composer parity: 173 fixtures green; fixtures updated to canonical shape with not_contains guards (static chrome gone) + a fast-loop case proving static<li>is now flagged. Assertions strengthened.AI assistance