Skip to content

Commit 3985596

Browse files
committed
Allow handling of non-attribute lexical updates
1 parent cfb54a7 commit 3985596

1 file changed

Lines changed: 59 additions & 23 deletions

File tree

lib/compat/wordpress-6.3/html-api/class-gutenberg-html-tag-processor-6-3.php

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,18 @@ class Gutenberg_HTML_Tag_Processor_6_3 {
528528
*/
529529
protected $lexical_updates = array();
530530

531+
/**
532+
* Attribute replacements to apply to input HTML document.
533+
*
534+
* Unlike more generic lexical updates, attribute updates are stored
535+
* in an associative array, where the keys are (lowercase-normalized)
536+
* attribute names, in order to avoid duplication.
537+
*
538+
* @since 6.3.0
539+
* @var WP_HTML_Text_Replacement[]
540+
*/
541+
private $attribute_updates = array();
542+
531543
/**
532544
* Tracks and limits `seek()` calls to prevent accidental infinite loops.
533545
*
@@ -1237,15 +1249,16 @@ private function skip_whitespace() {
12371249
}
12381250

12391251
/**
1240-
* Applies attribute updates and cleans up once a tag is fully parsed.
1252+
* Applies lexical updates and cleans up once a tag is fully parsed.
12411253
*
12421254
* @since 6.2.0
12431255
*
12441256
* @return void
12451257
*/
12461258
private function after_tag() {
1247-
$this->class_name_updates_to_attributes_updates();
1248-
$this->apply_attributes_updates();
1259+
$this->class_name_updates_to_attribute_updates();
1260+
$this->attribute_updates_to_lexical_updates();
1261+
$this->apply_lexical_updates();
12491262
$this->tag_name_starts_at = null;
12501263
$this->tag_name_length = null;
12511264
$this->tag_ends_at = null;
@@ -1254,17 +1267,17 @@ private function after_tag() {
12541267
}
12551268

12561269
/**
1257-
* Converts class name updates into tag attributes updates
1270+
* Converts class name updates into tag attribute updates
12581271
* (they are accumulated in different data formats for performance).
12591272
*
1260-
* @see $lexical_updates
1273+
* @see $attribute_updates
12611274
* @see $classname_updates
12621275
*
12631276
* @since 6.2.0
12641277
*
12651278
* @return void
12661279
*/
1267-
private function class_name_updates_to_attributes_updates() {
1280+
private function class_name_updates_to_attribute_updates() {
12681281
if ( count( $this->classname_updates ) === 0 ) {
12691282
return;
12701283
}
@@ -1398,14 +1411,33 @@ private function class_name_updates_to_attributes_updates() {
13981411
}
13991412

14001413
/**
1401-
* Applies attribute updates to HTML document.
1414+
* Converts attribute updates into lexical updates.
1415+
*
1416+
* This method is only meant to run right before the attribute updates are applied.
1417+
* The behavior in all other cases is undefined.
1418+
*
1419+
* @return void
1420+
* @since 6.3.0
1421+
*
1422+
* @see $attribute_updates
1423+
* @see $lexical_updates
1424+
*/
1425+
private function attribute_updates_to_lexical_updates() {
1426+
foreach ( $this->attribute_updates as $update ) {
1427+
$this->lexical_updates[] = $update;
1428+
}
1429+
$this->attribute_updates = array();
1430+
}
1431+
1432+
/**
1433+
* Applies lexical updates to HTML document.
14021434
*
14031435
* @since 6.2.0
14041436
* @since 6.3.0 Invalidate any bookmarks whose targets are overwritten.
14051437
*
14061438
* @return void
14071439
*/
1408-
private function apply_attributes_updates() {
1440+
private function apply_lexical_updates() {
14091441
if ( ! count( $this->lexical_updates ) ) {
14101442
return;
14111443
}
@@ -1527,8 +1559,8 @@ public function seek( $bookmark_name ) {
15271559
*
15281560
* @since 6.2.0
15291561
*
1530-
* @param WP_HTML_Text_Replacement $a First attribute update.
1531-
* @param WP_HTML_Text_Replacement $b Second attribute update.
1562+
* @param WP_HTML_Text_Replacement $a First lexical update.
1563+
* @param WP_HTML_Text_Replacement $b Second lexical update.
15321564
* @return int Comparison value for string order.
15331565
*/
15341566
private static function sort_start_ascending( $a, $b ) {
@@ -1564,11 +1596,11 @@ private static function sort_start_ascending( $a, $b ) {
15641596
* @return string|boolean|null Value of enqueued update if present, otherwise false.
15651597
*/
15661598
private function get_enqueued_attribute_value( $comparable_name ) {
1567-
if ( ! isset( $this->lexical_updates[ $comparable_name ] ) ) {
1599+
if ( ! isset( $this->attribute_updates[ $comparable_name ] ) ) {
15681600
return false;
15691601
}
15701602

1571-
$enqueued_text = $this->lexical_updates[ $comparable_name ]->text;
1603+
$enqueued_text = $this->attribute_updates[ $comparable_name ]->text;
15721604

15731605
// Removed attributes erase the entire span.
15741606
if ( '' === $enqueued_text ) {
@@ -1641,7 +1673,7 @@ public function get_attribute( $name ) {
16411673

16421674
/*
16431675
* For every attribute other than `class` it's possible to perform a quick check if
1644-
* there's an enqueued lexical update whose value takes priority over what's found in
1676+
* there's an enqueued attribute update whose value takes priority over what's found in
16451677
* the input document.
16461678
*
16471679
* The `class` attribute is special though because of the exposed helpers `add_class`
@@ -1651,7 +1683,7 @@ public function get_attribute( $name ) {
16511683
* into an attribute value update.
16521684
*/
16531685
if ( 'class' === $name ) {
1654-
$this->class_name_updates_to_attributes_updates();
1686+
$this->class_name_updates_to_attribute_updates();
16551687
}
16561688

16571689
// Return any enqueued attribute value updates if they exist.
@@ -1879,8 +1911,8 @@ public function set_attribute( $name, $value ) {
18791911
*
18801912
* Result: <div id="new"/>
18811913
*/
1882-
$existing_attribute = $this->attributes[ $comparable_name ];
1883-
$this->lexical_updates[ $name ] = new WP_HTML_Text_Replacement(
1914+
$existing_attribute = $this->attributes[ $comparable_name ];
1915+
$this->attribute_updates[ $name ] = new WP_HTML_Text_Replacement(
18841916
$existing_attribute->start,
18851917
$existing_attribute->end,
18861918
$updated_attribute
@@ -1897,7 +1929,7 @@ public function set_attribute( $name, $value ) {
18971929
*
18981930
* Result: <div id="new"/>
18991931
*/
1900-
$this->lexical_updates[ $comparable_name ] = new WP_HTML_Text_Replacement(
1932+
$this->attribute_updates[ $comparable_name ] = new WP_HTML_Text_Replacement(
19011933
$this->tag_name_starts_at + $this->tag_name_length,
19021934
$this->tag_name_starts_at + $this->tag_name_length,
19031935
' ' . $updated_attribute
@@ -1955,8 +1987,8 @@ public function remove_attribute( $name ) {
19551987
* and when that attribute wasn't originally present.
19561988
*/
19571989
if ( ! isset( $this->attributes[ $name ] ) ) {
1958-
if ( isset( $this->lexical_updates[ $name ] ) ) {
1959-
unset( $this->lexical_updates[ $name ] );
1990+
if ( isset( $this->attribute_updates[ $name ] ) ) {
1991+
unset( $this->attribute_updates[ $name ] );
19601992
}
19611993
return false;
19621994
}
@@ -1972,7 +2004,7 @@ public function remove_attribute( $name ) {
19722004
*
19732005
* Result: <div />
19742006
*/
1975-
$this->lexical_updates[ $name ] = new WP_HTML_Text_Replacement(
2007+
$this->attribute_updates[ $name ] = new WP_HTML_Text_Replacement(
19762008
$this->attributes[ $name ]->start,
19772009
$this->attributes[ $name ]->end,
19782010
''
@@ -2041,7 +2073,10 @@ public function __toString() {
20412073
* @return string The processed HTML.
20422074
*/
20432075
public function get_updated_html() {
2044-
$requires_no_updating = 0 === count( $this->classname_updates ) && 0 === count( $this->lexical_updates );
2076+
$requires_no_updating =
2077+
0 === count( $this->classname_updates ) &&
2078+
0 === count( $this->attribute_updates ) &&
2079+
0 === count( $this->lexical_updates );
20452080

20462081
/*
20472082
* When there is nothing more to update and nothing has already been
@@ -2072,8 +2107,9 @@ public function get_updated_html() {
20722107
*
20732108
* Note: `apply_attributes_updates()` modifies `$this->output_buffer`.
20742109
*/
2075-
$this->class_name_updates_to_attributes_updates();
2076-
$this->apply_attributes_updates();
2110+
$this->class_name_updates_to_attribute_updates();
2111+
$this->attribute_updates_to_lexical_updates();
2112+
$this->apply_lexical_updates();
20772113

20782114
/*
20792115
* 2. Replace the original HTML with the now-updated HTML so that it's possible to

0 commit comments

Comments
 (0)