From 55d155d64a50bc7b002344a6802c90698b0f5d0f Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Tue, 3 Mar 2026 11:28:58 -0600 Subject: [PATCH] Block Processor: add get_attribute_replacement(). There are useful times to modify the JSON attributes within a block. This change proposes a new method which performs serialization on a set of new attributes, and returns an update description on how to apply those attributes textually against a document to make the edit. This returns a `WP_HTML_Text_Replacement` instance with the range of bytes that should be replaced, as well as the serialized content of the update. --- src/wp-includes/class-wp-block-processor.php | 47 ++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/wp-includes/class-wp-block-processor.php b/src/wp-includes/class-wp-block-processor.php index 7b20fbf85d3bf..3244b9d633d4f 100644 --- a/src/wp-includes/class-wp-block-processor.php +++ b/src/wp-includes/class-wp-block-processor.php @@ -1891,6 +1891,53 @@ public function allocate_and_return_parsed_attributes(): ?array { : null; } + /** + * Returns an indicator for how to replace the attributes in the given block, + * including byte offsets for the replacement and full serialization of attributes. + * + * @since {WP_VERSION} + * + * @param array|null $new_attributes Serialize these attributes into the block. + * @return WP_HTML_Text_Replacement|null + */ + public function get_attribute_replacement( $new_attributes ): ?WP_HTML_Text_Replacement { + if ( self::MATCHED !== $this->state || ! in_array( $this->type, array( self::OPENER, self::CLOSER ), true ) ) { + return null; + } + + if ( null === $new_attributes ) { + if ( 0 === $this->json_length ) { + return null; + } + + $whitespace_length = strspn( $this->source_text, " \t\f\r\n", $this->json_at + $this->json_length + 1 ); + return new WP_HTML_Text_Replacement( + $this->json_at, + $this->json_length + $whitespace_length, + '' + ); + } + + $encoded_attributes = wp_json_encode( $new_attributes, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ); + $encoded_attributes = strtr( + $encoded_attributes, + array( + '\\\\' => '\u005c', + '--' => '\u002d\u002d', + '<' => '\u003c', + '>' => '\u003e', + '&' => '\u0026', + '\\"' => '\u0022', + ) + ); + + return new WP_HTML_Text_Replacement( + $this->json_at, + $this->json_length, + $encoded_attributes + ); + } + /** * Returns the span representing the currently-matched delimiter, if matched, otherwise `null`. *