Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 22 additions & 7 deletions src/wp-includes/html-api/class-wp-html-tag-processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -1401,6 +1401,7 @@ private function class_name_updates_to_attributes_updates() {
* Applies attribute updates to HTML document.
*
* @since 6.2.0
* @since 6.3.0 Invalidate any bookmarks whose targets are overwritten.
*
* @return void
*/
Expand Down Expand Up @@ -1431,7 +1432,7 @@ private function apply_attributes_updates() {
* Adjust bookmark locations to account for how the text
* replacements adjust offsets in the input document.
*/
foreach ( $this->bookmarks as $bookmark ) {
foreach ( $this->bookmarks as $bookmark_name => $bookmark ) {
/*
* Each lexical update which appears before the bookmark's endpoints
* might shift the offsets for those endpoints. Loop through each change
Expand All @@ -1442,20 +1443,22 @@ private function apply_attributes_updates() {
$tail_delta = 0;

foreach ( $this->lexical_updates as $diff ) {
$update_head = $bookmark->start >= $diff->start;
$update_tail = $bookmark->end >= $diff->start;

if ( ! $update_head && ! $update_tail ) {
if ( $bookmark->start < $diff->start && $bookmark->end < $diff->start ) {
break;
}

if ( $bookmark->start >= $diff->start && $bookmark->end < $diff->end ) {
$this->release_bookmark( $bookmark_name );
continue 2;
}

$delta = strlen( $diff->text ) - ( $diff->end - $diff->start );

if ( $update_head ) {
if ( $bookmark->start >= $diff->start ) {
$head_delta += $delta;
}

if ( $update_tail ) {
if ( $bookmark->end >= $diff->end ) {
$tail_delta += $delta;
}
}
Expand All @@ -1467,6 +1470,18 @@ private function apply_attributes_updates() {
$this->lexical_updates = array();
}

/**
* Checks whether a bookmark with the given name exists.
*
* @since 6.3.0
*
* @param string $bookmark_name Name to identify a bookmark that potentially exists.
* @return bool Whether that bookmark exists.
*/
public function has_bookmark( $bookmark_name ) {
return array_key_exists( $bookmark_name, $this->bookmarks );
}

/**
* Move the internal cursor in the Tag Processor to a given bookmark's location.
*
Expand Down
35 changes: 35 additions & 0 deletions tests/phpunit/tests/html-api/wpHtmlTagProcessor-bookmark.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,41 @@ public function test_release_bookmark() {
$this->assertTrue( $p->release_bookmark( 'first li' ), 'Could not release a bookmark' );
}

/**
* @ticket 57788
*
* @covers WP_HTML_Tag_Processor::has_bookmark
*/
public function test_has_bookmark_returns_false_if_bookmark_does_not_exist() {
$p = new WP_HTML_Tag_Processor( '<div>Test</div>' );
$this->assertFalse( $p->has_bookmark( 'my-bookmark' ) );
}

/**
* @ticket 57788
*
* @covers WP_HTML_Tag_Processor::has_bookmark
*/
public function test_has_bookmark_returns_true_if_bookmark_exists() {
$p = new WP_HTML_Tag_Processor( '<div>Test</div>' );
$p->next_tag();
$p->set_bookmark( 'my-bookmark' );
$this->assertTrue( $p->has_bookmark( 'my-bookmark' ) );
}

/**
* @ticket 57788
*
* @covers WP_HTML_Tag_Processor::has_bookmark
*/
public function test_has_bookmark_returns_false_if_bookmark_has_been_released() {
$p = new WP_HTML_Tag_Processor( '<div>Test</div>' );
$p->next_tag();
$p->set_bookmark( 'my-bookmark' );
$p->release_bookmark( 'my-bookmark' );
$this->assertFalse( $p->has_bookmark( 'my-bookmark' ) );
}

/**
* @ticket 56299
*
Expand Down