Skip to content

Commit 5aae390

Browse files
committed
Begin transition for next_tag() to align with base class behavior
1 parent 069dc53 commit 5aae390

File tree

7 files changed

+111
-56
lines changed

7 files changed

+111
-56
lines changed

plugins/embed-optimizer/hooks.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,13 @@ function embed_optimizer_add_non_optimization_detective_hooks(): void {
4444
* @param string $optimization_detective_version Current version of the optimization detective plugin.
4545
*/
4646
function embed_optimizer_init_optimization_detective( string $optimization_detective_version ): void {
47-
$required_od_version = '0.9.0';
48-
if ( version_compare( (string) strtok( $optimization_detective_version, '-' ), $required_od_version, '<' ) ) {
47+
if (
48+
version_compare( (string) strtok( $optimization_detective_version, '-' ), '1.0.0', '<' )
49+
||
50+
'1.0.0-beta1' === $optimization_detective_version
51+
||
52+
'1.0.0-beta2' === $optimization_detective_version
53+
) {
4954
add_action(
5055
'admin_notices',
5156
static function (): void {
@@ -253,7 +258,7 @@ function embed_optimizer_update_markup( WP_HTML_Tag_Processor $html_processor, b
253258
}
254259
}
255260
}
256-
} while ( $html_processor->next_tag() );
261+
} while ( $html_processor->next_tag( array( 'tag_closers' => 'visit' ) ) );
257262
// If there was only one non-inline script, make it lazy.
258263
if ( 1 === $script_count && ! $has_inline_script && $html_processor->has_bookmark( $bookmark_names['script'] ) ) {
259264
$needs_lazy_script = true;

plugins/image-prioritizer/class-image-prioritizer-img-tag-visitor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ private function process_picture( OD_HTML_Tag_Processor $processor, OD_Tag_Visit
226226
$crossorigin = null;
227227

228228
// Loop through child tags until we reach the closing PICTURE tag.
229-
while ( $processor->next_tag() ) {
229+
while ( $processor->next_tag( array( 'tag_closers' => 'visit' ) ) ) {
230230
$tag = $processor->get_tag();
231231

232232
// If we reached the closing PICTURE tag, break.

plugins/image-prioritizer/helper.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,13 @@
2121
* @param string $optimization_detective_version Current version of the optimization detective plugin.
2222
*/
2323
function image_prioritizer_init( string $optimization_detective_version ): void {
24-
$required_od_version = '0.9.0';
25-
if ( ! version_compare( (string) strtok( $optimization_detective_version, '-' ), $required_od_version, '>=' ) ) {
24+
if (
25+
version_compare( (string) strtok( $optimization_detective_version, '-' ), '1.0.0', '<' )
26+
||
27+
'1.0.0-beta1' === $optimization_detective_version
28+
||
29+
'1.0.0-beta2' === $optimization_detective_version
30+
) {
2631
add_action(
2732
'admin_notices',
2833
static function (): void {

plugins/optimization-detective/class-od-html-tag-processor.php

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -250,17 +250,18 @@ final class OD_HTML_Tag_Processor extends WP_HTML_Tag_Processor {
250250
*
251251
* @inheritDoc
252252
* @since 0.4.0
253-
* @since n.e.x.t Passing a $query is now allowed.
253+
* @since n.e.x.t Passing a $query is now allowed. In a future release, this will default to skipping tag closers.
254254
*
255255
* @param array{tag_name?: string|null, match_offset?: int|null, class_name?: string|null, tag_closers?: string|null}|null $query Query.
256256
* @return bool Whether a tag was matched.
257-
*
258-
* @throws InvalidArgumentException If attempting to pass a query.
259257
*/
260258
public function next_tag( $query = null ): bool {
261259
if ( null === $query ) {
262-
// For back-compat with tag visitor which previously relied next_tag() always visiting tag closers.
263-
$query = array( array( 'tag_closers' => 'visit' ) );
260+
$query = array( 'tag_closers' => 'visit' );
261+
$this->warn(
262+
__METHOD__,
263+
esc_html__( 'Previously this method always visited tag closers and did not allow a query to be supplied. Now, however, a query can be supplied. To align this method with the behavior of the base class, a future version of this method will default to skipping tag closers.', 'optimization-detective' )
264+
);
264265
}
265266
return parent::next_tag( $query );
266267
}
@@ -269,17 +270,11 @@ public function next_tag( $query = null ): bool {
269270
* Finds the next open tag.
270271
*
271272
* @since 0.4.0
272-
* @deprecated
273273
*
274274
* @return bool Whether a tag was matched.
275275
*/
276276
public function next_open_tag(): bool {
277-
while ( $this->next_tag( array( 'tag_closers' => 'visit' ) ) ) {
278-
if ( ! $this->is_tag_closer() ) {
279-
return true;
280-
}
281-
}
282-
return false;
277+
return $this->next_tag( array( 'tag_closers' => 'skip' ) );
283278
}
284279

285280
/**

plugins/optimization-detective/load.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Description: Provides a framework for leveraging real user metrics to detect optimizations for improving page performance.
66
* Requires at least: 6.6
77
* Requires PHP: 7.2
8-
* Version: 1.0.0-beta2
8+
* Version: 1.0.0-beta3
99
* Author: WordPress Performance Team
1010
* Author URI: https://make.wordpress.org/performance/
1111
* License: GPLv2 or later
@@ -71,7 +71,7 @@ static function ( string $global_var_name, string $version, Closure $load ): voi
7171
}
7272
)(
7373
'optimization_detective_pending_plugin',
74-
'1.0.0-beta2',
74+
'1.0.0-beta3',
7575
static function ( string $version ): void {
7676
if ( defined( 'OPTIMIZATION_DETECTIVE_VERSION' ) ) {
7777
return;

plugins/optimization-detective/optimization.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ function od_optimize_template_output_buffer( string $buffer ): string {
238238
// If the initial tag is not an open HTML tag, then abort since the buffer is not a complete HTML document.
239239
$processor = new OD_HTML_Tag_Processor( $buffer );
240240
if ( ! (
241-
$processor->next_tag() &&
241+
$processor->next_tag( array( 'tag_closers' => 'visit' ) ) &&
242242
! $processor->is_tag_closer() &&
243243
'HTML' === $processor->get_tag()
244244
) ) {
@@ -359,7 +359,7 @@ function od_optimize_template_output_buffer( string $buffer ): string {
359359
if (
360360
in_array( 'NOSCRIPT', $processor->get_breadcrumbs(), true )
361361
||
362-
str_starts_with( $processor->get_xpath(), "/HTML/BODY/DIV[@id='wpadminbar']" )
362+
str_starts_with( $processor->get_stored_xpath(), "/HTML/BODY/DIV[@id='wpadminbar']" )
363363
) {
364364
continue;
365365
}

plugins/optimization-detective/tests/test-class-od-html-tag-processor.php

Lines changed: 84 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -341,18 +341,20 @@ public function data_provider_sample_documents(): array {
341341
</body>
342342
</html>
343343
',
344-
'open_tags' => array( 'HTML', 'HEAD', 'BODY', 'DIV', 'IMG', 'DIV', 'IMG', 'DIV', 'IMG', 'DIV', 'IMG' ),
344+
'open_tags' => array( 'HTML', 'HEAD', 'BODY', 'DIV', 'IMG', 'DIV', 'IMG', 'DIV', 'IMG', 'DIV', 'IMG', 'DIV', 'IMG' ),
345345
'xpath_breadcrumbs' => array(
346-
'/HTML' => array( 'HTML' ),
347-
'/HTML/HEAD' => array( 'HTML', 'HEAD' ),
348-
'/HTML/BODY' => array( 'HTML', 'BODY' ),
349-
'/HTML/BODY/DIV[@id=\'header\']' => array( 'HTML', 'BODY', 'DIV' ),
346+
'/HTML' => array( 'HTML' ),
347+
'/HTML/HEAD' => array( 'HTML', 'HEAD' ),
348+
'/HTML/BODY' => array( 'HTML', 'BODY' ),
349+
'/HTML/BODY/DIV[@id=\'wpadminbar\']' => array( 'HTML', 'BODY', 'DIV' ),
350+
'/HTML/BODY/DIV[@id=\'wpadminbar\']/*[1][self::IMG]' => array( 'HTML', 'BODY', 'DIV', 'IMG' ),
351+
'/HTML/BODY/DIV[@id=\'header\']' => array( 'HTML', 'BODY', 'DIV' ),
350352
'/HTML/BODY/DIV[@id=\'header\']/*[1][self::IMG]' => array( 'HTML', 'BODY', 'DIV', 'IMG' ),
351-
'/HTML/BODY/DIV[@id=\'primary\']' => array( 'HTML', 'BODY', 'DIV' ),
353+
'/HTML/BODY/DIV[@id=\'primary\']' => array( 'HTML', 'BODY', 'DIV' ),
352354
'/HTML/BODY/DIV[@id=\'primary\']/*[1][self::IMG]' => array( 'HTML', 'BODY', 'DIV', 'IMG' ),
353-
'/HTML/BODY/DIV[@id=\'secondary\']' => array( 'HTML', 'BODY', 'DIV' ),
355+
'/HTML/BODY/DIV[@id=\'secondary\']' => array( 'HTML', 'BODY', 'DIV' ),
354356
'/HTML/BODY/DIV[@id=\'secondary\']/*[1][self::IMG]' => array( 'HTML', 'BODY', 'DIV', 'IMG' ),
355-
'/HTML/BODY/DIV[@id=\'colophon\']' => array( 'HTML', 'BODY', 'DIV' ),
357+
'/HTML/BODY/DIV[@id=\'colophon\']' => array( 'HTML', 'BODY', 'DIV' ),
356358
'/HTML/BODY/DIV[@id=\'colophon\']/*[1][self::IMG]' => array( 'HTML', 'BODY', 'DIV', 'IMG' ),
357359
),
358360
),
@@ -392,25 +394,27 @@ public function data_provider_sample_documents(): array {
392394
</body>
393395
</html>
394396
',
395-
'open_tags' => array( 'HTML', 'HEAD', 'BODY', 'DIV', 'IMG', 'DIV', 'IMG', 'DIV', 'IMG', 'DIV', 'IMG', 'DIV', 'IMG', 'DIV', 'IMG', 'DIV', 'IMG' ),
397+
'open_tags' => array( 'HTML', 'HEAD', 'BODY', 'DIV', 'IMG', 'DIV', 'IMG', 'DIV', 'IMG', 'DIV', 'IMG', 'DIV', 'IMG', 'DIV', 'IMG', 'DIV', 'IMG', 'DIV', 'IMG' ),
396398
'xpath_breadcrumbs' => array(
397-
'/HTML' => array( 'HTML' ),
398-
'/HTML/HEAD' => array( 'HTML', 'HEAD' ),
399-
'/HTML/BODY' => array( 'HTML', 'BODY' ),
400-
'/HTML/BODY/DIV[@role=\'banner\']' => array( 'HTML', 'BODY', 'DIV' ),
399+
'/HTML' => array( 'HTML' ),
400+
'/HTML/HEAD' => array( 'HTML', 'HEAD' ),
401+
'/HTML/BODY' => array( 'HTML', 'BODY' ),
402+
'/HTML/BODY/DIV[@id=\'wpadminbar\']' => array( 'HTML', 'BODY', 'DIV' ),
403+
'/HTML/BODY/DIV[@id=\'wpadminbar\']/*[1][self::IMG]' => array( 'HTML', 'BODY', 'DIV', 'IMG' ),
404+
'/HTML/BODY/DIV[@role=\'banner\']' => array( 'HTML', 'BODY', 'DIV' ),
401405
'/HTML/BODY/DIV[@role=\'banner\']/*[1][self::IMG]' => array( 'HTML', 'BODY', 'DIV', 'IMG' ),
402406
'/HTML/BODY/DIV[@class=\'content-area main\']' => array( 'HTML', 'BODY', 'DIV' ),
403407
'/HTML/BODY/DIV[@class=\'content-area main\']/*[1][self::IMG]' => array( 'HTML', 'BODY', 'DIV', 'IMG' ),
404408
'/HTML/BODY/DIV[@class=\'widget-area\']' => array( 'HTML', 'BODY', 'DIV' ),
405409
'/HTML/BODY/DIV[@class=\'widget-area\']/*[1][self::IMG]' => array( 'HTML', 'BODY', 'DIV', 'IMG' ),
406410
'/HTML/BODY/DIV[@class=\'site-footer\']' => array( 'HTML', 'BODY', 'DIV' ),
407411
'/HTML/BODY/DIV[@class=\'site-footer\']/*[1][self::IMG]' => array( 'HTML', 'BODY', 'DIV', 'IMG' ),
408-
'/HTML/BODY/DIV[@class=\'\']' => array( 'HTML', 'BODY', 'DIV' ),
412+
'/HTML/BODY/DIV[@class=\'\']' => array( 'HTML', 'BODY', 'DIV' ),
409413
'/HTML/BODY/DIV[@class=\'\']/*[1][self::IMG]' => array( 'HTML', 'BODY', 'DIV', 'IMG' ),
410-
'/HTML/BODY/DIV[@role=\'\']' => array( 'HTML', 'BODY', 'DIV' ),
414+
'/HTML/BODY/DIV[@role=\'\']' => array( 'HTML', 'BODY', 'DIV' ),
411415
'/HTML/BODY/DIV[@role=\'\']/*[1][self::IMG]' => array( 'HTML', 'BODY', 'DIV', 'IMG' ),
412-
'/HTML/BODY/DIV' => array( 'HTML', 'BODY', 'DIV' ),
413-
'/HTML/BODY/DIV/*[1][self::IMG]' => array( 'HTML', 'BODY', 'DIV', 'IMG' ),
416+
'/HTML/BODY/DIV' => array( 'HTML', 'BODY', 'DIV' ),
417+
'/HTML/BODY/DIV/*[1][self::IMG]' => array( 'HTML', 'BODY', 'DIV', 'IMG' ),
414418
),
415419
),
416420
);
@@ -442,7 +446,7 @@ public function test_next_tag_and_get_xpath( string $document, array $open_tags,
442446
$this->assertSame( '', $p->get_stored_xpath(), 'Expected empty XPath since iteration has not started.' );
443447
$actual_open_tags = array();
444448
$actual_xpath_breadcrumbs_mapping = array();
445-
while ( $p->next_open_tag() ) {
449+
while ( $p->next_tag( array( 'tag_closers' => 'skip' ) ) ) {
446450
$actual_open_tags[] = $p->get_tag();
447451

448452
$xpath = $p->get_stored_xpath();
@@ -466,14 +470,60 @@ public function test_next_tag_and_get_xpath( string $document, array $open_tags,
466470
}
467471

468472
/**
469-
* Test next_tag() passing query which is invalid.
473+
* Test next_tag() passing query.
470474
*
471475
* @covers ::next_tag
476+
* @covers ::get_xpath
477+
* @covers ::get_current_depth
472478
*/
473479
public function test_next_tag_with_query(): void {
474-
$this->expectException( InvalidArgumentException::class );
475-
$p = new OD_HTML_Tag_Processor( '<html></html>' );
476-
$p->next_tag( array( 'tag_name' => 'HTML' ) );
480+
$html = '
481+
<!DOCTYPE html>
482+
<html>
483+
<head>
484+
<title></title>
485+
</head>
486+
<body>
487+
<main>
488+
<p>Hello world</p>
489+
<figure>
490+
<img src="https://example.com/img1.jpg">
491+
</figure>
492+
<figure>
493+
<img src="https://example.com/img2.jpg">
494+
</figure>
495+
<div class="foo">
496+
Foo!
497+
</div>
498+
</main>
499+
</body>
500+
</html>
501+
';
502+
503+
$p = new OD_HTML_Tag_Processor( $html );
504+
$this->assertTrue( $p->next_tag( array( 'tag_name' => 'HTML' ) ) );
505+
$this->assertTrue( $p->set_bookmark( 'document_root' ) );
506+
$this->assertSame( 1, $p->get_current_depth() );
507+
508+
$this->assertTrue( $p->next_tag( array( 'tag_name' => 'IMG' ) ) );
509+
$this->assertEquals( '/HTML/BODY/MAIN/*[2][self::FIGURE]/*[1][self::IMG]', $p->get_xpath() );
510+
$this->assertSame( 5, $p->get_current_depth() );
511+
512+
$this->assertTrue( $p->next_tag( array( 'class_name' => 'foo' ) ) );
513+
$this->assertEquals( '/HTML/BODY/MAIN/*[4][self::DIV]', $p->get_xpath() );
514+
$this->assertSame( 4, $p->get_current_depth() );
515+
516+
$this->assertTrue( $p->seek( 'document_root' ) );
517+
$this->assertTrue(
518+
$p->next_tag(
519+
array(
520+
'tag_name' => 'IMG',
521+
'match_offset' => 2,
522+
)
523+
)
524+
);
525+
$this->assertEquals( '/HTML/BODY/MAIN/*[3][self::FIGURE]/*[1][self::IMG]', $p->get_xpath() );
526+
$this->assertSame( 5, $p->get_current_depth() );
477527
}
478528

479529
/**
@@ -484,15 +534,15 @@ public function test_next_tag_with_query(): void {
484534
public function test_expects_closer(): void {
485535
$p = new OD_HTML_Tag_Processor( '<html><body><hr></body></html>' );
486536
$this->assertFalse( $p->expects_closer() );
487-
while ( $p->next_tag() ) {
537+
while ( $p->next_tag( array( 'tag_closers' => 'visit' ) ) ) {
488538
if ( 'BODY' === $p->get_tag() ) {
489539
break;
490540
}
491541
}
492542
$this->assertSame( 'BODY', $p->get_tag() );
493543
$this->assertFalse( $p->expects_closer( 'IMG' ) );
494544
$this->assertTrue( $p->expects_closer() );
495-
$p->next_tag();
545+
$p->next_tag( array( 'tag_closers' => 'visit' ) );
496546
$this->assertSame( 'HR', $p->get_tag() );
497547
$this->assertFalse( $p->expects_closer() );
498548
$this->assertTrue( $p->expects_closer( 'DIV' ) );
@@ -594,7 +644,7 @@ public function test_get_updated_html_when_out_of_bookmarks(): void {
594644
</html>
595645
';
596646
$processor = new OD_HTML_Tag_Processor( $html );
597-
$this->assertTrue( $processor->next_tag() );
647+
$this->assertTrue( $processor->next_tag( array( 'tag_closers' => 'visit' ) ) );
598648
$this->assertEquals( 'HTML', $processor->get_tag() );
599649
$max_bookmarks = max( WP_HTML_Processor::MAX_BOOKMARKS, WP_HTML_Tag_Processor::MAX_BOOKMARKS );
600650
for ( $i = 0; $i < $max_bookmarks + 1; $i++ ) {
@@ -710,7 +760,7 @@ public function test_bookmarking_and_seeking(): void {
710760
if ( $processor->get_current_depth() < $embed_block_depth ) {
711761
break;
712762
}
713-
} while ( $processor->next_tag() );
763+
} while ( $processor->next_tag( array( 'tag_closers' => 'visit' ) ) );
714764
}
715765
}
716766

@@ -790,31 +840,31 @@ public function test_get_cursor_move_count(): void {
790840
)
791841
);
792842
$this->assertSame( 0, $processor->get_cursor_move_count() );
793-
$this->assertTrue( $processor->next_tag() );
843+
$this->assertTrue( $processor->next_tag( array( 'tag_closers' => 'visit' ) ) );
794844
$this->assertSame( 'HTML', $processor->get_tag() );
795845
$this->assertTrue( $processor->set_bookmark( 'document_root' ) );
796846
$this->assertSame( 1, $processor->get_cursor_move_count() );
797-
$this->assertTrue( $processor->next_tag() );
847+
$this->assertTrue( $processor->next_tag( array( 'tag_closers' => 'visit' ) ) );
798848
$this->assertSame( 'HEAD', $processor->get_tag() );
799849
$this->assertSame( 3, $processor->get_cursor_move_count() ); // Note that next_token() call #2 was for the whitespace between <html> and <head>.
800-
$this->assertTrue( $processor->next_tag() );
850+
$this->assertTrue( $processor->next_tag( array( 'tag_closers' => 'visit' ) ) );
801851
$this->assertSame( 'HEAD', $processor->get_tag() );
802852
$this->assertTrue( $processor->is_tag_closer() );
803853
$this->assertSame( 4, $processor->get_cursor_move_count() );
804-
$this->assertTrue( $processor->next_tag() );
854+
$this->assertTrue( $processor->next_tag( array( 'tag_closers' => 'visit' ) ) );
805855
$this->assertSame( 'BODY', $processor->get_tag() );
806856
$this->assertSame( 6, $processor->get_cursor_move_count() ); // Note that next_token() call #5 was for the whitespace between </head> and <body>.
807-
$this->assertTrue( $processor->next_tag() );
857+
$this->assertTrue( $processor->next_tag( array( 'tag_closers' => 'visit' ) ) );
808858
$this->assertSame( 'BODY', $processor->get_tag() );
809859
$this->assertTrue( $processor->is_tag_closer() );
810860
$this->assertSame( 7, $processor->get_cursor_move_count() );
811-
$this->assertTrue( $processor->next_tag() );
861+
$this->assertTrue( $processor->next_tag( array( 'tag_closers' => 'visit' ) ) );
812862
$this->assertSame( 'HTML', $processor->get_tag() );
813863
$this->assertTrue( $processor->is_tag_closer() );
814864
$this->assertSame( 9, $processor->get_cursor_move_count() ); // Note that next_token() call #8 was for the whitespace between </body> and <html>.
815-
$this->assertFalse( $processor->next_tag() );
865+
$this->assertFalse( $processor->next_tag( array( 'tag_closers' => 'visit' ) ) );
816866
$this->assertSame( 10, $processor->get_cursor_move_count() );
817-
$this->assertFalse( $processor->next_tag() );
867+
$this->assertFalse( $processor->next_tag( array( 'tag_closers' => 'visit' ) ) );
818868
$this->assertSame( 11, $processor->get_cursor_move_count() );
819869
$this->assertTrue( $processor->seek( 'document_root' ) );
820870
$this->assertSame( 12, $processor->get_cursor_move_count() );

0 commit comments

Comments
 (0)