Skip to content

Commit fcef283

Browse files
committed
Convert HTML spans to act like void blocks; there is no closer.
1 parent a0eb1c7 commit fcef283

2 files changed

Lines changed: 101 additions & 197 deletions

File tree

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

Lines changed: 18 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@
138138
*
139139
* These special block types can be passed into any method which searches for blocks.
140140
*
141+
* There is one additional special block type which may be returned from
142+
* {@see self::get_printable_block_type()}. This is the `#innerHTML` type, which
143+
* indicates that the HTML span on which the processor is paused is inner HTML for
144+
* a containing block.
145+
*
141146
* ### Spans of HTML
142147
*
143148
* Non-block content plays a complicated role in processing block documents. This
@@ -258,10 +263,6 @@
258263
* with a reimplementation of {@see static::get_attributes()}.
259264
*
260265
* @since 6.9.0
261-
* @todo Add optimized lookup for blocks of a known name
262-
* @todo is it necessary to have opening and closing HTML delimiters? or would one text node work?
263-
* @todo there will almost never be incomplete tokens, but we check on every step of tokenization.
264-
* Could we run a happy-path without checking and then perform a single verification at the end?
265266
*/
266267
class WP_Block_Processor {
267268
/**
@@ -456,8 +457,7 @@ class WP_Block_Processor {
456457
*
457458
* @see self::READY
458459
* @see self::MATCHED
459-
* @see self::HTML_OPEN
460-
* @see self::HTML_CLOSE
460+
* @see self::HTML_SPAN
461461
* @see self::INCOMPLETE_INPUT
462462
* @see self::COMPLETE
463463
*
@@ -745,11 +745,6 @@ public function next_token() {
745745
$this->was_void = false;
746746
}
747747

748-
if ( self::HTML_OPEN === $this->state ) {
749-
$this->state = self::HTML_CLOSE;
750-
return true;
751-
}
752-
753748
$text = $this->source_text;
754749
$end = strlen( $text );
755750

@@ -760,7 +755,7 @@ public function next_token() {
760755
* document it implies that a real delimiter was found; otherwise this must be the
761756
* terminating HTML span and the parsing is complete.
762757
*/
763-
if ( self::HTML_CLOSE === $this->state ) {
758+
if ( self::HTML_SPAN === $this->state ) {
764759
if ( $this->matched_delimiter_at >= $end ) {
765760
$this->state = self::COMPLETE;
766761
return false;
@@ -829,7 +824,7 @@ public function next_token() {
829824

830825
// Whether or not there is a potential delimiter, there might be an HTML span.
831826
if ( $after_prev_delimiter < ( $end - $backup ) ) {
832-
$this->state = self::HTML_OPEN;
827+
$this->state = self::HTML_SPAN;
833828
$this->after_previous_delimiter = $after_prev_delimiter;
834829
$this->matched_delimiter_at = $end - $backup;
835830
$this->matched_delimiter_length = $backup;
@@ -1101,7 +1096,7 @@ public function next_token() {
11011096

11021097
// HTML spans are visited before the delimiter that follows them.
11031098
if ( $comment_opening_at > $after_prev_delimiter ) {
1104-
$this->state = self::HTML_OPEN;
1099+
$this->state = self::HTML_SPAN;
11051100
$this->open_blocks_at[] = $after_prev_delimiter;
11061101
$this->open_blocks_length[] = 0;
11071102
$this->was_void = true;
@@ -1376,11 +1371,8 @@ public function get_last_json_error(): int {
13761371
*/
13771372
public function get_delimiter_type(): ?string {
13781373
switch ( $this->state ) {
1379-
case self::HTML_OPEN:
1380-
return self::OPENER;
1381-
1382-
case self::HTML_CLOSE:
1383-
return self::CLOSER;
1374+
case self::HTML_SPAN:
1375+
return self::VOID;
13841376

13851377
case self::MATCHED:
13861378
return $this->type;
@@ -1555,12 +1547,8 @@ public static function are_equal_block_types( $a_text, $a_at, $a_length, $b_text
15551547
* opens a block of one of the given block types, if provided.
15561548
*/
15571549
public function opens_block( string ...$block_type ): bool {
1558-
if ( self::HTML_CLOSE === $this->state ) {
1559-
return false;
1560-
}
1561-
15621550
// HTML spans only open implicit freeform content at the top level.
1563-
if ( self::HTML_OPEN === $this->state && 1 !== count( $this->open_blocks_at ) ) {
1551+
if ( self::HTML_SPAN === $this->state && 1 !== count( $this->open_blocks_at ) ) {
15641552
return false;
15651553
}
15661554

@@ -1597,10 +1585,7 @@ public function opens_block( string ...$block_type ): bool {
15971585
* @return bool Whether the scanner is matched on an HTML span.
15981586
*/
15991587
public function is_html(): bool {
1600-
return (
1601-
self::HTML_OPEN === $this->state ||
1602-
self::HTML_CLOSE === $this->state
1603-
);
1588+
return self::HTML_SPAN === $this->state;
16041589
}
16051590

16061591
/**
@@ -1650,11 +1635,6 @@ public function get_html_content_and_advance(): ?string {
16501635
return null;
16511636
}
16521637

1653-
// Finish on the (implicit) end of the HTML span.
1654-
if ( self::HTML_OPEN === $this->state ) {
1655-
$this->state = self::HTML_CLOSE;
1656-
}
1657-
16581638
return substr(
16591639
$this->source_text,
16601640
$this->after_previous_delimiter,
@@ -1764,7 +1744,9 @@ public function get_printable_block_type(): ?string {
17641744

17651745
// This is a core/freeform text block, it’s special.
17661746
if ( $this->is_html() ) {
1767-
return 'core/freeform';
1747+
return 1 === count( $this->open_blocks_at )
1748+
? 'core/freeform'
1749+
: '#innerHTML';
17681750
}
17691751

17701752
$block_type = substr( $this->source_text, $this->namespace_at, $this->name_at - $this->namespace_at + $this->name_length );
@@ -1895,8 +1877,7 @@ public function allocate_and_return_parsed_attributes(): ?array {
18951877
*/
18961878
public function get_span(): ?WP_HTML_Span {
18971879
switch ( $this->state ) {
1898-
case self::HTML_OPEN:
1899-
case self::HTML_CLOSE:
1880+
case self::HTML_SPAN:
19001881
return new WP_HTML_Span( $this->after_previous_delimiter, $this->matched_delimiter_at - $this->after_previous_delimiter );
19011882

19021883
case self::MATCHED:
@@ -1964,16 +1945,7 @@ public function get_span(): ?WP_HTML_Span {
19641945
*
19651946
* @since 6.9.0
19661947
*/
1967-
const HTML_OPEN = 'scanner-opening-freeform';
1968-
1969-
/**
1970-
* Indicates that the scanner is matched on the closing of an implicit freeform delimiter.
1971-
*
1972-
* @see self::$state
1973-
*
1974-
* @since 6.9.0
1975-
*/
1976-
const HTML_CLOSE = 'scanner-closing-freeform';
1948+
const HTML_SPAN = 'scanner-html-span';
19771949

19781950
/**
19791951
* Indicates that the parser started parsing a block comment delimiter, but

0 commit comments

Comments
 (0)