Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 0 additions & 70 deletions src/wp-includes/class-wp-block-bindings-processor.php

This file was deleted.

58 changes: 54 additions & 4 deletions src/wp-includes/class-wp-block.php
Original file line number Diff line number Diff line change
Expand Up @@ -294,9 +294,9 @@ public function __get( $name ) {
* @return array The computed block attributes for the provided block bindings.
*/
private function process_block_bindings() {
$block_type = $this->name;
$parsed_block = $this->parsed_block;
$computed_attributes = array();
$block_type = $this->name;
$parsed_block = $this->parsed_block;
$computed_attributes = array();

$supported_block_attributes =
self::BLOCK_BINDINGS_SUPPORTED_ATTRIBUTES[ $block_type ] ??
Expand Down Expand Up @@ -417,7 +417,7 @@ private function replace_html( string $block_content, string $attribute_name, $s
switch ( $block_type->attributes[ $attribute_name ]['source'] ) {
case 'html':
case 'rich-text':
$block_reader = WP_Block_Bindings_Processor::create_fragment( $block_content );
$block_reader = self::get_block_bindings_processor( $block_content );

// TODO: Support for CSS selectors whenever they are ready in the HTML API.
// In the meantime, support comma-separated selectors by exploding them into an array.
Expand Down Expand Up @@ -462,6 +462,56 @@ private function replace_html( string $block_content, string $attribute_name, $s
}
}

private static function get_block_bindings_processor( string $block_content ) {
static $internal_processor_class = null;

@dmsnell dmsnell Aug 25, 2025

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m assuming this was done as an optimization; if so, it’s pointless because anonymous classes are static in PHP anyway. At parse time it will create a separate class with a generated name and then when instantiating it or calling a static method on it, PHP calls from the generated class instead of some dynamic variable dispatch as the code suggests.

<?php

$c = new class () {
    public function speak() { return __CLASS__; }
    public static function name() { return __CLASS__; }
};

echo $c->speak() . PHP_EOL;
echo $c::name() . PHP_EOL;
class@anonymous/in/1H8Jo:3$0
class@anonymous/in/1H8Jo:3$0
VLD output
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/1H8Jo
function name:  (null)
number of ops:  14
compiled vars:  !0 = $c
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
    3     0  E >   DECLARE_ANON_CLASS                                
          1        NEW                                              $2      $1
          2        DO_FCALL                                      0          
          3        ASSIGN                                                   !0, $2
    8     4        INIT_METHOD_CALL                                         !0, 'speak'
          5        DO_FCALL                                      0  $5      
          6        CONCAT                                           ~6      $5, '%0A'
          7        ECHO                                                     ~6
    9     8        FETCH_CLASS                                   0  $7      !0
          9        INIT_STATIC_METHOD_CALL                                  $7, 'name'
         10        DO_FCALL                                      0  $8      
         11        CONCAT                                           ~9      $8, '%0A'
         12        ECHO                                                     ~9
   10    13      > RETURN                                                   1

Class class@anonymous:
Function speak:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename: /in/1H8Jo
function name: speak
number of ops: 2
compiled vars: none
line #* E I O op fetch ext return operands

4     0  E > > RETURN                                                   'class%40anonymous%00%2Fin%2F1H8Jo%3A3%240'
      1*     > RETURN                                                   null

End of function speak

Function name:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename: /in/1H8Jo
function name: name
number of ops: 2
compiled vars: none
line #* E I O op fetch ext return operands

5     0  E > > RETURN                                                   'class%40anonymous%00%2Fin%2F1H8Jo%3A3%240'
      1*     > RETURN                                                   null

End of function name

End of class class@anonymous.

so assigning it to a static variable does nothing but duplicate it.

if ( null === $internal_processor_class ) {
$internal_processor_class = new class('', WP_HTML_Processor::CONSTRUCTOR_UNLOCK_CODE) extends WP_HTML_Processor {
private $output = '';
private $end_of_flushed = 0;

public function build() {
return $this->output . substr( $this->get_updated_html(), $this->end_of_flushed );
}

/**
* Replace the rich text content between a tag opener and matching closer.
*
* When stopped on a tag opener, replace the content enclosed by it and its
* matching closer with the provided rich text.
*
* @param string $rich_text The rich text to replace the original content with.
* @return bool True on success.
*/
public function replace_rich_text( $rich_text ) {
if ( $this->is_tag_closer() ) {
return false;
}

$depth = $this->get_current_depth();

$this->set_bookmark( '_wp_block_bindings_tag_opener' );
// The bookmark names are prefixed with `_` so the key below has an extra `_`.
$bm = $this->bookmarks['__wp_block_bindings_tag_opener'];
$this->output .= substr( $this->get_updated_html(), $this->end_of_flushed, $bm->start + $bm->length );
$this->output .= $rich_text;
$this->release_bookmark( '_wp_block_bindings_tag_opener' );

// Find matching tag closer.
while ( $this->next_token() && $this->get_current_depth() >= $depth ) {
}

$this->set_bookmark( '_wp_block_bindings_tag_closer' );
$bm = $this->bookmarks['__wp_block_bindings_tag_closer'];
$this->end_of_flushed = $bm->start;
$this->release_bookmark( '_wp_block_bindings_tag_closer' );

return true;
}
};
}

return $internal_processor_class::create_fragment( $block_content );
}

/**
* Generates the render output for the block.
Expand Down
1 change: 0 additions & 1 deletion src/wp-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,6 @@
require ABSPATH . WPINC . '/sitemaps/providers/class-wp-sitemaps-posts.php';
require ABSPATH . WPINC . '/sitemaps/providers/class-wp-sitemaps-taxonomies.php';
require ABSPATH . WPINC . '/sitemaps/providers/class-wp-sitemaps-users.php';
require ABSPATH . WPINC . '/class-wp-block-bindings-processor.php';
require ABSPATH . WPINC . '/class-wp-block-bindings-source.php';
require ABSPATH . WPINC . '/class-wp-block-bindings-registry.php';
require ABSPATH . WPINC . '/class-wp-block-editor-context.php';
Expand Down