Skip to content

Commit e1149d6

Browse files
committed
Preserve comments when removing style declarations
1 parent 9038612 commit e1149d6

2 files changed

Lines changed: 58 additions & 8 deletions

File tree

src/wp-includes/html-api/class-wp-html-style-attribute-processor.php

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -202,18 +202,14 @@ public function remove_declaration(): bool {
202202
return false;
203203
}
204204

205-
if ( '' === trim( substr( $this->style, 0, $declaration['leading_start'] ), self::WHITESPACE ) ) {
206-
$remove_start = $declaration['leading_start'];
207-
$remove_end = $declaration['trailing_end'];
208-
} else {
209-
$remove_start = $declaration['leading_start'];
210-
$remove_end = $declaration['after'];
211-
}
205+
$remove_start = $this->get_offset_before_preceding_whitespace( $declaration['start'] );
206+
$remove_end = $this->get_offset_after_following_whitespace( $declaration['after'] );
207+
$replacement = ( $remove_start > 0 && $remove_end < strlen( $this->style ) ) ? ' ' : '';
212208

213209
$this->queue_lexical_update(
214210
$remove_start,
215211
$remove_end - $remove_start,
216-
'',
212+
$replacement,
217213
$this->current_declaration
218214
);
219215

@@ -681,6 +677,36 @@ private function is_ignored_token( array $token ): bool {
681677
);
682678
}
683679

680+
/**
681+
* Gets the byte offset before contiguous whitespace ending at an offset.
682+
*
683+
* @param int $offset Byte offset.
684+
* @return int Offset before preceding whitespace.
685+
*/
686+
private function get_offset_before_preceding_whitespace( int $offset ): int {
687+
while ( $offset > 0 && false !== strpos( self::WHITESPACE, $this->style[ $offset - 1 ] ) ) {
688+
--$offset;
689+
}
690+
691+
return $offset;
692+
}
693+
694+
/**
695+
* Gets the byte offset after contiguous whitespace beginning at an offset.
696+
*
697+
* @param int $offset Byte offset.
698+
* @return int Offset after following whitespace.
699+
*/
700+
private function get_offset_after_following_whitespace( int $offset ): int {
701+
$length = strlen( $this->style );
702+
703+
while ( $offset < $length && false !== strpos( self::WHITESPACE, $this->style[ $offset ] ) ) {
704+
++$offset;
705+
}
706+
707+
return $offset;
708+
}
709+
684710
/**
685711
* Gets the current declaration metadata.
686712
*

tests/phpunit/tests/html-api/wpHtmlStyleAttributeProcessor.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,30 @@ public function test_remove_declaration_removes_adjacent_duplicate_declarations(
183183
$this->assertSame( 'background: white;', $processor->get_updated_style() );
184184
}
185185

186+
/**
187+
* @covers ::remove_declaration
188+
* @covers ::get_updated_style
189+
*/
190+
public function test_remove_declaration_preserves_surrounding_comments() {
191+
$processor = new WP_HTML_Style_Attribute_Processor( '/*keep*/ color: red; background: white;' );
192+
193+
$this->assertTrue( $processor->next_declaration( 'color' ) );
194+
$this->assertTrue( $processor->remove_declaration() );
195+
$this->assertSame( '/*keep*/ background: white;', $processor->get_updated_style() );
196+
197+
$processor = new WP_HTML_Style_Attribute_Processor( 'color: red; /*keep*/ background: white;' );
198+
199+
$this->assertTrue( $processor->next_declaration( 'color' ) );
200+
$this->assertTrue( $processor->remove_declaration() );
201+
$this->assertSame( '/*keep*/ background: white;', $processor->get_updated_style() );
202+
203+
$processor = new WP_HTML_Style_Attribute_Processor( 'color: red; /*keep*/ background: white;' );
204+
205+
$this->assertTrue( $processor->next_declaration( 'background' ) );
206+
$this->assertTrue( $processor->remove_declaration() );
207+
$this->assertSame( 'color: red; /*keep*/', $processor->get_updated_style() );
208+
}
209+
186210
/**
187211
* @covers ::append_declaration
188212
* @covers ::get_updated_style

0 commit comments

Comments
 (0)