Block Bindings: Preserve nested lists when binding List Item content#78991
Draft
cbravobernal wants to merge 10 commits into
Draft
Block Bindings: Preserve nested lists when binding List Item content#78991cbravobernal wants to merge 10 commits into
cbravobernal wants to merge 10 commits into
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Unlinked AccountsThe following contributors have not linked their GitHub and WordPress.org accounts: @sauliusv@git.wordpress.org. Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases. If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
6bcecfa to
dab2d81
Compare
Add server-side rendering support so a bound `core/list-item` content attribute is replaced without dropping nested List inner blocks rendered inside the same `<li>`. All logic lives in the wordpress-7.1 compat layer: a `render_block_data` filter hides the binding from Core's generic rich-text replacement, and a `render_block` filter resolves the value through the existing `gutenberg_process_block_bindings()` helper and applies it with a nested-list-aware replacement. The shipped wordpress-6.9 block-bindings code is left untouched and no new hooks are introduced. Adds PHPUnit coverage (plain text, nested/ordered/deep lists, empty value, pattern overrides, sanitization, non-list inner blocks) and an editor e2e test. Builds on WordPress#78947 (list-item block bindings support). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The compat code in this PR is a plugin-only shim that preserves nested lists when binding list item content. It is not backported to Core: the Core fix is a different, general implementation in WordPress/wordpress-develop#12113, after which this workaround can be removed. Classify the PR with the `No Core Sync Required` label instead of a backport-changelog entry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extend the locked List Item case to assert the Link control is hidden alongside Bold; since `contenteditable=false` disables the whole rich text, these stand in for every inline format. Add a List Item test for an unregistered binding source: editing is locked and the "Source not registered" warning is surfaced. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
d4ae1c6 to
85e57e3
Compare
The WP_Block_Processor scan re-derived what the parser already provides: serialize_block() concatenates innerContent chunks verbatim, so the HTML before the first inner block is exactly innerContent[0] on every WordPress version. Reading it directly drops the redundant scan, which could also cut early on raw text resembling a block delimiter. Also remove the unreachable ReflectionException handling: method_exists() already guarantees the method exists before reflection. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Verifies the editor canvas and the front end both render the bound value while preserving nested list inner blocks, complementing the existing locking and post-meta editing coverage. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Make SOURCE_LABEL a plain string (the registered label was a nested array) and point the list item render tests' covers annotations at WP_Block::render, which is what they exercise. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add a marker above the inner-blocks preservation workaround noting the whole block can be removed once the minimum required WordPress version includes the WP_Block::replace_html() fix (wordpress-develop#12113). Detection is runtime, so the workaround is already inert on fixed Core.
The non-nested List Item binding tests (plain text, sanitization, inline image) exercise only the enablement filter and now live in WordPress#78947. Keep here the cases that depend on the inner-block preservation workaround: nested lists, ordered and deeply nested lists, empty values, non-list inner blocks and pattern overrides.
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.
Part of the List Item block bindings work, split for review hygiene into two PRs (mirroring the Core split on Trac #65406):
core/list-itemcontentas a bindable attribute (theblock_bindings_supported_attributesfilter). The filter PR. Lands first.<li>, and the generic binding replacement would drop the nested list. This adds a Gutenberg-side workaround that preserves the nested inner blocks.Relationship to Core
This is the plugin compat counterpart of the Core fix:
WP_Block::replace_html()inner-blocks preservation (the real fix).core/list-itemenablement in Core.The workaround here is runtime-gated:
gutenberg_core_preserves_inner_blocks_in_rich_text_block_bindings()detects whether Core already has the fix (4th param onreplace_html()). On fixed Core the workaround is inert and Core handles the binding. A marker comment flags the whole block for removal once the minimum required WordPress version ships the Core fix.