@@ -57,6 +57,13 @@ class WP_HTML_Style_Attribute_Processor {
5757 */
5858 private $ current_declaration = -1 ;
5959
60+ /**
61+ * Whether the current declaration was removed and no new declaration has been selected.
62+ *
63+ * @var bool
64+ */
65+ private $ current_declaration_removed = false ;
66+
6067 /**
6168 * Lexical updates to apply to the original style attribute value.
6269 *
@@ -102,12 +109,14 @@ public function next_declaration( ?string $property_name = null ): bool {
102109 null === $ property_name ||
103110 $ this ->matches_property_name ( $ this ->declarations [ $ i ]['name ' ], $ property_name )
104111 ) {
105- $ this ->current_declaration = $ i ;
112+ $ this ->current_declaration = $ i ;
113+ $ this ->current_declaration_removed = false ;
106114 return true ;
107115 }
108116 }
109117
110- $ this ->current_declaration = count ( $ this ->declarations );
118+ $ this ->current_declaration = count ( $ this ->declarations );
119+ $ this ->current_declaration_removed = false ;
111120 return false ;
112121 }
113122
@@ -174,6 +183,8 @@ public function set_value( string $value, ?bool $important = null ): bool {
174183 $ this ->current_declaration
175184 );
176185
186+ $ this ->apply_lexical_updates ( $ this ->current_declaration );
187+
177188 return true ;
178189 }
179190
@@ -206,6 +217,8 @@ public function remove_declaration(): bool {
206217 $ this ->current_declaration
207218 );
208219
220+ $ this ->apply_lexical_updates ( $ this ->current_declaration - 1 , true );
221+
209222 return true ;
210223 }
211224
@@ -225,9 +238,10 @@ public function append_declaration( string $property_name, string $value, bool $
225238 return false ;
226239 }
227240
228- $ trimmed_style = rtrim ( $ this ->style , self ::WHITESPACE );
229- $ insert_at = strlen ( $ trimmed_style );
230- $ separator = $ this ->has_queued_append_at ( $ insert_at ) ? ' ' : '' ;
241+ $ old_declaration_count = count ( $ this ->declarations );
242+ $ trimmed_style = rtrim ( $ this ->style , self ::WHITESPACE );
243+ $ insert_at = strlen ( $ trimmed_style );
244+ $ separator = $ this ->has_queued_append_at ( $ insert_at ) ? ' ' : '' ;
231245
232246 if ( '' === $ separator && '' !== trim ( $ trimmed_style , self ::WHITESPACE ) ) {
233247 $ separator = ( '; ' === substr ( $ trimmed_style , -1 ) ) ? ' ' : '; ' ;
@@ -240,6 +254,16 @@ public function append_declaration( string $property_name, string $value, bool $
240254 null
241255 );
242256
257+ $ append_after_exhausted_cursor = $ this ->current_declaration >= $ old_declaration_count ;
258+ $ current_after_append = $ append_after_exhausted_cursor
259+ ? $ old_declaration_count - 1
260+ : $ this ->current_declaration ;
261+
262+ $ this ->apply_lexical_updates (
263+ $ current_after_append ,
264+ $ this ->current_declaration_removed || $ append_after_exhausted_cursor
265+ );
266+
243267 return true ;
244268 }
245269
@@ -662,13 +686,40 @@ private function is_ignored_token( array $token ): bool {
662686 * @return array{name:string, raw_name:string, leading_start:int, start:int, after:int, trailing_end:int, value_start:int, value_end:int, important:bool}|null
663687 */
664688 private function get_current_declaration (): ?array {
665- if ( $ this ->current_declaration < 0 || ! isset ( $ this ->declarations [ $ this ->current_declaration ] ) ) {
689+ if (
690+ $ this ->current_declaration_removed ||
691+ $ this ->current_declaration < 0 ||
692+ ! isset ( $ this ->declarations [ $ this ->current_declaration ] )
693+ ) {
666694 return null ;
667695 }
668696
669697 return $ this ->declarations [ $ this ->current_declaration ];
670698 }
671699
700+ /**
701+ * Applies queued lexical updates and reparses the updated style attribute value.
702+ *
703+ * @param int $current_declaration Declaration index to keep before the next cursor advance.
704+ * @param bool $current_declaration_removed Optional. Whether the current declaration was removed.
705+ */
706+ private function apply_lexical_updates ( int $ current_declaration , bool $ current_declaration_removed = false ): void {
707+ $ this ->style = $ this ->get_updated_style ();
708+
709+ $ this ->tokens = array ();
710+ $ this ->declarations = array ();
711+ $ this ->lexical_updates = array ();
712+ $ this ->lexical_update_order = 0 ;
713+ $ this ->current_declaration = $ current_declaration ;
714+ $ this ->current_declaration_removed = $ current_declaration_removed ;
715+
716+ $ this ->parse ();
717+
718+ if ( $ this ->current_declaration >= count ( $ this ->declarations ) ) {
719+ $ this ->current_declaration = count ( $ this ->declarations );
720+ }
721+ }
722+
672723 /**
673724 * Queues a lexical update, replacing any earlier update for the same declaration.
674725 *
0 commit comments