Make WordPress Core

Changeset 55555


Ignore:
Timestamp:
03/16/2023 01:09:55 PM (20 months ago)
Author:
hellofromTonya
Message:

HTML API: Add bookmark invalidation logic.

While WP_HTML_Tag_Processor currently only supports changing a given tag's attributes, the plan is to provide methods to make broader changes (possibly through a subclass of WP_HTML_Tag_Processor). The API will have the potential of replacing a tag that a bookmark points to. To prepare, this changeset makes sure that all bookmarks affected by a HTML replacement are invalidated (i.e. released).

Changes:

  • Extends the existing loop in WP_HTML_Tag_Processor::apply_attributes_updates() that adjusts bookmarks' start and end positions upon HTML changes to check if the entire bookmark is within a portion of the HTML that has been replaced.
  • Adds `WP_HTML_Tag_Processor::has_bookmark() to check whether the given bookmark name exists.

References:

Follow-up to [55203].

Props bernhard-reiter, dmsnell, zieladam.
Fixes #57788.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/html-api/class-wp-html-tag-processor.php

    r55477 r55555  
    14051405     *
    14061406     * @since 6.2.0
     1407     * @since 6.3.0 Invalidate any bookmarks whose targets are overwritten.
    14071408     *
    14081409     * @return void
     
    14351436         * replacements adjust offsets in the input document.
    14361437         */
    1437         foreach ( $this->bookmarks as $bookmark ) {
     1438        foreach ( $this->bookmarks as $bookmark_name => $bookmark ) {
    14381439            /*
    14391440             * Each lexical update which appears before the bookmark's endpoints
     
    14461447
    14471448            foreach ( $this->lexical_updates as $diff ) {
    1448                 $update_head = $bookmark->start >= $diff->start;
    1449                 $update_tail = $bookmark->end >= $diff->start;
    1450 
    1451                 if ( ! $update_head && ! $update_tail ) {
     1449                if ( $bookmark->start < $diff->start && $bookmark->end < $diff->start ) {
    14521450                    break;
    14531451                }
    14541452
     1453                if ( $bookmark->start >= $diff->start && $bookmark->end < $diff->end ) {
     1454                    $this->release_bookmark( $bookmark_name );
     1455                    continue 2;
     1456                }
     1457
    14551458                $delta = strlen( $diff->text ) - ( $diff->end - $diff->start );
    14561459
    1457                 if ( $update_head ) {
     1460                if ( $bookmark->start >= $diff->start ) {
    14581461                    $head_delta += $delta;
    14591462                }
    14601463
    1461                 if ( $update_tail ) {
     1464                if ( $bookmark->end >= $diff->end ) {
    14621465                    $tail_delta += $delta;
    14631466                }
     
    14691472
    14701473        $this->lexical_updates = array();
     1474    }
     1475
     1476    /**
     1477     * Checks whether a bookmark with the given name exists.
     1478     *
     1479     * @since 6.3.0
     1480     *
     1481     * @param string $bookmark_name Name to identify a bookmark that potentially exists.
     1482     * @return bool Whether that bookmark exists.
     1483     */
     1484    public function has_bookmark( $bookmark_name ) {
     1485        return array_key_exists( $bookmark_name, $this->bookmarks );
    14711486    }
    14721487
  • trunk/tests/phpunit/tests/html-api/wpHtmlTagProcessor-bookmark.php

    r55407 r55555  
    3939        $p->set_bookmark( 'first li' );
    4040        $this->assertTrue( $p->release_bookmark( 'first li' ), 'Could not release a bookmark' );
     41    }
     42
     43    /**
     44     * @ticket 57788
     45     *
     46     * @covers WP_HTML_Tag_Processor::has_bookmark
     47     */
     48    public function test_has_bookmark_returns_false_if_bookmark_does_not_exist() {
     49        $p = new WP_HTML_Tag_Processor( '<div>Test</div>' );
     50        $this->assertFalse( $p->has_bookmark( 'my-bookmark' ) );
     51    }
     52
     53    /**
     54     * @ticket 57788
     55     *
     56     * @covers WP_HTML_Tag_Processor::has_bookmark
     57     */
     58    public function test_has_bookmark_returns_true_if_bookmark_exists() {
     59        $p = new WP_HTML_Tag_Processor( '<div>Test</div>' );
     60        $p->next_tag();
     61        $p->set_bookmark( 'my-bookmark' );
     62        $this->assertTrue( $p->has_bookmark( 'my-bookmark' ) );
     63    }
     64
     65    /**
     66     * @ticket 57788
     67     *
     68     * @covers WP_HTML_Tag_Processor::has_bookmark
     69     */
     70    public function test_has_bookmark_returns_false_if_bookmark_has_been_released() {
     71        $p = new WP_HTML_Tag_Processor( '<div>Test</div>' );
     72        $p->next_tag();
     73        $p->set_bookmark( 'my-bookmark' );
     74        $p->release_bookmark( 'my-bookmark' );
     75        $this->assertFalse( $p->has_bookmark( 'my-bookmark' ) );
    4176    }
    4277
Note: See TracChangeset for help on using the changeset viewer.