Skip to content

Commit c178d11

Browse files
committed
Block Processor: Fix is_block_type() for inner HTML
Previously, the WP_Block_Processor class was making a mistake in mis-reporting whether a token matches a block type when #innerHTML spans are involved. This patch fixes the logic, which was originally written before a distinction between inner HTML and top-level freeform content was built. Developed in #10701 Discussed in https://core.trac.wordpress.org/ticket/64485 Fixes #64485. git-svn-id: https://develop.svn.wordpress.org/trunk@61452 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 5a53b94 commit c178d11

2 files changed

Lines changed: 110 additions & 6 deletions

File tree

src/wp-includes/class-wp-block-processor.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,12 +1440,17 @@ public function is_block_type( string $block_type ): bool {
14401440
return true;
14411441
}
14421442

1443-
// This is a core/freeform text block, it’s special.
1444-
if ( $this->is_html() && 0 === ( $this->open_blocks_length[0] ?? null ) ) {
1445-
return (
1446-
'core/freeform' === $block_type ||
1447-
'freeform' === $block_type
1448-
);
1443+
if ( $this->is_html() ) {
1444+
// This is a core/freeform text block, it’s special.
1445+
if ( 0 === ( $this->open_blocks_length[0] ?? null ) ) {
1446+
return (
1447+
'core/freeform' === $block_type ||
1448+
'freeform' === $block_type
1449+
);
1450+
}
1451+
1452+
// Otherwise this is innerHTML and not a block.
1453+
return false;
14491454
}
14501455

14511456
return $this->are_equal_block_types( $this->source_text, $this->namespace_at, $this->name_at - $this->namespace_at + $this->name_length, $block_type, 0, strlen( $block_type ) );

tests/phpunit/tests/block-processor/wpBlockProcessor.php

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,46 @@ public function test_reports_if_block_is_of_type( $html, $block_type ) {
747747
}
748748
}
749749

750+
/**
751+
* Verifies that innerHTML only matches as a block type when checking with the wildcard '*'.
752+
*
753+
* @ticket 64485
754+
*
755+
* @covers ::is_block_type()
756+
*/
757+
public function test_inner_html_is_only_a_block_type_match_with_the_wildcard() {
758+
$processor = new WP_Block_Processor( '0<!-- wp:b1 -->1<!-- wp:b2 -->' );
759+
760+
$processor->next_token();
761+
$this->assertTrue(
762+
$processor->is_block_type( 'freeform' ),
763+
'Failed to detect top-level freeform HTML as freeform block: check test setup.'
764+
);
765+
766+
$processor->next_token();
767+
$this->assertTrue(
768+
$processor->is_block_type( 'b1' ),
769+
'Failed to detect opening delimiter as b1 block type: check test setup.'
770+
);
771+
772+
$processor->next_token();
773+
$this->assertFalse(
774+
(
775+
$processor->is_block_type( 'freeform' ) ||
776+
$processor->is_block_type( 'b1' ) ||
777+
$processor->is_block_type( 'core/freeform' ) ||
778+
$processor->is_block_type( 'core/b1' ) ||
779+
$processor->is_block_type( '' )
780+
),
781+
'Failed to reject innerHTML as a matched block type.'
782+
);
783+
784+
$this->assertTrue(
785+
$processor->is_block_type( '*' ),
786+
'Failed to accept innerHTML as a wildcard block-type match.'
787+
);
788+
}
789+
750790
/**
751791
* Verifies that the processor indicates if the currently-matched delimiter
752792
* opens a block of a given block type. This is true for openers and void delimiters.
@@ -1211,6 +1251,65 @@ public static function data_content_and_delimiter_spans() {
12111251
);
12121252
}
12131253

1254+
/**
1255+
* Verifies that next_block( $block_type ) scans directly to the appropriate tokens.
1256+
*
1257+
* @ticket 64485
1258+
*
1259+
* @dataProvider data_markup_with_block_of_given_type
1260+
*
1261+
* @param string $html Contains block markup, including the tested block type.
1262+
* @param string $block_type Jump to this block type.
1263+
*/
1264+
public function test_scans_directly_to_requested_block_type( string $html, string $block_type ) {
1265+
$processor = new WP_Block_Processor( $html );
1266+
1267+
$this->assertTrue(
1268+
$processor->next_block( $block_type ),
1269+
'Failed to find block of requested type.'
1270+
);
1271+
1272+
$full_block_type = WP_Block_Processor::normalize_block_type( $block_type );
1273+
1274+
if ( 'core/freeform' === $full_block_type ) {
1275+
$this->assertTrue(
1276+
$processor->is_html(),
1277+
'Failed to match on HTML token when looking for freeform content.'
1278+
);
1279+
1280+
$this->assertSame(
1281+
0,
1282+
$processor->get_depth(),
1283+
'Failed to scan to top-level freeform content when searching for freeform.'
1284+
);
1285+
} else {
1286+
$this->assertFalse(
1287+
$processor->is_html(),
1288+
'Matched on HTML token when looking for block delimiter.'
1289+
);
1290+
}
1291+
1292+
$this->assertSame(
1293+
$full_block_type,
1294+
$processor->get_printable_block_type(),
1295+
'Scanned to token of wrong block type.'
1296+
);
1297+
}
1298+
1299+
/**
1300+
* Data provider.
1301+
*
1302+
* @return array[]
1303+
*/
1304+
public static function data_markup_with_block_of_given_type() {
1305+
return array(
1306+
'At start of HTML' => array( '<!-- wp:target -->', 'target' ),
1307+
'After freeform text' => array( 'prefix<!-- wp:target -->', 'target' ),
1308+
'After outer block' => array( 'prefix<!-- wp:group --><!-- wp:target -->', 'target' ),
1309+
'After innerHTML' => array( 'prefix<!-- wp:group -->inner<!-- wp:target -->', 'target' ),
1310+
);
1311+
}
1312+
12141313
//
12151314
// Test helpers.
12161315
//

0 commit comments

Comments
 (0)