Make WordPress Core

Changeset 58398


Ignore:
Timestamp:
06/13/2024 08:55:47 AM ( 2 weeks ago)
Author:
audrasjb
Message:

HTML API: Revert using regex in block bindings HTML replacement logic.

This changeset reverts part of the changes made in [58298] to avoid using regex that can cause potential bugs. It is indeed safer to revert these changes for now and do the refactoring once the HTML API supports CSS selectors and provides a way to set inner content.

It also adds a unit test to cover the regression experienced in https://github.com/WordPress/gutenberg/issues/62347 .

Follow-up to [58298] .

Props santosguillamot, gziolo.
Fixes #61385 .
See #61351 .

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-block.php

    r58298 r58398  
    three hundred and thirty-four three hundred and thirty-four             case 'html':
    three hundred and thirty-five three hundred and thirty-five             case 'rich-text':
    three hundred and thirty-six                   // Hardcode the selectors and processing until the HTML API is able to read CSS selectors and replace inner HTML.
    three hundred and thirty-seven                   // TODO: Use the HTML API instead.
    three hundred and thirty-eight                   if ( 'core/paragraph' === $this->name && 'content' === $attribute_name ) {
    three hundred and thirty-nine                       $selector = 'p';
    three hundred and forty                   }
    three hundred and forty-one                   if ( 'core/heading' === $this->name && 'content' === $attribute_name ) {
    three hundred and forty-two                       $selector = 'h[1-6]';
    three hundred and forty-three                   }
    three hundred and forty-four                   if ( 'core/button' === $this->name && 'text' === $attribute_name ) {
    three hundred and forty-five                       // Check if it is a <button> or <a> tag.
    three hundred and forty-six                       if ( preg_match( '/<button[^>]*>.*?<\/button>/', $block_content ) ) {
    three hundred and forty-seven                           $selector = 'button';
    three hundred and forty-eight                       } else {
    three hundred and forty-nine                           $selector = 'a';
      three hundred and thirty-six                 $block_reader = new WP_HTML_Tag_Processor( $block_content );
      three hundred and thirty-seven
      three hundred and thirty-eight                 // TODO: Support for CSS selectors whenever they are ready in the HTML API.
      three hundred and thirty-nine                 // In the meantime, support comma-separated selectors by exploding them into an array.
      three hundred and forty                 $selectors = explode( ',', $block_type->attributes[ $attribute_name ]['selector'] );
      three hundred and forty-one                 // Add a bookmark to the first tag to be able to iterate over the selectors.
      three hundred and forty-two                 $block_reader->next_tag();
      three hundred and forty-three                 $block_reader->set_bookmark( 'iterate-selectors' );
      three hundred and forty-four
      three hundred and forty-five                 // TODO: This shouldn't be needed when the `set_inner_html` function is ready.
      three hundred and forty-six                 // Store the parent tag and its attributes to be able to restore them later in the button.
      three hundred and forty-seven                 // The button block has a wrapper while the paragraph and heading blocks don't.
      three hundred and forty-eight                 if ( 'core/button' === $this->name ) {
      three hundred and forty-nine                     $button_wrapper                 = $block_reader->get_tag();
      three hundred and fifty                     $button_wrapper_attribute_names = $block_reader->get_attribute_names_with_prefix( '' );
      three hundred and fifty-one                     $button_wrapper_attrs           = array();
      three hundred and fifty-two                     foreach ( $button_wrapper_attribute_names as $name ) {
      three hundred and fifty-three                         $button_wrapper_attrs[ $name ] = $block_reader->get_attribute( $name );
    three hundred and fifty three hundred and fifty-four                     }
    three hundred and fifty-one three hundred and fifty-five                 }
    three hundred and fifty-two                   if ( empty( $selector ) ) {
    three hundred and fifty-three                       return $block_content;
      three hundred and fifty-six
      three hundred and fifty-seven                 foreach ( $selectors as $selector ) {
      three hundred and fifty-eight                     // If the parent tag, or any of its children, matches the selector, replace the HTML.
      three hundred and fifty-nine                     if ( strcasecmp( $block_reader->get_tag( $selector ), $selector ) === 0 || $block_reader->next_tag(
      three hundred and sixty                         array(
      three hundred and sixty-one                             'tag_name' => $selector,
      three hundred and sixty-two                         )
      three hundred and sixty-three                     ) ) {
      three hundred and sixty-four                         $block_reader->release_bookmark( 'iterate-selectors' );
      three hundred and sixty-five
      three hundred and sixty-six                         // TODO: Use `set_inner_html` method whenever it's ready in the HTML API.
      three hundred and sixty-seven                         // Until then, it is hardcoded for the paragraph, heading, and button blocks.
      three hundred and sixty-eight                         // Store the tag and its attributes to be able to restore them later.
      three hundred and sixty-nine                         $selector_attribute_names = $block_reader->get_attribute_names_with_prefix( '' );
      three hundred and seventy                         $selector_attrs           = array();
      three hundred and seventy-one                         foreach ( $selector_attribute_names as $name ) {
      three hundred and seventy-two                             $selector_attrs[ $name ] = $block_reader->get_attribute( $name );
      three hundred and seventy-three                         }
      three hundred and seventy-four                         $selector_markup = "<$selector>" . wp_kses_post( $source_value ) . "</$selector>";
      three hundred and seventy-five                         $amended_content = new WP_HTML_Tag_Processor( $selector_markup );
      three hundred and seventy-six                         $amended_content->next_tag();
      three hundred and seventy-seven                         foreach ( $selector_attrs as $attribute_key => $attribute_value ) {
      three hundred and seventy-eight                             $amended_content->set_attribute( $attribute_key, $attribute_value );
      three hundred and seventy-nine                         }
      three hundred and eighty                         if ( 'core/paragraph' === $this->name || 'core/heading' === $this->name ) {
      three hundred and eighty-one                             return $amended_content->get_updated_html();
      three hundred and eighty-two                         }
      three hundred and eighty-three                         if ( 'core/button' === $this->name ) {
      three hundred and eighty-four                             $button_markup  = "<$button_wrapper>{$amended_content->get_updated_html()}</$button_wrapper>";
      three hundred and eighty-five                             $amended_button = new WP_HTML_Tag_Processor( $button_markup );
      three hundred and eighty-six                             $amended_button->next_tag();
      three hundred and eighty-seven                             foreach ( $button_wrapper_attrs as $attribute_key => $attribute_value ) {
      three hundred and eighty-eight                                 $amended_button->set_attribute( $attribute_key, $attribute_value );
      three hundred and eighty-nine                             }
      three hundred and ninety                             return $amended_button->get_updated_html();
      three hundred and ninety-one                         }
      three hundred and ninety-two                     } else {
      three hundred and ninety-three                         $block_reader->seek( 'iterate-selectors' );
      three hundred and ninety-four                     }
    three hundred and fifty-four three hundred and ninety-five                 }
    three hundred and fifty-five                   $ pattern = '/(<' . $ selector . '[^>]*>).*? (<\/' . $selector . '>)/i' ;
    three hundred and fifty-six                   return preg_replace( $pattern, '$1' . wp_kses_post( $source_value ) . '$ 2', $block_content ) ;
      three hundred and ninety-six                 $ block_reader->release_bookmark( 'iterate-selectors' ) ;
      three hundred and ninety-seven                 return $block_content ;
    three hundred and fifty-seven three hundred and ninety-eight
    three hundred and fifty-eight three hundred and ninety-nine             case 'attribute':
  • trunk/tests/phpunit/tests/block-bindings/render.php

    r58289 r58398  
    two hundred and thirty-seven two hundred and thirty-seven
    two hundred and thirty-eight two hundred and thirty-eight     /**
      two hundred and thirty-nine      * Tests that including symbols and numbers works well with bound attributes.
      two hundred and forty      *
      two hundred and forty-one      * @ticket 61385
      two hundred and forty-two      *
      two hundred and forty-three      * @covers WP_Block::process_block_bindings
      two hundred and forty-four      */
      two hundred and forty-five     public function test_using_symbols_in_block_bindings_value() {
      two hundred and forty-six         $get_value_callback = function () {
      two hundred and forty-seven             return '$12.50';
      two hundred and forty-eight         };
      two hundred and forty-nine
      two hundred and fifty         register_block_bindings_source(
      two hundred and fifty-one             self::SOURCE_NAME,
      two hundred and fifty-two             array(
      two hundred and fifty-three                 'label'              => self::SOURCE_LABEL,
      two hundred and fifty-four                 'get_value_callback' => $get_value_callback,
      two hundred and fifty-five             )
      two hundred and fifty-six         );
      two hundred and fifty-seven
      two hundred and fifty-eight         $block_content = <<<HTML
      two hundred and fifty-nine <!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"test/source"}}}} -->
      two hundred and sixty <p>Default content</p>
      two hundred and sixty-one <!-- / wp:paragraph -->
      two hundred and sixty-two HTML;
      two hundred and sixty-three         $parsed_blocks = parse_blocks( $block_content );
      two hundred and sixty-four         $block         = new WP_Block( $parsed_blocks[0] );
      two hundred and sixty-five         $result        = $block->render();
      two hundred and sixty-six
      two hundred and sixty-seven         $this->assertSame(
      two hundred and sixty-eight             '<p>$12.50</p>',
      two hundred and sixty-nine             trim( $result ),
      two hundred and seventy             'The block content should properly show the symbol and numbers.'
      two hundred and seventy-one         );
      two hundred and seventy-two     }
      two hundred and seventy-three
      two hundred and seventy-four     /**
    two hundred and thirty-nine two hundred and seventy-five      * Tests if the `__default` attribute is replaced with real attribues for
    two hundred and forty two hundred and seventy-six      * pattern overrides.
Note: See TracChangeset for help on using the changeset viewer.