@@ -294,9 +294,9 @@ public function __get( $name ) {
294294 * @return array The computed block attributes for the provided block bindings.
295295 */
296296 private function process_block_bindings () {
297- $ block_type = $ this ->name ;
298- $ parsed_block = $ this ->parsed_block ;
299- $ computed_attributes = array ();
297+ $ block_type = $ this ->name ;
298+ $ parsed_block = $ this ->parsed_block ;
299+ $ computed_attributes = array ();
300300
301301 $ supported_block_attributes =
302302 self ::BLOCK_BINDINGS_SUPPORTED_ATTRIBUTES [ $ block_type ] ??
@@ -417,7 +417,7 @@ private function replace_html( string $block_content, string $attribute_name, $s
417417 switch ( $ block_type ->attributes [ $ attribute_name ]['source ' ] ) {
418418 case 'html ' :
419419 case 'rich-text ' :
420- $ block_reader = WP_Block_Bindings_Processor:: create_fragment ( $ block_content );
420+ $ block_reader = self :: get_block_bindings_processor ( $ block_content );
421421
422422 // TODO: Support for CSS selectors whenever they are ready in the HTML API.
423423 // In the meantime, support comma-separated selectors by exploding them into an array.
@@ -462,6 +462,56 @@ private function replace_html( string $block_content, string $attribute_name, $s
462462 }
463463 }
464464
465+ private static function get_block_bindings_processor ( string $ block_content ) {
466+ static $ internal_processor_class = null ;
467+ if ( null === $ internal_processor_class ) {
468+ $ internal_processor_class = new class ('' , WP_HTML_Processor::CONSTRUCTOR_UNLOCK_CODE ) extends WP_HTML_Processor {
469+ private $ output = '' ;
470+ private $ end_of_flushed = 0 ;
471+
472+ public function build () {
473+ return $ this ->output . substr ( $ this ->get_updated_html (), $ this ->end_of_flushed );
474+ }
475+
476+ /**
477+ * Replace the rich text content between a tag opener and matching closer.
478+ *
479+ * When stopped on a tag opener, replace the content enclosed by it and its
480+ * matching closer with the provided rich text.
481+ *
482+ * @param string $rich_text The rich text to replace the original content with.
483+ * @return bool True on success.
484+ */
485+ public function replace_rich_text ( $ rich_text ) {
486+ if ( $ this ->is_tag_closer () ) {
487+ return false ;
488+ }
489+
490+ $ depth = $ this ->get_current_depth ();
491+
492+ $ this ->set_bookmark ( '_wp_block_bindings_tag_opener ' );
493+ // The bookmark names are prefixed with `_` so the key below has an extra `_`.
494+ $ bm = $ this ->bookmarks ['__wp_block_bindings_tag_opener ' ];
495+ $ this ->output .= substr ( $ this ->get_updated_html (), $ this ->end_of_flushed , $ bm ->start + $ bm ->length );
496+ $ this ->output .= $ rich_text ;
497+ $ this ->release_bookmark ( '_wp_block_bindings_tag_opener ' );
498+
499+ // Find matching tag closer.
500+ while ( $ this ->next_token () && $ this ->get_current_depth () >= $ depth ) {
501+ }
502+
503+ $ this ->set_bookmark ( '_wp_block_bindings_tag_closer ' );
504+ $ bm = $ this ->bookmarks ['__wp_block_bindings_tag_closer ' ];
505+ $ this ->end_of_flushed = $ bm ->start ;
506+ $ this ->release_bookmark ( '_wp_block_bindings_tag_closer ' );
507+
508+ return true ;
509+ }
510+ };
511+ }
512+
513+ return $ internal_processor_class ::create_fragment ( $ block_content );
514+ }
465515
466516 /**
467517 * Generates the render output for the block.
0 commit comments