From 80bd30e4c1be58e5b606f917f637a962cdf9e9da Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Fri, 28 Jun 2024 15:45:08 +0000 Subject: [PATCH 01/53] Tests: Use `assertSame()` in `WP_Interactivity_API` tests. This ensures that not only the return values match the expected results, but also that their type is the same. Going forward, stricter type checking by using `assertSame()` should generally be preferred to `assertEquals()` where appropriate, to make the tests more reliable. Follow-up to [57563], [57649], [57822], [57826], [57835], [58159], [58327]. See #61530. git-svn-id: https://develop.svn.wordpress.org/trunk@58594 602fd350-edb4-49c9-b593-d223f7449a82 --- .../wpInteractivityAPI-wp-class.php | 32 ++-- .../wpInteractivityAPI-wp-context.php | 56 +++---- .../wpInteractivityAPI-wp-each.php | 58 +++---- .../wpInteractivityAPI-wp-interactive.php | 36 ++-- .../wpInteractivityAPI-wp-router-region.php | 10 +- .../wpInteractivityAPI-wp-style.php | 66 ++++---- .../wpInteractivityAPI-wp-text.php | 22 +-- .../interactivity-api/wpInteractivityAPI.php | 156 +++++++++--------- .../wpInteractivityAPIDirectivesProcessor.php | 46 +++--- .../wpInteractivityAPIFunctions.php | 68 ++++---- 10 files changed, 275 insertions(+), 275 deletions(-) diff --git a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-class.php b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-class.php index b9cf16952be91..d7bf77bb66470 100644 --- a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-class.php +++ b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-class.php @@ -58,7 +58,7 @@ private function process_directives( $html ) { public function test_wp_class_sets_class_name() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-class', $p->get_attribute( 'class' ) ); + $this->assertSame( 'some-class', $p->get_attribute( 'class' ) ); } /** @@ -76,7 +76,7 @@ public function test_wp_class_sets_multiple_class_names() { data-wp-class--other-class="myPlugin::state.true" >Text'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-class other-class', $p->get_attribute( 'class' ) ); + $this->assertSame( 'some-class other-class', $p->get_attribute( 'class' ) ); } /** @@ -94,7 +94,7 @@ public function test_wp_class_handles_multiple_class_names_with_different_values data-wp-class--other-class="myPlugin::state.false" >Text'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-class', $p->get_attribute( 'class' ) ); + $this->assertSame( 'some-class', $p->get_attribute( 'class' ) ); $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-class', $p->get_attribute( 'class' ) ); + $this->assertSame( 'some-class', $p->get_attribute( 'class' ) ); } /** @@ -116,7 +116,7 @@ class="other-class" public function test_wp_class_sets_class_name_when_class_attribute_exists() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'other-class some-class', $p->get_attribute( 'class' ) ); + $this->assertSame( 'other-class some-class', $p->get_attribute( 'class' ) ); } /** @@ -143,7 +143,7 @@ public function test_wp_class_doesnt_add_class_attribute_on_false() { public function test_wp_class_doesnt_add_class_name_on_false() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'other-class', $p->get_attribute( 'class' ) ); + $this->assertSame( 'other-class', $p->get_attribute( 'class' ) ); } /** @@ -157,7 +157,7 @@ public function test_wp_class_doesnt_add_class_name_on_false() { public function test_wp_class_keeps_class_name_when_class_name_exists() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-class', $p->get_attribute( 'class' ) ); + $this->assertSame( 'some-class', $p->get_attribute( 'class' ) ); } /** @@ -171,7 +171,7 @@ public function test_wp_class_keeps_class_name_when_class_name_exists() { public function test_wp_class_keeps_class_name_when_class_name_exists_and_is_not_the_only_one() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'other-class some-class', $p->get_attribute( 'class' ) ); + $this->assertSame( 'other-class some-class', $p->get_attribute( 'class' ) ); } /** @@ -199,7 +199,7 @@ public function test_wp_class_removes_class_attribute_when_class_name_exists_and public function test_wp_class_removes_class_name_when_class_name_exists_and_is_not_the_only_one() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'other-class', $p->get_attribute( 'class' ) ); + $this->assertSame( 'other-class', $p->get_attribute( 'class' ) ); } /** @@ -227,7 +227,7 @@ public function test_wp_class_doesnt_remove_empty_class_attribute() { public function test_wp_class_doesnt_change_class_attribute_with_empty_directive_suffix() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'other-class', $p->get_attribute( 'class' ) ); + $this->assertSame( 'other-class', $p->get_attribute( 'class' ) ); } /** @@ -242,7 +242,7 @@ public function test_wp_class_doesnt_change_class_attribute_with_empty_directive public function test_wp_class_doesnt_change_class_attribute_with_empty_value() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'other-class', $p->get_attribute( 'class' ) ); + $this->assertSame( 'other-class', $p->get_attribute( 'class' ) ); } /** @@ -257,7 +257,7 @@ public function test_wp_class_doesnt_change_class_attribute_with_empty_value() { public function test_wp_class_doesnt_change_class_attribute_without_value() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'other-class', $p->get_attribute( 'class' ) ); + $this->assertSame( 'other-class', $p->get_attribute( 'class' ) ); } /** @@ -271,7 +271,7 @@ public function test_wp_class_doesnt_change_class_attribute_without_value() { public function test_wp_class_works_with_multiple_directives() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-class', $p->get_attribute( 'class' ) ); + $this->assertSame( 'some-class', $p->get_attribute( 'class' ) ); } /** @@ -286,17 +286,17 @@ public function test_wp_class_sets_class_name_on_truthy_values() { $this->interactivity->state( 'myPlugin', array( 'text' => 'some text' ) ); $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-class', $p->get_attribute( 'class' ) ); + $this->assertSame( 'some-class', $p->get_attribute( 'class' ) ); $this->interactivity->state( 'myPlugin', array( 'array' => array( 1, 2 ) ) ); $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-class', $p->get_attribute( 'class' ) ); + $this->assertSame( 'some-class', $p->get_attribute( 'class' ) ); $this->interactivity->state( 'myPlugin', array( 'number' => 1 ) ); $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-class', $p->get_attribute( 'class' ) ); + $this->assertSame( 'some-class', $p->get_attribute( 'class' ) ); } /** diff --git a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-context.php b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-context.php index 93e2528126215..442c62c84e52f 100644 --- a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-context.php +++ b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-context.php @@ -56,7 +56,7 @@ public function test_wp_context_directive_sets_a_context_in_a_custom_namespace() '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } /** @@ -78,7 +78,7 @@ class="test" '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } /** @@ -99,9 +99,9 @@ public function test_wp_context_directive_merges_context_in_the_same_custom_name '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id-1', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-1', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( 'some-id-2', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-2', $p->get_attribute( 'id' ) ); } /** @@ -121,7 +121,7 @@ public function test_wp_context_directive_overwrites_context_in_the_same_custom_ '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id-2', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-2', $p->get_attribute( 'id' ) ); } /** @@ -142,9 +142,9 @@ public function test_wp_context_directive_replaces_old_context_after_closing_tag '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id-2', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-2', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( 'some-id-1', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-1', $p->get_attribute( 'id' ) ); } /** @@ -165,9 +165,9 @@ public function test_wp_context_directive_merges_context_in_different_custom_nam '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id-1', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-1', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( 'some-id-2', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-2', $p->get_attribute( 'id' ) ); } /** @@ -206,9 +206,9 @@ public function test_wp_context_directive_doesnt_overwrite_context_on_malformed_ '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id-1', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-1', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( 'some-id-1', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-1', $p->get_attribute( 'id' ) ); } /** @@ -247,9 +247,9 @@ public function test_wp_context_directive_doesnt_overwrite_context_on_empty_cont '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id-1', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-1', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( 'some-id-1', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-1', $p->get_attribute( 'id' ) ); } /** @@ -288,9 +288,9 @@ public function test_wp_context_directive_doesnt_overwrite_context_on_context_wi '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id-1', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-1', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( 'some-id-1', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-1', $p->get_attribute( 'id' ) ); } /** @@ -307,7 +307,7 @@ public function test_wp_context_works_with_multiple_directives() { '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } /** @@ -346,7 +346,7 @@ public function test_wp_context_directive_works_with_default_namespace() { '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } /** @@ -368,7 +368,7 @@ public function test_wp_context_directive_overrides_default_namespace() { '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } /** @@ -389,7 +389,7 @@ public function test_wp_context_directive_overrides_default_namespace_with_same_ '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } /** @@ -416,11 +416,11 @@ public function test_wp_context_directive_works_with_nested_default_namespaces() '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'other-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'other-id', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); $this->assertNull( $p->get_attribute( 'id' ) ); } @@ -445,7 +445,7 @@ class="test" '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } /** @@ -469,9 +469,9 @@ public function test_wp_context_directive_merges_context_in_the_same_default_nam '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id-1', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-1', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( 'some-id-2', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-2', $p->get_attribute( 'id' ) ); } /** @@ -494,7 +494,7 @@ public function test_wp_context_directive_overwrites_context_in_the_same_default '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id-2', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-2', $p->get_attribute( 'id' ) ); } /** @@ -518,8 +518,8 @@ public function test_wp_context_directive_replaces_old_context_after_closing_tag '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id-2', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-2', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( 'some-id-1', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id-1', $p->get_attribute( 'id' ) ); } } diff --git a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-each.php b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-each.php index 4628ec702a67b..0446fa461df14 100644 --- a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-each.php +++ b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-each.php @@ -42,7 +42,7 @@ public function test_wp_each_doesnt_do_anything_on_non_template_tags() { '; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $original, $new ); + $this->assertSame( $original, $new ); } /** @@ -68,7 +68,7 @@ public function test_wp_each_doesnt_do_anything_on_associative_arrays() { '; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $original, $new ); + $this->assertSame( $original, $new ); } /** @@ -92,7 +92,7 @@ public function test_wp_each_simple_tags() { '2' . '
Text
'; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); } /** @@ -116,7 +116,7 @@ public function test_wp_each_empty_array() { '' . '
Text
'; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); } /** @@ -145,7 +145,7 @@ public function test_wp_each_merges_context_correctly() { '
New text
' . ''; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); } /** @@ -173,7 +173,7 @@ public function test_wp_each_gets_arrays_from_context() { '
Text
' . ''; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); } /** @@ -201,7 +201,7 @@ public function test_wp_each_default_namespace() { '
Text
' . ''; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); } /** @@ -229,7 +229,7 @@ public function test_wp_each_multiple_tags_per_item() { '2' . '
Text
'; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); } /** @@ -257,7 +257,7 @@ public function test_wp_each_void_tags() { '' . '
Text
'; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); } /** @@ -286,7 +286,7 @@ public function test_wp_each_void_and_non_void_tags() { '2' . '
Text
'; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); } /** @@ -318,7 +318,7 @@ public function test_wp_each_nested_tags() { '' . '
Text
'; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); } /** @@ -361,7 +361,7 @@ public function test_wp_each_nested_item_properties() { 'two' . '
Text
'; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); } /** @@ -385,7 +385,7 @@ public function test_wp_each_different_item_names() { '2' . '
Text
'; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); } /** @@ -410,7 +410,7 @@ public function test_wp_each_different_item_names_transforms_camelcase() { '2' . '
Text
'; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); } /** @@ -426,14 +426,14 @@ public function test_wp_each_doesnt_work_with_top_level_text() { 'id: ' . ''; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $original, $new ); + $this->assertSame( $original, $new ); $original = '' . ''; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $original, $new ); + $this->assertSame( $original, $new ); // But it should work fine with spaces and linebreaks. $original = ' @@ -444,9 +444,9 @@ public function test_wp_each_doesnt_work_with_top_level_text() { $p = new WP_HTML_Tag_Processor( $new ); $p->next_tag( array( 'class_name' => 'test' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( '1', $p->get_attribute( 'id' ) ); + $this->assertSame( '1', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( '2', $p->get_attribute( 'id' ) ); + $this->assertSame( '2', $p->get_attribute( 'id' ) ); } /** @@ -487,7 +487,7 @@ public function test_wp_each_nested_template_tags() { '4' . '
Text
'; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); } /** @@ -533,7 +533,7 @@ public function test_wp_each_directly_nested_template_tags() { '4' . '
Text
'; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); } /** @@ -571,7 +571,7 @@ public function test_wp_each_nested_template_tags_using_previous_item_as_list() '4' . '
Text
'; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); } /** @@ -590,7 +590,7 @@ public function test_wp_each_unbalanced_tags() { '' . '
Text
'; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $original, $new ); + $this->assertSame( $original, $new ); } /** @@ -614,7 +614,7 @@ public function test_wp_each_unbalanced_tags_in_nested_template_tags() { '' . '
Text
'; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $original, $new ); + $this->assertSame( $original, $new ); } /** @@ -639,23 +639,23 @@ public function test_wp_each_doesnt_process_if_not_array() { $this->interactivity->state( 'myPlugin', array( 'list' => null ) ); $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); $this->interactivity->state( 'myPlugin', array( 'list' => 'Text' ) ); $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); $this->interactivity->state( 'myPlugin', array( 'list' => 100 ) ); $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); $this->interactivity->state( 'myPlugin', array( 'list' => false ) ); $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); $this->interactivity->state( 'myPlugin', array( 'list' => true ) ); $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); } /** @@ -682,6 +682,6 @@ public function test_wp_each_doesnt_process_with_manual_server_directive_process '2' . '
Text
'; $new = $this->interactivity->process_directives( $original ); - $this->assertEquals( $expected, $new ); + $this->assertSame( $expected, $new ); } } diff --git a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-interactive.php b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-interactive.php index 65f4e4258b4e3..c1f3b9c8d2ae2 100644 --- a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-interactive.php +++ b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-interactive.php @@ -58,7 +58,7 @@ public function test_wp_interactive_sets_a_default_namespace_with_object() { '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } /** @@ -76,7 +76,7 @@ public function test_wp_interactive_sets_a_default_namespace_with_string() { '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } /** @@ -97,9 +97,9 @@ public function test_wp_interactive_replaces_the_previous_default_namespace() { '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( 'other-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'other-id', $p->get_attribute( 'id' ) ); } /** @@ -121,9 +121,9 @@ public function test_wp_interactive_json_without_namespace_doesnt_replace_the_pr '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } /** @@ -144,9 +144,9 @@ public function test_wp_interactive_with_empty_value_doesnt_replace_the_previous '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } /** @@ -167,9 +167,9 @@ public function test_wp_interactive_with_invalid_value_doesnt_replace_the_previo '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } /** @@ -190,9 +190,9 @@ public function test_wp_interactive_without_value_doesnt_replace_the_previous_de '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } /** @@ -209,7 +209,7 @@ public function test_wp_interactive_works_with_multiple_directives() { '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } /** @@ -227,7 +227,7 @@ public function test_wp_interactive_namespace_can_be_override_by_custom_one() { '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'other-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'other-id', $p->get_attribute( 'id' ) ); } /** @@ -248,9 +248,9 @@ public function test_wp_interactive_set_is_unset_on_closing_tag() { '; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( 'other-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'other-id', $p->get_attribute( 'id' ) ); $html = '
@@ -261,8 +261,8 @@ public function test_wp_interactive_set_is_unset_on_closing_tag() {
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'other-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'other-id', $p->get_attribute( 'id' ) ); $p->next_tag( array( 'class_name' => 'test' ) ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } } diff --git a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-router-region.php b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-router-region.php index 88a03e483db59..8d8cdb6228d2e 100644 --- a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-router-region.php +++ b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-router-region.php @@ -88,9 +88,9 @@ public function test_wp_router_region_missing() { $html = '
Nothing here
'; $new_html = $this->interactivity->process_directives( $html ); $footer = $this->render_wp_footer(); - $this->assertEquals( $html, $new_html ); - $this->assertEquals( '', $footer ); - $this->assertEquals( '', get_echo( 'wp_print_styles' ) ); + $this->assertSame( $html, $new_html ); + $this->assertSame( '', $footer ); + $this->assertSame( '', get_echo( 'wp_print_styles' ) ); } /** @@ -108,14 +108,14 @@ public function test_wp_router_region_adds_loading_bar_aria_live_region_only_onc
Another interactive region
'; $new_html = $this->interactivity->process_directives( $html ); - $this->assertEquals( $html, $new_html ); + $this->assertSame( $html, $new_html ); // Check that the style is loaded, but only once. $styles = get_echo( 'wp_print_styles' ); $query = array( 'tag_name' => 'style' ); $p = new WP_HTML_Tag_Processor( $styles ); $this->assertTrue( $p->next_tag( $query ) ); - $this->assertEquals( 'wp-interactivity-router-animations-inline-css', $p->get_attribute( 'id' ) ); + $this->assertSame( 'wp-interactivity-router-animations-inline-css', $p->get_attribute( 'id' ) ); $this->assertStringContainsString( '.wp-interactivity-router-loading-bar', $styles ); $this->assertFalse( $p->next_tag( $query ) ); diff --git a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-style.php b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-style.php index 3b645b0dd4df3..b69f0c79c392f 100644 --- a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-style.php +++ b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-style.php @@ -61,47 +61,47 @@ private function merge_style_property( $style_attribute_value, $style_property_n public function test_merge_style_property_sets_properties() { // Adds property on empty style attribute. $result = $this->merge_style_property( '', 'color', 'green' ); - $this->assertEquals( 'color:green;', $result ); + $this->assertSame( 'color:green;', $result ); // Changes style property when there is an existing property. $result = $this->merge_style_property( 'color:red;', 'color', 'green' ); - $this->assertEquals( 'color:green;', $result ); + $this->assertSame( 'color:green;', $result ); // Adds a new property when the existing one does not match. $result = $this->merge_style_property( 'color:red;', 'background', 'blue' ); - $this->assertEquals( 'color:red;background:blue;', $result ); + $this->assertSame( 'color:red;background:blue;', $result ); // Handles multiple existing properties. $result = $this->merge_style_property( 'color:red;margin:5px;', 'color', 'green' ); - $this->assertEquals( 'margin:5px;color:green;', $result ); + $this->assertSame( 'margin:5px;color:green;', $result ); // Adds a new property when multiple existing properties do not match. $result = $this->merge_style_property( 'color:red;margin:5px;', 'padding', '10px' ); - $this->assertEquals( 'color:red;margin:5px;padding:10px;', $result ); + $this->assertSame( 'color:red;margin:5px;padding:10px;', $result ); // Removes whitespaces in all properties. $result = $this->merge_style_property( ' color : red; margin : 5px; ', 'padding', ' 10px ' ); - $this->assertEquals( 'color:red;margin:5px;padding:10px;', $result ); + $this->assertSame( 'color:red;margin:5px;padding:10px;', $result ); // Updates a property when it's not the first one in the value. $result = $this->merge_style_property( 'color:red;margin:5px;', 'margin', '15px' ); - $this->assertEquals( 'color:red;margin:15px;', $result ); + $this->assertSame( 'color:red;margin:15px;', $result ); // Adds missing trailing semicolon. $result = $this->merge_style_property( 'color:red;margin:5px', 'padding', '10px' ); - $this->assertEquals( 'color:red;margin:5px;padding:10px;', $result ); + $this->assertSame( 'color:red;margin:5px;padding:10px;', $result ); // Doesn't add double semicolons. $result = $this->merge_style_property( 'color:red;margin:5px;', 'padding', '10px;' ); - $this->assertEquals( 'color:red;margin:5px;padding:10px;', $result ); + $this->assertSame( 'color:red;margin:5px;padding:10px;', $result ); // Handles empty properties in the input. $result = $this->merge_style_property( 'color:red;;margin:5px;;', 'padding', '10px' ); - $this->assertEquals( 'color:red;margin:5px;padding:10px;', $result ); + $this->assertSame( 'color:red;margin:5px;padding:10px;', $result ); // Moves the modified property to the end. $result = $this->merge_style_property( 'border-style: dashed; border: 3px solid red;', 'border-style', 'inset' ); - $this->assertEquals( 'border:3px solid red;border-style:inset;', $result ); + $this->assertSame( 'border:3px solid red;border-style:inset;', $result ); } /** @@ -115,35 +115,35 @@ public function test_merge_style_property_sets_properties() { public function test_merge_style_property_with_falsy_values() { // Removes a property with an empty string. $result = $this->merge_style_property( 'color:red;margin:5px;', 'color', '' ); - $this->assertEquals( 'margin:5px;', $result ); + $this->assertSame( 'margin:5px;', $result ); // Removes a property with null. $result = $this->merge_style_property( 'color:red;margin:5px;', 'color', null ); - $this->assertEquals( 'margin:5px;', $result ); + $this->assertSame( 'margin:5px;', $result ); // Removes a property with false. $result = $this->merge_style_property( 'color:red;margin:5px;', 'color', false ); - $this->assertEquals( 'margin:5px;', $result ); + $this->assertSame( 'margin:5px;', $result ); // Removes a property with 0. $result = $this->merge_style_property( 'color:red;margin:5px;', 'color', 0 ); - $this->assertEquals( 'margin:5px;', $result ); + $this->assertSame( 'margin:5px;', $result ); // It doesn't add a new property with an empty string. $result = $this->merge_style_property( 'color:red;', 'padding', '' ); - $this->assertEquals( 'color:red;', $result ); + $this->assertSame( 'color:red;', $result ); // It doesn't add a new property with null. $result = $this->merge_style_property( 'color:red;', 'padding', null ); - $this->assertEquals( 'color:red;', $result ); + $this->assertSame( 'color:red;', $result ); // It doesn't add a new property with false. $result = $this->merge_style_property( 'color:red;', 'padding', false ); - $this->assertEquals( 'color:red;', $result ); + $this->assertSame( 'color:red;', $result ); // It doesn't add a new property with 0. $result = $this->merge_style_property( 'color:red;', 'padding', 0 ); - $this->assertEquals( 'color:red;', $result ); + $this->assertSame( 'color:red;', $result ); } /** @@ -170,7 +170,7 @@ private function process_directives( $html ) { public function test_wp_style_sets_style_attribute() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'color:green;', $p->get_attribute( 'style' ) ); + $this->assertSame( 'color:green;', $p->get_attribute( 'style' ) ); } /** @@ -188,7 +188,7 @@ public function test_wp_style_sets_multiple_style_properties() { data-wp-style--background="myPlugin::state.green" >Text'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'color:green;background:green;', $p->get_attribute( 'style' ) ); + $this->assertSame( 'color:green;background:green;', $p->get_attribute( 'style' ) ); } /** @@ -206,7 +206,7 @@ public function test_wp_style_sets_multiple_style_properties_with_different_valu data-wp-style--background="myPlugin::state.false" >Text'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'color:green;', $p->get_attribute( 'style' ) ); + $this->assertSame( 'color:green;', $p->get_attribute( 'style' ) ); $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'color:green;', $p->get_attribute( 'style' ) ); + $this->assertSame( 'color:green;', $p->get_attribute( 'style' ) ); } /** @@ -229,7 +229,7 @@ public function test_wp_style_sets_multiple_style_properties_with_different_valu public function test_wp_style_sets_style_property_when_style_attribute_exists() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'padding:10px;color:green;', $p->get_attribute( 'style' ) ); + $this->assertSame( 'padding:10px;color:green;', $p->get_attribute( 'style' ) ); } /** @@ -243,7 +243,7 @@ public function test_wp_style_sets_style_property_when_style_attribute_exists() public function test_wp_style_overwrites_style_property_when_style_property_exists() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'color:green;', $p->get_attribute( 'style' ) ); + $this->assertSame( 'color:green;', $p->get_attribute( 'style' ) ); } /** @@ -271,7 +271,7 @@ public function test_wp_style_doesnt_add_style_attribute_on_false() { public function test_wp_style_doesnt_add_style_property_on_false() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'padding:10px;', $p->get_attribute( 'style' ) ); + $this->assertSame( 'padding:10px;', $p->get_attribute( 'style' ) ); } /** @@ -285,7 +285,7 @@ public function test_wp_style_doesnt_add_style_property_on_false() { public function test_wp_style_keeps_style_property_when_style_property_exists() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'color:green;', $p->get_attribute( 'style' ) ); + $this->assertSame( 'color:green;', $p->get_attribute( 'style' ) ); } /** @@ -299,7 +299,7 @@ public function test_wp_style_keeps_style_property_when_style_property_exists() public function test_wp_style_keeps_style_property_when_style_property_exists_and_is_not_the_only_one() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'padding:10px;color:green;', $p->get_attribute( 'style' ) ); + $this->assertSame( 'padding:10px;color:green;', $p->get_attribute( 'style' ) ); } /** @@ -327,7 +327,7 @@ public function test_wp_style_removes_style_attribute_when_style_property_exists public function test_wp_style_removes_style_property_when_style_property_exists_and_is_not_the_only_one() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'padding:10px;', $p->get_attribute( 'style' ) ); + $this->assertSame( 'padding:10px;', $p->get_attribute( 'style' ) ); } /** @@ -355,7 +355,7 @@ public function test_wp_style_doesnt_remove_empty_style_attribute() { public function test_wp_style_doesnt_change_style_attribute_with_empty_directive_suffix() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'padding:10px;', $p->get_attribute( 'style' ) ); + $this->assertSame( 'padding:10px;', $p->get_attribute( 'style' ) ); } /** @@ -370,7 +370,7 @@ public function test_wp_style_doesnt_change_style_attribute_with_empty_directive public function test_wp_style_doesnt_change_style_attribute_with_empty_value() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'padding:10px;', $p->get_attribute( 'style' ) ); + $this->assertSame( 'padding:10px;', $p->get_attribute( 'style' ) ); } /** @@ -385,7 +385,7 @@ public function test_wp_style_doesnt_change_style_attribute_with_empty_value() { public function test_wp_style_doesnt_change_style_attribute_without_value() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'padding:10px;', $p->get_attribute( 'style' ) ); + $this->assertSame( 'padding:10px;', $p->get_attribute( 'style' ) ); } /** @@ -399,7 +399,7 @@ public function test_wp_style_doesnt_change_style_attribute_without_value() { public function test_wp_style_works_with_multiple_directives() { $html = '
Text
'; list($p) = $this->process_directives( $html ); - $this->assertEquals( 'color:green;', $p->get_attribute( 'style' ) ); + $this->assertSame( 'color:green;', $p->get_attribute( 'style' ) ); } /** diff --git a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-text.php b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-text.php index d031698707960..dc19b1117de39 100644 --- a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-text.php +++ b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI-wp-text.php @@ -39,7 +39,7 @@ public function set_up() { public function test_wp_text_sets_inner_content() { $html = '
Text
'; $new_html = $this->interactivity->process_directives( $html ); - $this->assertEquals( '
Updated
', $new_html ); + $this->assertSame( '
Updated
', $new_html ); } /** @@ -53,7 +53,7 @@ public function test_wp_text_sets_inner_content_numbers() { $this->interactivity->state( 'myPlugin', array( 'number' => 100 ) ); $html = '
Text
'; $new_html = $this->interactivity->process_directives( $html ); - $this->assertEquals( '
100
', $new_html ); + $this->assertSame( '
100
', $new_html ); } /** @@ -77,23 +77,23 @@ public function test_wp_text_removes_inner_content_on_types_that_are_not_strings ); $html = '
Text
'; $new_html = $this->interactivity->process_directives( $html ); - $this->assertEquals( '
', $new_html ); + $this->assertSame( '
', $new_html ); $html = '
Text
'; $new_html = $this->interactivity->process_directives( $html ); - $this->assertEquals( '
', $new_html ); + $this->assertSame( '
', $new_html ); $html = '
Text
'; $new_html = $this->interactivity->process_directives( $html ); - $this->assertEquals( '
', $new_html ); + $this->assertSame( '
', $new_html ); $html = '
Text
'; $new_html = $this->interactivity->process_directives( $html ); - $this->assertEquals( '
', $new_html ); + $this->assertSame( '
', $new_html ); $html = '
Text
'; $new_html = $this->interactivity->process_directives( $html ); - $this->assertEquals( '
', $new_html ); + $this->assertSame( '
', $new_html ); } /** @@ -107,7 +107,7 @@ public function test_wp_text_removes_inner_content_on_types_that_are_not_strings public function test_wp_text_sets_inner_content_with_nested_tags() { $html = '
Text
Another text
'; $new_html = $this->interactivity->process_directives( $html ); - $this->assertEquals( '
Updated
', $new_html ); + $this->assertSame( '
Updated
', $new_html ); } /** @@ -121,7 +121,7 @@ public function test_wp_text_sets_inner_content_with_nested_tags() { public function test_wp_text_sets_inner_content_even_with_unbalanced_but_different_tags_inside_content() { $html = '
Text
'; $new_html = $this->interactivity->process_directives( $html ); - $this->assertEquals( '
Updated
', $new_html ); + $this->assertSame( '
Updated
', $new_html ); } /** @@ -137,7 +137,7 @@ public function test_wp_text_sets_inner_content_even_with_unbalanced_but_differe public function test_wp_text_fails_with_unbalanced_and_same_tags_inside_content() { $html = '
Text
'; $new_html = $this->interactivity->process_directives( $html ); - $this->assertEquals( '
Text
', $new_html ); + $this->assertSame( '
Text
', $new_html ); } /** @@ -152,6 +152,6 @@ public function test_wp_text_cant_set_inner_html_in_the_content() { $this->interactivity->state( 'myPlugin', array( 'text' => 'Updated' ) ); $html = '
Text
'; $new_html = $this->interactivity->process_directives( $html ); - $this->assertEquals( '
<span>Updated</span>
', $new_html ); + $this->assertSame( '
<span>Updated</span>
', $new_html ); } } diff --git a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php index 25c8c2dc3abce..9832b65bf4874 100644 --- a/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php +++ b/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php @@ -69,8 +69,8 @@ private function set_internal_context_stack( ...$stack ) { * @covers ::config */ public function test_state_and_config_should_be_empty() { - $this->assertEquals( array(), $this->interactivity->state( 'myPlugin' ) ); - $this->assertEquals( array(), $this->interactivity->config( 'myPlugin' ) ); + $this->assertSame( array(), $this->interactivity->state( 'myPlugin' ) ); + $this->assertSame( array(), $this->interactivity->config( 'myPlugin' ) ); } /** @@ -89,9 +89,9 @@ public function test_state_and_config_can_be_changed() { 'nested' => array( 'c' => 3 ), ); $result = $this->interactivity->state( 'myPlugin', $state ); - $this->assertEquals( $state, $result ); + $this->assertSame( $state, $result ); $result = $this->interactivity->config( 'myPlugin', $state ); - $this->assertEquals( $state, $result ); + $this->assertSame( $state, $result ); } /** @@ -106,14 +106,14 @@ public function test_state_and_config_can_be_merged() { $this->interactivity->state( 'myPlugin', array( 'a' => 1 ) ); $this->interactivity->state( 'myPlugin', array( 'b' => 2 ) ); $this->interactivity->state( 'otherPlugin', array( 'c' => 3 ) ); - $this->assertEquals( + $this->assertSame( array( 'a' => 1, 'b' => 2, ), $this->interactivity->state( 'myPlugin' ) ); - $this->assertEquals( + $this->assertSame( array( 'c' => 3 ), $this->interactivity->state( 'otherPlugin' ) ); @@ -121,14 +121,14 @@ public function test_state_and_config_can_be_merged() { $this->interactivity->config( 'myPlugin', array( 'a' => 1 ) ); $this->interactivity->config( 'myPlugin', array( 'b' => 2 ) ); $this->interactivity->config( 'otherPlugin', array( 'c' => 3 ) ); - $this->assertEquals( + $this->assertSame( array( 'a' => 1, 'b' => 2, ), $this->interactivity->config( 'myPlugin' ) ); - $this->assertEquals( + $this->assertSame( array( 'c' => 3 ), $this->interactivity->config( 'otherPlugin' ) ); } @@ -145,14 +145,14 @@ public function test_state_and_config_can_be_merged() { public function test_state_and_config_existing_props_can_be_overwritten() { $this->interactivity->state( 'myPlugin', array( 'a' => 1 ) ); $this->interactivity->state( 'myPlugin', array( 'a' => 2 ) ); - $this->assertEquals( + $this->assertSame( array( 'a' => 2 ), $this->interactivity->state( 'myPlugin' ) ); $this->interactivity->config( 'myPlugin', array( 'a' => 1 ) ); $this->interactivity->config( 'myPlugin', array( 'a' => 2 ) ); - $this->assertEquals( + $this->assertSame( array( 'a' => 2 ), $this->interactivity->config( 'myPlugin' ) ); @@ -170,14 +170,14 @@ public function test_state_and_config_existing_props_can_be_overwritten() { public function test_state_and_config_existing_indexed_arrays_are_replaced() { $this->interactivity->state( 'myPlugin', array( 'a' => array( 1, 2 ) ) ); $this->interactivity->state( 'myPlugin', array( 'a' => array( 3, 4 ) ) ); - $this->assertEquals( + $this->assertSame( array( 'a' => array( 3, 4 ) ), $this->interactivity->state( 'myPlugin' ) ); $this->interactivity->config( 'myPlugin', array( 'a' => array( 1, 2 ) ) ); $this->interactivity->config( 'myPlugin', array( 'a' => array( 3, 4 ) ) ); - $this->assertEquals( + $this->assertSame( array( 'a' => array( 3, 4 ) ), $this->interactivity->config( 'myPlugin' ) ); @@ -218,10 +218,10 @@ public function test_state_and_config_is_correctly_printed() { 'otherPlugin' => array( 'b' => 2 ), ); - $this->assertEquals( + $this->assertSame( array( - 'state' => $data, 'config' => $data, + 'state' => $data, ), $result ); @@ -251,7 +251,7 @@ public function test_state_and_config_dont_print_when_empty() { public function test_config_not_printed_when_empty() { $this->interactivity->state( 'myPlugin', array( 'a' => 1 ) ); $result = $this->print_client_interactivity_data(); - $this->assertEquals( array( 'state' => array( 'myPlugin' => array( 'a' => 1 ) ) ), $result ); + $this->assertSame( array( 'state' => array( 'myPlugin' => array( 'a' => 1 ) ) ), $result ); } /** @@ -265,7 +265,7 @@ public function test_config_not_printed_when_empty() { public function test_state_not_printed_when_empty() { $this->interactivity->config( 'myPlugin', array( 'a' => 1 ) ); $result = $this->print_client_interactivity_data(); - $this->assertEquals( array( 'config' => array( 'myPlugin' => array( 'a' => 1 ) ) ), $result ); + $this->assertSame( array( 'config' => array( 'myPlugin' => array( 'a' => 1 ) ) ), $result ); } /** @@ -286,7 +286,7 @@ public function test_state_not_printed_when_empty_array() { SCRIPT_TAG; - $this->assertSame( $expected, $printed_script ); + $this->assertSameIgnoreEOL( $expected, $printed_script ); } /** @@ -319,7 +319,7 @@ public function test_state_printed_correctly_with_nested_empty_array() { SCRIPT_TAG; - $this->assertSame( $expected, $printed_script ); + $this->assertSameIgnoreEOL( $expected, $printed_script ); } /** @@ -340,7 +340,7 @@ public function test_config_not_printed_when_empty_array() { SCRIPT_TAG; - $this->assertSame( $expected, $printed_script ); + $this->assertSameIgnoreEOL( $expected, $printed_script ); } /** @@ -373,7 +373,7 @@ public function test_config_printed_correctly_with_nested_empty_array() { SCRIPT_TAG; - $this->assertSame( $expected, $printed_script ); + $this->assertSameIgnoreEOL( $expected, $printed_script ); } /** @@ -410,7 +410,7 @@ public function test_state_and_config_escape_special_characters() { $expected = <<<"JSON" {"config":{"myPlugin":{"chars":"&\\u003C\\u003E/"}},"state":{"myPlugin":{"ampersand":"&","less-than sign":"\\u003C","greater-than sign":"\\u003E","solidus":"/","line separator":"\u{2028}","paragraph separator":"\u{2029}","flag of england":"\u{1F3F4}\u{E0067}\u{E0062}\u{E0065}\u{E006E}\u{E0067}\u{E007F}","malicious script closer":"\\u003C/script\\u003E","entity-encoded malicious script closer":"</script>"}}} JSON; - $this->assertEquals( $expected, $interactivity_data_string[1] ); + $this->assertSame( $expected, $interactivity_data_string[1] ); } /** @@ -450,7 +450,7 @@ public function test_state_and_config_escape_special_characters_non_utf8() { $expected = <<<"JSON" {"config":{"myPlugin":{"chars":"&\\u003C\\u003E/"}},"state":{"myPlugin":{"ampersand":"&","less-than sign":"\\u003C","greater-than sign":"\\u003E","solidus":"/","line separator":"\\u2028","paragraph separator":"\\u2029","flag of england":"\\ud83c\\udff4\\udb40\\udc67\\udb40\\udc62\\udb40\\udc65\\udb40\\udc6e\\udb40\\udc67\\udb40\\udc7f","malicious script closer":"\\u003C/script\\u003E","entity-encoded malicious script closer":"</script>"}}} JSON; - $this->assertEquals( $expected, $interactivity_data_string[1] ); + $this->assertSame( $expected, $interactivity_data_string[1] ); } /** @@ -467,7 +467,7 @@ public function test_state_without_namespace() { $this->interactivity->state( 'myPlugin', array( 'a' => 1 ) ); $this->interactivity->state( 'otherPlugin', array( 'b' => 2 ) ); - $this->assertEquals( + $this->assertSame( array( 'a' => 1 ), $this->interactivity->state() ); @@ -488,7 +488,7 @@ public function test_state_with_data_and_invalid_namespace() { $this->interactivity->state( 'myPlugin', array( 'a' => 1 ) ); $this->interactivity->state( 'otherPlugin', array( 'b' => 2 ) ); - $this->assertEquals( + $this->assertSame( array(), $this->interactivity->state( null, array( 'newProp' => 'value' ) ) ); @@ -508,7 +508,7 @@ public function test_state_with_empty_string_as_namespace() { $this->interactivity->state( 'myPlugin', array( 'a' => 1 ) ); $this->interactivity->state( 'otherPlugin', array( 'b' => 2 ) ); - $this->assertEquals( + $this->assertSame( array(), $this->interactivity->state( '' ) ); @@ -524,7 +524,7 @@ public function test_state_with_empty_string_as_namespace() { * @expectedIncorrectUsage WP_Interactivity_API::state */ public function test_state_without_namespace_outside_directive_processing() { - $this->assertEquals( + $this->assertSame( array(), $this->interactivity->state() ); @@ -550,11 +550,11 @@ public function test_get_context_with_namespace() { ) ); - $this->assertEquals( + $this->assertSame( array( 'a' => 1 ), $this->interactivity->get_context( 'myPlugin' ) ); - $this->assertEquals( + $this->assertSame( array( 'b' => 2 ), $this->interactivity->get_context( 'otherPlugin' ) ); @@ -580,7 +580,7 @@ public function test_get_context_without_namespace() { ) ); - $this->assertEquals( + $this->assertSame( array( 'a' => 1 ), $this->interactivity->get_context() ); @@ -598,7 +598,7 @@ public function test_get_context_with_empty_context_stack() { $this->set_internal_namespace_stack( 'myPlugin' ); $this->set_internal_context_stack(); - $this->assertEquals( + $this->assertSame( array(), $this->interactivity->get_context( 'myPlugin' ) ); @@ -623,7 +623,7 @@ public function test_get_context_with_undefined_namespace() { ) ); - $this->assertEquals( + $this->assertSame( array(), $this->interactivity->get_context( 'otherPlugin' ) ); @@ -648,7 +648,7 @@ public function test_get_context_with_empty_namespace() { ) ); - $this->assertEquals( + $this->assertSame( array(), $this->interactivity->get_context( '' ) ); @@ -666,7 +666,7 @@ public function test_get_context_with_empty_namespace() { */ public function test_get_context_outside_of_directive_processing() { $context = $this->interactivity->get_context(); - $this->assertEquals( array(), $context ); + $this->assertSame( array(), $context ); } /** @@ -681,55 +681,55 @@ public function test_extract_directive_value() { $extract_directive_value->setAccessible( true ); $result = $extract_directive_value->invoke( $this->interactivity, 'state.foo', 'myPlugin' ); - $this->assertEquals( array( 'myPlugin', 'state.foo' ), $result ); + $this->assertSame( array( 'myPlugin', 'state.foo' ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, 'otherPlugin::state.foo', 'myPlugin' ); - $this->assertEquals( array( 'otherPlugin', 'state.foo' ), $result ); + $this->assertSame( array( 'otherPlugin', 'state.foo' ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, '{ "isOpen": false }', 'myPlugin' ); - $this->assertEquals( array( 'myPlugin', array( 'isOpen' => false ) ), $result ); + $this->assertSame( array( 'myPlugin', array( 'isOpen' => false ) ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, 'otherPlugin::{ "isOpen": false }', 'myPlugin' ); - $this->assertEquals( array( 'otherPlugin', array( 'isOpen' => false ) ), $result ); + $this->assertSame( array( 'otherPlugin', array( 'isOpen' => false ) ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, 'true', 'myPlugin' ); - $this->assertEquals( array( 'myPlugin', true ), $result ); + $this->assertSame( array( 'myPlugin', true ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, 'false', 'myPlugin' ); - $this->assertEquals( array( 'myPlugin', false ), $result ); + $this->assertSame( array( 'myPlugin', false ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, 'null', 'myPlugin' ); - $this->assertEquals( array( 'myPlugin', null ), $result ); + $this->assertSame( array( 'myPlugin', null ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, '100', 'myPlugin' ); - $this->assertEquals( array( 'myPlugin', 100 ), $result ); + $this->assertSame( array( 'myPlugin', 100 ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, '1.2', 'myPlugin' ); - $this->assertEquals( array( 'myPlugin', 1.2 ), $result ); + $this->assertSame( array( 'myPlugin', 1.2 ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, '1.2.3', 'myPlugin' ); - $this->assertEquals( array( 'myPlugin', '1.2.3' ), $result ); + $this->assertSame( array( 'myPlugin', '1.2.3' ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, 'otherPlugin::true', 'myPlugin' ); - $this->assertEquals( array( 'otherPlugin', true ), $result ); + $this->assertSame( array( 'otherPlugin', true ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, 'otherPlugin::false', 'myPlugin' ); - $this->assertEquals( array( 'otherPlugin', false ), $result ); + $this->assertSame( array( 'otherPlugin', false ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, 'otherPlugin::null', 'myPlugin' ); - $this->assertEquals( array( 'otherPlugin', null ), $result ); + $this->assertSame( array( 'otherPlugin', null ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, 'otherPlugin::100', 'myPlugin' ); - $this->assertEquals( array( 'otherPlugin', 100 ), $result ); + $this->assertSame( array( 'otherPlugin', 100 ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, 'otherPlugin::1.2', 'myPlugin' ); - $this->assertEquals( array( 'otherPlugin', 1.2 ), $result ); + $this->assertSame( array( 'otherPlugin', 1.2 ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, 'otherPlugin::1.2.3', 'myPlugin' ); - $this->assertEquals( array( 'otherPlugin', '1.2.3' ), $result ); + $this->assertSame( array( 'otherPlugin', '1.2.3' ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, 'otherPlugin::[{"o":4}, null, 3e6]', 'myPlugin' ); - $this->assertEquals( array( 'otherPlugin', array( array( 'o' => 4 ), null, 3000000.0 ) ), $result ); + $this->assertSame( array( 'otherPlugin', array( array( 'o' => 4 ), null, 3000000.0 ) ), $result ); } /** @@ -744,26 +744,26 @@ public function test_extract_directive_value_empty_values() { $extract_directive_value->setAccessible( true ); $result = $extract_directive_value->invoke( $this->interactivity, '', 'myPlugin' ); - $this->assertEquals( array( 'myPlugin', null ), $result ); + $this->assertSame( array( 'myPlugin', null ), $result ); // This is a boolean attribute. $result = $extract_directive_value->invoke( $this->interactivity, true, 'myPlugin' ); - $this->assertEquals( array( 'myPlugin', null ), $result ); + $this->assertSame( array( 'myPlugin', null ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, false, 'myPlugin' ); - $this->assertEquals( array( 'myPlugin', null ), $result ); + $this->assertSame( array( 'myPlugin', null ), $result ); $result = $extract_directive_value->invoke( $this->interactivity, null, 'myPlugin' ); - $this->assertEquals( array( 'myPlugin', null ), $result ); + $this->assertSame( array( 'myPlugin', null ), $result ); // A string ending in `::` without any extra characters is not considered a // namespace. $result = $extract_directive_value->invoke( $this->interactivity, 'myPlugin::', 'myPlugin' ); - $this->assertEquals( array( 'myPlugin', 'myPlugin::' ), $result ); + $this->assertSame( array( 'myPlugin', 'myPlugin::' ), $result ); // A namespace with invalid characters is not considered a valid namespace. $result = $extract_directive_value->invoke( $this->interactivity, '$myPlugin::state.foo', 'myPlugin' ); - $this->assertEquals( array( 'myPlugin', '$myPlugin::state.foo' ), $result ); + $this->assertSame( array( 'myPlugin', '$myPlugin::state.foo' ), $result ); } /** @@ -779,11 +779,11 @@ public function test_extract_directive_value_invalid_json() { // Invalid JSON due to missing quotes. Returns the original value. $result = $extract_directive_value->invoke( $this->interactivity, '{ isOpen: false }', 'myPlugin' ); - $this->assertEquals( array( 'myPlugin', '{ isOpen: false }' ), $result ); + $this->assertSame( array( 'myPlugin', '{ isOpen: false }' ), $result ); // Null string. Returns null. $result = $extract_directive_value->invoke( $this->interactivity, 'null', 'myPlugin' ); - $this->assertEquals( array( 'myPlugin', null ), $result ); + $this->assertSame( array( 'myPlugin', null ), $result ); } /** @@ -799,13 +799,13 @@ public function test_extract_prefix_and_suffix() { $extract_prefix_and_suffix->setAccessible( true ); $result = $extract_prefix_and_suffix->invoke( $this->interactivity, 'data-wp-interactive' ); - $this->assertEquals( array( 'data-wp-interactive' ), $result ); + $this->assertSame( array( 'data-wp-interactive' ), $result ); $result = $extract_prefix_and_suffix->invoke( $this->interactivity, 'data-wp-bind--src' ); - $this->assertEquals( array( 'data-wp-bind', 'src' ), $result ); + $this->assertSame( array( 'data-wp-bind', 'src' ), $result ); $result = $extract_prefix_and_suffix->invoke( $this->interactivity, 'data-wp-foo--and--bar' ); - $this->assertEquals( array( 'data-wp-foo', 'and--bar' ), $result ); + $this->assertSame( array( 'data-wp-foo', 'and--bar' ), $result ); } /** @@ -819,11 +819,11 @@ public function test_extract_prefix_and_suffix() { public function test_process_directives_do_nothing_without_directives() { $html = '
Inner content here
'; $processed_html = $this->interactivity->process_directives( $html ); - $this->assertEquals( $html, $processed_html ); + $this->assertSame( $html, $processed_html ); $html = '
ContentMore Content
'; $processed_html = $this->interactivity->process_directives( $html ); - $this->assertEquals( $html, $processed_html ); + $this->assertSame( $html, $processed_html ); } /** @@ -840,7 +840,7 @@ public function test_process_directives_changes_html_with_balanced_tags() { $processed_html = $this->interactivity->process_directives( $html ); $p = new WP_HTML_Tag_Processor( $processed_html ); $p->next_tag(); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } /** @@ -853,7 +853,7 @@ public function test_process_directives_changes_html_with_balanced_tags() { public function test_process_directives_doesnt_fail_with_unknown_directives() { $html = '
Text
'; $processed_html = $this->interactivity->process_directives( $html ); - $this->assertEquals( $html, $processed_html ); + $this->assertSame( $html, $processed_html ); } /** @@ -876,9 +876,9 @@ public function test_process_directives_process_the_directives_in_the_correct_or $processed_html = $this->interactivity->process_directives( $html ); $p = new WP_HTML_Tag_Processor( $processed_html ); $p->next_tag(); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); - $this->assertEquals( 'some-class', $p->get_attribute( 'class' ) ); - $this->assertEquals( 'display:none;', $p->get_attribute( 'style' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-class', $p->get_attribute( 'class' ) ); + $this->assertSame( 'display:none;', $p->get_attribute( 'style' ) ); $this->assertStringContainsString( 'Updated', $p->get_updated_html() ); $this->assertStringNotContainsString( 'Text', $p->get_updated_html() ); } @@ -952,7 +952,7 @@ public function test_process_directives_changes_html_if_contains_svgs() { $processed_html = $this->interactivity->process_directives( $html ); $p = new WP_HTML_Tag_Processor( $processed_html ); $p->next_tag( 'div' ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } /** @@ -1017,7 +1017,7 @@ public function test_process_directives_change_html_if_contains_math() { $p->next_tag( 'math' ); $this->assertNull( $p->get_attribute( 'id' ) ); $p->next_tag( 'div' ); - $this->assertEquals( 'some-id', $p->get_attribute( 'id' ) ); + $this->assertSame( 'some-id', $p->get_attribute( 'id' ) ); } /** @@ -1121,16 +1121,16 @@ public function offsetUnset( $offset ): void {} $this->set_internal_namespace_stack( 'myPlugin' ); $result = $this->evaluate( 'state.key' ); - $this->assertEquals( 'myPlugin-state', $result ); + $this->assertSame( 'myPlugin-state', $result ); $result = $this->evaluate( 'context.key' ); - $this->assertEquals( 'myPlugin-context', $result ); + $this->assertSame( 'myPlugin-context', $result ); $result = $this->evaluate( 'otherPlugin::state.key' ); - $this->assertEquals( 'otherPlugin-state', $result ); + $this->assertSame( 'otherPlugin-state', $result ); $result = $this->evaluate( 'otherPlugin::context.key' ); - $this->assertEquals( 'otherPlugin-context', $result ); + $this->assertSame( 'otherPlugin-context', $result ); $result = $this->evaluate( 'state.obj.prop' ); $this->assertSame( 'object property', $result ); @@ -1241,16 +1241,16 @@ public function test_evaluate_nested_value() { $this->set_internal_namespace_stack( 'myPlugin' ); $result = $this->evaluate( 'state.nested.key' ); - $this->assertEquals( 'myPlugin-state-nested', $result ); + $this->assertSame( 'myPlugin-state-nested', $result ); $result = $this->evaluate( 'context.nested.key' ); - $this->assertEquals( 'myPlugin-context-nested', $result ); + $this->assertSame( 'myPlugin-context-nested', $result ); $result = $this->evaluate( 'otherPlugin::state.nested.key' ); - $this->assertEquals( 'otherPlugin-state-nested', $result ); + $this->assertSame( 'otherPlugin-state-nested', $result ); $result = $this->evaluate( 'otherPlugin::context.nested.key' ); - $this->assertEquals( 'otherPlugin-context-nested', $result ); + $this->assertSame( 'otherPlugin-context-nested', $result ); } /** diff --git a/tests/phpunit/tests/interactivity-api/wpInteractivityAPIDirectivesProcessor.php b/tests/phpunit/tests/interactivity-api/wpInteractivityAPIDirectivesProcessor.php index 5812c061666c8..d674f5e54ce06 100644 --- a/tests/phpunit/tests/interactivity-api/wpInteractivityAPIDirectivesProcessor.php +++ b/tests/phpunit/tests/interactivity-api/wpInteractivityAPIDirectivesProcessor.php @@ -24,14 +24,14 @@ public function test_get_content_between_balanced_template_tags_standard_tags() $content = ''; $p = new WP_Interactivity_API_Directives_Processor( $content ); $p->next_tag(); - $this->assertEquals( 'Text', $p->get_content_between_balanced_template_tags() ); + $this->assertSame( 'Text', $p->get_content_between_balanced_template_tags() ); $content = ''; $p = new WP_Interactivity_API_Directives_Processor( $content ); $p->next_tag(); - $this->assertEquals( 'Text', $p->get_content_between_balanced_template_tags() ); + $this->assertSame( 'Text', $p->get_content_between_balanced_template_tags() ); $p->next_tag(); - $this->assertEquals( 'More text', $p->get_content_between_balanced_template_tags() ); + $this->assertSame( 'More text', $p->get_content_between_balanced_template_tags() ); } /** @@ -46,7 +46,7 @@ public function test_get_content_between_balanced_template_tags_empty_tag() { $content = ''; $p = new WP_Interactivity_API_Directives_Processor( $content ); $p->next_tag(); - $this->assertEquals( '', $p->get_content_between_balanced_template_tags() ); + $this->assertSame( '', $p->get_content_between_balanced_template_tags() ); } /** @@ -81,12 +81,12 @@ public function test_get_content_between_balanced_template_tags_nested_tags() { $content = ''; $p = new WP_Interactivity_API_Directives_Processor( $content ); $p->next_tag(); - $this->assertEquals( 'ContentMore Content', $p->get_content_between_balanced_template_tags() ); + $this->assertSame( 'ContentMore Content', $p->get_content_between_balanced_template_tags() ); $content = ''; $p = new WP_Interactivity_API_Directives_Processor( $content ); $p->next_tag(); - $this->assertEquals( '', $p->get_content_between_balanced_template_tags() ); + $this->assertSame( '', $p->get_content_between_balanced_template_tags() ); } /** @@ -131,7 +131,7 @@ public function test_get_content_between_balanced_template_tags_with_unbalanced_ $content = ''; $p = new WP_Interactivity_API_Directives_Processor( $content ); $p->next_tag(); - $this->assertEquals( 'Missing opening span', $p->get_content_between_balanced_template_tags() ); + $this->assertSame( 'Missing opening span', $p->get_content_between_balanced_template_tags() ); } /** @@ -163,10 +163,10 @@ public function test_get_content_between_balanced_template_tags_positions_cursor $p = new WP_Interactivity_API_Directives_Processor( $content ); $p->next_tag(); $p->get_content_between_balanced_template_tags(); - $this->assertEquals( 'TEMPLATE', $p->get_tag() ); + $this->assertSame( 'TEMPLATE', $p->get_tag() ); $this->assertTrue( $p->is_tag_closer() ); $p->next_tag(); - $this->assertEquals( 'DIV', $p->get_tag() ); + $this->assertSame( 'DIV', $p->get_tag() ); } /** @@ -479,13 +479,13 @@ public function test_append_content_after_template_tag_closer_simple_tags() { $this->assertTrue( $result ); $this->assertEquals( $content_1 . $content_2, $p ); $p->next_tag( array( 'tag_closers' => 'visit' ) ); - $this->assertEquals( 'content-2', $p->get_attribute( 'class' ) ); + $this->assertSame( 'content-2', $p->get_attribute( 'class' ) ); $p->next_tag( array( 'tag_closers' => 'visit' ) ); $result = $p->append_content_after_template_tag_closer( $content_3 ); $this->assertTrue( $result ); $p->next_tag( array( 'tag_closers' => 'visit' ) ); $this->assertEquals( $content_1 . $content_2 . $content_3, $p ); - $this->assertEquals( 'content-3', $p->get_attribute( 'class' ) ); + $this->assertSame( 'content-3', $p->get_attribute( 'class' ) ); } /** @@ -509,7 +509,7 @@ public function test_append_content_after_template_tag_closer_in_the_middle_of_t $this->assertTrue( $result ); $this->assertEquals( $content_1 . $content_2 . $content_3, $p ); $p->next_tag( array( 'tag_closers' => 'visit' ) ); - $this->assertEquals( 'content-3', $p->get_attribute( 'class' ) ); + $this->assertSame( 'content-3', $p->get_attribute( 'class' ) ); $p = new WP_Interactivity_API_Directives_Processor( $content_1 . $content_3 ); $p->next_tag( array( 'tag_closers' => 'visit' ) ); @@ -518,7 +518,7 @@ public function test_append_content_after_template_tag_closer_in_the_middle_of_t $this->assertTrue( $result ); $this->assertEquals( $content_1 . $content_4 . $content_3, $p ); $p->next_tag( array( 'tag_closers' => 'visit' ) ); - $this->assertEquals( 'content-4', $p->get_attribute( 'class' ) ); + $this->assertSame( 'content-4', $p->get_attribute( 'class' ) ); } /** @@ -558,16 +558,16 @@ public function test_append_content_after_template_tag_closer_multiple_calls_in_ $this->assertTrue( $result ); $this->assertEquals( $content_1 . $content_2, $p ); $p->next_tag( array( 'tag_closers' => 'visit' ) ); - $this->assertEquals( 'content-2', $p->get_attribute( 'class' ) ); + $this->assertSame( 'content-2', $p->get_attribute( 'class' ) ); // Rewinds to the first template. $p->seek( 'first template' ); $p->release_bookmark( 'first template' ); - $this->assertEquals( 'content-1', $p->get_attribute( 'class' ) ); + $this->assertSame( 'content-1', $p->get_attribute( 'class' ) ); $p->next_tag( array( 'tag_closers' => 'visit' ) ); $result = $p->append_content_after_template_tag_closer( $content_3 ); $this->assertEquals( $content_1 . $content_3 . $content_2, $p ); $p->next_tag( array( 'tag_closers' => 'visit' ) ); - $this->assertEquals( 'content-3', $p->get_attribute( 'class' ) ); + $this->assertSame( 'content-3', $p->get_attribute( 'class' ) ); } /** @@ -615,9 +615,9 @@ public function test_append_content_after_template_tag_closer_with_existing_tags $this->assertTrue( $result ); $this->assertEquals( $content_1 . $content_2, $p ); $p->next_tag(); - $this->assertEquals( 'content-2-template-1', $p->get_attribute( 'class' ) ); + $this->assertSame( 'content-2-template-1', $p->get_attribute( 'class' ) ); $p->next_tag(); - $this->assertEquals( 'content-2-template-2', $p->get_attribute( 'class' ) ); + $this->assertSame( 'content-2-template-2', $p->get_attribute( 'class' ) ); $p->next_tag( array( 'tag_closers' => 'visit' ) ); $result = $p->append_content_after_template_tag_closer( $content_3 ); $this->assertTrue( $result ); @@ -640,7 +640,7 @@ public function test_append_content_after_template_tag_closer_empty() { $result = $p->append_content_after_template_tag_closer( '' ); $this->assertFalse( $result ); $this->assertEquals( $content, $p ); - $this->assertEquals( 'TEMPLATE', $p->get_tag() ); // It didn't move. + $this->assertSame( 'TEMPLATE', $p->get_tag() ); // It didn't move. $this->assertTrue( $p->is_tag_closer() ); // It didn't move. } @@ -694,7 +694,7 @@ public function test_next_balanced_tag_closer_tag_standard_tags() { $p = new WP_Interactivity_API_Directives_Processor( $content ); $p->next_tag(); $this->assertTrue( $p->next_balanced_tag_closer_tag() ); - $this->assertEquals( 'DIV', $p->get_tag() ); + $this->assertSame( 'DIV', $p->get_tag() ); $this->assertTrue( $p->is_tag_closer() ); } @@ -731,14 +731,14 @@ public function test_next_balanced_tag_closer_tag_nested_tags() { $p = new WP_Interactivity_API_Directives_Processor( $content ); $p->next_tag(); $this->assertTrue( $p->next_balanced_tag_closer_tag() ); - $this->assertEquals( 'DIV', $p->get_tag() ); + $this->assertSame( 'DIV', $p->get_tag() ); $this->assertTrue( $p->is_tag_closer() ); $content = '
Nested content
'; $p = new WP_Interactivity_API_Directives_Processor( $content ); $p->next_tag(); $this->assertTrue( $p->next_balanced_tag_closer_tag() ); - $this->assertEquals( 'DIV', $p->get_tag() ); + $this->assertSame( 'DIV', $p->get_tag() ); $this->assertTrue( $p->is_tag_closer() ); $this->assertFalse( $p->next_tag() ); // No more content. } @@ -793,7 +793,7 @@ public function test_skip_to_tag_closer() { $p->next_tag(); $this->assertTrue( $p->skip_to_tag_closer() ); $this->assertTrue( $p->is_tag_closer() ); - $this->assertEquals( 'DIV', $p->get_tag() ); + $this->assertSame( 'DIV', $p->get_tag() ); } /** diff --git a/tests/phpunit/tests/interactivity-api/wpInteractivityAPIFunctions.php b/tests/phpunit/tests/interactivity-api/wpInteractivityAPIFunctions.php index 259b8a32b744b..8a59f181a3b99 100644 --- a/tests/phpunit/tests/interactivity-api/wpInteractivityAPIFunctions.php +++ b/tests/phpunit/tests/interactivity-api/wpInteractivityAPIFunctions.php @@ -76,7 +76,7 @@ public function test_process_directives_of_single_interactive_block() { $rendered_blocks = do_blocks( $post_content ); $p = new WP_HTML_Tag_Processor( $rendered_blocks ); $p->next_tag( array( 'class_name' => 'interactive/block-1' ) ); - $this->assertEquals( '1', $p->get_attribute( 'value' ) ); + $this->assertSame( '1', $p->get_attribute( 'value' ) ); } /** @@ -97,13 +97,13 @@ public function test_process_directives_of_multiple_interactive_blocks_in_parall $rendered_blocks = do_blocks( $post_content ); $p = new WP_HTML_Tag_Processor( $rendered_blocks ); $p->next_tag( array( 'class_name' => 'interactive/block-1' ) ); - $this->assertEquals( '1', $p->get_attribute( 'value' ) ); + $this->assertSame( '1', $p->get_attribute( 'value' ) ); $p->next_tag( array( 'class_name' => 'interactive/block-2' ) ); - $this->assertEquals( '2', $p->get_attribute( 'value' ) ); + $this->assertSame( '2', $p->get_attribute( 'value' ) ); $p->next_tag( array( 'class_name' => 'non-interactive/block-3' ) ); $this->assertNull( $p->get_attribute( 'value' ) ); $p->next_tag( array( 'class_name' => 'interactive/block-4' ) ); - $this->assertEquals( '4', $p->get_attribute( 'value' ) ); + $this->assertSame( '4', $p->get_attribute( 'value' ) ); } /** @@ -122,7 +122,7 @@ public function test_process_directives_of_interactive_block_inside_non_interact $rendered_blocks = do_blocks( $post_content ); $p = new WP_HTML_Tag_Processor( $rendered_blocks ); $p->next_tag( array( 'class_name' => 'interactive/block-2' ) ); - $this->assertEquals( '2', $p->get_attribute( 'value' ) ); + $this->assertSame( '2', $p->get_attribute( 'value' ) ); } /** @@ -143,9 +143,9 @@ public function test_process_directives_of_multiple_interactive_blocks_inside_no $rendered_blocks = do_blocks( $post_content ); $p = new WP_HTML_Tag_Processor( $rendered_blocks ); $p->next_tag( array( 'class_name' => 'interactive/block-2' ) ); - $this->assertEquals( '2', $p->get_attribute( 'value' ) ); + $this->assertSame( '2', $p->get_attribute( 'value' ) ); $p->next_tag( array( 'class_name' => 'interactive/block-3' ) ); - $this->assertEquals( '3', $p->get_attribute( 'value' ) ); + $this->assertSame( '3', $p->get_attribute( 'value' ) ); } /** @@ -168,9 +168,9 @@ public function test_process_directives_of_interactive_block_inside_multiple_non $rendered_blocks = do_blocks( $post_content ); $p = new WP_HTML_Tag_Processor( $rendered_blocks ); $p->next_tag( array( 'class_name' => 'interactive/block-2' ) ); - $this->assertEquals( '2', $p->get_attribute( 'value' ) ); + $this->assertSame( '2', $p->get_attribute( 'value' ) ); $p->next_tag( array( 'class_name' => 'interactive/block-4' ) ); - $this->assertEquals( '4', $p->get_attribute( 'value' ) ); + $this->assertSame( '4', $p->get_attribute( 'value' ) ); } /** @@ -190,7 +190,7 @@ public function test_process_directives_of_interactive_block_containing_non_inte $rendered_blocks = do_blocks( $post_content ); $p = new WP_HTML_Tag_Processor( $rendered_blocks ); $p->next_tag( array( 'class_name' => 'interactive/block-1' ) ); - $this->assertEquals( '1', $p->get_attribute( 'value' ) ); + $this->assertSame( '1', $p->get_attribute( 'value' ) ); $p->next_tag( array( 'class_name' => 'non-interactive/block-2' ) ); $this->assertNull( $p->get_attribute( 'value' ) ); } @@ -212,9 +212,9 @@ public function test_process_directives_of_interactive_block_containing_non_inte $rendered_blocks = do_blocks( $post_content ); $p = new WP_HTML_Tag_Processor( $rendered_blocks ); $p->next_tag( array( 'class_name' => 'interactive/block-1' ) ); - $this->assertEquals( '1', $p->get_attribute( 'value' ) ); + $this->assertSame( '1', $p->get_attribute( 'value' ) ); $p->next_tag( array( 'class_name' => 'non-interactive/block-2' ) ); - $this->assertEquals( '1', $p->get_attribute( 'value' ) ); + $this->assertSame( '1', $p->get_attribute( 'value' ) ); } /** @@ -238,13 +238,13 @@ public function test_process_directives_of_interactive_block_containing_nested_i $rendered_blocks = do_blocks( $post_content ); $p = new WP_HTML_Tag_Processor( $rendered_blocks ); $p->next_tag( array( 'class_name' => 'interactive/block-1' ) ); - $this->assertEquals( '1', $p->get_attribute( 'value' ) ); + $this->assertSame( '1', $p->get_attribute( 'value' ) ); $p->next_tag( array( 'class_name' => 'interactive/block-2' ) ); - $this->assertEquals( '2', $p->get_attribute( 'value' ) ); + $this->assertSame( '2', $p->get_attribute( 'value' ) ); $p->next_tag( array( 'class_name' => 'non-interactive/block-3' ) ); - $this->assertEquals( '2', $p->get_attribute( 'value' ) ); + $this->assertSame( '2', $p->get_attribute( 'value' ) ); $p->next_tag( array( 'class_name' => 'non-interactive/block-4' ) ); - $this->assertEquals( '1', $p->get_attribute( 'value' ) ); + $this->assertSame( '1', $p->get_attribute( 'value' ) ); } /** @@ -288,7 +288,7 @@ public function test_process_directives_only_process_the_root_interactive_blocks $html = '
'; $this->data_wp_test_processor_count = 0; wp_interactivity_process_directives( $html ); - $this->assertEquals( 1, $this->data_wp_test_processor_count ); + $this->assertSame( 1, $this->data_wp_test_processor_count ); register_block_type( 'test/custom-directive-block', @@ -309,7 +309,7 @@ public function test_process_directives_only_process_the_root_interactive_blocks $this->data_wp_test_processor_count = 0; do_blocks( $post_content ); unregister_block_type( 'test/custom-directive-block' ); - $this->assertEquals( 2, $this->data_wp_test_processor_count ); + $this->assertSame( 2, $this->data_wp_test_processor_count ); $directive_processors->setValue( null, $old_directive_processors ); } @@ -343,7 +343,7 @@ function test_render_block_data( $parsed_block ) { $processor->next_tag( array( 'data-wp-interactive' => 'nameSpace' ) ); remove_filter( 'render_block_data', 'test_render_block_data' ); unregister_block_type( 'test/custom-directive-block' ); - $this->assertEquals( 'test', $processor->get_attribute( 'value' ) ); + $this->assertSame( 'test', $processor->get_attribute( 'value' ) ); } /** @@ -355,8 +355,8 @@ function test_render_block_data( $parsed_block ) { * @covers wp_interactivity_data_wp_context */ public function test_wp_interactivity_data_wp_context_with_different_arrays() { - $this->assertEquals( 'data-wp-context=\'{}\'', wp_interactivity_data_wp_context( array() ) ); - $this->assertEquals( + $this->assertSame( 'data-wp-context=\'{}\'', wp_interactivity_data_wp_context( array() ) ); + $this->assertSame( 'data-wp-context=\'{"a":1,"b":"2","c":true}\'', wp_interactivity_data_wp_context( array( @@ -366,11 +366,11 @@ public function test_wp_interactivity_data_wp_context_with_different_arrays() { ) ) ); - $this->assertEquals( + $this->assertSame( 'data-wp-context=\'{"a":[1,2]}\'', wp_interactivity_data_wp_context( array( 'a' => array( 1, 2 ) ) ) ); - $this->assertEquals( + $this->assertSame( 'data-wp-context=\'[1,2]\'', wp_interactivity_data_wp_context( array( 1, 2 ) ) ); @@ -385,8 +385,8 @@ public function test_wp_interactivity_data_wp_context_with_different_arrays() { * @covers wp_interactivity_data_wp_context */ public function test_wp_interactivity_data_wp_context_with_different_arrays_and_a_namespace() { - $this->assertEquals( 'data-wp-context=\'myPlugin::{}\'', wp_interactivity_data_wp_context( array(), 'myPlugin' ) ); - $this->assertEquals( + $this->assertSame( 'data-wp-context=\'myPlugin::{}\'', wp_interactivity_data_wp_context( array(), 'myPlugin' ) ); + $this->assertSame( 'data-wp-context=\'myPlugin::{"a":1,"b":"2","c":true}\'', wp_interactivity_data_wp_context( array( @@ -397,11 +397,11 @@ public function test_wp_interactivity_data_wp_context_with_different_arrays_and_ 'myPlugin' ) ); - $this->assertEquals( + $this->assertSame( 'data-wp-context=\'myPlugin::{"a":[1,2]}\'', wp_interactivity_data_wp_context( array( 'a' => array( 1, 2 ) ), 'myPlugin' ) ); - $this->assertEquals( + $this->assertSame( 'data-wp-context=\'myPlugin::[1,2]\'', wp_interactivity_data_wp_context( array( 1, 2 ), 'myPlugin' ) ); @@ -418,10 +418,10 @@ public function test_wp_interactivity_data_wp_context_with_different_arrays_and_ * @covers wp_interactivity_data_wp_context */ public function test_wp_interactivity_data_wp_context_with_json_flags() { - $this->assertEquals( 'data-wp-context=\'{"tag":"\u003Cfoo\u003E"}\'', wp_interactivity_data_wp_context( array( 'tag' => '' ) ) ); - $this->assertEquals( 'data-wp-context=\'{"apos":"\u0027bar\u0027"}\'', wp_interactivity_data_wp_context( array( 'apos' => "'bar'" ) ) ); - $this->assertEquals( 'data-wp-context=\'{"quot":"\u0022baz\u0022"}\'', wp_interactivity_data_wp_context( array( 'quot' => '"baz"' ) ) ); - $this->assertEquals( 'data-wp-context=\'{"amp":"T\u0026T"}\'', wp_interactivity_data_wp_context( array( 'amp' => 'T&T' ) ) ); + $this->assertSame( 'data-wp-context=\'{"tag":"\u003Cfoo\u003E"}\'', wp_interactivity_data_wp_context( array( 'tag' => '' ) ) ); + $this->assertSame( 'data-wp-context=\'{"apos":"\u0027bar\u0027"}\'', wp_interactivity_data_wp_context( array( 'apos' => "'bar'" ) ) ); + $this->assertSame( 'data-wp-context=\'{"quot":"\u0022baz\u0022"}\'', wp_interactivity_data_wp_context( array( 'quot' => '"baz"' ) ) ); + $this->assertSame( 'data-wp-context=\'{"amp":"T\u0026T"}\'', wp_interactivity_data_wp_context( array( 'amp' => 'T&T' ) ) ); } /** @@ -448,7 +448,7 @@ public function test_process_directives_in_tags_that_dont_visit_closer_tag() { $processor = new WP_HTML_Tag_Processor( $processed_content ); $processor->next_tag( array( 'class_name' => 'test' ) ); unregister_block_type( 'test/custom-directive-block' ); - $this->assertEquals( '1', $processor->get_attribute( 'src' ) ); + $this->assertSame( '1', $processor->get_attribute( 'src' ) ); } /** @@ -488,8 +488,8 @@ public function test_process_context_directive_in_void_tags() { ); $second_input_value = $processor->get_attribute( 'value' ); unregister_block_type( 'test/custom-directive-block' ); - $this->assertEquals( 'inner', $first_input_value ); - $this->assertEquals( 'outer', $second_input_value ); + $this->assertSame( 'inner', $first_input_value ); + $this->assertSame( 'outer', $second_input_value ); } /** From b9ecee377a35ba042d7b30e9480f66e543f7196a Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Fri, 28 Jun 2024 18:16:56 +0000 Subject: [PATCH 02/53] Build/Test Tools: Introduce two additional reusable PHPUnit workflows. The changes associated with #61213 aim to update all branches potentially receiving security updates to use the same workflow files for easier maintenance as much as possible. However, there are times when the logic found in GitHub Action workflow files changes pretty drastically. For PHPUnit testing, there are 2 instances where this occurred: the 5.2 and 5.9 branches. This changeset introduces 2 new reusable PHPUnit workflow files for use the 4.1-5.1 and 5.2-5.9 branches. Including these workflows in `trunk` makes it more clear which version of the workflow file is used by these old branches, and allows Dependabot to open PRs for updating 3rd-party actions within these workflows. Props jorbin. See #61213. git-svn-id: https://develop.svn.wordpress.org/trunk@58595 602fd350-edb4-49c9-b593-d223f7449a82 --- .../workflows/reusable-phpunit-tests-v1.yml | 184 ++++++++++++++++ .../workflows/reusable-phpunit-tests-v2.yml | 205 ++++++++++++++++++ .github/workflows/reusable-phpunit-tests.yml | 2 + 3 files changed, 391 insertions(+) create mode 100644 .github/workflows/reusable-phpunit-tests-v1.yml create mode 100644 .github/workflows/reusable-phpunit-tests-v2.yml diff --git a/.github/workflows/reusable-phpunit-tests-v1.yml b/.github/workflows/reusable-phpunit-tests-v1.yml new file mode 100644 index 0000000000000..8331d863f8258 --- /dev/null +++ b/.github/workflows/reusable-phpunit-tests-v1.yml @@ -0,0 +1,184 @@ +## +# DEPRECATED +# +# A reusable workflow that runs the PHPUnit test suite with the specified configuration. +# +# This workflow is used by branches 4.1 through 5.1. +## +name: Run PHPUnit tests + +on: + workflow_call: + inputs: + os: + description: 'Operating system to run tests on' + required: false + type: 'string' + default: 'ubuntu-latest' + php: + description: 'The version of PHP to use, in the format of X.Y' + required: true + type: 'string' + phpunit: + description: 'The PHPUnit version to use when running tests. See .env for details about valid values.' + required: false + type: 'string' + default: ${{ inputs.php }}-fpm + multisite: + description: 'Whether to run tests as multisite' + required: false + type: 'boolean' + default: false + split_slow: + description: 'Whether to run slow tests group.' + required: false + type: 'boolean' + default: false + memcached: + description: 'Whether to test with memcached enabled' + required: false + type: 'boolean' + default: false + phpunit-config: + description: 'The PHPUnit configuration file to use' + required: false + type: 'string' + default: 'phpunit.xml.dist' + allow-errors: + description: 'Whether to continue when test errors occur.' + required: false + type: boolean + default: false +env: + LOCAL_PHP: ${{ inputs.php }}-fpm + LOCAL_PHPUNIT: ${{ inputs.phpunit && inputs.phpunit || inputs.php }}-fpm + LOCAL_PHP_MEMCACHED: ${{ inputs.memcached }} + PHPUNIT_CONFIG: ${{ inputs.phpunit-config }} + PHPUNIT_SCRIPT: php + PUPPETEER_SKIP_DOWNLOAD: ${{ true }} + SLOW_TESTS: 'external-http,media' + +jobs: + # Runs the PHPUnit tests for WordPress. + # + # Performs the following steps: + # - Sets environment variables. + # - Sets up the environment variables needed for testing with memcached (if desired). + # - Installs NodeJS. + # - Build WordPress + # _ Installs npm dependencies. + # - Configures caching for Composer. + # _ Installs Composer dependencies (if desired). + # - Logs Docker debug information (about the Docker installation within the runner). + # - Starts the WordPress Docker container. + # - Starts the Memcached server after the Docker network has been created (if desired). + # - Logs general debug information about the runner. + # - Logs the running Docker containers. + # - Logs debug information from inside the WordPress Docker container. + # - Logs debug information about what's installed within the WordPress Docker containers. + # - Install WordPress within the Docker container. + # - Run the PHPUnit tests. + test-php: + name: PHP ${{ inputs.php }} / ${{ inputs.multisite && ' Multisite' || 'Single site' }}${{ inputs.split_slow && ' slow tests' || '' }}${{ inputs.memcached && ' with memcached' || '' }} + runs-on: ${{ inputs.os }} + timeout-minutes: 20 + + steps: + - name: Configure environment variables + run: | + echo "PHP_FPM_UID=$(id -u)" >> $GITHUB_ENV + echo "PHP_FPM_GID=$(id -g)" >> $GITHUB_ENV + + - name: Checkout repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + with: + show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} + + - name: Set up Node.js + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version-file: '.nvmrc' + cache: npm + + - name: Install Dependencies + run: npm ci + + - name: Build WordPress + run: npm run build + + - name: Cache Composer dependencies + if: ${{ env.COMPOSER_INSTALL == true }} + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + env: + cache-name: cache-composer-dependencies + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-php-${{ inputs.php }}-composer-${{ hashFiles('**/composer.lock') }} + + - name: Install Composer dependencies + if: ${{ env.COMPOSER_INSTALL == true }} + run: | + docker compose run --rm php composer --version + docker compose run --rm php composer install + + - name: Docker debug information + run: | + docker -v + docker compose -v + + - name: Start Docker environment + run: | + npm run env:start + + # The memcached server needs to start after the Docker network has been set up with `npm run env:start`. + - name: Start the Memcached server. + if: ${{ inputs.memcached }} + run: | + cp tests/phpunit/includes/object-cache.php build/wp-content/object-cache.php + docker run --name memcached --net $(basename "$PWD")_wpdevnet -d memcached + + - name: General debug information + run: | + npm --version + node --version + curl --version + git --version + svn --version + + - name: Log running Docker containers + run: docker ps -a + + - name: WordPress Docker container debug information + run: | + docker compose run --rm mysql mysql --version + docker compose run --rm php php --version + docker compose run --rm php php -m + docker compose run --rm php php -i + docker compose run --rm php locale -a + + - name: Install WordPress + run: npm run env:install + + - name: Run slow PHPUnit tests + if: ${{ inputs.split_slow }} + run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c ${{ env.PHPUNIT_CONFIG }} --group ${{ env.SLOW_TESTS }} + + - name: Run PHPUnit tests for single site excluding slow tests + if: ${{ inputs.php < '7.0' && ! inputs.split_slow && ! inputs.multisite }} + run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c ${{ env.PHPUNIT_CONFIG }} --exclude-group ${{ env.SLOW_TESTS }},ajax,ms-files,ms-required + + - name: Run PHPUnit tests for Multisite excluding slow tests + if: ${{ inputs.php < '7.0' && ! inputs.split_slow && inputs.multisite }} + run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c ${{ env.PHPUNIT_CONFIG }} --exclude-group ${{ env.SLOW_TESTS }},ajax,ms-files,ms-excluded,oembed-headers + + - name: Run PHPUnit tests + if: ${{ inputs.php >= '7.0' }} + run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c ${{ env.PHPUNIT_CONFIG }} + + - name: Run AJAX tests + if: ${{ ! inputs.multisite && ! inputs.split_slow }} + run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c ${{ env.PHPUNIT_CONFIG }} --group ajax + + - name: Run external HTTP tests + if: ${{ ! inputs.multisite && ! inputs.split_slow }} + run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c phpunit.xml.dist --group external-http diff --git a/.github/workflows/reusable-phpunit-tests-v2.yml b/.github/workflows/reusable-phpunit-tests-v2.yml new file mode 100644 index 0000000000000..e9539d377ea03 --- /dev/null +++ b/.github/workflows/reusable-phpunit-tests-v2.yml @@ -0,0 +1,205 @@ +## +# DEPRECATED +# +# A reusable workflow that runs the PHPUnit test suite with the specified configuration. +# +# This workflow is used by branches 5.2 through 5.8. +## +name: Run PHPUnit tests + +on: + workflow_call: + inputs: + os: + description: 'Operating system to run tests on' + required: false + type: 'string' + default: 'ubuntu-latest' + php: + description: 'The version of PHP to use, in the format of X.Y' + required: true + type: 'string' + multisite: + description: 'Whether to run tests as multisite' + required: false + type: 'boolean' + default: false + split_slow: + description: 'Whether to run slow tests group.' + required: false + type: 'boolean' + default: false + test_ajax: + description: 'Whether to run AJAX tests.' + required: false + type: 'boolean' + default: true + memcached: + description: 'Whether to test with memcached enabled' + required: false + type: 'boolean' + default: false + phpunit-config: + description: 'The PHPUnit configuration file to use' + required: false + type: 'string' + default: 'phpunit.xml.dist' + report: + description: 'Whether to report results to WordPress.org Hosting Tests' + required: false + type: 'boolean' + default: false + allow-errors: + description: 'Whether to continue when test errors occur.' + required: false + type: boolean + default: false +env: + LOCAL_PHP: ${{ inputs.php }}-fpm + LOCAL_PHP_MEMCACHED: ${{ inputs.memcached }} + PHPUNIT_CONFIG: ${{ inputs.phpunit-config }} + PUPPETEER_SKIP_DOWNLOAD: ${{ true }} + # Controls which npm script to use for running PHPUnit tests. Options ar `php` and `php-composer`. + PHPUNIT_SCRIPT: php + SLOW_TESTS: 'external-http,media' + +jobs: + # Runs the PHPUnit tests for WordPress. + # + # Performs the following steps: + # - Sets environment variables. + # - Checks out the repository. + # - Installs Node.js. + # - Installs npm dependencies + # - Configures caching for Composer. + # - Installs Composer dependencies. + # - Logs Docker debug information (about the Docker installation within the runner). + # - Starts the WordPress Docker container. + # - Logs general debug information about the runner. + # - Logs the running Docker containers. + # - Logs debug information from inside the WordPress Docker container. + # - Install WordPress within the Docker container. + # - Run the PHPUnit tests. + # - Ensures version-controlled files are not modified or deleted. + test-php: + name: PHP ${{ inputs.php }} / ${{ inputs.multisite && ' Multisite' || 'Single Site' }}${{ inputs.split_slow && ' slow tests' || '' }}${{ inputs.memcached && ' with memcached' || '' }} + runs-on: ${{ inputs.os }} + timeout-minutes: 20 + + steps: + - name: Configure environment variables + run: | + echo "PHP_FPM_UID=$(id -u)" >> $GITHUB_ENV + echo "PHP_FPM_GID=$(id -g)" >> $GITHUB_ENV + + - name: Checkout repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + with: + show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} + + - name: Install Node.js + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version-file: '.nvmrc' + cache: npm + + - name: Install npm dependencies + run: npm ci + + - name: Get composer cache directory + id: composer-cache + run: echo "composer_dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache Composer dependencies + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + env: + cache-name: cache-composer-dependencies + with: + path: ${{ steps.composer-cache.outputs.composer_dir }} + key: ${{ runner.os }}-php-${{ inputs.php }}-composer-${{ hashFiles('**/composer.lock') }} + + - name: Install Composer dependencies + run: | + docker compose run --rm php composer --version + + # The PHPUnit 7.x phar is not compatible with PHP 8 and won't be updated, + # as PHPUnit 7 is no longer supported. The Composer-installed PHPUnit should be + # used for PHP 8 testing instead. + if [ ${{ env.LOCAL_PHP }} == '8.0-fpm' ]; then + docker compose run --rm php composer install --ignore-platform-reqs + echo "PHPUNIT_SCRIPT=php-composer" >> $GITHUB_ENV + elif [ ${{ env.LOCAL_PHP }} == '7.1-fpm' ]; then + docker compose run --rm php composer update + git checkout -- composer.lock + elif [[ ${{ env.LOCAL_PHP }} == '5.6-fpm' || ${{ env.LOCAL_PHP }} == '7.0-fpm' ]]; then + docker compose run --rm php composer require --dev phpunit/phpunit:"^5.7" --update-with-dependencies + git checkout -- composer.lock composer.json + else + docker compose run --rm php composer install + fi + + - name: Docker debug information + run: | + docker -v + docker compose -v + + - name: Start Docker environment + run: | + npm run env:start + + - name: General debug information + run: | + npm --version + node --version + curl --version + git --version + + - name: Log running Docker containers + run: docker ps -a + + - name: WordPress Docker container debug information + run: | + docker compose run --rm mysql mysql --version + docker compose run --rm php php --version + docker compose run --rm php php -m + docker compose run --rm php php -i + docker compose run --rm php locale -a + + - name: Install WordPress + run: npm run env:install + + - name: Run slow PHPUnit tests + if: ${{ inputs.split_slow }} + run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c ${{ env.PHPUNIT_CONFIG }} --group ${{ env.SLOW_TESTS }} + + - name: Run PHPUnit tests for single site excluding slow tests + if: ${{ inputs.php < '7.0' && ! inputs.split_slow && ! inputs.multisite }} + run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c ${{ env.PHPUNIT_CONFIG }} --exclude-group ${{ env.SLOW_TESTS }},ajax,ms-files,ms-required + + - name: Run PHPUnit tests for Multisite excluding slow tests + if: ${{ inputs.php < '7.0' && ! inputs.split_slow && inputs.multisite }} + run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c ${{ env.PHPUNIT_CONFIG }} --exclude-group ${{ env.SLOW_TESTS }},ajax,ms-files,ms-excluded,oembed-headers + + - name: Run PHPUnit tests + if: ${{ inputs.php >= '7.0' }} + run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c ${{ env.PHPUNIT_CONFIG }} + + - name: Run AJAX tests + if: ${{ ! inputs.split_slow&& inputs.test_ajax }} + run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c ${{ env.PHPUNIT_CONFIG }} --group ajax + + - name: Run ms-files tests as a multisite install + if: ${{ inputs.multisite && ! inputs.split_slow }} + run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c ${{ env.PHPUNIT_CONFIG }} --group ms-files + + - name: Run external HTTP tests + if: ${{ ! inputs.multisite && ! inputs.split_slow }} + run: npm run test:${{ env.PHPUNIT_SCRIPT }} -- --verbose -c phpunit.xml.dist --group external-http + + # __fakegroup__ is excluded to force PHPUnit to ignore the settings in phpunit.xml.dist. + - name: Run (xDebug) tests + if: ${{ ! inputs.split_slow }} + run: LOCAL_PHP_XDEBUG=true npm run test:${{ env.PHPUNIT_SCRIPT }} -- -v --group xdebug --exclude-group __fakegroup__ + + - name: Ensure version-controlled files are not modified or deleted + run: git diff --exit-code diff --git a/.github/workflows/reusable-phpunit-tests.yml b/.github/workflows/reusable-phpunit-tests.yml index d5302b83b2a07..ed0e8f7b13cba 100644 --- a/.github/workflows/reusable-phpunit-tests.yml +++ b/.github/workflows/reusable-phpunit-tests.yml @@ -1,5 +1,7 @@ ## # A reusable workflow that runs the PHPUnit test suite with the specified configuration. +# +# This workflow is used by `trunk` and branches >= 5.9. ## name: Run PHPUnit tests From d3ac93a93839fbe5e441309607786bacdad755cd Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Fri, 28 Jun 2024 18:19:51 +0000 Subject: [PATCH 03/53] Build/Test Tools: Allow older branches to use Coding Standards workflow. This updates the reusable coding standards GitHub Actions workflow to support the old way of running PHPCS commands when the `old-branches` input flag is set to `true`. This allows the 5.1-5.4 branches to use the same workflow as all other 5.5+ branches. See #61213. git-svn-id: https://develop.svn.wordpress.org/trunk@58596 602fd350-edb4-49c9-b593-d223f7449a82 --- .github/workflows/reusable-coding-standards-php.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/reusable-coding-standards-php.yml b/.github/workflows/reusable-coding-standards-php.yml index 3f8520c2f74d7..296b61bcbd499 100644 --- a/.github/workflows/reusable-coding-standards-php.yml +++ b/.github/workflows/reusable-coding-standards-php.yml @@ -11,6 +11,11 @@ on: required: false type: 'string' default: 'latest' + old-branch: + description: 'Whether this is an old branch that runs phpcbf instead of phpcs' + required: false + type: 'boolean' + default: false jobs: # Runs the PHP coding standards checks. @@ -74,6 +79,7 @@ jobs: - name: Run PHPCS on all Core files id: phpcs-core + if: ${{ ! inputs.old-branch }} run: phpcs -n --report-full --cache=./.cache/phpcs-src.json --report-checkstyle=./.cache/phpcs-report.xml - name: Show PHPCS results in PR @@ -82,11 +88,16 @@ jobs: - name: Check test suite files for warnings id: phpcs-tests + if: ${{ ! inputs.old-branch }} run: phpcs tests --report-full --cache=./.cache/phpcs-tests.json --report-checkstyle=./.cache/phpcs-tests-report.xml - name: Show test suite scan results in PR if: ${{ always() && steps.phpcs-tests.outcome == 'failure' }} run: cs2pr ./.cache/phpcs-tests-report.xml + - name: Run PHPCBF on all Core files (old branches) + if: ${{ inputs.old-branch }} + run: phpcbf + - name: Ensure version-controlled files are not modified during the tests run: git diff --exit-code From 57910f67dd4ba8b1db1a5699be916ce0c805a69b Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Sat, 29 Jun 2024 09:29:08 +0000 Subject: [PATCH 04/53] Date/Time: Replace abbreviations for minutes in `human_time_diff()`. This ensures that relative times are formatted the same way in both JS and PHP. Follow-up to [1976], [2124], [4658], [41018], [56496]. Props wildworks. Fixes #61535. git-svn-id: https://develop.svn.wordpress.org/trunk@58600 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/formatting.php | 4 ++-- tests/phpunit/tests/formatting/humanTimeDiff.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php index 85ca2452123d4..8e2aa3cfa9ad0 100644 --- a/src/wp-includes/formatting.php +++ b/src/wp-includes/formatting.php @@ -3856,7 +3856,7 @@ function sanitize_email( $email ) { * Determines the difference between two timestamps. * * The difference is returned in a human-readable format such as "1 hour", - * "5 mins", "2 days". + * "5 minutes", "2 days". * * @since 1.5.0 * @since 5.3.0 Added support for showing a difference in seconds. @@ -3885,7 +3885,7 @@ function human_time_diff( $from, $to = 0 ) { $mins = 1; } /* translators: Time difference between two dates, in minutes (min=minute). %s: Number of minutes. */ - $since = sprintf( _n( '%s min', '%s mins', $mins ), $mins ); + $since = sprintf( _n( '%s minutes', '%s minutes', $mins ), $mins ); } elseif ( $diff < DAY_IN_SECONDS && $diff >= HOUR_IN_SECONDS ) { $hours = round( $diff / HOUR_IN_SECONDS ); if ( $hours <= 1 ) { diff --git a/tests/phpunit/tests/formatting/humanTimeDiff.php b/tests/phpunit/tests/formatting/humanTimeDiff.php index 0a2bffb367b5a..fcf4ff43d46c9 100644 --- a/tests/phpunit/tests/formatting/humanTimeDiff.php +++ b/tests/phpunit/tests/formatting/humanTimeDiff.php @@ -27,7 +27,7 @@ public function data_human_time_diff() { 'Test a difference of 37 seconds.', ), array( - '5 mins', + '5 minutes', new DateTime( '2016-01-01 12:05:00' ), 'Test a difference of 5 minutes.', ), From 6645c75e54c377d5adccc8e065562514f89a5427 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Sun, 30 Jun 2024 14:56:23 +0000 Subject: [PATCH 05/53] Date/Time: Correct singular form for minutes in `human_time_diff()`. Follow-up to [58600]. Props wildworks. See #61535. git-svn-id: https://develop.svn.wordpress.org/trunk@58601 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/formatting.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/formatting.php b/src/wp-includes/formatting.php index 8e2aa3cfa9ad0..cd1ee2689489e 100644 --- a/src/wp-includes/formatting.php +++ b/src/wp-includes/formatting.php @@ -3884,8 +3884,8 @@ function human_time_diff( $from, $to = 0 ) { if ( $mins <= 1 ) { $mins = 1; } - /* translators: Time difference between two dates, in minutes (min=minute). %s: Number of minutes. */ - $since = sprintf( _n( '%s minutes', '%s minutes', $mins ), $mins ); + /* translators: Time difference between two dates, in minutes. %s: Number of minutes. */ + $since = sprintf( _n( '%s minute', '%s minutes', $mins ), $mins ); } elseif ( $diff < DAY_IN_SECONDS && $diff >= HOUR_IN_SECONDS ) { $hours = round( $diff / HOUR_IN_SECONDS ); if ( $hours <= 1 ) { From 80409a2420c3766e54ef120cf9043e041c3372dd Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Mon, 1 Jul 2024 20:43:55 +0000 Subject: [PATCH 06/53] REST API: Correct image cropping tools in the block editor. As of [58457], the width and height cropping values are cast to an integer before the comparison to see if the target width and height differ from the original width and height. Since they are now integers, it exposes a bug where the `&&` of the `if` conditional meant that if you were only cropping in one dimension, the check wouldn't pass, and cropping would not occur. In the block editor, the cropping tools are aspect ratio based, so one of the dimensions will always match that of the source image. Therefore, now that the values are cast as integers, the condition that allows a cropping to occur needs to be updated. If either width or height is different from the source image, then a crop should be allowed. Follow-up to [50124], [58457]. Props andrewserong, jrf, kevin940726. Fixes #61514. See #59782. git-svn-id: https://develop.svn.wordpress.org/trunk@58612 602fd350-edb4-49c9-b593-d223f7449a82 --- .../class-wp-rest-attachments-controller.php | 2 +- .../rest-api/rest-attachments-controller.php | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php index 370025d927d2f..cbc62b49ea17b 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php @@ -626,7 +626,7 @@ public function edit_media_item( $request ) { $width = (int) round( ( $size['width'] * $args['width'] ) / 100.0 ); $height = (int) round( ( $size['height'] * $args['height'] ) / 100.0 ); - if ( $size['width'] !== $width && $size['height'] !== $height ) { + if ( $size['width'] !== $width || $size['height'] !== $height ) { $result = $image_editor->crop( $crop_x, $crop_y, $width, $height ); if ( is_wp_error( $result ) ) { diff --git a/tests/phpunit/tests/rest-api/rest-attachments-controller.php b/tests/phpunit/tests/rest-api/rest-attachments-controller.php index 074c710c740f5..737c32b8e1ab1 100644 --- a/tests/phpunit/tests/rest-api/rest-attachments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-attachments-controller.php @@ -2381,6 +2381,43 @@ public function test_edit_image_crop() { ); } + /** + * @ticket 61514 + * @requires function imagejpeg + */ + public function test_edit_image_crop_one_axis() { + wp_set_current_user( self::$superadmin_id ); + $attachment = self::factory()->attachment->create_upload_object( self::$test_file ); + + $this->setup_mock_editor(); + WP_Image_Editor_Mock::$size_return = array( + 'width' => 640, + 'height' => 480, + ); + + WP_Image_Editor_Mock::$edit_return['crop'] = new WP_Error(); + + $request = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment}/edit" ); + $request->set_body_params( + array( + 'x' => 50, + 'y' => 0, + 'width' => 10, + 'height' => 100, + 'src' => wp_get_attachment_image_url( $attachment, 'full' ), + + ) + ); + $response = rest_do_request( $request ); + $this->assertErrorResponse( 'rest_image_crop_failed', $response, 500 ); + + $this->assertCount( 1, WP_Image_Editor_Mock::$spy['crop'] ); + $this->assertSame( + array( 320, 0, 64, 480 ), + WP_Image_Editor_Mock::$spy['crop'][0] + ); + } + /** * @ticket 44405 * @requires function imagejpeg From cf064ef249931cfce2af007ec3a95b22b088c191 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Mon, 1 Jul 2024 23:34:19 +0000 Subject: [PATCH 07/53] HTML API: Optimize low-level parsing details in Tag Processor. Introduces a number of micro-level optimizations in the Tag Processor to improve token-scanning performance. Should contain no functional changes. Based on benchmarking against a list of the 100 most-visited websites, these changes result in an average improvement in performance of the Tag Processor for scanning tags from between 3.5% and 7.5%. Developed in https://github.com/WordPress/wordpress-develop/pull/6890 Discussed in https://core.trac.wordpress.org/ticket/61545 Follow-up to [55203]. See #61545. git-svn-id: https://develop.svn.wordpress.org/trunk@58613 602fd350-edb4-49c9-b593-d223f7449a82 --- .../html-api/class-wp-html-decoder.php | 26 ++-- .../html-api/class-wp-html-tag-processor.php | 118 ++++++------------ 2 files changed, 52 insertions(+), 92 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-decoder.php b/src/wp-includes/html-api/class-wp-html-decoder.php index 78976002b4a93..42c6424423711 100644 --- a/src/wp-includes/html-api/class-wp-html-decoder.php +++ b/src/wp-includes/html-api/class-wp-html-decoder.php @@ -141,7 +141,7 @@ public static function decode( $context, $text ) { while ( $at < $end ) { $next_character_reference_at = strpos( $text, '&', $at ); - if ( false === $next_character_reference_at || $next_character_reference_at >= $end ) { + if ( false === $next_character_reference_at ) { break; } @@ -436,26 +436,26 @@ public static function code_point_to_utf8_bytes( $code_point ) { } if ( $code_point <= 0x7FF ) { - $byte1 = ( $code_point >> 6 ) | 0xC0; - $byte2 = $code_point & 0x3F | 0x80; + $byte1 = chr( ( $code_point >> 6 ) | 0xC0 ); + $byte2 = chr( $code_point & 0x3F | 0x80 ); - return pack( 'CC', $byte1, $byte2 ); + return "{$byte1}{$byte2}"; } if ( $code_point <= 0xFFFF ) { - $byte1 = ( $code_point >> 12 ) | 0xE0; - $byte2 = ( $code_point >> 6 ) & 0x3F | 0x80; - $byte3 = $code_point & 0x3F | 0x80; + $byte1 = chr( ( $code_point >> 12 ) | 0xE0 ); + $byte2 = chr( ( $code_point >> 6 ) & 0x3F | 0x80 ); + $byte3 = chr( $code_point & 0x3F | 0x80 ); - return pack( 'CCC', $byte1, $byte2, $byte3 ); + return "{$byte1}{$byte2}{$byte3}"; } // Any values above U+10FFFF are eliminated above in the pre-check. - $byte1 = ( $code_point >> 18 ) | 0xF0; - $byte2 = ( $code_point >> 12 ) & 0x3F | 0x80; - $byte3 = ( $code_point >> 6 ) & 0x3F | 0x80; - $byte4 = $code_point & 0x3F | 0x80; + $byte1 = chr( ( $code_point >> 18 ) | 0xF0 ); + $byte2 = chr( ( $code_point >> 12 ) & 0x3F | 0x80 ); + $byte3 = chr( ( $code_point >> 6 ) & 0x3F | 0x80 ); + $byte4 = chr( $code_point & 0x3F | 0x80 ); - return pack( 'CCCC', $byte1, $byte2, $byte3, $byte4 ); + return "{$byte1}{$byte2}{$byte3}{$byte4}"; } } diff --git a/src/wp-includes/html-api/class-wp-html-tag-processor.php b/src/wp-includes/html-api/class-wp-html-tag-processor.php index 8fc75938c9384..a388af1ef79c3 100644 --- a/src/wp-includes/html-api/class-wp-html-tag-processor.php +++ b/src/wp-includes/html-api/class-wp-html-tag-processor.php @@ -1524,21 +1524,10 @@ private function parse_next_tag() { $was_at = $this->bytes_already_parsed; $at = $was_at; - while ( false !== $at && $at < $doc_length ) { + while ( $at < $doc_length ) { $at = strpos( $html, '<', $at ); - - /* - * This does not imply an incomplete parse; it indicates that there - * can be nothing left in the document other than a #text node. - */ if ( false === $at ) { - $this->parser_state = self::STATE_TEXT_NODE; - $this->token_starts_at = $was_at; - $this->token_length = strlen( $html ) - $was_at; - $this->text_starts_at = $was_at; - $this->text_length = $this->token_length; - $this->bytes_already_parsed = strlen( $html ); - return true; + break; } if ( $at > $was_at ) { @@ -1554,19 +1543,9 @@ private function parse_next_tag() { * * @see https://html.spec.whatwg.org/#tag-open-state */ - if ( strlen( $html ) > $at + 1 ) { - $next_character = $html[ $at + 1 ]; - $at_another_node = ( - '!' === $next_character || - '/' === $next_character || - '?' === $next_character || - ( 'A' <= $next_character && $next_character <= 'Z' ) || - ( 'a' <= $next_character && $next_character <= 'z' ) - ); - if ( ! $at_another_node ) { - ++$at; - continue; - } + if ( 1 !== strspn( $html, '!/?abcdefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ', $at + 1, 1 ) ) { + ++$at; + continue; } $this->parser_state = self::STATE_TEXT_NODE; @@ -1630,11 +1609,7 @@ private function parse_next_tag() { * `' ) + strlen( '-->' ); + $end = strrpos( $serialized_block, '', $template_part->content ); + } + + /* + * @ticket 60506 + * @ticket 60854 + */ + public function test_should_injected_hooked_block_into_template_part_first_child() { + register_block_type( + 'tests/my-block', + array( + 'block_hooks' => array( + 'core/template-part' => 'first_child', + ), + ) + ); + + $template_part = _build_block_template_result_from_file( + array( + 'slug' => 'header', + 'postTypes' => array( 'post' ), + 'path' => DIR_TESTDATA . '/templates/template.html', + ), + 'wp_template_part' + ); + $this->assertStringStartsWith( '', $template_part->content ); + } + + /* + * @ticket 60506 + * @ticket 60854 + */ + public function test_should_injected_hooked_block_into_template_part_last_child() { + register_block_type( + 'tests/my-block', + array( + 'block_hooks' => array( + 'core/template-part' => 'last_child', + ), + ) + ); + + $template_part = _build_block_template_result_from_file( + array( + 'slug' => 'header', + 'postTypes' => array( 'post' ), + 'path' => DIR_TESTDATA . '/templates/template.html', + ), + 'wp_template_part' + ); + $this->assertStringEndsWith( '', $template_part->content ); + } } diff --git a/tests/phpunit/tests/block-templates/buildBlockTemplateResultFromPost.php b/tests/phpunit/tests/block-templates/buildBlockTemplateResultFromPost.php index 586e9beded17b..839e5788bc6c3 100644 --- a/tests/phpunit/tests/block-templates/buildBlockTemplateResultFromPost.php +++ b/tests/phpunit/tests/block-templates/buildBlockTemplateResultFromPost.php @@ -111,6 +111,50 @@ public function test_should_inject_hooked_block_into_template_part() { $this->assertStringEndsWith( '', $template_part->content ); } + /* + * @ticket 59646 + * @ticket 60506 + * @ticket 60854 + */ + public function test_should_injected_hooked_block_into_template_part_first_child() { + register_block_type( + 'tests/my-block', + array( + 'block_hooks' => array( + 'core/template-part' => 'first_child', + ), + ) + ); + + $template_part = _build_block_template_result_from_post( + self::$template_part_post, + 'wp_template_part' + ); + $this->assertStringStartsWith( '', $template_part->content ); + } + + /* + * @ticket 59646 + * @ticket 60506 + * @ticket 60854 + */ + public function test_should_injected_hooked_block_into_template_part_last_child() { + register_block_type( + 'tests/my-block', + array( + 'block_hooks' => array( + 'core/template-part' => 'last_child', + ), + ) + ); + + $template_part = _build_block_template_result_from_post( + self::$template_part_post, + 'wp_template_part' + ); + $this->assertStringEndsWith( '', $template_part->content ); + } + /** * @ticket 59646 * @ticket 60506 diff --git a/tests/phpunit/tests/block-templates/injectIgnoredHookedBlocksMetadataAttributes.php b/tests/phpunit/tests/block-templates/injectIgnoredHookedBlocksMetadataAttributes.php index bc753504bbce0..1f8a66ee8546f 100644 --- a/tests/phpunit/tests/block-templates/injectIgnoredHookedBlocksMetadataAttributes.php +++ b/tests/phpunit/tests/block-templates/injectIgnoredHookedBlocksMetadataAttributes.php @@ -17,6 +17,7 @@ public function tear_down() { if ( WP_Block_Type_Registry::get_instance()->is_registered( 'tests/hooked-block' ) ) { unregister_block_type( 'tests/hooked-block' ); } + delete_post_meta( self::$template_part_post->ID, '_wp_ignored_hooked_blocks' ); parent::tear_down(); } @@ -38,14 +39,35 @@ public function test_hooked_block_types_filter_with_newly_created_template() { inject_ignored_hooked_blocks_metadata_attributes( $changes ); - $args = $action->get_args(); - $anchor_block_type = end( $args )[2]; - $context = end( $args )[3]; + $args = $action->get_args(); + $relative_positions = array_column( $args, 1 ); + $anchor_block_types = array_column( $args, 2 ); + $contexts = array_column( $args, 3 ); - $this->assertSame( 'tests/anchor-block', $anchor_block_type ); + $this->assertSame( + array( + 'before', + 'after', + ), + $relative_positions, + 'The relative positions passed to the hooked_block_types filter are incorrect.' + ); - $this->assertInstanceOf( 'WP_Block_Template', $context ); + $this->assertSame( + array( + 'tests/anchor-block', + 'tests/anchor-block', + ), + $anchor_block_types, + 'The anchor block types passed to the hooked_block_types filter are incorrect.' + ); + $context = $contexts[0]; + $this->assertSame( + array_fill( 0, count( $contexts ), $context ), + $contexts, + 'The context passed to the hooked_block_types filter should be the same for all calls.' + ); $this->assertSame( $changes->post_type, $context->type, @@ -69,6 +91,7 @@ public function test_hooked_block_types_filter_with_newly_created_template() { /** * @ticket 60754 + * @ticket 60854 */ public function test_hooked_block_types_filter_with_newly_created_template_part() { $action = new MockAction(); @@ -85,14 +108,48 @@ public function test_hooked_block_types_filter_with_newly_created_template_part( inject_ignored_hooked_blocks_metadata_attributes( $changes ); - $args = $action->get_args(); - $anchor_block_type = end( $args )[2]; - $context = end( $args )[3]; + $args = $action->get_args(); + $relative_positions = array_column( $args, 1 ); + $anchor_block_types = array_column( $args, 2 ); + $contexts = array_column( $args, 3 ); - $this->assertSame( 'tests/anchor-block', $anchor_block_type ); + $this->assertSame( + array( + 'before', + 'after', + 'first_child', + 'before', + 'after', + 'last_child', + ), + $relative_positions, + 'The relative positions passed to the hooked_block_types filter are incorrect.' + ); - $this->assertInstanceOf( 'WP_Block_Template', $context ); + $this->assertSame( + array( + 'core/template-part', + 'core/template-part', + 'core/template-part', + 'tests/anchor-block', + 'tests/anchor-block', + 'core/template-part', + ), + $anchor_block_types, + 'The anchor block types passed to the hooked_block_types filter are incorrect.' + ); + $context = $contexts[0]; + $this->assertSame( + array_fill( 0, count( $contexts ), $context ), + $contexts, + 'The context passed to the hooked_block_types filter should be the same for all calls.' + ); + $this->assertInstanceOf( + 'WP_Block_Template', + $context, + 'The context passed to the hooked_block_types filter is not an instance of WP_Block_Template.' + ); $this->assertSame( $changes->post_type, $context->type, @@ -140,14 +197,35 @@ public function test_hooked_block_types_filter_with_existing_template_file() { inject_ignored_hooked_blocks_metadata_attributes( $changes ); - $args = $action->get_args(); - $anchor_block_type = end( $args )[2]; - $context = end( $args )[3]; + $args = $action->get_args(); + $relative_positions = array_column( $args, 1 ); + $anchor_block_types = array_column( $args, 2 ); + $contexts = array_column( $args, 3 ); - $this->assertSame( 'tests/anchor-block', $anchor_block_type ); + $this->assertSame( + array( + 'before', + 'after', + ), + $relative_positions, + 'The relative positions passed to the hooked_block_types filter are incorrect.' + ); - $this->assertInstanceOf( 'WP_Block_Template', $context ); + $this->assertSame( + array( + 'tests/anchor-block', + 'tests/anchor-block', + ), + $anchor_block_types, + 'The anchor block types passed to the hooked_block_types filter are incorrect.' + ); + $context = $contexts[0]; + $this->assertSame( + array_fill( 0, count( $contexts ), $context ), + $contexts, + 'The context passed to the hooked_block_types filter should be the same for all calls.' + ); $this->assertSame( $changes->post_name, $context->slug, @@ -181,6 +259,7 @@ public function test_hooked_block_types_filter_with_existing_template_file() { /** * @ticket 60754 + * @ticket 60854 */ public function test_hooked_block_types_filter_with_existing_template_part_file() { $action = new MockAction(); @@ -201,14 +280,48 @@ public function test_hooked_block_types_filter_with_existing_template_part_file( inject_ignored_hooked_blocks_metadata_attributes( $changes ); - $args = $action->get_args(); - $anchor_block_type = end( $args )[2]; - $context = end( $args )[3]; + $args = $action->get_args(); + $relative_positions = array_column( $args, 1 ); + $anchor_block_types = array_column( $args, 2 ); + $contexts = array_column( $args, 3 ); - $this->assertSame( 'tests/anchor-block', $anchor_block_type ); + $this->assertSame( + array( + 'before', + 'after', + 'first_child', + 'before', + 'after', + 'last_child', + ), + $relative_positions, + 'The relative positions passed to the hooked_block_types filter are incorrect.' + ); - $this->assertInstanceOf( 'WP_Block_Template', $context ); + $this->assertSame( + array( + 'core/template-part', + 'core/template-part', + 'core/template-part', + 'tests/anchor-block', + 'tests/anchor-block', + 'core/template-part', + ), + $anchor_block_types, + 'The anchor block types passed to the hooked_block_types filter are incorrect.' + ); + $context = $contexts[0]; + $this->assertSame( + array_fill( 0, count( $contexts ), $context ), + $contexts, + 'The context passed to the hooked_block_types filter should be the same for all calls.' + ); + $this->assertInstanceOf( + 'WP_Block_Template', + $context, + 'The context passed to the hooked_block_types filter is not an instance of WP_Block_Template.' + ); $this->assertSame( $changes->post_name, $context->slug, @@ -259,14 +372,35 @@ public function test_hooked_block_types_filter_with_existing_template_post() { inject_ignored_hooked_blocks_metadata_attributes( $changes ); - $args = $action->get_args(); - $anchor_block_type = end( $args )[2]; - $context = end( $args )[3]; + $args = $action->get_args(); + $relative_positions = array_column( $args, 1 ); + $anchor_block_types = array_column( $args, 2 ); + $contexts = array_column( $args, 3 ); - $this->assertSame( 'tests/anchor-block', $anchor_block_type ); + $this->assertSame( + array( + 'before', + 'after', + ), + $relative_positions, + 'The relative positions passed to the hooked_block_types filter are incorrect.' + ); - $this->assertInstanceOf( 'WP_Block_Template', $context ); + $this->assertSame( + array( + 'tests/anchor-block', + 'tests/anchor-block', + ), + $anchor_block_types, + 'The anchor block types passed to the hooked_block_types filter are incorrect.' + ); + $context = $contexts[0]; + $this->assertSame( + array_fill( 0, count( $contexts ), $context ), + $contexts, + 'The context passed to the hooked_block_types filter should be the same for all calls.' + ); $this->assertSame( $changes->post_name, $context->slug, @@ -302,6 +436,7 @@ public function test_hooked_block_types_filter_with_existing_template_post() { /** * @ticket 60754 + * @ticket 60854 */ public function test_hooked_block_types_filter_with_existing_template_part_post() { $action = new MockAction(); @@ -318,14 +453,48 @@ public function test_hooked_block_types_filter_with_existing_template_part_post( inject_ignored_hooked_blocks_metadata_attributes( $changes ); - $args = $action->get_args(); - $anchor_block_type = end( $args )[2]; - $context = end( $args )[3]; + $args = $action->get_args(); + $relative_positions = array_column( $args, 1 ); + $anchor_block_types = array_column( $args, 2 ); + $contexts = array_column( $args, 3 ); - $this->assertSame( 'tests/anchor-block', $anchor_block_type ); + $this->assertSame( + array( + 'before', + 'after', + 'first_child', + 'before', + 'after', + 'last_child', + ), + $relative_positions, + 'The relative positions passed to the hooked_block_types filter are incorrect.' + ); - $this->assertInstanceOf( 'WP_Block_Template', $context ); + $this->assertSame( + array( + 'core/template-part', + 'core/template-part', + 'core/template-part', + 'tests/anchor-block', + 'tests/anchor-block', + 'core/template-part', + ), + $anchor_block_types, + 'The anchor block types passed to the hooked_block_types filter are incorrect.' + ); + $context = $contexts[0]; + $this->assertSame( + array_fill( 0, count( $contexts ), $context ), + $contexts, + 'The context passed to the hooked_block_types filter should be the same for all calls.' + ); + $this->assertInstanceOf( + 'WP_Block_Template', + $context, + 'The context passed to the hooked_block_types filter is not an instance of WP_Block_Template.' + ); $this->assertSame( $changes->post_name, $context->slug, @@ -419,4 +588,37 @@ public function test_inject_ignored_hooked_blocks_metadata_attributes_into_templ 'The hooked block was not injected into the anchor block\'s ignoredHookedBlocks metadata.' ); } + + /** + * @ticket 60854 + */ + public function test_inject_ignored_hooked_blocks_metadata_attributes_into_template_part_postmeta() { + register_block_type( + 'tests/hooked-block', + array( + 'block_hooks' => array( + 'core/template-part' => 'last_child', + ), + ) + ); + + $id = self::TEST_THEME . '//' . 'my_template_part'; + $template = get_block_template( $id, 'wp_template_part' ); + + $changes = new stdClass(); + $changes->ID = $template->wp_id; + $changes->post_content = 'Hello'; + + $post = inject_ignored_hooked_blocks_metadata_attributes( $changes ); + $this->assertSame( + array( 'tests/hooked-block' ), + json_decode( $post->meta_input['_wp_ignored_hooked_blocks'], true ), + 'The hooked block was not injected into the wp_template_part\'s _wp_ignored_hooked_blocks postmeta.' + ); + $this->assertSame( + $changes->post_content, + $post->post_content, + 'The template part\'s post content was modified.' + ); + } } From a2bb45dfad75fe48943632d57788a97333a4ebd9 Mon Sep 17 00:00:00 2001 From: bernhard-reiter Date: Tue, 2 Jul 2024 10:41:33 +0000 Subject: [PATCH 09/53] Block Hooks: Fix a number of multi-line comment openers. Add the missing second asterisk to a number of multi-line comment openers, and remove a superfluous second asterisk from two others. Follow-up to [58614]. Props mukesh27. See #60854. git-svn-id: https://develop.svn.wordpress.org/trunk@58615 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/block-template-utils.php | 4 ++-- .../block-templates/buildBlockTemplateResultFromFile.php | 4 ++-- .../block-templates/buildBlockTemplateResultFromPost.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/block-template-utils.php b/src/wp-includes/block-template-utils.php index 6a4df84a11f7c..f7a10ab672904 100644 --- a/src/wp-includes/block-template-utils.php +++ b/src/wp-includes/block-template-utils.php @@ -617,7 +617,7 @@ function _build_block_template_result_from_file( $template_file, $template_type } if ( 'wp_template_part' === $template->type && $has_hooked_blocks ) { - /** + /* * In order for hooked blocks to be inserted at positions first_child and last_child in a template part, * we need to wrap its content a mock template part block and traverse it. */ @@ -1022,7 +1022,7 @@ function _build_block_template_result_from_post( $post ) { $existing_ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true ); $attributes = ! empty( $existing_ignored_hooked_blocks ) ? array( 'metadata' => array( 'ignoredHookedBlocks' => json_decode( $existing_ignored_hooked_blocks, true ) ) ) : array(); - /** + /* * In order for hooked blocks to be inserted at positions first_child and last_child in a template part, * we need to wrap its content a mock template part block and traverse it. */ diff --git a/tests/phpunit/tests/block-templates/buildBlockTemplateResultFromFile.php b/tests/phpunit/tests/block-templates/buildBlockTemplateResultFromFile.php index b2c2f0af75be7..673e35af5b097 100644 --- a/tests/phpunit/tests/block-templates/buildBlockTemplateResultFromFile.php +++ b/tests/phpunit/tests/block-templates/buildBlockTemplateResultFromFile.php @@ -217,7 +217,7 @@ public function test_should_inject_hooked_block_into_template_part() { $this->assertStringEndsWith( '', $template_part->content ); } - /* + /** * @ticket 60506 * @ticket 60854 */ @@ -242,7 +242,7 @@ public function test_should_injected_hooked_block_into_template_part_first_child $this->assertStringStartsWith( '', $template_part->content ); } - /* + /** * @ticket 60506 * @ticket 60854 */ diff --git a/tests/phpunit/tests/block-templates/buildBlockTemplateResultFromPost.php b/tests/phpunit/tests/block-templates/buildBlockTemplateResultFromPost.php index 839e5788bc6c3..5dbf91d911f07 100644 --- a/tests/phpunit/tests/block-templates/buildBlockTemplateResultFromPost.php +++ b/tests/phpunit/tests/block-templates/buildBlockTemplateResultFromPost.php @@ -111,7 +111,7 @@ public function test_should_inject_hooked_block_into_template_part() { $this->assertStringEndsWith( '', $template_part->content ); } - /* + /** * @ticket 59646 * @ticket 60506 * @ticket 60854 @@ -133,7 +133,7 @@ public function test_should_injected_hooked_block_into_template_part_first_child $this->assertStringStartsWith( '', $template_part->content ); } - /* + /** * @ticket 59646 * @ticket 60506 * @ticket 60854 From d77bb088452293775e2f16225141ceff9994b171 Mon Sep 17 00:00:00 2001 From: Colin Stewart Date: Tue, 2 Jul 2024 11:50:53 +0000 Subject: [PATCH 10/53] Plugins: Remove extra paragraph from plugin row dependency notice. In `WP_Plugins_List_Table::add_dependencies_to_dependent_plugin_row()`, a `sprintf()` call previously wrapped the `%2$s` placeholder in paragraph tags. [57769] changed the placeholder's value to use `wp_get_admin_notice()`, which returns a paragraph-wrapped notice by default. As a result, the previous paragraph tags produced an extra, empty paragraph. This removes the paragraph tags around the `%2$s` placeholder. Follow-up to [57545], [57714], [57769]. Props mukesh27. Fixes #61546. git-svn-id: https://develop.svn.wordpress.org/trunk@58616 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/class-wp-plugins-list-table.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-admin/includes/class-wp-plugins-list-table.php b/src/wp-admin/includes/class-wp-plugins-list-table.php index 379cf56be9a70..b9cc969f1c599 100644 --- a/src/wp-admin/includes/class-wp-plugins-list-table.php +++ b/src/wp-admin/includes/class-wp-plugins-list-table.php @@ -1594,7 +1594,7 @@ protected function add_dependencies_to_dependent_plugin_row( $dependent ) { } printf( - '

%1$s

%2$s

', + '

%1$s

%2$s
', $requires, $notice ); From 486c9a2d80405d165ae8dbce963d03301bf6ecf3 Mon Sep 17 00:00:00 2001 From: Ella Date: Tue, 2 Jul 2024 14:51:16 +0000 Subject: [PATCH 11/53] Editor: Update packages for 6.6 RC 2. Fixes #61548. Fixes https://github.com/WordPress/wordpress-develop/pull/6953. See https://make.wordpress.org/core/handbook/about/release-cycle/block-editor-release-process-for-major-releases/#package-updates-and-core-patches. Props ellatrix, youknowriad. git-svn-id: https://develop.svn.wordpress.org/trunk@58617 602fd350-edb4-49c9-b593-d223f7449a82 --- package-lock.json | 398 +++++++++--------- package.json | 30 +- .../assets/script-loader-packages.min.php | 2 +- src/wp-includes/blocks/block/block.json | 6 +- src/wp-includes/blocks/blocks-json.php | 8 +- 5 files changed, 227 insertions(+), 217 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8023b662055f9..498313d908822 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,31 +14,31 @@ "@wordpress/api-fetch": "7.0.1", "@wordpress/autop": "4.0.1", "@wordpress/blob": "4.0.1", - "@wordpress/block-directory": "5.0.4", - "@wordpress/block-editor": "13.0.3", - "@wordpress/block-library": "9.0.4", + "@wordpress/block-directory": "5.0.5", + "@wordpress/block-editor": "13.0.4", + "@wordpress/block-library": "9.0.5", "@wordpress/block-serialization-default-parser": "5.0.1", "@wordpress/blocks": "13.0.3", "@wordpress/commands": "1.0.3", "@wordpress/components": "28.0.3", "@wordpress/compose": "7.0.1", - "@wordpress/core-commands": "1.0.3", - "@wordpress/core-data": "7.0.3", - "@wordpress/customize-widgets": "5.0.4", + "@wordpress/core-commands": "1.0.4", + "@wordpress/core-data": "7.0.4", + "@wordpress/customize-widgets": "5.0.5", "@wordpress/data": "10.0.2", "@wordpress/data-controls": "4.0.2", - "@wordpress/dataviews": "2.0.3", + "@wordpress/dataviews": "2.0.4", "@wordpress/date": "5.0.1", "@wordpress/deprecated": "4.0.1", "@wordpress/dom": "4.0.1", "@wordpress/dom-ready": "4.0.1", - "@wordpress/edit-post": "8.0.4", - "@wordpress/edit-site": "6.0.4", - "@wordpress/edit-widgets": "6.0.4", - "@wordpress/editor": "14.0.3", + "@wordpress/edit-post": "8.0.5", + "@wordpress/edit-site": "6.0.5", + "@wordpress/edit-widgets": "6.0.5", + "@wordpress/editor": "14.0.4", "@wordpress/element": "6.0.1", "@wordpress/escape-html": "3.0.1", - "@wordpress/format-library": "5.0.3", + "@wordpress/format-library": "5.0.4", "@wordpress/hooks": "4.0.1", "@wordpress/html-entities": "4.0.1", "@wordpress/i18n": "5.0.1", @@ -53,7 +53,7 @@ "@wordpress/media-utils": "5.0.1", "@wordpress/notices": "5.0.2", "@wordpress/nux": "9.0.3", - "@wordpress/patterns": "2.0.3", + "@wordpress/patterns": "2.0.4", "@wordpress/plugins": "7.0.3", "@wordpress/preferences": "4.0.3", "@wordpress/preferences-persistence": "2.0.1", @@ -61,7 +61,7 @@ "@wordpress/priority-queue": "3.0.1", "@wordpress/private-apis": "1.0.2", "@wordpress/redux-routine": "5.0.1", - "@wordpress/reusable-blocks": "5.0.3", + "@wordpress/reusable-blocks": "5.0.4", "@wordpress/rich-text": "7.0.2", "@wordpress/router": "1.0.2", "@wordpress/server-side-render": "5.0.3", @@ -73,7 +73,7 @@ "@wordpress/url": "4.0.1", "@wordpress/viewport": "6.0.2", "@wordpress/warning": "3.0.1", - "@wordpress/widgets": "4.0.3", + "@wordpress/widgets": "4.0.4", "@wordpress/wordcount": "4.0.1", "backbone": "1.5.0", "clipboard": "2.0.11", @@ -6160,21 +6160,21 @@ } }, "node_modules/@wordpress/block-directory": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@wordpress/block-directory/-/block-directory-5.0.4.tgz", - "integrity": "sha512-jatDnMr3tDNAG/TyCaw5EmOAuZkyByNBRLVp1V+0vm7h6KRmsmfKKd2x6Plk9suwqzpmXgz0o2MXCvLjt+FE/A==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@wordpress/block-directory/-/block-directory-5.0.5.tgz", + "integrity": "sha512-5JAfWA13wiLud+V2yS8uR4syInmqo9fcad391oetCfYxrYf5S3pH4WEdHamkNJsQ2a7pxkz7vaJsGa5VmkJYKA==", "dependencies": { "@babel/runtime": "^7.16.0", "@wordpress/a11y": "^4.0.1", "@wordpress/api-fetch": "^7.0.1", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/blocks": "^13.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", - "@wordpress/edit-post": "^8.0.4", - "@wordpress/editor": "^14.0.3", + "@wordpress/edit-post": "^8.0.5", + "@wordpress/editor": "^14.0.4", "@wordpress/element": "^6.0.1", "@wordpress/hooks": "^4.0.1", "@wordpress/html-entities": "^4.0.1", @@ -6196,9 +6196,9 @@ } }, "node_modules/@wordpress/block-editor": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-13.0.3.tgz", - "integrity": "sha512-vV4utZkfoTfw5BKatIuax91fs/NF5TRZBp2ayZp39kWwTR8P3sKoR+Ter8aEwGx58lqO+E7mAQzWI9L5K7PelQ==", + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-13.0.4.tgz", + "integrity": "sha512-Vtimmmc7JHHNgNBoCr6Ud7/vGPHyfQDck/g9+sTkedCXbqL/dapA9PZsT1UvHNF6xEvEWOrd+kRxOKbn0PcpSg==", "dependencies": { "@babel/runtime": "^7.16.0", "@emotion/react": "^11.7.1", @@ -6257,20 +6257,20 @@ } }, "node_modules/@wordpress/block-library": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/@wordpress/block-library/-/block-library-9.0.4.tgz", - "integrity": "sha512-bqrSIAXcGPxVlNKvrewnlgWeJg+VnPEFPHSqYCIkt0kGfkOtWm6COupq4sHjQ6ou5ElEW/3P6KSYamB5h2wTEQ==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@wordpress/block-library/-/block-library-9.0.5.tgz", + "integrity": "sha512-0A1ZKV/6xtzQtjlvdCxoBqNb0gyr/8UeLsf1NtAi4gBT8GWBsXYKBfFSJ9Q1K9ATYszN6e1XiZqtyCBBiUDjFA==", "dependencies": { "@babel/runtime": "^7.16.0", "@wordpress/a11y": "^4.0.1", "@wordpress/api-fetch": "^7.0.1", "@wordpress/autop": "^4.0.1", "@wordpress/blob": "^4.0.1", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/blocks": "^13.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/date": "^5.0.1", "@wordpress/deprecated": "^4.0.1", @@ -6286,10 +6286,10 @@ "@wordpress/keyboard-shortcuts": "^5.0.2", "@wordpress/keycodes": "^4.0.1", "@wordpress/notices": "^5.0.2", - "@wordpress/patterns": "^2.0.3", + "@wordpress/patterns": "^2.0.4", "@wordpress/primitives": "^4.0.1", "@wordpress/private-apis": "^1.0.2", - "@wordpress/reusable-blocks": "^5.0.3", + "@wordpress/reusable-blocks": "^5.0.4", "@wordpress/rich-text": "^7.0.2", "@wordpress/server-side-render": "^5.0.3", "@wordpress/url": "^4.0.1", @@ -6491,15 +6491,15 @@ } }, "node_modules/@wordpress/core-commands": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/core-commands/-/core-commands-1.0.3.tgz", - "integrity": "sha512-MxbCbJLjW4ysE44VDv3bD0eykxiZnoCM6NLTaywcv27VNALhqqJxxyglgjdwbIV5d6lC0dQPSAOLgenkzKPOoQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/core-commands/-/core-commands-1.0.4.tgz", + "integrity": "sha512-VModTm9itHB/p1yEgs8JtJ3iiRcLIh0a5prR21Mhhp2eWPk1Ydzbg5eTlOMVM/F/zaSFcNA4yLnQ0SiUc4p3Ow==", "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/commands": "^1.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/element": "^6.0.1", "@wordpress/i18n": "^5.0.1", @@ -6518,13 +6518,13 @@ } }, "node_modules/@wordpress/core-data": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-7.0.3.tgz", - "integrity": "sha512-2c8xloBhPC5QXzmz17gu3sMgBHjeaJ6CRR/pxt9Z4yzD6KA0xBJUmodnywvZmGHrIJMc21FPjSKSS8KD7xotzg==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-7.0.4.tgz", + "integrity": "sha512-qLGb31e9kS5tGGwvwGIr+MkfmmyzKktx7i53jk/w/zY559FvLOniQEJFEOyjC57WhT2alNvZtS5K+RGKD0tVlg==", "dependencies": { "@babel/runtime": "^7.16.0", "@wordpress/api-fetch": "^7.0.1", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/blocks": "^13.0.3", "@wordpress/compose": "^7.0.1", "@wordpress/data": "^10.0.2", @@ -6554,17 +6554,17 @@ } }, "node_modules/@wordpress/customize-widgets": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@wordpress/customize-widgets/-/customize-widgets-5.0.4.tgz", - "integrity": "sha512-Jrle8vrpyDoFbAQYYokJdMnYMzRRTW10ZC/GZlyAeUuezMqIC+oODBI2XS6vv4+uStw8G+3oeT+9Q0XVuO75uw==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@wordpress/customize-widgets/-/customize-widgets-5.0.5.tgz", + "integrity": "sha512-hE4e4MPWRYkxSxuYlzBLnmZWG5XpVE1TTy/7xJzpkFKfSaIY7ysiBTtSe3tYkL2ZwCAyA60IqbGqgAQUe2336w==", "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/block-editor": "^13.0.3", - "@wordpress/block-library": "^9.0.4", + "@wordpress/block-editor": "^13.0.4", + "@wordpress/block-library": "^9.0.5", "@wordpress/blocks": "^13.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/dom": "^4.0.1", "@wordpress/element": "^6.0.1", @@ -6578,7 +6578,7 @@ "@wordpress/media-utils": "^5.0.1", "@wordpress/preferences": "^4.0.3", "@wordpress/private-apis": "^1.0.2", - "@wordpress/widgets": "^4.0.3", + "@wordpress/widgets": "^4.0.4", "clsx": "^2.1.1", "fast-deep-equal": "^3.1.3" }, @@ -6639,9 +6639,9 @@ } }, "node_modules/@wordpress/dataviews": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/dataviews/-/dataviews-2.0.3.tgz", - "integrity": "sha512-+TDQsssoBBUMtb8y/wR9ZQvCOt7CENVxltTU0aI4bjBapjOtnpGIzr+ZoIbgC9q/WndepuxKNrUGiYpZplOefA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/dataviews/-/dataviews-2.0.4.tgz", + "integrity": "sha512-4FpLyvmiO0su4Fx3cLctqTIE+Bp1HCC1fHRFZw5JJgvkNXuAKHJRdpFCo1O11ZMH3ibxpWVshXZcfu7Z7HBWlw==", "dependencies": { "@ariakit/react": "^0.3.12", "@babel/runtime": "^7.16.0", @@ -6820,25 +6820,25 @@ } }, "node_modules/@wordpress/edit-post": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@wordpress/edit-post/-/edit-post-8.0.4.tgz", - "integrity": "sha512-gI3fauE2UjuNjon3eu+yHcVZ3DdtBVzy0a1x5OVexCs4kNqvXWVeeeqzjqG88g4UAgysNlF2HRECKMi+feTVxg==", + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/@wordpress/edit-post/-/edit-post-8.0.5.tgz", + "integrity": "sha512-NxEtAP7Ccz84COnuQKZji1UFi/CSeCD/8tr4yjvet4/4vvdlmTAR0GSIAeDl93ZmpNGCHF+d7mug2wDf9uLFtg==", "dependencies": { "@babel/runtime": "^7.16.0", "@wordpress/a11y": "^4.0.1", "@wordpress/api-fetch": "^7.0.1", - "@wordpress/block-editor": "^13.0.3", - "@wordpress/block-library": "^9.0.4", + "@wordpress/block-editor": "^13.0.4", + "@wordpress/block-library": "^9.0.5", "@wordpress/blocks": "^13.0.3", "@wordpress/commands": "^1.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-commands": "^1.0.3", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-commands": "^1.0.4", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/deprecated": "^4.0.1", "@wordpress/dom": "^4.0.1", - "@wordpress/editor": "^14.0.3", + "@wordpress/editor": "^14.0.4", "@wordpress/element": "^6.0.1", "@wordpress/hooks": "^4.0.1", "@wordpress/html-entities": "^4.0.1", @@ -6853,7 +6853,7 @@ "@wordpress/url": "^4.0.1", "@wordpress/viewport": "^6.0.2", "@wordpress/warning": "^3.0.1", - "@wordpress/widgets": "^4.0.3", + "@wordpress/widgets": "^4.0.4", "clsx": "^2.1.1", "memize": "^2.1.0" }, @@ -6867,29 +6867,29 @@ } }, "node_modules/@wordpress/edit-site": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@wordpress/edit-site/-/edit-site-6.0.4.tgz", - "integrity": "sha512-Qcfj/VzAG/ZQf1+v4gEXn/7pA1TgG+f4dsuL0v6/Q/Au/alyT2OI7NgGOXC6faVAtp9WCmPf3YcDgk5ej5bm1Q==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@wordpress/edit-site/-/edit-site-6.0.5.tgz", + "integrity": "sha512-MGTs34PLC/NWGb07zQl/CFSPZXLE9IAsbY6IJy6mMUWB7BxNXdsVwm5OK91zubZV+54vzL5eo5YTGCgVd+8zFA==", "dependencies": { "@babel/runtime": "^7.16.0", "@react-spring/web": "^9.4.5", "@wordpress/a11y": "^4.0.1", "@wordpress/api-fetch": "^7.0.1", "@wordpress/blob": "^4.0.1", - "@wordpress/block-editor": "^13.0.3", - "@wordpress/block-library": "^9.0.4", + "@wordpress/block-editor": "^13.0.4", + "@wordpress/block-library": "^9.0.5", "@wordpress/blocks": "^13.0.3", "@wordpress/commands": "^1.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-commands": "^1.0.3", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-commands": "^1.0.4", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", - "@wordpress/dataviews": "^2.0.3", + "@wordpress/dataviews": "^2.0.4", "@wordpress/date": "^5.0.1", "@wordpress/deprecated": "^4.0.1", "@wordpress/dom": "^4.0.1", - "@wordpress/editor": "^14.0.3", + "@wordpress/editor": "^14.0.4", "@wordpress/element": "^6.0.1", "@wordpress/escape-html": "^3.0.1", "@wordpress/hooks": "^4.0.1", @@ -6899,18 +6899,18 @@ "@wordpress/keyboard-shortcuts": "^5.0.2", "@wordpress/keycodes": "^4.0.1", "@wordpress/notices": "^5.0.2", - "@wordpress/patterns": "^2.0.3", + "@wordpress/patterns": "^2.0.4", "@wordpress/plugins": "^7.0.3", "@wordpress/preferences": "^4.0.3", "@wordpress/primitives": "^4.0.1", "@wordpress/priority-queue": "^3.0.1", "@wordpress/private-apis": "^1.0.2", - "@wordpress/reusable-blocks": "^5.0.3", + "@wordpress/reusable-blocks": "^5.0.4", "@wordpress/router": "^1.0.2", "@wordpress/style-engine": "^2.0.2", "@wordpress/url": "^4.0.1", "@wordpress/viewport": "^6.0.2", - "@wordpress/widgets": "^4.0.3", + "@wordpress/widgets": "^4.0.4", "@wordpress/wordcount": "^4.0.1", "change-case": "^4.1.2", "clsx": "^2.1.1", @@ -6929,18 +6929,18 @@ } }, "node_modules/@wordpress/edit-widgets": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@wordpress/edit-widgets/-/edit-widgets-6.0.4.tgz", - "integrity": "sha512-rMSmq5UZwljOv7i/2EdJhTWV9JCm8oTpwPvr/tAJgQ3OUiuNFpy0gA+SM8F7DtylUtl+9xV4F5GmhWNIGx4scg==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@wordpress/edit-widgets/-/edit-widgets-6.0.5.tgz", + "integrity": "sha512-+kAQyGDHN0raEbZ5piaACO2AZ62JAWoG5zDG8VN63vp9UiFvOodNwrljJ0afLcLIz6Kcb3BN8cjs65LBsjVvKQ==", "dependencies": { "@babel/runtime": "^7.16.0", "@wordpress/api-fetch": "^7.0.1", - "@wordpress/block-editor": "^13.0.3", - "@wordpress/block-library": "^9.0.4", + "@wordpress/block-editor": "^13.0.4", + "@wordpress/block-library": "^9.0.5", "@wordpress/blocks": "^13.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/deprecated": "^4.0.1", "@wordpress/dom": "^4.0.1", @@ -6953,13 +6953,13 @@ "@wordpress/keycodes": "^4.0.1", "@wordpress/media-utils": "^5.0.1", "@wordpress/notices": "^5.0.2", - "@wordpress/patterns": "^2.0.3", + "@wordpress/patterns": "^2.0.4", "@wordpress/plugins": "^7.0.3", "@wordpress/preferences": "^4.0.3", "@wordpress/private-apis": "^1.0.2", - "@wordpress/reusable-blocks": "^5.0.3", + "@wordpress/reusable-blocks": "^5.0.4", "@wordpress/url": "^4.0.1", - "@wordpress/widgets": "^4.0.3", + "@wordpress/widgets": "^4.0.4", "clsx": "^2.1.1" }, "engines": { @@ -6972,20 +6972,20 @@ } }, "node_modules/@wordpress/editor": { - "version": "14.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-14.0.3.tgz", - "integrity": "sha512-Rwv2xSTN+pqUVTMItpbMaulkIBGw1Linl5ODUx4mHeZBTYrjQD4qP4JH1nBYSHdmHr3HZAp+vgihHTHTgXkGCA==", + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-14.0.4.tgz", + "integrity": "sha512-Sy9dNAHJMFcHJzXlk8Y136+Ol0RmJ15CjhfnKZx4dxavRHrix5c+69MeQKavkmffrEN2XW9662C9cDlXAoczKg==", "dependencies": { "@babel/runtime": "^7.16.0", "@wordpress/a11y": "^4.0.1", "@wordpress/api-fetch": "^7.0.1", "@wordpress/blob": "^4.0.1", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/blocks": "^13.0.3", "@wordpress/commands": "^1.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/date": "^5.0.1", "@wordpress/deprecated": "^4.0.1", @@ -7000,11 +7000,11 @@ "@wordpress/keycodes": "^4.0.1", "@wordpress/media-utils": "^5.0.1", "@wordpress/notices": "^5.0.2", - "@wordpress/patterns": "^2.0.3", + "@wordpress/patterns": "^2.0.4", "@wordpress/plugins": "^7.0.3", "@wordpress/preferences": "^4.0.3", "@wordpress/private-apis": "^1.0.2", - "@wordpress/reusable-blocks": "^5.0.3", + "@wordpress/reusable-blocks": "^5.0.4", "@wordpress/rich-text": "^7.0.2", "@wordpress/server-side-render": "^5.0.3", "@wordpress/url": "^4.0.1", @@ -7120,13 +7120,13 @@ } }, "node_modules/@wordpress/format-library": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/format-library/-/format-library-5.0.3.tgz", - "integrity": "sha512-mD3738vO6pxKOiEBp4kaUrq03hsaVg8nBtFpBxWYozM1/CkSm9aKm3u73pixX4EdCL9VXo546WYNm4wCBeDiMg==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/format-library/-/format-library-5.0.4.tgz", + "integrity": "sha512-rdyibYZ2FnozrPRY7U1/8YRjoHHqjDDxmywLPtSqvJ95QhhBGMzCp+DJCWEpi/FANj8j4n5FLVala0W8xdStZA==", "dependencies": { "@babel/runtime": "^7.16.0", "@wordpress/a11y": "^4.0.1", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", "@wordpress/data": "^10.0.2", @@ -7431,17 +7431,17 @@ } }, "node_modules/@wordpress/patterns": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/patterns/-/patterns-2.0.3.tgz", - "integrity": "sha512-bAiaMAw/wGjYcrsBEEI4ZJv+y334VaTYYzw2JrGpAOpzNbw0UQmdNBz+aws8hRshnj0EZEyY3CY8k9sy47AR9g==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/patterns/-/patterns-2.0.4.tgz", + "integrity": "sha512-A5o490U8rAvZ9nJNz+ZWkP300hshfON0HE/FLmkxvwNCRxbnWAmdq1F5PQqmPthDC7NygFz90ZeEXg+iDJU49Q==", "dependencies": { "@babel/runtime": "^7.16.0", "@wordpress/a11y": "^4.0.1", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/blocks": "^13.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/element": "^6.0.1", "@wordpress/html-entities": "^4.0.1", @@ -7610,15 +7610,15 @@ } }, "node_modules/@wordpress/reusable-blocks": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/reusable-blocks/-/reusable-blocks-5.0.3.tgz", - "integrity": "sha512-nqr+/VDO42hB4d9fz07Eoen+SWi/H/9eeda76AdpgDzJq4oLmxxLgo/ze4lbnrYgdeeB3vSsKkJPi5ENPc9+jQ==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/reusable-blocks/-/reusable-blocks-5.0.4.tgz", + "integrity": "sha512-ie0ewJW/xIkvq8uupP20d7FDll58uuiqky+BV9f+GByWHbR8z01PQcErrlR4eId/epR5Cay+rHHLLwc0EV8A/A==", "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/blocks": "^13.0.3", "@wordpress/components": "^28.0.3", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/element": "^6.0.1", "@wordpress/i18n": "^5.0.1", @@ -8919,17 +8919,17 @@ } }, "node_modules/@wordpress/widgets": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/widgets/-/widgets-4.0.3.tgz", - "integrity": "sha512-/yY7ZWq80phLgrlL6kd4EJcrrG5nhWM7vGrHK8Hg0RBJ0zcQXMcfHG3a12Fxw5mbiKDLB3hKpNUJYxk+GpHcuQ==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/widgets/-/widgets-4.0.4.tgz", + "integrity": "sha512-n9VyatU28mFTQzn/O4NNPK9JQ0KeVYu4VhmVo4sxUeOxRJbdqGVW1L6MotnFn0uL/fbZOD5E07aiU22EJwJmlw==", "dependencies": { "@babel/runtime": "^7.16.0", "@wordpress/api-fetch": "^7.0.1", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/blocks": "^13.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/element": "^6.0.1", "@wordpress/i18n": "^5.0.1", @@ -38789,21 +38789,21 @@ } }, "@wordpress/block-directory": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@wordpress/block-directory/-/block-directory-5.0.4.tgz", - "integrity": "sha512-jatDnMr3tDNAG/TyCaw5EmOAuZkyByNBRLVp1V+0vm7h6KRmsmfKKd2x6Plk9suwqzpmXgz0o2MXCvLjt+FE/A==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@wordpress/block-directory/-/block-directory-5.0.5.tgz", + "integrity": "sha512-5JAfWA13wiLud+V2yS8uR4syInmqo9fcad391oetCfYxrYf5S3pH4WEdHamkNJsQ2a7pxkz7vaJsGa5VmkJYKA==", "requires": { "@babel/runtime": "^7.16.0", "@wordpress/a11y": "^4.0.1", "@wordpress/api-fetch": "^7.0.1", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/blocks": "^13.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", - "@wordpress/edit-post": "^8.0.4", - "@wordpress/editor": "^14.0.3", + "@wordpress/edit-post": "^8.0.5", + "@wordpress/editor": "^14.0.4", "@wordpress/element": "^6.0.1", "@wordpress/hooks": "^4.0.1", "@wordpress/html-entities": "^4.0.1", @@ -38817,9 +38817,9 @@ } }, "@wordpress/block-editor": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-13.0.3.tgz", - "integrity": "sha512-vV4utZkfoTfw5BKatIuax91fs/NF5TRZBp2ayZp39kWwTR8P3sKoR+Ter8aEwGx58lqO+E7mAQzWI9L5K7PelQ==", + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-13.0.4.tgz", + "integrity": "sha512-Vtimmmc7JHHNgNBoCr6Ud7/vGPHyfQDck/g9+sTkedCXbqL/dapA9PZsT1UvHNF6xEvEWOrd+kRxOKbn0PcpSg==", "requires": { "@babel/runtime": "^7.16.0", "@emotion/react": "^11.7.1", @@ -38870,20 +38870,20 @@ } }, "@wordpress/block-library": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/@wordpress/block-library/-/block-library-9.0.4.tgz", - "integrity": "sha512-bqrSIAXcGPxVlNKvrewnlgWeJg+VnPEFPHSqYCIkt0kGfkOtWm6COupq4sHjQ6ou5ElEW/3P6KSYamB5h2wTEQ==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@wordpress/block-library/-/block-library-9.0.5.tgz", + "integrity": "sha512-0A1ZKV/6xtzQtjlvdCxoBqNb0gyr/8UeLsf1NtAi4gBT8GWBsXYKBfFSJ9Q1K9ATYszN6e1XiZqtyCBBiUDjFA==", "requires": { "@babel/runtime": "^7.16.0", "@wordpress/a11y": "^4.0.1", "@wordpress/api-fetch": "^7.0.1", "@wordpress/autop": "^4.0.1", "@wordpress/blob": "^4.0.1", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/blocks": "^13.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/date": "^5.0.1", "@wordpress/deprecated": "^4.0.1", @@ -38899,10 +38899,10 @@ "@wordpress/keyboard-shortcuts": "^5.0.2", "@wordpress/keycodes": "^4.0.1", "@wordpress/notices": "^5.0.2", - "@wordpress/patterns": "^2.0.3", + "@wordpress/patterns": "^2.0.4", "@wordpress/primitives": "^4.0.1", "@wordpress/private-apis": "^1.0.2", - "@wordpress/reusable-blocks": "^5.0.3", + "@wordpress/reusable-blocks": "^5.0.4", "@wordpress/rich-text": "^7.0.2", "@wordpress/server-side-render": "^5.0.3", "@wordpress/url": "^4.0.1", @@ -39058,15 +39058,15 @@ } }, "@wordpress/core-commands": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/core-commands/-/core-commands-1.0.3.tgz", - "integrity": "sha512-MxbCbJLjW4ysE44VDv3bD0eykxiZnoCM6NLTaywcv27VNALhqqJxxyglgjdwbIV5d6lC0dQPSAOLgenkzKPOoQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/core-commands/-/core-commands-1.0.4.tgz", + "integrity": "sha512-VModTm9itHB/p1yEgs8JtJ3iiRcLIh0a5prR21Mhhp2eWPk1Ydzbg5eTlOMVM/F/zaSFcNA4yLnQ0SiUc4p3Ow==", "requires": { "@babel/runtime": "^7.16.0", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/commands": "^1.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/element": "^6.0.1", "@wordpress/i18n": "^5.0.1", @@ -39077,13 +39077,13 @@ } }, "@wordpress/core-data": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-7.0.3.tgz", - "integrity": "sha512-2c8xloBhPC5QXzmz17gu3sMgBHjeaJ6CRR/pxt9Z4yzD6KA0xBJUmodnywvZmGHrIJMc21FPjSKSS8KD7xotzg==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-7.0.4.tgz", + "integrity": "sha512-qLGb31e9kS5tGGwvwGIr+MkfmmyzKktx7i53jk/w/zY559FvLOniQEJFEOyjC57WhT2alNvZtS5K+RGKD0tVlg==", "requires": { "@babel/runtime": "^7.16.0", "@wordpress/api-fetch": "^7.0.1", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/blocks": "^13.0.3", "@wordpress/compose": "^7.0.1", "@wordpress/data": "^10.0.2", @@ -39105,17 +39105,17 @@ } }, "@wordpress/customize-widgets": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@wordpress/customize-widgets/-/customize-widgets-5.0.4.tgz", - "integrity": "sha512-Jrle8vrpyDoFbAQYYokJdMnYMzRRTW10ZC/GZlyAeUuezMqIC+oODBI2XS6vv4+uStw8G+3oeT+9Q0XVuO75uw==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@wordpress/customize-widgets/-/customize-widgets-5.0.5.tgz", + "integrity": "sha512-hE4e4MPWRYkxSxuYlzBLnmZWG5XpVE1TTy/7xJzpkFKfSaIY7ysiBTtSe3tYkL2ZwCAyA60IqbGqgAQUe2336w==", "requires": { "@babel/runtime": "^7.16.0", - "@wordpress/block-editor": "^13.0.3", - "@wordpress/block-library": "^9.0.4", + "@wordpress/block-editor": "^13.0.4", + "@wordpress/block-library": "^9.0.5", "@wordpress/blocks": "^13.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/dom": "^4.0.1", "@wordpress/element": "^6.0.1", @@ -39129,7 +39129,7 @@ "@wordpress/media-utils": "^5.0.1", "@wordpress/preferences": "^4.0.3", "@wordpress/private-apis": "^1.0.2", - "@wordpress/widgets": "^4.0.3", + "@wordpress/widgets": "^4.0.4", "clsx": "^2.1.1", "fast-deep-equal": "^3.1.3" } @@ -39168,9 +39168,9 @@ } }, "@wordpress/dataviews": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/dataviews/-/dataviews-2.0.3.tgz", - "integrity": "sha512-+TDQsssoBBUMtb8y/wR9ZQvCOt7CENVxltTU0aI4bjBapjOtnpGIzr+ZoIbgC9q/WndepuxKNrUGiYpZplOefA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/dataviews/-/dataviews-2.0.4.tgz", + "integrity": "sha512-4FpLyvmiO0su4Fx3cLctqTIE+Bp1HCC1fHRFZw5JJgvkNXuAKHJRdpFCo1O11ZMH3ibxpWVshXZcfu7Z7HBWlw==", "requires": { "@ariakit/react": "^0.3.12", "@babel/runtime": "^7.16.0", @@ -39296,25 +39296,25 @@ } }, "@wordpress/edit-post": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/@wordpress/edit-post/-/edit-post-8.0.4.tgz", - "integrity": "sha512-gI3fauE2UjuNjon3eu+yHcVZ3DdtBVzy0a1x5OVexCs4kNqvXWVeeeqzjqG88g4UAgysNlF2HRECKMi+feTVxg==", + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/@wordpress/edit-post/-/edit-post-8.0.5.tgz", + "integrity": "sha512-NxEtAP7Ccz84COnuQKZji1UFi/CSeCD/8tr4yjvet4/4vvdlmTAR0GSIAeDl93ZmpNGCHF+d7mug2wDf9uLFtg==", "requires": { "@babel/runtime": "^7.16.0", "@wordpress/a11y": "^4.0.1", "@wordpress/api-fetch": "^7.0.1", - "@wordpress/block-editor": "^13.0.3", - "@wordpress/block-library": "^9.0.4", + "@wordpress/block-editor": "^13.0.4", + "@wordpress/block-library": "^9.0.5", "@wordpress/blocks": "^13.0.3", "@wordpress/commands": "^1.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-commands": "^1.0.3", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-commands": "^1.0.4", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/deprecated": "^4.0.1", "@wordpress/dom": "^4.0.1", - "@wordpress/editor": "^14.0.3", + "@wordpress/editor": "^14.0.4", "@wordpress/element": "^6.0.1", "@wordpress/hooks": "^4.0.1", "@wordpress/html-entities": "^4.0.1", @@ -39329,35 +39329,35 @@ "@wordpress/url": "^4.0.1", "@wordpress/viewport": "^6.0.2", "@wordpress/warning": "^3.0.1", - "@wordpress/widgets": "^4.0.3", + "@wordpress/widgets": "^4.0.4", "clsx": "^2.1.1", "memize": "^2.1.0" } }, "@wordpress/edit-site": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@wordpress/edit-site/-/edit-site-6.0.4.tgz", - "integrity": "sha512-Qcfj/VzAG/ZQf1+v4gEXn/7pA1TgG+f4dsuL0v6/Q/Au/alyT2OI7NgGOXC6faVAtp9WCmPf3YcDgk5ej5bm1Q==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@wordpress/edit-site/-/edit-site-6.0.5.tgz", + "integrity": "sha512-MGTs34PLC/NWGb07zQl/CFSPZXLE9IAsbY6IJy6mMUWB7BxNXdsVwm5OK91zubZV+54vzL5eo5YTGCgVd+8zFA==", "requires": { "@babel/runtime": "^7.16.0", "@react-spring/web": "^9.4.5", "@wordpress/a11y": "^4.0.1", "@wordpress/api-fetch": "^7.0.1", "@wordpress/blob": "^4.0.1", - "@wordpress/block-editor": "^13.0.3", - "@wordpress/block-library": "^9.0.4", + "@wordpress/block-editor": "^13.0.4", + "@wordpress/block-library": "^9.0.5", "@wordpress/blocks": "^13.0.3", "@wordpress/commands": "^1.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-commands": "^1.0.3", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-commands": "^1.0.4", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", - "@wordpress/dataviews": "^2.0.3", + "@wordpress/dataviews": "^2.0.4", "@wordpress/date": "^5.0.1", "@wordpress/deprecated": "^4.0.1", "@wordpress/dom": "^4.0.1", - "@wordpress/editor": "^14.0.3", + "@wordpress/editor": "^14.0.4", "@wordpress/element": "^6.0.1", "@wordpress/escape-html": "^3.0.1", "@wordpress/hooks": "^4.0.1", @@ -39367,18 +39367,18 @@ "@wordpress/keyboard-shortcuts": "^5.0.2", "@wordpress/keycodes": "^4.0.1", "@wordpress/notices": "^5.0.2", - "@wordpress/patterns": "^2.0.3", + "@wordpress/patterns": "^2.0.4", "@wordpress/plugins": "^7.0.3", "@wordpress/preferences": "^4.0.3", "@wordpress/primitives": "^4.0.1", "@wordpress/priority-queue": "^3.0.1", "@wordpress/private-apis": "^1.0.2", - "@wordpress/reusable-blocks": "^5.0.3", + "@wordpress/reusable-blocks": "^5.0.4", "@wordpress/router": "^1.0.2", "@wordpress/style-engine": "^2.0.2", "@wordpress/url": "^4.0.1", "@wordpress/viewport": "^6.0.2", - "@wordpress/widgets": "^4.0.3", + "@wordpress/widgets": "^4.0.4", "@wordpress/wordcount": "^4.0.1", "change-case": "^4.1.2", "clsx": "^2.1.1", @@ -39389,18 +39389,18 @@ } }, "@wordpress/edit-widgets": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@wordpress/edit-widgets/-/edit-widgets-6.0.4.tgz", - "integrity": "sha512-rMSmq5UZwljOv7i/2EdJhTWV9JCm8oTpwPvr/tAJgQ3OUiuNFpy0gA+SM8F7DtylUtl+9xV4F5GmhWNIGx4scg==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@wordpress/edit-widgets/-/edit-widgets-6.0.5.tgz", + "integrity": "sha512-+kAQyGDHN0raEbZ5piaACO2AZ62JAWoG5zDG8VN63vp9UiFvOodNwrljJ0afLcLIz6Kcb3BN8cjs65LBsjVvKQ==", "requires": { "@babel/runtime": "^7.16.0", "@wordpress/api-fetch": "^7.0.1", - "@wordpress/block-editor": "^13.0.3", - "@wordpress/block-library": "^9.0.4", + "@wordpress/block-editor": "^13.0.4", + "@wordpress/block-library": "^9.0.5", "@wordpress/blocks": "^13.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/deprecated": "^4.0.1", "@wordpress/dom": "^4.0.1", @@ -39413,31 +39413,31 @@ "@wordpress/keycodes": "^4.0.1", "@wordpress/media-utils": "^5.0.1", "@wordpress/notices": "^5.0.2", - "@wordpress/patterns": "^2.0.3", + "@wordpress/patterns": "^2.0.4", "@wordpress/plugins": "^7.0.3", "@wordpress/preferences": "^4.0.3", "@wordpress/private-apis": "^1.0.2", - "@wordpress/reusable-blocks": "^5.0.3", + "@wordpress/reusable-blocks": "^5.0.4", "@wordpress/url": "^4.0.1", - "@wordpress/widgets": "^4.0.3", + "@wordpress/widgets": "^4.0.4", "clsx": "^2.1.1" } }, "@wordpress/editor": { - "version": "14.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-14.0.3.tgz", - "integrity": "sha512-Rwv2xSTN+pqUVTMItpbMaulkIBGw1Linl5ODUx4mHeZBTYrjQD4qP4JH1nBYSHdmHr3HZAp+vgihHTHTgXkGCA==", + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-14.0.4.tgz", + "integrity": "sha512-Sy9dNAHJMFcHJzXlk8Y136+Ol0RmJ15CjhfnKZx4dxavRHrix5c+69MeQKavkmffrEN2XW9662C9cDlXAoczKg==", "requires": { "@babel/runtime": "^7.16.0", "@wordpress/a11y": "^4.0.1", "@wordpress/api-fetch": "^7.0.1", "@wordpress/blob": "^4.0.1", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/blocks": "^13.0.3", "@wordpress/commands": "^1.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/date": "^5.0.1", "@wordpress/deprecated": "^4.0.1", @@ -39452,11 +39452,11 @@ "@wordpress/keycodes": "^4.0.1", "@wordpress/media-utils": "^5.0.1", "@wordpress/notices": "^5.0.2", - "@wordpress/patterns": "^2.0.3", + "@wordpress/patterns": "^2.0.4", "@wordpress/plugins": "^7.0.3", "@wordpress/preferences": "^4.0.3", "@wordpress/private-apis": "^1.0.2", - "@wordpress/reusable-blocks": "^5.0.3", + "@wordpress/reusable-blocks": "^5.0.4", "@wordpress/rich-text": "^7.0.2", "@wordpress/server-side-render": "^5.0.3", "@wordpress/url": "^4.0.1", @@ -39534,13 +39534,13 @@ } }, "@wordpress/format-library": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/format-library/-/format-library-5.0.3.tgz", - "integrity": "sha512-mD3738vO6pxKOiEBp4kaUrq03hsaVg8nBtFpBxWYozM1/CkSm9aKm3u73pixX4EdCL9VXo546WYNm4wCBeDiMg==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/format-library/-/format-library-5.0.4.tgz", + "integrity": "sha512-rdyibYZ2FnozrPRY7U1/8YRjoHHqjDDxmywLPtSqvJ95QhhBGMzCp+DJCWEpi/FANj8j4n5FLVala0W8xdStZA==", "requires": { "@babel/runtime": "^7.16.0", "@wordpress/a11y": "^4.0.1", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", "@wordpress/data": "^10.0.2", @@ -39738,17 +39738,17 @@ } }, "@wordpress/patterns": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/patterns/-/patterns-2.0.3.tgz", - "integrity": "sha512-bAiaMAw/wGjYcrsBEEI4ZJv+y334VaTYYzw2JrGpAOpzNbw0UQmdNBz+aws8hRshnj0EZEyY3CY8k9sy47AR9g==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/patterns/-/patterns-2.0.4.tgz", + "integrity": "sha512-A5o490U8rAvZ9nJNz+ZWkP300hshfON0HE/FLmkxvwNCRxbnWAmdq1F5PQqmPthDC7NygFz90ZeEXg+iDJU49Q==", "requires": { "@babel/runtime": "^7.16.0", "@wordpress/a11y": "^4.0.1", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/blocks": "^13.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/element": "^6.0.1", "@wordpress/html-entities": "^4.0.1", @@ -39856,15 +39856,15 @@ } }, "@wordpress/reusable-blocks": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/reusable-blocks/-/reusable-blocks-5.0.3.tgz", - "integrity": "sha512-nqr+/VDO42hB4d9fz07Eoen+SWi/H/9eeda76AdpgDzJq4oLmxxLgo/ze4lbnrYgdeeB3vSsKkJPi5ENPc9+jQ==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/reusable-blocks/-/reusable-blocks-5.0.4.tgz", + "integrity": "sha512-ie0ewJW/xIkvq8uupP20d7FDll58uuiqky+BV9f+GByWHbR8z01PQcErrlR4eId/epR5Cay+rHHLLwc0EV8A/A==", "requires": { "@babel/runtime": "^7.16.0", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/blocks": "^13.0.3", "@wordpress/components": "^28.0.3", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/element": "^6.0.1", "@wordpress/i18n": "^5.0.1", @@ -40728,17 +40728,17 @@ "integrity": "sha512-xSVH/zMAg4ABeNOWo6mlkF+TDBDQNaWVdMNzi+yvGoSDImhaM6Bqrhr1e/65AS29iajnqQt6dlu7E56o5FZlcg==" }, "@wordpress/widgets": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@wordpress/widgets/-/widgets-4.0.3.tgz", - "integrity": "sha512-/yY7ZWq80phLgrlL6kd4EJcrrG5nhWM7vGrHK8Hg0RBJ0zcQXMcfHG3a12Fxw5mbiKDLB3hKpNUJYxk+GpHcuQ==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@wordpress/widgets/-/widgets-4.0.4.tgz", + "integrity": "sha512-n9VyatU28mFTQzn/O4NNPK9JQ0KeVYu4VhmVo4sxUeOxRJbdqGVW1L6MotnFn0uL/fbZOD5E07aiU22EJwJmlw==", "requires": { "@babel/runtime": "^7.16.0", "@wordpress/api-fetch": "^7.0.1", - "@wordpress/block-editor": "^13.0.3", + "@wordpress/block-editor": "^13.0.4", "@wordpress/blocks": "^13.0.3", "@wordpress/components": "^28.0.3", "@wordpress/compose": "^7.0.1", - "@wordpress/core-data": "^7.0.3", + "@wordpress/core-data": "^7.0.4", "@wordpress/data": "^10.0.2", "@wordpress/element": "^6.0.1", "@wordpress/i18n": "^5.0.1", diff --git a/package.json b/package.json index 4041a61d25006..62cb44d6cc97e 100644 --- a/package.json +++ b/package.json @@ -83,31 +83,31 @@ "@wordpress/api-fetch": "7.0.1", "@wordpress/autop": "4.0.1", "@wordpress/blob": "4.0.1", - "@wordpress/block-directory": "5.0.4", - "@wordpress/block-editor": "13.0.3", - "@wordpress/block-library": "9.0.4", + "@wordpress/block-directory": "5.0.5", + "@wordpress/block-editor": "13.0.4", + "@wordpress/block-library": "9.0.5", "@wordpress/block-serialization-default-parser": "5.0.1", "@wordpress/blocks": "13.0.3", "@wordpress/commands": "1.0.3", "@wordpress/components": "28.0.3", "@wordpress/compose": "7.0.1", - "@wordpress/core-commands": "1.0.3", - "@wordpress/core-data": "7.0.3", - "@wordpress/customize-widgets": "5.0.4", + "@wordpress/core-commands": "1.0.4", + "@wordpress/core-data": "7.0.4", + "@wordpress/customize-widgets": "5.0.5", "@wordpress/data": "10.0.2", "@wordpress/data-controls": "4.0.2", - "@wordpress/dataviews": "2.0.3", + "@wordpress/dataviews": "2.0.4", "@wordpress/date": "5.0.1", "@wordpress/deprecated": "4.0.1", "@wordpress/dom": "4.0.1", "@wordpress/dom-ready": "4.0.1", - "@wordpress/edit-post": "8.0.4", - "@wordpress/edit-site": "6.0.4", - "@wordpress/edit-widgets": "6.0.4", - "@wordpress/editor": "14.0.3", + "@wordpress/edit-post": "8.0.5", + "@wordpress/edit-site": "6.0.5", + "@wordpress/edit-widgets": "6.0.5", + "@wordpress/editor": "14.0.4", "@wordpress/element": "6.0.1", "@wordpress/escape-html": "3.0.1", - "@wordpress/format-library": "5.0.3", + "@wordpress/format-library": "5.0.4", "@wordpress/hooks": "4.0.1", "@wordpress/html-entities": "4.0.1", "@wordpress/i18n": "5.0.1", @@ -122,7 +122,7 @@ "@wordpress/media-utils": "5.0.1", "@wordpress/notices": "5.0.2", "@wordpress/nux": "9.0.3", - "@wordpress/patterns": "2.0.3", + "@wordpress/patterns": "2.0.4", "@wordpress/plugins": "7.0.3", "@wordpress/preferences": "4.0.3", "@wordpress/preferences-persistence": "2.0.1", @@ -130,7 +130,7 @@ "@wordpress/priority-queue": "3.0.1", "@wordpress/private-apis": "1.0.2", "@wordpress/redux-routine": "5.0.1", - "@wordpress/reusable-blocks": "5.0.3", + "@wordpress/reusable-blocks": "5.0.4", "@wordpress/rich-text": "7.0.2", "@wordpress/router": "1.0.2", "@wordpress/server-side-render": "5.0.3", @@ -142,7 +142,7 @@ "@wordpress/url": "4.0.1", "@wordpress/viewport": "6.0.2", "@wordpress/warning": "3.0.1", - "@wordpress/widgets": "4.0.3", + "@wordpress/widgets": "4.0.4", "@wordpress/wordcount": "4.0.1", "backbone": "1.5.0", "clipboard": "2.0.11", diff --git a/src/wp-includes/assets/script-loader-packages.min.php b/src/wp-includes/assets/script-loader-packages.min.php index 2be33f4016df3..a1997701d6a7c 100644 --- a/src/wp-includes/assets/script-loader-packages.min.php +++ b/src/wp-includes/assets/script-loader-packages.min.php @@ -1 +1 @@ - array('dependencies' => array('wp-dom-ready', 'wp-i18n'), 'version' => 'd90eebea464f6c09bfd5'), 'annotations.min.js' => array('dependencies' => array('wp-data', 'wp-hooks', 'wp-i18n', 'wp-rich-text'), 'version' => '238360e96c76d37a2468'), 'api-fetch.min.js' => array('dependencies' => array('wp-i18n', 'wp-url'), 'version' => '4c185334c5ec26e149cc'), 'autop.min.js' => array('dependencies' => array(), 'version' => '9fb50649848277dd318d'), 'blob.min.js' => array('dependencies' => array(), 'version' => '9113eed771d446f4a556'), 'block-directory.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-a11y', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-notices', 'wp-plugins', 'wp-primitives', 'wp-private-apis', 'wp-url'), 'version' => '286a70e45f3a8522a72a'), 'block-editor.min.js' => array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-a11y', 'wp-api-fetch', 'wp-blob', 'wp-blocks', 'wp-commands', 'wp-components', 'wp-compose', 'wp-data', 'wp-date', 'wp-deprecated', 'wp-dom', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-is-shallow-equal', 'wp-keyboard-shortcuts', 'wp-keycodes', 'wp-notices', 'wp-preferences', 'wp-primitives', 'wp-private-apis', 'wp-rich-text', 'wp-style-engine', 'wp-token-list', 'wp-url', 'wp-warning', 'wp-wordcount'), 'version' => '923f5626c77e376cefe7'), 'block-library.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-a11y', 'wp-api-fetch', 'wp-autop', 'wp-blob', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-date', 'wp-deprecated', 'wp-dom', 'wp-element', 'wp-escape-html', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-keycodes', 'wp-notices', 'wp-patterns', 'wp-primitives', 'wp-private-apis', 'wp-rich-text', 'wp-server-side-render', 'wp-url', 'wp-viewport', 'wp-wordcount'), 'version' => '789183efb6ee10a7eda3'), 'block-serialization-default-parser.min.js' => array('dependencies' => array(), 'version' => '14d44daebf663d05d330'), 'blocks.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-autop', 'wp-blob', 'wp-block-serialization-default-parser', 'wp-data', 'wp-deprecated', 'wp-dom', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-is-shallow-equal', 'wp-private-apis', 'wp-rich-text', 'wp-shortcode'), 'version' => '0d232d232463200f5cfd'), 'commands.min.js' => array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-primitives', 'wp-private-apis'), 'version' => '73d702f6367f60b06d89'), 'components.min.js' => array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-a11y', 'wp-compose', 'wp-date', 'wp-deprecated', 'wp-dom', 'wp-element', 'wp-escape-html', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-is-shallow-equal', 'wp-keycodes', 'wp-primitives', 'wp-private-apis', 'wp-rich-text', 'wp-warning'), 'version' => '36b97398bf090476214e'), 'compose.min.js' => array('dependencies' => array('react', 'react-jsx-runtime', 'wp-deprecated', 'wp-dom', 'wp-element', 'wp-is-shallow-equal', 'wp-keycodes', 'wp-priority-queue'), 'version' => 'b8d54449305350b51869'), 'core-commands.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-commands', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives', 'wp-private-apis', 'wp-router', 'wp-url'), 'version' => 'e69dd29bbed89764e60f'), 'core-data.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-compose', 'wp-data', 'wp-deprecated', 'wp-element', 'wp-html-entities', 'wp-i18n', 'wp-is-shallow-equal', 'wp-private-apis', 'wp-rich-text', 'wp-url'), 'version' => 'a1dd4d12e0ddd5d76418'), 'customize-widgets.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-is-shallow-equal', 'wp-keyboard-shortcuts', 'wp-keycodes', 'wp-media-utils', 'wp-preferences', 'wp-primitives', 'wp-private-apis', 'wp-widgets'), 'version' => '9b7db92a95af0a39ae98'), 'data.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-compose', 'wp-deprecated', 'wp-element', 'wp-is-shallow-equal', 'wp-priority-queue', 'wp-private-apis', 'wp-redux-routine'), 'version' => '7c62e39de0308c73d50c'), 'data-controls.min.js' => array('dependencies' => array('wp-api-fetch', 'wp-data', 'wp-deprecated'), 'version' => '49f5587e8b90f9e7cc7e'), 'date.min.js' => array('dependencies' => array('moment', 'wp-deprecated'), 'version' => 'aaca6387d1cf924acc51'), 'deprecated.min.js' => array('dependencies' => array('wp-hooks'), 'version' => 'e1f84915c5e8ae38964c'), 'dom.min.js' => array('dependencies' => array('wp-deprecated'), 'version' => '4ecffbffba91b10c5c7a'), 'dom-ready.min.js' => array('dependencies' => array(), 'version' => 'f77871ff7694fffea381'), 'edit-post.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-commands', 'wp-components', 'wp-compose', 'wp-core-commands', 'wp-core-data', 'wp-data', 'wp-deprecated', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-keycodes', 'wp-notices', 'wp-plugins', 'wp-preferences', 'wp-primitives', 'wp-private-apis', 'wp-url', 'wp-widgets'), 'version' => 'f55d87aa6a5f158f1aec'), 'edit-site.min.js' => array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-a11y', 'wp-api-fetch', 'wp-blob', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-commands', 'wp-components', 'wp-compose', 'wp-core-commands', 'wp-core-data', 'wp-data', 'wp-date', 'wp-deprecated', 'wp-dom', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-keycodes', 'wp-notices', 'wp-patterns', 'wp-plugins', 'wp-preferences', 'wp-primitives', 'wp-priority-queue', 'wp-private-apis', 'wp-router', 'wp-url', 'wp-widgets'), 'version' => 'ac2999b763a1862f7a8b'), 'edit-widgets.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-deprecated', 'wp-dom', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-keycodes', 'wp-media-utils', 'wp-notices', 'wp-patterns', 'wp-plugins', 'wp-preferences', 'wp-primitives', 'wp-private-apis', 'wp-url', 'wp-viewport', 'wp-widgets'), 'version' => '974884730aac247c3a3e'), 'editor.min.js' => array('dependencies' => array('react', 'react-jsx-runtime', 'wp-a11y', 'wp-api-fetch', 'wp-blob', 'wp-block-editor', 'wp-blocks', 'wp-commands', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-date', 'wp-deprecated', 'wp-dom', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-keycodes', 'wp-media-utils', 'wp-notices', 'wp-patterns', 'wp-plugins', 'wp-preferences', 'wp-primitives', 'wp-private-apis', 'wp-rich-text', 'wp-server-side-render', 'wp-url', 'wp-viewport', 'wp-warning', 'wp-wordcount'), 'version' => 'e6cb9c8ac7fcce3b5e32'), 'element.min.js' => array('dependencies' => array('react', 'react-dom', 'wp-escape-html'), 'version' => 'cb762d190aebbec25b27'), 'escape-html.min.js' => array('dependencies' => array(), 'version' => '6561a406d2d232a6fbd2'), 'format-library.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-a11y', 'wp-block-editor', 'wp-components', 'wp-data', 'wp-element', 'wp-html-entities', 'wp-i18n', 'wp-primitives', 'wp-private-apis', 'wp-rich-text', 'wp-url'), 'version' => 'e3618e6d17a1146f03e4'), 'hooks.min.js' => array('dependencies' => array(), 'version' => '2810c76e705dd1a53b18'), 'html-entities.min.js' => array('dependencies' => array(), 'version' => '2cd3358363e0675638fb'), 'i18n.min.js' => array('dependencies' => array('wp-hooks'), 'version' => '5e580eb46a90c2b997e6'), 'is-shallow-equal.min.js' => array('dependencies' => array(), 'version' => 'e0f9f1d78d83f5196979'), 'keyboard-shortcuts.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-data', 'wp-element', 'wp-keycodes'), 'version' => '32686e58e84193ce808b'), 'keycodes.min.js' => array('dependencies' => array('wp-i18n'), 'version' => '034ff647a54b018581d3'), 'list-reusable-blocks.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-blob', 'wp-components', 'wp-compose', 'wp-element', 'wp-i18n'), 'version' => '0eaedbf902a3af0eee37'), 'media-utils.min.js' => array('dependencies' => array('wp-api-fetch', 'wp-blob', 'wp-element', 'wp-i18n'), 'version' => '1cf582d3c080c8694c8c'), 'notices.min.js' => array('dependencies' => array('wp-data'), 'version' => '673a68a7ac2f556ed50b'), 'nux.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-components', 'wp-compose', 'wp-data', 'wp-deprecated', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => 'b8f02a77b1489668fb50'), 'patterns.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-a11y', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-html-entities', 'wp-i18n', 'wp-notices', 'wp-primitives', 'wp-private-apis', 'wp-url'), 'version' => '52e6ada8ff0a9f3a138e'), 'plugins.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-compose', 'wp-element', 'wp-hooks', 'wp-is-shallow-equal', 'wp-primitives'), 'version' => 'ef6da4a9b2747b62c09c'), 'preferences.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-a11y', 'wp-components', 'wp-compose', 'wp-data', 'wp-deprecated', 'wp-element', 'wp-i18n', 'wp-primitives', 'wp-private-apis'), 'version' => 'e7b06b8f8bdd714600e9'), 'preferences-persistence.min.js' => array('dependencies' => array('wp-api-fetch'), 'version' => '9307a8c9e3254140a223'), 'primitives.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-element'), 'version' => 'aef2543ab60c8c9bb609'), 'priority-queue.min.js' => array('dependencies' => array(), 'version' => '9c21c957c7e50ffdbf48'), 'private-apis.min.js' => array('dependencies' => array(), 'version' => '17a2e640b653d742da6e'), 'redux-routine.min.js' => array('dependencies' => array(), 'version' => 'a0a172871afaeb261566'), 'reusable-blocks.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-notices', 'wp-primitives', 'wp-private-apis', 'wp-url'), 'version' => '5c420cb83017d586169a'), 'rich-text.min.js' => array('dependencies' => array('wp-a11y', 'wp-compose', 'wp-data', 'wp-deprecated', 'wp-element', 'wp-escape-html', 'wp-i18n', 'wp-keycodes'), 'version' => '4021b9e4e9ef4d3cd868'), 'router.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-element', 'wp-private-apis', 'wp-url'), 'version' => 'e4887fecc16ef03e908f'), 'server-side-render.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '1e0f25c205ebeb30bcd2'), 'shortcode.min.js' => array('dependencies' => array(), 'version' => 'b7747eee0efafd2f0c3b'), 'style-engine.min.js' => array('dependencies' => array(), 'version' => '86ba6721a03e5b921dfe'), 'token-list.min.js' => array('dependencies' => array(), 'version' => '05f8a6df6258f0081718'), 'undo-manager.min.js' => array('dependencies' => array('wp-is-shallow-equal'), 'version' => 'f0698003cb0f0a7bd794'), 'url.min.js' => array('dependencies' => array(), 'version' => '36ae0e4dd9043bb8749b'), 'viewport.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-compose', 'wp-data'), 'version' => '829c9a30d366e1e5054c'), 'warning.min.js' => array('dependencies' => array(), 'version' => 'ed7c8b0940914f4fe44b'), 'widgets.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-notices', 'wp-primitives'), 'version' => '53f9d5d5df6f21e39834'), 'wordcount.min.js' => array('dependencies' => array(), 'version' => '55d8c2bf3dc99e7ea5ec')); + array('dependencies' => array('wp-dom-ready', 'wp-i18n'), 'version' => 'd90eebea464f6c09bfd5'), 'annotations.min.js' => array('dependencies' => array('wp-data', 'wp-hooks', 'wp-i18n', 'wp-rich-text'), 'version' => '238360e96c76d37a2468'), 'api-fetch.min.js' => array('dependencies' => array('wp-i18n', 'wp-url'), 'version' => '4c185334c5ec26e149cc'), 'autop.min.js' => array('dependencies' => array(), 'version' => '9fb50649848277dd318d'), 'blob.min.js' => array('dependencies' => array(), 'version' => '9113eed771d446f4a556'), 'block-directory.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-a11y', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-notices', 'wp-plugins', 'wp-primitives', 'wp-private-apis', 'wp-url'), 'version' => '286a70e45f3a8522a72a'), 'block-editor.min.js' => array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-a11y', 'wp-api-fetch', 'wp-blob', 'wp-blocks', 'wp-commands', 'wp-components', 'wp-compose', 'wp-data', 'wp-date', 'wp-deprecated', 'wp-dom', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-is-shallow-equal', 'wp-keyboard-shortcuts', 'wp-keycodes', 'wp-notices', 'wp-preferences', 'wp-primitives', 'wp-private-apis', 'wp-rich-text', 'wp-style-engine', 'wp-token-list', 'wp-url', 'wp-warning', 'wp-wordcount'), 'version' => 'eaed80842415cb2c8140'), 'block-library.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-a11y', 'wp-api-fetch', 'wp-autop', 'wp-blob', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-date', 'wp-deprecated', 'wp-dom', 'wp-element', 'wp-escape-html', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-keycodes', 'wp-notices', 'wp-patterns', 'wp-primitives', 'wp-private-apis', 'wp-rich-text', 'wp-server-side-render', 'wp-url', 'wp-viewport', 'wp-wordcount'), 'version' => '96b614e020e4ab48838d'), 'block-serialization-default-parser.min.js' => array('dependencies' => array(), 'version' => '14d44daebf663d05d330'), 'blocks.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-autop', 'wp-blob', 'wp-block-serialization-default-parser', 'wp-data', 'wp-deprecated', 'wp-dom', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-is-shallow-equal', 'wp-private-apis', 'wp-rich-text', 'wp-shortcode'), 'version' => '0d232d232463200f5cfd'), 'commands.min.js' => array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-primitives', 'wp-private-apis'), 'version' => '73d702f6367f60b06d89'), 'components.min.js' => array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-a11y', 'wp-compose', 'wp-date', 'wp-deprecated', 'wp-dom', 'wp-element', 'wp-escape-html', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-is-shallow-equal', 'wp-keycodes', 'wp-primitives', 'wp-private-apis', 'wp-rich-text', 'wp-warning'), 'version' => '36b97398bf090476214e'), 'compose.min.js' => array('dependencies' => array('react', 'react-jsx-runtime', 'wp-deprecated', 'wp-dom', 'wp-element', 'wp-is-shallow-equal', 'wp-keycodes', 'wp-priority-queue'), 'version' => 'b8d54449305350b51869'), 'core-commands.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-commands', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives', 'wp-private-apis', 'wp-router', 'wp-url'), 'version' => 'e69dd29bbed89764e60f'), 'core-data.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-compose', 'wp-data', 'wp-deprecated', 'wp-element', 'wp-html-entities', 'wp-i18n', 'wp-is-shallow-equal', 'wp-private-apis', 'wp-rich-text', 'wp-url'), 'version' => 'a1dd4d12e0ddd5d76418'), 'customize-widgets.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-is-shallow-equal', 'wp-keyboard-shortcuts', 'wp-keycodes', 'wp-media-utils', 'wp-preferences', 'wp-primitives', 'wp-private-apis', 'wp-widgets'), 'version' => '9b7db92a95af0a39ae98'), 'data.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-compose', 'wp-deprecated', 'wp-element', 'wp-is-shallow-equal', 'wp-priority-queue', 'wp-private-apis', 'wp-redux-routine'), 'version' => '7c62e39de0308c73d50c'), 'data-controls.min.js' => array('dependencies' => array('wp-api-fetch', 'wp-data', 'wp-deprecated'), 'version' => '49f5587e8b90f9e7cc7e'), 'date.min.js' => array('dependencies' => array('moment', 'wp-deprecated'), 'version' => 'aaca6387d1cf924acc51'), 'deprecated.min.js' => array('dependencies' => array('wp-hooks'), 'version' => 'e1f84915c5e8ae38964c'), 'dom.min.js' => array('dependencies' => array('wp-deprecated'), 'version' => '4ecffbffba91b10c5c7a'), 'dom-ready.min.js' => array('dependencies' => array(), 'version' => 'f77871ff7694fffea381'), 'edit-post.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-commands', 'wp-components', 'wp-compose', 'wp-core-commands', 'wp-core-data', 'wp-data', 'wp-deprecated', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-keycodes', 'wp-notices', 'wp-plugins', 'wp-preferences', 'wp-primitives', 'wp-private-apis', 'wp-url', 'wp-widgets'), 'version' => 'f55d87aa6a5f158f1aec'), 'edit-site.min.js' => array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-a11y', 'wp-api-fetch', 'wp-blob', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-commands', 'wp-components', 'wp-compose', 'wp-core-commands', 'wp-core-data', 'wp-data', 'wp-date', 'wp-deprecated', 'wp-dom', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-keycodes', 'wp-notices', 'wp-patterns', 'wp-plugins', 'wp-preferences', 'wp-primitives', 'wp-priority-queue', 'wp-private-apis', 'wp-router', 'wp-url', 'wp-widgets'), 'version' => '34dd596ec3cbcaf84177'), 'edit-widgets.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-deprecated', 'wp-dom', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-keycodes', 'wp-media-utils', 'wp-notices', 'wp-patterns', 'wp-plugins', 'wp-preferences', 'wp-primitives', 'wp-private-apis', 'wp-url', 'wp-viewport', 'wp-widgets'), 'version' => '974884730aac247c3a3e'), 'editor.min.js' => array('dependencies' => array('react', 'react-jsx-runtime', 'wp-a11y', 'wp-api-fetch', 'wp-blob', 'wp-block-editor', 'wp-blocks', 'wp-commands', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-date', 'wp-deprecated', 'wp-dom', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-keycodes', 'wp-media-utils', 'wp-notices', 'wp-patterns', 'wp-plugins', 'wp-preferences', 'wp-primitives', 'wp-private-apis', 'wp-rich-text', 'wp-server-side-render', 'wp-url', 'wp-viewport', 'wp-warning', 'wp-wordcount'), 'version' => '29c0c50a059d2f0d31de'), 'element.min.js' => array('dependencies' => array('react', 'react-dom', 'wp-escape-html'), 'version' => 'cb762d190aebbec25b27'), 'escape-html.min.js' => array('dependencies' => array(), 'version' => '6561a406d2d232a6fbd2'), 'format-library.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-a11y', 'wp-block-editor', 'wp-components', 'wp-data', 'wp-element', 'wp-html-entities', 'wp-i18n', 'wp-primitives', 'wp-private-apis', 'wp-rich-text', 'wp-url'), 'version' => 'e3618e6d17a1146f03e4'), 'hooks.min.js' => array('dependencies' => array(), 'version' => '2810c76e705dd1a53b18'), 'html-entities.min.js' => array('dependencies' => array(), 'version' => '2cd3358363e0675638fb'), 'i18n.min.js' => array('dependencies' => array('wp-hooks'), 'version' => '5e580eb46a90c2b997e6'), 'is-shallow-equal.min.js' => array('dependencies' => array(), 'version' => 'e0f9f1d78d83f5196979'), 'keyboard-shortcuts.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-data', 'wp-element', 'wp-keycodes'), 'version' => '32686e58e84193ce808b'), 'keycodes.min.js' => array('dependencies' => array('wp-i18n'), 'version' => '034ff647a54b018581d3'), 'list-reusable-blocks.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-blob', 'wp-components', 'wp-compose', 'wp-element', 'wp-i18n'), 'version' => '0eaedbf902a3af0eee37'), 'media-utils.min.js' => array('dependencies' => array('wp-api-fetch', 'wp-blob', 'wp-element', 'wp-i18n'), 'version' => '1cf582d3c080c8694c8c'), 'notices.min.js' => array('dependencies' => array('wp-data'), 'version' => '673a68a7ac2f556ed50b'), 'nux.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-components', 'wp-compose', 'wp-data', 'wp-deprecated', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => 'b8f02a77b1489668fb50'), 'patterns.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-a11y', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-html-entities', 'wp-i18n', 'wp-notices', 'wp-primitives', 'wp-private-apis', 'wp-url'), 'version' => '2bb44334a17254b90b83'), 'plugins.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-compose', 'wp-element', 'wp-hooks', 'wp-is-shallow-equal', 'wp-primitives'), 'version' => 'ef6da4a9b2747b62c09c'), 'preferences.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-a11y', 'wp-components', 'wp-compose', 'wp-data', 'wp-deprecated', 'wp-element', 'wp-i18n', 'wp-primitives', 'wp-private-apis'), 'version' => 'e7b06b8f8bdd714600e9'), 'preferences-persistence.min.js' => array('dependencies' => array('wp-api-fetch'), 'version' => '9307a8c9e3254140a223'), 'primitives.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-element'), 'version' => 'aef2543ab60c8c9bb609'), 'priority-queue.min.js' => array('dependencies' => array(), 'version' => '9c21c957c7e50ffdbf48'), 'private-apis.min.js' => array('dependencies' => array(), 'version' => '17a2e640b653d742da6e'), 'redux-routine.min.js' => array('dependencies' => array(), 'version' => 'a0a172871afaeb261566'), 'reusable-blocks.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-notices', 'wp-primitives', 'wp-private-apis', 'wp-url'), 'version' => '5c420cb83017d586169a'), 'rich-text.min.js' => array('dependencies' => array('wp-a11y', 'wp-compose', 'wp-data', 'wp-deprecated', 'wp-element', 'wp-escape-html', 'wp-i18n', 'wp-keycodes'), 'version' => '4021b9e4e9ef4d3cd868'), 'router.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-element', 'wp-private-apis', 'wp-url'), 'version' => 'e4887fecc16ef03e908f'), 'server-side-render.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-data', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '1e0f25c205ebeb30bcd2'), 'shortcode.min.js' => array('dependencies' => array(), 'version' => 'b7747eee0efafd2f0c3b'), 'style-engine.min.js' => array('dependencies' => array(), 'version' => '86ba6721a03e5b921dfe'), 'token-list.min.js' => array('dependencies' => array(), 'version' => '05f8a6df6258f0081718'), 'undo-manager.min.js' => array('dependencies' => array('wp-is-shallow-equal'), 'version' => 'f0698003cb0f0a7bd794'), 'url.min.js' => array('dependencies' => array(), 'version' => '36ae0e4dd9043bb8749b'), 'viewport.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-compose', 'wp-data'), 'version' => '829c9a30d366e1e5054c'), 'warning.min.js' => array('dependencies' => array(), 'version' => 'ed7c8b0940914f4fe44b'), 'widgets.min.js' => array('dependencies' => array('react-jsx-runtime', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-notices', 'wp-primitives'), 'version' => '53f9d5d5df6f21e39834'), 'wordcount.min.js' => array('dependencies' => array(), 'version' => '55d8c2bf3dc99e7ea5ec')); diff --git a/src/wp-includes/blocks/block/block.json b/src/wp-includes/blocks/block/block.json index 34dcb9a396ac6..fdce3bcc02e07 100644 --- a/src/wp-includes/blocks/block/block.json +++ b/src/wp-includes/blocks/block/block.json @@ -12,9 +12,13 @@ "type": "number" }, "content": { - "type": "object" + "type": "object", + "default": {} } }, + "providesContext": { + "pattern/overrides": "content" + }, "supports": { "customClassName": false, "html": false, diff --git a/src/wp-includes/blocks/blocks-json.php b/src/wp-includes/blocks/blocks-json.php index bbab74be034c9..46e84707f5822 100644 --- a/src/wp-includes/blocks/blocks-json.php +++ b/src/wp-includes/blocks/blocks-json.php @@ -207,9 +207,15 @@ 'type' => 'number' ), 'content' => array( - 'type' => 'object' + 'type' => 'object', + 'default' => array( + + ) ) ), + 'providesContext' => array( + 'pattern/overrides' => 'content' + ), 'supports' => array( 'customClassName' => false, 'html' => false, From 6af639581727ae631d2d7e9c99106f93f11f00fa Mon Sep 17 00:00:00 2001 From: Kelly Choyce-Dwan Date: Tue, 2 Jul 2024 15:13:13 +0000 Subject: [PATCH 12/53] Help/About: Add images to the About page. The images have been uploaded to the w.org CDN and added into the About page. Additionally, the link to the release page has been fixed, and an extra translator note about the escaped percent sign has been added. Follow-up to [58568]. Props ryelle, joen. See #61320. git-svn-id: https://develop.svn.wordpress.org/trunk@58618 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/about.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/wp-admin/about.php b/src/wp-admin/about.php index c64df64f7cc5b..a794ab9ec6668 100644 --- a/src/wp-admin/about.php +++ b/src/wp-admin/about.php @@ -65,7 +65,7 @@
- +
@@ -73,7 +73,7 @@
- +
@@ -89,7 +89,7 @@
- +
@@ -97,7 +97,7 @@
- +
@@ -124,7 +124,7 @@

data-wp-on-async' ); @@ -152,7 +152,7 @@

- +
From 67aa1d99bdf5ef136b360131a9ada662290d49e1 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Tue, 2 Jul 2024 17:44:50 +0000 Subject: [PATCH 13/53] Login and Registration: Remove redundant escaping in `wp-login.php`. * `$user_login` in the `login` action is already escaped on output. * `$user_login` and `$user_email` in the `register` action are already unslashed a few lines above. Follow-up to [3120], [4339], [8454], [11104], [23416], [23554], [23594], [46640]. Props johnjamesjacoby, rajinsharwar, narenin. Fixes #55335. git-svn-id: https://develop.svn.wordpress.org/trunk@58623 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-login.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wp-login.php b/src/wp-login.php index 16faccb703687..45d7794c84ed7 100644 --- a/src/wp-login.php +++ b/src/wp-login.php @@ -1160,11 +1160,11 @@ function wp_login_viewport_meta() {

- +

- +

get_error_code() || 'empty_password' === $errors->get_error_code() ) ? esc_attr( wp_unslash( $_POST['log'] ) ) : ''; + $user_login = ( 'incorrect_password' === $errors->get_error_code() || 'empty_password' === $errors->get_error_code() ) ? wp_unslash( $_POST['log'] ) : ''; } $rememberme = ! empty( $_POST['rememberme'] ); From 24646a4313e563eb62511cf1e477a06e07779660 Mon Sep 17 00:00:00 2001 From: Tammie Lister Date: Tue, 2 Jul 2024 19:59:17 +0000 Subject: [PATCH 14/53] Twenty Nineteen: Adds center alignment to Archives and Categories List blocks. When selecting center alignment for Archives or Categories List blocks the alignment was not matching. It is worth noting this fixes for these blocks but another ticket could be made to fix for titles. Props pranitdugad, sabernhardt. Fixes #47044. git-svn-id: https://develop.svn.wordpress.org/trunk@58627 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-content/themes/twentynineteen/style-editor.css | 5 +++++ src/wp-content/themes/twentynineteen/style-editor.scss | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/wp-content/themes/twentynineteen/style-editor.css b/src/wp-content/themes/twentynineteen/style-editor.css index 4619b0177f14e..c736c6d4a376c 100644 --- a/src/wp-content/themes/twentynineteen/style-editor.css +++ b/src/wp-content/themes/twentynineteen/style-editor.css @@ -1366,6 +1366,11 @@ ul.wp-block-archives li ul, margin-bottom: -0.75rem; } +.wp-block[data-align="center"] > .wp-block-archives, +.wp-block[data-align="center"] > .wp-block-categories { + text-align: center; +} + /** === Latest Posts === */ .wp-block-latest-posts .wp-block-latest-posts__post-date { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; diff --git a/src/wp-content/themes/twentynineteen/style-editor.scss b/src/wp-content/themes/twentynineteen/style-editor.scss index de3c8a7c9352c..3695af6a368c1 100644 --- a/src/wp-content/themes/twentynineteen/style-editor.scss +++ b/src/wp-content/themes/twentynineteen/style-editor.scss @@ -756,6 +756,11 @@ ul.wp-block-archives, } +.wp-block[data-align="center"] > .wp-block-archives, +.wp-block[data-align="center"] > .wp-block-categories { + text-align: center; +} + /** === Latest Posts === */ .wp-block-latest-posts { From f1a3d209ba391140bf0cf2720a9faa1824ba213d Mon Sep 17 00:00:00 2001 From: Tammie Lister Date: Tue, 2 Jul 2024 20:34:04 +0000 Subject: [PATCH 15/53] Twenty Twenty-One: Resolves bug on primary navigation. The primary navigation was stuck in a vertical list when resize. This resolves that with positioning. Props nek285, mukesh27. Fixes #52663. git-svn-id: https://develop.svn.wordpress.org/trunk@58629 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-content/themes/twentytwentyone/assets/css/ie.css | 2 +- .../twentytwentyone/assets/sass/06-components/navigation.scss | 2 +- src/wp-content/themes/twentytwentyone/style-rtl.css | 2 +- src/wp-content/themes/twentytwentyone/style.css | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wp-content/themes/twentytwentyone/assets/css/ie.css b/src/wp-content/themes/twentytwentyone/assets/css/ie.css index 87d14784e5264..e1f4b9d09a372 100644 --- a/src/wp-content/themes/twentytwentyone/assets/css/ie.css +++ b/src/wp-content/themes/twentytwentyone/assets/css/ie.css @@ -5167,7 +5167,7 @@ h1.page-title { } .primary-navigation-open .primary-navigation > .primary-menu-container { - position: absolute; + position: relative; visibility: visible; opacity: 1; transform: translateY(0); diff --git a/src/wp-content/themes/twentytwentyone/assets/sass/06-components/navigation.scss b/src/wp-content/themes/twentytwentyone/assets/sass/06-components/navigation.scss index d716ba3fb9882..58f2d054c4bdb 100644 --- a/src/wp-content/themes/twentytwentyone/assets/sass/06-components/navigation.scss +++ b/src/wp-content/themes/twentytwentyone/assets/sass/06-components/navigation.scss @@ -143,7 +143,7 @@ } > .primary-menu-container { - position: absolute; + position: relative; visibility: visible; opacity: 1; transform: translateY(0); diff --git a/src/wp-content/themes/twentytwentyone/style-rtl.css b/src/wp-content/themes/twentytwentyone/style-rtl.css index 32d227633b05d..1e4ab84aa7da1 100644 --- a/src/wp-content/themes/twentytwentyone/style-rtl.css +++ b/src/wp-content/themes/twentytwentyone/style-rtl.css @@ -4661,7 +4661,7 @@ h1.page-title { } .primary-navigation-open .primary-navigation > .primary-menu-container { - position: absolute; + position: relative; visibility: visible; opacity: 1; transform: translateY(0); diff --git a/src/wp-content/themes/twentytwentyone/style.css b/src/wp-content/themes/twentytwentyone/style.css index 8500e2d240d95..83cbdf3db0891 100644 --- a/src/wp-content/themes/twentytwentyone/style.css +++ b/src/wp-content/themes/twentytwentyone/style.css @@ -4681,7 +4681,7 @@ h1.page-title { } .primary-navigation-open .primary-navigation > .primary-menu-container { - position: absolute; + position: relative; visibility: visible; opacity: 1; transform: translateY(0); From d510058b793eb2deedb41ce1a6ec631ccdd6d5d5 Mon Sep 17 00:00:00 2001 From: Tammie Lister Date: Tue, 2 Jul 2024 20:46:46 +0000 Subject: [PATCH 16/53] Twenty Nineteen: Fixes font size and citation display for Pullquote block. The pullquote block text decoration was not the same front and within the editor. This resolves that and resets. Props pitamdey, viralsampat, sabernhardt. Fixes #61507. git-svn-id: https://develop.svn.wordpress.org/trunk@58630 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-content/themes/twentynineteen/sass/blocks/_blocks.scss | 3 ++- src/wp-content/themes/twentynineteen/style-rtl.css | 3 ++- src/wp-content/themes/twentynineteen/style.css | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/wp-content/themes/twentynineteen/sass/blocks/_blocks.scss b/src/wp-content/themes/twentynineteen/sass/blocks/_blocks.scss index 65acd0f19ca1b..33788b7bf470d 100644 --- a/src/wp-content/themes/twentynineteen/sass/blocks/_blocks.scss +++ b/src/wp-content/themes/twentynineteen/sass/blocks/_blocks.scss @@ -370,6 +370,7 @@ border-color: transparent; border-width: 2px; padding: $size__spacing-unit; + font-size: 1em; blockquote { border: none; @@ -396,7 +397,7 @@ } cite { - display: inline-block; + display: block; @include font-family( $font__heading ); line-height: 1.6; text-transform: none; diff --git a/src/wp-content/themes/twentynineteen/style-rtl.css b/src/wp-content/themes/twentynineteen/style-rtl.css index 6f298863cc2aa..154fa40d289f6 100644 --- a/src/wp-content/themes/twentynineteen/style-rtl.css +++ b/src/wp-content/themes/twentynineteen/style-rtl.css @@ -5681,6 +5681,7 @@ body.page .main-navigation { border-color: transparent; border-width: 2px; padding: 1rem; + font-size: 1em; } .entry .entry-content .wp-block-pullquote blockquote { @@ -5710,7 +5711,7 @@ body.page .main-navigation { } .entry .entry-content .wp-block-pullquote cite { - display: inline-block; + display: block; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; line-height: 1.6; text-transform: none; diff --git a/src/wp-content/themes/twentynineteen/style.css b/src/wp-content/themes/twentynineteen/style.css index d388a2254aa73..83e66158d0bce 100644 --- a/src/wp-content/themes/twentynineteen/style.css +++ b/src/wp-content/themes/twentynineteen/style.css @@ -5693,6 +5693,7 @@ body.page .main-navigation { border-color: transparent; border-width: 2px; padding: 1rem; + font-size: 1em; } .entry .entry-content .wp-block-pullquote blockquote { @@ -5722,7 +5723,7 @@ body.page .main-navigation { } .entry .entry-content .wp-block-pullquote cite { - display: inline-block; + display: block; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; line-height: 1.6; text-transform: none; From ea3327ab6ee2cecc5ac1a006cf06927856383ab9 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Tue, 2 Jul 2024 21:45:18 +0000 Subject: [PATCH 17/53] HTML API: Add missing insertion mode constants. As the HTML Processor starts to support other insertion modes outside of "IN BODY" it needs to be aware of those other modes. This patch introduces the missing insertion modes in preparation for adding that support. Extracted as necessary prep work to the following more complete change: https://github.com/WordPress/wordpress-develop/pull/6020 Props jonsurrell. See #61549. git-svn-id: https://develop.svn.wordpress.org/trunk@58631 602fd350-edb4-49c9-b593-d223f7449a82 --- .../class-wp-html-processor-state.php | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-html-processor-state.php b/src/wp-includes/html-api/class-wp-html-processor-state.php index 9cf10c344107a..659a019f7e0da 100644 --- a/src/wp-includes/html-api/class-wp-html-processor-state.php +++ b/src/wp-includes/html-api/class-wp-html-processor-state.php @@ -59,6 +59,162 @@ class WP_HTML_Processor_State { */ const INSERTION_MODE_IN_BODY = 'insertion-mode-in-body'; + /** + * In select insertion mode for full HTML parser. + * + * @since 6.7.0 + * + * @see https://html.spec.whatwg.org/#parsing-main-inselect + * @see WP_HTML_Processor_State::$insertion_mode + * + * @var string + */ + const INSERTION_MODE_IN_SELECT = 'insertion-mode-in-select'; + + /** + * In select in table insertion mode for full HTML parser. + * + * @since 6.7.0 + * + * @see https://html.spec.whatwg.org/#parsing-main-inselectintable + * @see WP_HTML_Processor_State::$insertion_mode + * + * @var string + */ + const INSERTION_MODE_IN_SELECT_IN_TABLE = 'insertion-mode-in-select-in-table'; + + /** + * In table insertion mode for full HTML parser. + * + * @since 6.7.0 + * + * @see https://html.spec.whatwg.org/#parsing-main-intable + * @see WP_HTML_Processor_State::$insertion_mode + * + * @var string + */ + const INSERTION_MODE_IN_TABLE = 'insertion-mode-in-table'; + + /** + * In caption insertion mode for full HTML parser. + * + * @since 6.7.0 + * + * @see https://html.spec.whatwg.org/#parsing-main-incaption + * @see WP_HTML_Processor_State::$insertion_mode + * + * @var string + */ + const INSERTION_MODE_IN_CAPTION = 'insertion-mode-in-caption'; + + /** + * In table body insertion mode for full HTML parser. + * + * @since 6.7.0 + * + * @see https://html.spec.whatwg.org/#parsing-main-intablebody + * @see WP_HTML_Processor_State::$insertion_mode + * + * @var string + */ + const INSERTION_MODE_IN_TABLE_BODY = 'insertion-mode-in-table-body'; + + /** + * In row insertion mode for full HTML parser. + * + * @since 6.7.0 + * + * @see https://html.spec.whatwg.org/#parsing-main-inrow + * @see WP_HTML_Processor_State::$insertion_mode + * + * @var string + */ + const INSERTION_MODE_IN_ROW = 'insertion-mode-in-row'; + + /** + * In cell insertion mode for full HTML parser. + * + * @since 6.7.0 + * + * @see https://html.spec.whatwg.org/#parsing-main-incell + * @see WP_HTML_Processor_State::$insertion_mode + * + * @var string + */ + const INSERTION_MODE_IN_CELL = 'insertion-mode-in-cell'; + + /** + * In column group insertion mode for full HTML parser. + * + * @since 6.7.0 + * + * @see https://html.spec.whatwg.org/#parsing-main-incolumngroup + * @see WP_HTML_Processor_State::$insertion_mode + * + * @var string + */ + const INSERTION_MODE_IN_COLUMN_GROUP = 'insertion-mode-in-column-group'; + + /** + * In frameset insertion mode for full HTML parser. + * + * @since 6.7.0 + * + * @see https://html.spec.whatwg.org/#parsing-main-inframeset + * @see WP_HTML_Processor_State::$insertion_mode + * + * @var string + */ + const INSERTION_MODE_IN_FRAMESET = 'insertion-mode-in-frameset'; + + /** + * In head insertion mode for full HTML parser. + * + * @since 6.7.0 + * + * @see https://html.spec.whatwg.org/#parsing-main-inhead + * @see WP_HTML_Processor_State::$insertion_mode + * + * @var string + */ + const INSERTION_MODE_IN_HEAD = 'insertion-mode-in-head'; + + /** + * Before head insertion mode for full HTML parser. + * + * @since 6.7.0 + * + * @see https://html.spec.whatwg.org/#parsing-main-beforehead + * @see WP_HTML_Processor_State::$insertion_mode + * + * @var string + */ + const INSERTION_MODE_BEFORE_HEAD = 'insertion-mode-before-head'; + + /** + * After head insertion mode for full HTML parser. + * + * @since 6.7.0 + * + * @see https://html.spec.whatwg.org/#parsing-main-afterhead + * @see WP_HTML_Processor_State::$insertion_mode + * + * @var string + */ + const INSERTION_MODE_AFTER_HEAD = 'insertion-mode-after-head'; + + /** + * In template insertion mode for full HTML parser. + * + * @since 6.7.0 + * + * @see https://html.spec.whatwg.org/#parsing-main-intemplate + * @see WP_HTML_Processor_State::$insertion_mode + * + * @var string + */ + const INSERTION_MODE_IN_TEMPLATE = 'insertion-mode-in-template'; + /** * Tracks open elements while scanning HTML. * From 2930212ff6bf6619d026f525ceab2719c5229597 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Tue, 2 Jul 2024 23:23:23 +0000 Subject: [PATCH 18/53] Themes: add "description" key to i18n schema Add "description" key to the theme.json i18n schema. Follows r56041. Fixes #61543. Props ramonopoly, oandregal. git-svn-id: https://develop.svn.wordpress.org/trunk@58632 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/theme-i18n.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wp-includes/theme-i18n.json b/src/wp-includes/theme-i18n.json index 7ce52317ed65d..1781b9356f4bf 100644 --- a/src/wp-includes/theme-i18n.json +++ b/src/wp-includes/theme-i18n.json @@ -1,5 +1,6 @@ { "title": "Style variation name", + "description": "Style variation description", "settings": { "typography": { "fontSizes": [ From de74333c46f6f6f166d6ac90fc0a8267199060e3 Mon Sep 17 00:00:00 2001 From: Tammie Lister Date: Wed, 3 Jul 2024 10:27:33 +0000 Subject: [PATCH 19/53] Twenty Ten: Fixes table and calendar block font size issues. The table and calendar block font sizes were not the same on front and in editor. This resolves in using relative line-height. Props iamfarhan09, bijit027, sabernhardt. Fixes #58362. git-svn-id: https://develop.svn.wordpress.org/trunk@58633 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-content/themes/twentyten/blocks.css | 8 ++++++++ src/wp-content/themes/twentyten/editor-blocks.css | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/wp-content/themes/twentyten/blocks.css b/src/wp-content/themes/twentyten/blocks.css index fb53e7be63ec8..0bceba13bf871 100644 --- a/src/wp-content/themes/twentyten/blocks.css +++ b/src/wp-content/themes/twentyten/blocks.css @@ -156,6 +156,14 @@ p.has-drop-cap:not(:focus)::first-letter { background: #f2f7fc; } +#content .wp-block-table[style*="font-size"] *, +#content .wp-block-table[class*="-font-size"] *, +#content .wp-block-calendar[style*="font-size"] *, +#content .wp-block-calendar[class*="-font-size"] * { + font-size: inherit; + line-height: 1.5; +} + /*-------------------------------------------------------------- 4.0 Blocks - Layout Elements --------------------------------------------------------------*/ diff --git a/src/wp-content/themes/twentyten/editor-blocks.css b/src/wp-content/themes/twentyten/editor-blocks.css index 86b2f5f8756a1..bdf98220f8b22 100644 --- a/src/wp-content/themes/twentyten/editor-blocks.css +++ b/src/wp-content/themes/twentyten/editor-blocks.css @@ -294,6 +294,14 @@ p.has-drop-cap:not(:focus)::first-letter { padding-top: 0; } +.wp-block-table[style*="font-size"] *, +.wp-block-table[class*="-font-size"] *, +.wp-block-calendar[style*="font-size"] *, +.wp-block-calendar[class*="-font-size"] * { + font-size: inherit; + line-height: 1.5; +} + /*-------------------------------------------------------------- 5.0 Blocks - Widgets --------------------------------------------------------------*/ From a28522877e030c0cea267875843ec7ed29e7d41b Mon Sep 17 00:00:00 2001 From: Tammie Lister Date: Wed, 3 Jul 2024 10:45:35 +0000 Subject: [PATCH 20/53] Twenty Seventeen and Twenty Ten: Fixes gallery captions being at the bottom of images. The margin specified in this theme caused issues when the gallery was placed in another block. This fix covers both themes as the selector is used within both. Props pevogam, sabernhardt. Fixes #58362. git-svn-id: https://develop.svn.wordpress.org/trunk@58634 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-content/themes/twentyeleven/blocks.css | 8 ++++---- .../themes/twentyseventeen/assets/css/blocks.css | 4 ++-- src/wp-content/themes/twentyten/blocks.css | 2 +- src/wp-content/themes/twentyten/editor-blocks.css | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/wp-content/themes/twentyeleven/blocks.css b/src/wp-content/themes/twentyeleven/blocks.css index a4da8c83ee440..65f176c1bd259 100644 --- a/src/wp-content/themes/twentyeleven/blocks.css +++ b/src/wp-content/themes/twentyeleven/blocks.css @@ -30,7 +30,7 @@ figure[class^="wp-block-"] { font-size: 12px; } -[class^="wp-block-"]:not(.wp-block-gallery) figcaption { +[class^="wp-block-"]:not(.wp-block-gallery) > figcaption { color: #666; margin-bottom: 1.625em; max-width: 96%; @@ -40,7 +40,7 @@ figure[class^="wp-block-"] { text-align: left; } -[class^="wp-block-"]:not(.wp-block-gallery) figcaption:before { +[class^="wp-block-"]:not(.wp-block-gallery) > figcaption:before { color: #666; content: '\2014'; font-size: 14px; @@ -52,13 +52,13 @@ figure[class^="wp-block-"] { top: 0; } -.rtl [class^="wp-block-"]:not(.wp-block-gallery) figcaption { +.rtl [class^="wp-block-"]:not(.wp-block-gallery) > figcaption { padding-left: 0; padding-right: 40px; text-align: right; } -.rtl [class^="wp-block-"]:not(.wp-block-gallery) figcaption:before { +.rtl [class^="wp-block-"]:not(.wp-block-gallery) > figcaption:before { left: 0; margin-left: 5px; margin-right: 0; diff --git a/src/wp-content/themes/twentyseventeen/assets/css/blocks.css b/src/wp-content/themes/twentyseventeen/assets/css/blocks.css index b3b077f587641..65efb8378a16c 100644 --- a/src/wp-content/themes/twentyseventeen/assets/css/blocks.css +++ b/src/wp-content/themes/twentyseventeen/assets/css/blocks.css @@ -20,13 +20,13 @@ Description: Used to style blocks. /* Captions */ -[class^="wp-block-"]:not(.wp-block-gallery) figcaption { +[class^="wp-block-"]:not(.wp-block-gallery) > figcaption { font-style: italic; margin-bottom: 1.5em; text-align: left; } -.rtl [class^="wp-block-"]:not(.wp-block-gallery) figcaption { +.rtl [class^="wp-block-"]:not(.wp-block-gallery) > figcaption { text-align: right; } diff --git a/src/wp-content/themes/twentyten/blocks.css b/src/wp-content/themes/twentyten/blocks.css index 0bceba13bf871..b439e24eaf374 100644 --- a/src/wp-content/themes/twentyten/blocks.css +++ b/src/wp-content/themes/twentyten/blocks.css @@ -20,7 +20,7 @@ Description: Used to style blocks. /* Captions */ -[class^="wp-block-"]:not(.wp-block-gallery) figcaption { +[class^="wp-block-"]:not(.wp-block-gallery) > figcaption { color: #777; font-family: "Helvetica Neue", Arial, Helvetica, "Nimbus Sans L", sans-serif; } diff --git a/src/wp-content/themes/twentyten/editor-blocks.css b/src/wp-content/themes/twentyten/editor-blocks.css index bdf98220f8b22..d315ee240e264 100644 --- a/src/wp-content/themes/twentyten/editor-blocks.css +++ b/src/wp-content/themes/twentyten/editor-blocks.css @@ -149,7 +149,7 @@ Description: Used to style blocks in the editor. /* Caption styles */ -[class^="wp-block-"] figcaption { +[class^="wp-block-"]:not(.wp-block-gallery) > figcaption { color: #777; font-family: "Helvetica Neue", Arial, Helvetica, "Nimbus Sans L", sans-serif; } From 6d40ef3adf053ba0d8d81e13163686d037e2588f Mon Sep 17 00:00:00 2001 From: Tammie Lister Date: Wed, 3 Jul 2024 11:02:50 +0000 Subject: [PATCH 21/53] Twenty Sixteen: Fixes editor styles for table and calendar blocks and captions. The table and calendar block font sizes were not as expected on front end within editor. This includes changes for header cells (th), removes redundant font size rules, corrects font-weight and updates figcaption selector along with editing text alignment and adding RTL font selection. Props nidhidhandhukiya, sabernhardt, sheulyshila, iamfarhan09, bijit027, jannathsyeda, pooja1210, shailu25, hmbashar. Fixes #58355. git-svn-id: https://develop.svn.wordpress.org/trunk@58635 602fd350-edb4-49c9-b593-d223f7449a82 --- .../twentysixteen/css/editor-blocks.css | 12 +++++------ .../themes/twentysixteen/css/editor-style.css | 20 ++++++++++--------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/wp-content/themes/twentysixteen/css/editor-blocks.css b/src/wp-content/themes/twentysixteen/css/editor-blocks.css index 6fd2ddb01e530..6d2a23662d623 100644 --- a/src/wp-content/themes/twentysixteen/css/editor-blocks.css +++ b/src/wp-content/themes/twentysixteen/css/editor-blocks.css @@ -27,6 +27,10 @@ Description: Used to style blocks in the editor. line-height: 1.75; } +.rtl .editor-styles-wrapper { + font-family: Arial, Tahoma, sans-serif; +} + .edit-post-visual-editor .editor-block-list__block { color: #1a1a1a; } @@ -262,16 +266,12 @@ Description: Used to style blocks in the editor. /* Captions */ -[class^="wp-block-"] figcaption { +figure[class*="wp-block-"] > figcaption { color: #686868; font-style: italic; line-height: 1.6153846154; padding-top: 0.5384615385em; - text-align: left; -} - -.rtl [class^="wp-block-"] figcaption { - text-align: right; + text-align: start; } /*-------------------------------------------------------------- diff --git a/src/wp-content/themes/twentysixteen/css/editor-style.css b/src/wp-content/themes/twentysixteen/css/editor-style.css index ef1682efee4bc..6f7d7e92e3302 100644 --- a/src/wp-content/themes/twentysixteen/css/editor-style.css +++ b/src/wp-content/themes/twentysixteen/css/editor-style.css @@ -313,19 +313,22 @@ table th, .mce-item-table th, table caption { border-width: 0 1px 1px 0; - font-size: 16px; font-weight: 700; padding: 7px; - text-align: left; + text-align: start; vertical-align: baseline; } +table caption { + font-weight: normal; +} + table td, .mce-item-table td { border-width: 0 1px 1px 0; - font-size: 16px; padding: 7px; vertical-align: baseline; + text-align: start; } img { @@ -502,6 +505,11 @@ fieldset { * 8.0 - RTL */ +body.rtl, +[dir="rtl"] body { + font-family: Arial, Tahoma, sans-serif; +} + .rtl blockquote { border: 0 solid #1a1a1a; border-right-width: 4px; @@ -533,9 +541,3 @@ fieldset { margin-right: 24px; margin-left: auto; } - -.rtl table th, -.rtl .mce-item-table th, -.rtl table caption { - text-align: right; -} From 4454f4aa2c6dd18b0a68a01c766b56b4a4d63d01 Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Wed, 3 Jul 2024 15:51:48 +0000 Subject: [PATCH 22/53] Build/Test Tools: Rename current reusable PHPUnit workflow. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds a ` -v3` suffix to the current reusable PHPUnit workflow name. This avoids having to update older branches in the future when the workflow’s logic drastically changes and a `v4` is needed. See #61213. git-svn-id: https://develop.svn.wordpress.org/trunk@58645 602fd350-edb4-49c9-b593-d223f7449a82 --- .github/workflows/phpunit-tests.yml | 4 ++-- ...usable-phpunit-tests.yml => reusable-phpunit-tests-v3.yml} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename .github/workflows/{reusable-phpunit-tests.yml => reusable-phpunit-tests-v3.yml} (100%) diff --git a/.github/workflows/phpunit-tests.yml b/.github/workflows/phpunit-tests.yml index b40237f82802d..663b93bba48a9 100644 --- a/.github/workflows/phpunit-tests.yml +++ b/.github/workflows/phpunit-tests.yml @@ -36,7 +36,7 @@ jobs: # test-with-mysql: name: PHP ${{ matrix.php }} - uses: WordPress/wordpress-develop/.github/workflows/reusable-phpunit-tests.yml@trunk + uses: WordPress/wordpress-develop/.github/workflows/reusable-phpunit-tests-v3.yml@trunk permissions: contents: read secrets: inherit @@ -108,7 +108,7 @@ jobs: # test-with-mariadb: name: PHP ${{ matrix.php }} - uses: WordPress/wordpress-develop/.github/workflows/reusable-phpunit-tests.yml@trunk + uses: WordPress/wordpress-develop/.github/workflows/reusable-phpunit-tests-v3.yml@trunk permissions: contents: read secrets: inherit diff --git a/.github/workflows/reusable-phpunit-tests.yml b/.github/workflows/reusable-phpunit-tests-v3.yml similarity index 100% rename from .github/workflows/reusable-phpunit-tests.yml rename to .github/workflows/reusable-phpunit-tests-v3.yml From 5466b9c82674c30c885076fce8b99b4bfece8ab0 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Wed, 3 Jul 2024 16:08:55 +0000 Subject: [PATCH 23/53] Users: Pass the previous state of the user as context to the `wp_set_password` hook. Follow-up to [55056], [55250]. Props dd32. Fixes #61541. git-svn-id: https://develop.svn.wordpress.org/trunk@58653 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/pluggable.php | 10 +++++++--- tests/phpunit/tests/auth.php | 10 ++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/pluggable.php b/src/wp-includes/pluggable.php index 5ed63e539cf66..04a4ef8b55797 100644 --- a/src/wp-includes/pluggable.php +++ b/src/wp-includes/pluggable.php @@ -2768,6 +2768,8 @@ function wp_rand( $min = null, $max = null ) { function wp_set_password( $password, $user_id ) { global $wpdb; + $old_user_data = get_userdata( $user_id ); + $hash = wp_hash_password( $password ); $wpdb->update( $wpdb->users, @@ -2784,11 +2786,13 @@ function wp_set_password( $password, $user_id ) { * Fires after the user password is set. * * @since 6.2.0 + * @since 6.7.0 The `$old_user_data` parameter was added. * - * @param string $password The plaintext password just set. - * @param int $user_id The ID of the user whose password was just set. + * @param string $password The plaintext password just set. + * @param int $user_id The ID of the user whose password was just set. + * @param WP_User $old_user_data Object containing user's data prior to update. */ - do_action( 'wp_set_password', $password, $user_id ); + do_action( 'wp_set_password', $password, $user_id, $old_user_data ); } endif; diff --git a/tests/phpunit/tests/auth.php b/tests/phpunit/tests/auth.php index a28051dc09e2d..5c196b499fcce 100644 --- a/tests/phpunit/tests/auth.php +++ b/tests/phpunit/tests/auth.php @@ -115,16 +115,22 @@ public function test_password_trimming() { * Tests hooking into wp_set_password(). * * @ticket 57436 + * @ticket 61541 * * @covers ::wp_set_password */ public function test_wp_set_password_action() { $action = new MockAction(); - add_action( 'wp_set_password', array( $action, 'action' ) ); - wp_set_password( 'A simple password', self::$user_id ); + $previous_user_pass = get_user_by( 'id', $this->user->ID )->user_pass; + + add_action( 'wp_set_password', array( $action, 'action' ), 10, 3 ); + wp_set_password( 'A simple password', $this->user->ID ); $this->assertSame( 1, $action->get_call_count() ); + + // Check that the old data passed through the hook is correct. + $this->assertSame( $previous_user_pass, $action->get_args()[0][2]->user_pass ); } /** From e65f0f261fc2a7b09f8dd951b4a77aac05b4c274 Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Wed, 3 Jul 2024 16:28:48 +0000 Subject: [PATCH 24/53] Build/Test Tools: Fix workflow names in test old branches workflow. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the changes in [58165] and [58645] and all associated backports, the workflow that dispatches regular testing in older branches needed to be updated. - The `test-npm.yml` workflow no longer exists. - The `test-build-processes.yml` has taken the place of `test-npm.yml` in all branches. Also, the workflow will now run whenever an old version of the reusable PHPUnit workflow is updated (v1 or v2). This is to ensure the changes don’t cause any compatibility problems in older branches. See #61213. git-svn-id: https://develop.svn.wordpress.org/trunk@58654 602fd350-edb4-49c9-b593-d223f7449a82 --- .github/workflows/test-old-branches.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test-old-branches.yml b/.github/workflows/test-old-branches.yml index bf749673563bb..397f2c6ef350f 100644 --- a/.github/workflows/test-old-branches.yml +++ b/.github/workflows/test-old-branches.yml @@ -7,6 +7,8 @@ on: - trunk paths: - '.github/workflows/test-old-branches.yml' + - '.github/workflows/reusable-phpunit-tests-v1.yml' + - '.github/workflows/reusable-phpunit-tests-v2.yml' # Run twice a month on the 1st and 15th at 00:00 UTC. schedule: - cron: '0 0 1 * *' @@ -34,7 +36,7 @@ jobs: 'coding-standards.yml', 'javascript-tests.yml', 'phpunit-tests.yml', - 'test-npm.yml' + 'test-build-processes.yml' ] branch: [ '6.6', '6.5', '6.4', '6.3', '6.2', '6.1','6.0', @@ -102,10 +104,6 @@ jobs: - branch: '6.2' workflow: 'performance.yml' - # Build Process testing was introduced in 6.5. - - branch: '6.5' - workflow: 'test-build-processes.yml' - # Run all branches monthly, but only the currently supported one twice per month. steps: - name: Dispatch workflow run From 28930fc10907782bd560ba810b8c1f0fe4c74521 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Wed, 3 Jul 2024 17:05:46 +0000 Subject: [PATCH 25/53] HTML API: Implement the _reset insertion mode appropriately_ algorithm. In order to add support for the SELECT and TABLE tags in the HTML Processor, it needs to implement the HTML algorithm named "reset the insertion mode appropriately". This patch implements that algorithm to unblock the additional tag support. The algorithm resets the parsing mode after specific state changes in complicated situations where alternative rules are in effect (such as rules governing how the parser handles tags found within a TABLE element). Developed in https://github.com/WordPress/wordpress-develop/pull/6020 Discussed in https://core.trac.wordpress.org/ticket/61549 Props dmsnell, jonsurrell. Fixes #61549. git-svn-id: https://develop.svn.wordpress.org/trunk@58656 602fd350-edb4-49c9-b593-d223f7449a82 --- .../class-wp-html-processor-state.php | 22 +++ .../html-api/class-wp-html-processor.php | 183 ++++++++++++++++++ 2 files changed, 205 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-html-processor-state.php b/src/wp-includes/html-api/class-wp-html-processor-state.php index 659a019f7e0da..f6e3721665402 100644 --- a/src/wp-includes/html-api/class-wp-html-processor-state.php +++ b/src/wp-includes/html-api/class-wp-html-processor-state.php @@ -215,6 +215,17 @@ class WP_HTML_Processor_State { */ const INSERTION_MODE_IN_TEMPLATE = 'insertion-mode-in-template'; + /** + * The stack of template insertion modes. + * + * @since 6.7.0 + * + * @see https://html.spec.whatwg.org/#the-insertion-mode:stack-of-template-insertion-modes + * + * @var array + */ + public $stack_of_template_insertion_modes = array(); + /** * Tracks open elements while scanning HTML. * @@ -272,6 +283,17 @@ class WP_HTML_Processor_State { */ public $context_node = null; + /** + * HEAD element pointer. + * + * @since 6.7.0 + * + * @see https://html.spec.whatwg.org/multipage/parsing.html#head-element-pointer + * + * @var WP_HTML_Token|null + */ + public $head_element = null; + /** * The frameset-ok flag indicates if a `FRAMESET` element is allowed in the current state. * diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 29f1c7ac6d4cc..32800218f6404 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -2129,6 +2129,189 @@ private function reconstruct_active_formatting_elements() { throw new WP_HTML_Unsupported_Exception( 'Cannot reconstruct active formatting elements when advancing and rewinding is required.' ); } + /** + * Runs the reset the insertion mode appropriately algorithm. + * + * @since 6.7.0 + * + * @see https://html.spec.whatwg.org/multipage/parsing.html#reset-the-insertion-mode-appropriately + */ + public function reset_insertion_mode(): void { + // Set the first node. + $first_node = null; + foreach ( $this->state->stack_of_open_elements->walk_down() as $first_node ) { + break; + } + + /* + * > 1. Let _last_ be false. + */ + $last = false; + foreach ( $this->state->stack_of_open_elements->walk_up() as $node ) { + /* + * > 2. Let _node_ be the last node in the stack of open elements. + * > 3. _Loop_: If _node_ is the first node in the stack of open elements, then set _last_ + * > to true, and, if the parser was created as part of the HTML fragment parsing + * > algorithm (fragment case), set node to the context element passed to + * > that algorithm. + * > … + */ + if ( $node === $first_node ) { + $last = true; + if ( isset( $this->context_node ) ) { + $node = $this->context_node; + } + } + + switch ( $node->node_name ) { + /* + * > 4. If node is a `select` element, run these substeps: + * > 1. If _last_ is true, jump to the step below labeled done. + * > 2. Let _ancestor_ be _node_. + * > 3. _Loop_: If _ancestor_ is the first node in the stack of open elements, + * > jump to the step below labeled done. + * > 4. Let ancestor be the node before ancestor in the stack of open elements. + * > … + * > 7. Jump back to the step labeled _loop_. + * > 8. _Done_: Switch the insertion mode to "in select" and return. + */ + case 'SELECT': + if ( ! $last ) { + foreach ( $this->state->stack_of_open_elements->walk_up( $node ) as $ancestor ) { + switch ( $ancestor->node_name ) { + /* + * > 5. If _ancestor_ is a `template` node, jump to the step below + * > labeled _done_. + */ + case 'TEMPLATE': + break 2; + + /* + * > 6. If _ancestor_ is a `table` node, switch the insertion mode to + * > "in select in table" and return. + */ + case 'TABLE': + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT_IN_TABLE; + return; + } + } + } + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT; + return; + + /* + * > 5. If _node_ is a `td` or `th` element and _last_ is false, then switch the + * > insertion mode to "in cell" and return. + */ + case 'TD': + case 'TH': + if ( ! $last ) { + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_CELL; + return; + } + break; + + /* + * > 6. If _node_ is a `tr` element, then switch the insertion mode to "in row" + * > and return. + */ + case 'TR': + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; + return; + + /* + * > 7. If _node_ is a `tbody`, `thead`, or `tfoot` element, then switch the + * > insertion mode to "in table body" and return. + */ + case 'TBODY': + case 'THEAD': + case 'TFOOT': + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; + return; + + /* + * > 8. If _node_ is a `caption` element, then switch the insertion mode to + * > "in caption" and return. + */ + case 'CAPTION': + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION; + return; + + /* + * > 9. If _node_ is a `colgroup` element, then switch the insertion mode to + * > "in column group" and return. + */ + case 'COLGROUP': + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP; + return; + + /* + * > 10. If _node_ is a `table` element, then switch the insertion mode to + * > "in table" and return. + */ + case 'TABLE': + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; + return; + + /* + * > 11. If _node_ is a `template` element, then switch the insertion mode to the + * > current template insertion mode and return. + */ + case 'TEMPLATE': + $this->state->insertion_mode = end( $this->state->stack_of_template_insertion_modes ); + return; + + /* + * > 12. If _node_ is a `head` element and _last_ is false, then switch the + * > insertion mode to "in head" and return. + */ + case 'HEAD': + if ( ! $last ) { + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD; + return; + } + break; + + /* + * > 13. If _node_ is a `body` element, then switch the insertion mode to "in body" + * > and return. + */ + case 'BODY': + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; + return; + + /* + * > 14. If _node_ is a `frameset` element, then switch the insertion mode to + * > "in frameset" and return. (fragment case) + */ + case 'FRAMESET': + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_FRAMESET; + return; + + /* + * > 15. If _node_ is an `html` element, run these substeps: + * > 1. If the head element pointer is null, switch the insertion mode to + * > "before head" and return. (fragment case) + * > 2. Otherwise, the head element pointer is not null, switch the insertion + * > mode to "after head" and return. + */ + case 'HTML': + $this->state->insertion_mode = isset( $this->state->head_element ) + ? WP_HTML_Processor_State::INSERTION_MODE_AFTER_HEAD + : WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HEAD; + return; + } + } + + /* + * > 16. If _last_ is true, then switch the insertion mode to "in body" + * > and return. (fragment case) + * + * This is only reachable if `$last` is true, as per the fragment parsing case. + */ + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY; + } + /** * Runs the adoption agency algorithm. * From 80b7747ef165dd5ed0150003a8c2f957f097609e Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Thu, 4 Jul 2024 04:18:52 +0000 Subject: [PATCH 26/53] Help/About: Update performance improvements string. Updates the performance improvements string with the finalized percentage improvement in the editor and to improve styling and language consistency. Props ryelle, annezazu, peterwilsoncc. Fixes #61320. git-svn-id: https://develop.svn.wordpress.org/trunk@58671 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/about.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wp-admin/about.php b/src/wp-admin/about.php index a794ab9ec6668..ad87ec8f678f8 100644 --- a/src/wp-admin/about.php +++ b/src/wp-admin/about.php @@ -124,8 +124,9 @@

WP_Theme_JSON', 'data-wp-on-async' ); ?> From 922949fb97334ec0bff551afb0bd8116ff8ade7c Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Thu, 4 Jul 2024 11:20:33 +0000 Subject: [PATCH 27/53] Docs: Update AJAX in Plugins HelpHub link to avoid unnecessary redirection. Follow-up to [17045], [20713], [41065], [45674], [55412], [57854], [58131], [58132]. Props shailu25. See #60732, #60699. git-svn-id: https://develop.svn.wordpress.org/trunk@58672 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/admin-ajax.php | 2 +- src/wp-settings.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-admin/admin-ajax.php b/src/wp-admin/admin-ajax.php index b6645fd5ca0e8..3ad60f95766e3 100644 --- a/src/wp-admin/admin-ajax.php +++ b/src/wp-admin/admin-ajax.php @@ -5,7 +5,7 @@ * @package WordPress * @subpackage Administration * - * @link https://codex.wordpress.org/AJAX_in_Plugins + * @link https://developer.wordpress.org/plugins/javascript/ajax */ /** diff --git a/src/wp-settings.php b/src/wp-settings.php index a682c2a50380a..369493f3fcec0 100644 --- a/src/wp-settings.php +++ b/src/wp-settings.php @@ -715,7 +715,7 @@ * Ajax requests should use wp-admin/admin-ajax.php. admin-ajax.php can handle requests for * users not logged in. * - * @link https://codex.wordpress.org/AJAX_in_Plugins + * @link https://developer.wordpress.org/plugins/javascript/ajax * * @since 3.0.0 */ From b867b58f3761b9f363d382362dd1634b7301ef4e Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 19 Jan 2024 19:18:18 +0100 Subject: [PATCH 28/53] Implement SELECT and related tags handling --- .../html-api/class-wp-html-open-elements.php | 23 ++- .../html-api/class-wp-html-processor.php | 164 +++++++++++++++++- 2 files changed, 179 insertions(+), 8 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-open-elements.php b/src/wp-includes/html-api/class-wp-html-open-elements.php index 15479801dda10..c304ba57a0cca 100644 --- a/src/wp-includes/html-api/class-wp-html-open-elements.php +++ b/src/wp-includes/html-api/class-wp-html-open-elements.php @@ -269,19 +269,34 @@ public function has_element_in_table_scope( $tag_name ) { /** * Returns whether a particular element is in select scope. * - * @since 6.4.0 + * @since 6.4.0 - Stub, always throws. + * @since 6.5.0 - Implemented. * * @see https://html.spec.whatwg.org/#has-an-element-in-select-scope * - * @throws WP_HTML_Unsupported_Exception Always until this function is implemented. + * > The stack of open elements is said to have a particular element in select scope when it has + * > that element in the specific scope consisting of all element types except the following: + * > - optgroup in the HTML namespace + * > - option in the HTML namespace * * @param string $tag_name Name of tag to check. * @return bool Whether given element is in scope. */ public function has_element_in_select_scope( $tag_name ) { - throw new WP_HTML_Unsupported_Exception( 'Cannot process elements depending on select scope.' ); + foreach ( $this->walk_up() as $node ) { + if ( $node->node_name === $tag_name ) { + return true; + } - return false; // The linter requires this unreachable code until the function is implemented and can return. + if ( + 'OPTION' !== $node->node_name && + 'OPTGROUP' !== $node->node_name + ) { + return false; + } + } + + return false; } /** diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 32800218f6404..cc371519f775b 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -101,7 +101,7 @@ * * - Containers: ADDRESS, BLOCKQUOTE, DETAILS, DIALOG, DIV, FOOTER, HEADER, MAIN, MENU, SPAN, SUMMARY. * - Custom elements: All custom elements are supported. :) - * - Form elements: BUTTON, DATALIST, FIELDSET, INPUT, LABEL, LEGEND, METER, PROGRESS, SEARCH. + * - Form elements: BUTTON, DATALIST, FIELDSET, INPUT, LABEL, LEGEND, METER, OPTGROUP, OPTION, PROGRESS, SEARCH, SELECT. * - Formatting elements: B, BIG, CODE, EM, FONT, I, PRE, SMALL, STRIKE, STRONG, TT, U, WBR. * - Heading elements: H1, H2, H3, H4, H5, H6, HGROUP. * - Links: A. @@ -757,6 +757,9 @@ public function step( $node_to_process = self::PROCESS_NEXT_NODE ) { case WP_HTML_Processor_State::INSERTION_MODE_IN_BODY: return $this->step_in_body(); + case WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT: + return $this->step_in_select(); + default: $this->last_error = self::ERROR_UNSUPPORTED; throw new WP_HTML_Unsupported_Exception( "No support for parsing in the '{$this->state->insertion_mode}' state." ); @@ -1336,6 +1339,50 @@ private function step_in_body() { case '+TRACK': $this->insert_html_element( $this->state->current_token ); return true; + + /* + * > A start tag whose tag name is "select" + */ + case '+SELECT': + $this->reconstruct_active_formatting_elements(); + $this->insert_html_element( $this->state->current_token ); + $this->state->frameset_ok = false; + + // If the insertion mode is one of + // - "in table" + // - "in caption" + // - "in table body" + // - "in row" + // - "in cell" + // then switch the insertion mode to "in select in table" + // + // Otherwise, switch the insertion mode to "in select". + switch ( $this->state->insertion_mode ) { + case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE: + case WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION: + case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY: + case WP_HTML_Processor_State::INSERTION_MODE_IN_ROW: + case WP_HTML_Processor_State::INSERTION_MODE_IN_CELL: + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT_IN_TABLE; + break; + default: + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT; + break; + } + return true; + + /* + * > A start tag whose tag name is one of: "optgroup", "option" + */ + case '+OPTGROUP': + case '+OPTION': + $current_node = $this->state->stack_of_open_elements->current_node(); + if ( $current_node && 'OPTION' === $current_node->node_name ) { + $this->state->stack_of_open_elements->pop(); + } + $this->reconstruct_active_formatting_elements(); + $this->insert_html_element( $this->state->current_token ); + return true; } /* @@ -1378,8 +1425,6 @@ private function step_in_body() { case 'NOFRAMES': case 'NOSCRIPT': case 'OBJECT': - case 'OPTGROUP': - case 'OPTION': case 'PLAINTEXT': case 'RB': case 'RP': @@ -1387,7 +1432,6 @@ private function step_in_body() { case 'RTC': case 'SARCASM': case 'SCRIPT': - case 'SELECT': case 'STYLE': case 'SVG': case 'TABLE': @@ -1448,6 +1492,118 @@ private function step_in_body() { } } + /** + * Parses next element in the 'in select' insertion mode. + * + * This internal function performs the 'in select' insertion mode + * logic for the generalized WP_HTML_Processor::step() function. + * + * @since 6.5.0 + * + * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. + * + * @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inselect + * @see WP_HTML_Processor::step + * + * @return bool Whether an element was found. + */ + private function step_in_select() { + $tag_name = $this->get_tag(); + $op_sigil = $this->is_tag_closer() ? '-' : '+'; + $op = "{$op_sigil}{$tag_name}"; + + switch ( $op ) { + /* + * > A start tag whose tag name is "html" + */ + case '+HTML': + $this->last_error = self::ERROR_UNSUPPORTED; + throw new WP_HTML_Unsupported_Exception( "Cannot process {$tag_name} element." ); + + /* + * > A start tag whose tag name is "option" + */ + case '+OPTION': + $current_node = $this->state->stack_of_open_elements->current_node(); + if ( $current_node && 'OPTION' === $current_node->node_name ) { + $this->state->stack_of_open_elements->pop(); + } + $this->insert_html_element( $this->state->current_token ); + return true; + + /* + * > A start tag whose tag name is "optgroup" + * > A start tag whose tag name is "hr" + */ + case '+OPTGROUP': + case '+HR': + $current_node = $this->state->stack_of_open_elements->current_node(); + if ( $current_node && 'OPTION' === $current_node->node_name ) { + $this->state->stack_of_open_elements->pop(); + // If we've popped, update the current_node + $current_node = $this->state->stack_of_open_elements->current_node(); + } + + if ( $current_node && 'OPTGROUP' === $current_node->node_name ) { + $this->state->stack_of_open_elements->pop(); + } + + $this->insert_html_element( $this->state->current_token ); + return true; + + /* + * > An end tag whose tag name is "optgroup" + */ + case '-OPTGROUP': + $walker = $this->state->stack_of_open_elements->walk_up(); + $current_node = $walker->current(); + if ( ! $current_node ) { + return $this->step(); + } + if ( 'OPTGROUP' === $current_node->node_name ) { + $this->state->stack_of_open_elements->pop(); + return true; + } + + $walker->next(); + $current_node_parent = $walker->current(); + if ( 'OPTION' === $current_node->node_name && 'OPTGROUP' === $current_node_parent->node_name ) { + $this->state->stack_of_open_elements->pop(); + $this->state->stack_of_open_elements->pop(); + return true; + } + return $this->step(); + + /* + * > An end tag whose tag name is "option" + */ + case '-OPTION': + $current_node = $this->state->stack_of_open_elements->current_node(); + if ( $current_node && 'OPTION' === $current_node->node_name ) { + $this->state->stack_of_open_elements->pop(); + return true; + } + return $this->step(); + + /* + * > An end tag whose tag name is "select" + * > A start tag whose tag name is "select" + */ + case '-SELECT': + case '+SELECT': + if ( ! $this->state->stack_of_open_elements->has_element_in_select_scope( 'SELECT' ) ) { + return $this->step(); + } + $this->state->stack_of_open_elements->pop_until( 'SELECT' ); + $this->state->stack_of_open_elements->pop(); + $this->reset_insertion_mode(); + return true; + } + + $this->last_error = self::ERROR_UNSUPPORTED; + throw new WP_HTML_Unsupported_Exception( "Cannot process {$tag_name} element." ); + } + /* * Internal helpers */ From 9245930e6d8697a7de47ef1bbb1b75a402e66dbf Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 3 Jul 2024 20:54:44 +0200 Subject: [PATCH 29/53] Remove SELECT from unsupported elements test --- tests/phpunit/tests/html-api/wpHtmlProcessorBreadcrumbs.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessorBreadcrumbs.php b/tests/phpunit/tests/html-api/wpHtmlProcessorBreadcrumbs.php index 01dcd9c32d7fb..403f40a1da032 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessorBreadcrumbs.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessorBreadcrumbs.php @@ -189,15 +189,12 @@ public static function data_unsupported_elements() { 'NOFRAMES', // Neutralized. 'NOSCRIPT', 'OBJECT', - 'OPTGROUP', - 'OPTION', 'PLAINTEXT', // Neutralized. 'RB', // Neutralized. 'RP', 'RT', 'RTC', // Neutralized. 'SCRIPT', - 'SELECT', 'STYLE', 'SVG', 'TABLE', From 267a27be1007181eceb06b95aa68de5e7109df18 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 3 Jul 2024 20:57:11 +0200 Subject: [PATCH 30/53] Remove SELECT scope optgroup/option tests --- .../tests/html-api/wpHtmlSupportRequiredOpenElements.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpHtmlSupportRequiredOpenElements.php b/tests/phpunit/tests/html-api/wpHtmlSupportRequiredOpenElements.php index c2e8c697e8156..48255190ad50c 100644 --- a/tests/phpunit/tests/html-api/wpHtmlSupportRequiredOpenElements.php +++ b/tests/phpunit/tests/html-api/wpHtmlSupportRequiredOpenElements.php @@ -308,9 +308,5 @@ public function test_has_element_in_select_scope_needs_support() { * FOREIGNOBJECT, DESC, TITLE. */ $this->ensure_support_is_added_everywhere( 'SVG' ); - - // These elements are specific to SELECT scope. - $this->ensure_support_is_added_everywhere( 'OPTGROUP' ); - $this->ensure_support_is_added_everywhere( 'OPTION' ); } } From b0475fb11c4c02b9484411764991de1a119c6ead Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 3 Jul 2024 20:57:57 +0200 Subject: [PATCH 31/53] Remove SELECT, OPTION, OPTGROUP from unsupported tags --- tests/phpunit/tests/html-api/wpHtmlProcessor.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor.php b/tests/phpunit/tests/html-api/wpHtmlProcessor.php index 536f6fdf4dd8f..b842703a7a135 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor.php @@ -406,8 +406,6 @@ public static function data_unsupported_special_in_body_tags() { 'NOFRAMES' => array( 'NOFRAMES' ), 'NOSCRIPT' => array( 'NOSCRIPT' ), 'OBJECT' => array( 'OBJECT' ), - 'OPTGROUP' => array( 'OPTGROUP' ), - 'OPTION' => array( 'OPTION' ), 'PLAINTEXT' => array( 'PLAINTEXT' ), 'RB' => array( 'RB' ), 'RP' => array( 'RP' ), @@ -415,7 +413,6 @@ public static function data_unsupported_special_in_body_tags() { 'RTC' => array( 'RTC' ), 'SARCASM' => array( 'SARCASM' ), 'SCRIPT' => array( 'SCRIPT' ), - 'SELECT' => array( 'SELECT' ), 'STYLE' => array( 'STYLE' ), 'SVG' => array( 'SVG' ), 'TABLE' => array( 'TABLE' ), From 1944b6646c5945e75c787284637bbffcd1353cf6 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 3 Jul 2024 20:58:54 +0200 Subject: [PATCH 32/53] Remove OPTION,OPTGROUP from gen implied end tags unsupported test --- .../tests/html-api/wpHtmlSupportRequiredHtmlProcessor.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpHtmlSupportRequiredHtmlProcessor.php b/tests/phpunit/tests/html-api/wpHtmlSupportRequiredHtmlProcessor.php index 2d3cd21ce461b..07943cd62a2f4 100644 --- a/tests/phpunit/tests/html-api/wpHtmlSupportRequiredHtmlProcessor.php +++ b/tests/phpunit/tests/html-api/wpHtmlSupportRequiredHtmlProcessor.php @@ -58,8 +58,6 @@ private function ensure_support_is_added_everywhere( $tag_name ) { * @covers WP_HTML_Processor::generate_implied_end_tags */ public function test_generate_implied_end_tags_needs_support() { - $this->ensure_support_is_added_everywhere( 'OPTGROUP' ); - $this->ensure_support_is_added_everywhere( 'OPTION' ); $this->ensure_support_is_added_everywhere( 'RB' ); $this->ensure_support_is_added_everywhere( 'RP' ); $this->ensure_support_is_added_everywhere( 'RT' ); @@ -79,8 +77,6 @@ public function test_generate_implied_end_tags_needs_support() { public function test_generate_implied_end_tags_thoroughly_needs_support() { $this->ensure_support_is_added_everywhere( 'CAPTION' ); $this->ensure_support_is_added_everywhere( 'COLGROUP' ); - $this->ensure_support_is_added_everywhere( 'OPTGROUP' ); - $this->ensure_support_is_added_everywhere( 'OPTION' ); $this->ensure_support_is_added_everywhere( 'RB' ); $this->ensure_support_is_added_everywhere( 'RP' ); $this->ensure_support_is_added_everywhere( 'RT' ); From 8d4b4dfd5ef7a550b5d4cfbd2bd3a947a239d899 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 4 Jul 2024 13:28:22 +0200 Subject: [PATCH 33/53] Add OPTION, OPTGROUP to implied end tags --- src/wp-includes/html-api/class-wp-html-processor.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index cc371519f775b..509cfb5b164d6 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -2192,6 +2192,7 @@ private function close_a_p_element() { * Closes elements that have implied end tags. * * @since 6.4.0 + * @since 6.7.0 Support "option" and "optgroup". * * @see https://html.spec.whatwg.org/#generate-implied-end-tags * @@ -2202,6 +2203,8 @@ private function generate_implied_end_tags( $except_for_this_element = null ) { 'DD', 'DT', 'LI', + 'OPTGROUP', + 'OPTION', 'P', ); @@ -2230,6 +2233,8 @@ private function generate_implied_end_tags_thoroughly() { 'DD', 'DT', 'LI', + 'OPTGROUP', + 'OPTION', 'P', ); From 140411904e9da10d44878a0f595111111eb828fd Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 4 Jul 2024 13:44:42 +0200 Subject: [PATCH 34/53] Update step_in_select since tag --- src/wp-includes/html-api/class-wp-html-processor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 509cfb5b164d6..eb1d092f698e5 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -1498,7 +1498,7 @@ private function step_in_body() { * This internal function performs the 'in select' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * - * @since 6.5.0 + * @since 6.7.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * From dc0bbb90d8205c24d84287d8292078cf55505457 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 4 Jul 2024 16:04:09 +0200 Subject: [PATCH 35/53] Update since tags on in_select_scope --- src/wp-includes/html-api/class-wp-html-open-elements.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-open-elements.php b/src/wp-includes/html-api/class-wp-html-open-elements.php index c304ba57a0cca..117bfb4a04eac 100644 --- a/src/wp-includes/html-api/class-wp-html-open-elements.php +++ b/src/wp-includes/html-api/class-wp-html-open-elements.php @@ -269,8 +269,8 @@ public function has_element_in_table_scope( $tag_name ) { /** * Returns whether a particular element is in select scope. * - * @since 6.4.0 - Stub, always throws. - * @since 6.5.0 - Implemented. + * @since 6.4.0 Stub implementation (throws). + * @since 6.7.0 Full implementation. * * @see https://html.spec.whatwg.org/#has-an-element-in-select-scope * From 9d9984463dac791c28fab4434c6e26a24d9d4b43 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 4 Jul 2024 16:14:32 +0200 Subject: [PATCH 36/53] =?UTF-8?q?Implement=20in=5Fselect=5Fscope=20via=20?= =?UTF-8?q?=E2=80=A6in=5Fspecific=5Fscope?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../html-api/class-wp-html-open-elements.php | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-open-elements.php b/src/wp-includes/html-api/class-wp-html-open-elements.php index 117bfb4a04eac..0fd8ae43b0c42 100644 --- a/src/wp-includes/html-api/class-wp-html-open-elements.php +++ b/src/wp-includes/html-api/class-wp-html-open-elements.php @@ -156,11 +156,15 @@ public function current_node() { * * @see https://html.spec.whatwg.org/#has-an-element-in-the-specific-scope * - * @param string $tag_name Name of tag check. - * @param string[] $termination_list List of elements that terminate the search. + * @param string $tag_name Name of tag check. + * @param string[] $termination_list List of elements that terminate the search. + * @param string $termination_behavior Optional. "include" or "exclude". If "include" + * (default), the terminate when any tag in + * `$termination_list` is reached. Otherwise, + * terminate when any _other_ tag is reached. * @return bool Whether the element was found in a specific scope. */ - public function has_element_in_specific_scope( $tag_name, $termination_list ) { + public function has_element_in_specific_scope( $tag_name, $termination_list, $termination_behavior = 'include' ) { foreach ( $this->walk_up() as $node ) { if ( $node->node_name === $tag_name ) { return true; @@ -178,7 +182,10 @@ public function has_element_in_specific_scope( $tag_name, $termination_list ) { return false; } - if ( in_array( $node->node_name, $termination_list, true ) ) { + $terminate = 'include' === $termination_behavior + ? in_array( $node->node_name, $termination_list, true ) + : ! in_array( $node->node_name, $termination_list, true ); + if ( $terminate ) { return false; } } @@ -283,20 +290,11 @@ public function has_element_in_table_scope( $tag_name ) { * @return bool Whether given element is in scope. */ public function has_element_in_select_scope( $tag_name ) { - foreach ( $this->walk_up() as $node ) { - if ( $node->node_name === $tag_name ) { - return true; - } - - if ( - 'OPTION' !== $node->node_name && - 'OPTGROUP' !== $node->node_name - ) { - return false; - } - } - - return false; + return $this->has_element_in_specific_scope( + $tag_name, + array( 'OPTION', 'OPTGROUP' ), + 'exclude' + ); } /** From ceae9d4fa7d29f063db2ccb2ae13ec1eb1330816 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 2 Feb 2024 17:00:08 +0100 Subject: [PATCH 37/53] Work on table support --- ...ass-wp-html-active-formatting-elements.php | 4 + .../html-api/class-wp-html-processor.php | 245 +++++++++++++++++- 2 files changed, 237 insertions(+), 12 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-active-formatting-elements.php b/src/wp-includes/html-api/class-wp-html-active-formatting-elements.php index 9f7fee9076243..0f71d9d70fc0e 100644 --- a/src/wp-includes/html-api/class-wp-html-active-formatting-elements.php +++ b/src/wp-includes/html-api/class-wp-html-active-formatting-elements.php @@ -184,4 +184,8 @@ public function walk_up() { yield $this->stack[ $i ]; } } + + public function set_marker() { + $this->push( new WP_HTML_Token( null, 'marker', false ) ); + } } diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index eb1d092f698e5..e96f1043f12f0 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -760,6 +760,9 @@ public function step( $node_to_process = self::PROCESS_NEXT_NODE ) { case WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT: return $this->step_in_select(); + case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE: + return $this->step_in_table(); + default: $this->last_error = self::ERROR_UNSUPPORTED; throw new WP_HTML_Unsupported_Exception( "No support for parsing in the '{$this->state->insertion_mode}' state." ); @@ -1279,6 +1282,17 @@ private function step_in_body() { $this->run_adoption_agency_algorithm(); return true; + /* + * > A start tag whose tag name is "table" + */ + case '+TABLE': + if ( $this->state->stack_of_open_elements->has_p_in_button_scope() ) { + $this->close_a_p_element(); + } + $this->insert_html_element( $this->state->current_token ); + $this->state->frameset_ok = false; + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; + /* * > An end tag whose tag name is "br" * > Parse error. Drop the attributes from the token, and act as described in the next @@ -1383,6 +1397,22 @@ private function step_in_body() { $this->reconstruct_active_formatting_elements(); $this->insert_html_element( $this->state->current_token ); return true; + + /* + * > A start tag whose tag name is one of: "caption", "col", "colgroup", "frame", "head", "tbody", "td", "tfoot", "th", "thead", "tr" + */ + case 'CAPTION': + case 'COL': + case 'COLGROUP': + case 'FRAME': + case 'HEAD': + case 'TBODY': + case 'TD': + case 'TFOOT': + case 'TH': + case 'THEAD': + case 'TR': + return $this->step(); } /* @@ -1407,13 +1437,8 @@ private function step_in_body() { case 'BASEFONT': case 'BGSOUND': case 'BODY': - case 'CAPTION': - case 'COL': - case 'COLGROUP': case 'FORM': - case 'FRAME': case 'FRAMESET': - case 'HEAD': case 'HTML': case 'IFRAME': case 'LINK': @@ -1434,16 +1459,9 @@ private function step_in_body() { case 'SCRIPT': case 'STYLE': case 'SVG': - case 'TABLE': - case 'TBODY': - case 'TD': case 'TEMPLATE': case 'TEXTAREA': - case 'TFOOT': - case 'TH': - case 'THEAD': case 'TITLE': - case 'TR': case 'XMP': $this->last_error = self::ERROR_UNSUPPORTED; throw new WP_HTML_Unsupported_Exception( "Cannot process {$token_name} element." ); @@ -1604,6 +1622,186 @@ private function step_in_select() { throw new WP_HTML_Unsupported_Exception( "Cannot process {$tag_name} element." ); } + /** + * Parses next element in the 'in table' insertion mode. + * + * This internal function performs the 'in table' insertion mode + * logic for the generalized WP_HTML_Processor::step() function. + * + * @since 6.5.0 + * + * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. + * + * @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-intable + * @see WP_HTML_Processor::step + * + * @return bool Whether an element was found. + */ + private function step_in_table() { + $tag_name = $this->get_tag(); + $op_sigil = $this->is_tag_closer() ? '-' : '+'; + $op = "{$op_sigil}{$tag_name}"; + + switch ( $op ) { + /* + * > A character token, if the current node is table, tbody, template, tfoot, thead, or tr element + */ + /* + * > A comment token + */ + /* + * > A DOCTYPE token + */ + /* + * > A start tag whose tag name is "caption" + */ + case "+CAPTION": + $this->clear_stack_to_table_context(); + $this->state->active_formatting_elements->set_marker(); + $this->insert_html_element( $this->state->current_token ); + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION; + return true; + + /* + * > A start tag whose tag name is "colgroup" + */ + case "+COLGROUP": + $this->clear_stack_to_table_context(); + $this->insert_html_element( $this->state->current_token ); + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP; + return true; + + /* + * > A start tag whose tag name is "col" + */ + case "+COL": + $this->clear_stack_to_table_context(); + $this->insert_html_element( + new WP_HTML_Token( null, 'COLGROUP', false ) + ); + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP; + return $this->step( self::REPROCESS_CURRENT_NODE ); + + /* + * > A start tag whose tag name is one of: "tbody", "tfoot", "thead" + */ + case "+TBODY": + case "+TFOOT": + case "+THEAD": + $this->clear_stack_to_table_context(); + $this->insert_html_element( $this->state->current_token ); + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; + return true; + + /* + * > A start tag whose tag name is one of: "td", "th", "tr" + */ + case "+TD": + case "+TH": + case "+TR": + $this->clear_stack_to_table_context(); + $this->insert_html_element( + new WP_HTML_Token( null, 'TBODY', false ) + ); + return $this->step( self::REPROCESS_CURRENT_NODE ); + + /* + * > A start tag whose tag name is "table" + */ + case "+TABLE": + // pase error + if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TABLE' ) ) { + return $this->step(); + } + $this->state->stack_of_open_elements->pop_until( 'TABLE' ); + $this->reset_insertion_mode(); + return $this->step( self::REPROCESS_CURRENT_NODE ); + + /* + * > An end tag whose tag name is "table" + */ + case "-TABLE": + if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TABLE' ) ) { + // parse error + return $this->step(); + } + $this->state->stack_of_open_elements->pop_until( 'TABLE' ); + $this->reset_insertion_mode(); + return true; + + /* + * > An end tag whose tag name is one of: "body", "caption", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr" + */ + case "-BODY": + case "-CAPTION": + case "-COL": + case "-COLGROUP": + case "-HTML": + case "-TBODY": + case "-TD": + case "-TFOOT": + case "-TH": + case "-THEAD": + case "-TR": + // parse error + return $this->step(); + + /* + * > A start tag whose tag name is one of: "style", "script", "template" + * > An end tag whose tag name is "template" + */ + case "+STYLE": + case "+SCRIPT": + case "+TEMPLATE": + case "-TEMPLATE": + // > Process the token using the rules for the "in head" insertion mode. + $this->last_error = self::ERROR_UNSUPPORTED; + throw new WP_HTML_Unsupported_Exception( "Cannot process {$tag_name} element." ); + + /* + * > A start tag whose tag name is "input" + * + * > If the token does not have an attribute with the name "type", or if it does, but + * > that attribute's value is not an ASCII case-insensitive match for the string + * > "hidden", then: act as described in the "anything else" entry below. + */ + case "+INPUT": + $type_attribute = $this->get_attribute( 'type' ); + if ( ! is_string( $type_attribute ) || 'hidden' !== strtolower( $type_attribute ) ) { + goto in_table_anything_else; + } + // parse error + $this->insert_html_element( $this->state->current_token ); + return true; + + /* + * > A start tag whose tag name is "form" + */ + case "+FORM": + if ( + $this->state->stack_of_open_elements->has_element_in_scope( 'TEMPLATE' ) || + + ) { + } + + /* + * > An end-of-file token + */ + /* + * > Anything else + * > Parse error. Enable foster parenting, process the token using the rules for the + * > "in body" insertion mode, and then disable foster parenting. + */ + default: + in_table_anything_else: + $this->last_error = self::ERROR_UNSUPPORTED; + throw new WP_HTML_Unsupported_Exception( "Cannot process {$tag_name} element." ); + } + + $this->last_error = self::ERROR_UNSUPPORTED; + throw new WP_HTML_Unsupported_Exception( "Cannot process {$tag_name} element." ); + } + /* * Internal helpers */ @@ -1627,6 +1825,29 @@ private function bookmark_token() { return "{$this->bookmark_counter}"; } + /** + * Clear the stack back to a table context. + * + * > When the steps above require the UA to clear the stack back to a table context, it means + * > that the UA must, while the current node is not a table, template, or html element, pop + * > elements from the stack of open elements. + * + * @see https://html.spec.whatwg.org/multipage/parsing.html#clear-the-stack-back-to-a-table-context + */ + private function clear_stack_to_table_context() { + // @todo we could add saftey here checking insertion modes… + foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { + if ( + $item->node_name === 'TABLE' || + $item->node_name === 'TEMPLATE' || + $item->node_name === 'HTML' + ) { + break; + } + $this->state->stack_of_open_elements->remove_node( $item ); + } + } + /* * HTML semantic overrides for Tag Processor */ From 922948aed2400b384037653ee1952875d1065f49 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Sun, 4 Feb 2024 18:49:12 +0100 Subject: [PATCH 38/53] table processing --- .../html-api/class-wp-html-processor.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index e96f1043f12f0..130d26a6e7ad7 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -1292,6 +1292,7 @@ private function step_in_body() { $this->insert_html_element( $this->state->current_token ); $this->state->frameset_ok = false; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; + return true; /* * > An end tag whose tag name is "br" @@ -1703,6 +1704,7 @@ private function step_in_table() { $this->insert_html_element( new WP_HTML_Token( null, 'TBODY', false ) ); + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); /* @@ -1780,13 +1782,18 @@ private function step_in_table() { case "+FORM": if ( $this->state->stack_of_open_elements->has_element_in_scope( 'TEMPLATE' ) || - + $this->has_element_pointer( 'FORM' ) ) { + return $this->step(); } + $this->insert_html_element( $this->state->current_token ); + $this->set_element_pointer( 'FORM' ); + return true; /* * > An end-of-file token */ + /* * > Anything else * > Parse error. Enable foster parenting, process the token using the rules for the @@ -2391,6 +2398,14 @@ public function has_bookmark( $bookmark_name ) { return parent::has_bookmark( "_{$bookmark_name}" ); } + private function set_element_pointer( string $tag_name ) { + return parent::set_bookmark( "element_pointer_{$tag_name}" ); + } + + private function has_element_pointer( string $tag_name ) { + return parent::has_bookmark( "element_pointer_{$tag_name}" ); + } + /* * HTML Parsing Algorithms */ From 89184defdf5c35884ce8942d9d3837419ab4fe06 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Sun, 4 Feb 2024 19:30:25 +0100 Subject: [PATCH 39/53] Disable FRAME / HEAD --- src/wp-includes/html-api/class-wp-html-processor.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 130d26a6e7ad7..6b7379b6cd8c4 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -1439,7 +1439,9 @@ private function step_in_body() { case 'BGSOUND': case 'BODY': case 'FORM': + case 'FRAME': case 'FRAMESET': + case 'HEAD': case 'HTML': case 'IFRAME': case 'LINK': From a68527a8962750a076bd8d8678365d2e23148fda Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Mon, 5 Feb 2024 12:26:09 +0100 Subject: [PATCH 40/53] In table body rules --- .../html-api/class-wp-html-processor.php | 140 +++++++++++++++++- 1 file changed, 137 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 6b7379b6cd8c4..3ee2a0bdeda2f 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -763,7 +763,12 @@ public function step( $node_to_process = self::PROCESS_NEXT_NODE ) { case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE: return $this->step_in_table(); + case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY: + return $this->step_in_table_body(); + default: + echo "\n MODE: " . $this->state->insertion_mode . "\n"; + $this->last_error = self::ERROR_UNSUPPORTED; throw new WP_HTML_Unsupported_Exception( "No support for parsing in the '{$this->state->insertion_mode}' state." ); } @@ -1806,9 +1811,111 @@ private function step_in_table() { $this->last_error = self::ERROR_UNSUPPORTED; throw new WP_HTML_Unsupported_Exception( "Cannot process {$tag_name} element." ); } + } - $this->last_error = self::ERROR_UNSUPPORTED; - throw new WP_HTML_Unsupported_Exception( "Cannot process {$tag_name} element." ); + /** + * Parses next element in the 'in table body' insertion mode. + * + * This internal function performs the 'in table body' insertion mode + * logic for the generalized WP_HTML_Processor::step() function. + * + * @since 6.5.0 + * + * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. + * + * @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-intbody + * @see WP_HTML_Processor::step + * + * @return bool Whether an element was found. + */ + private function step_in_table_body() { + $tag_name = $this->get_tag(); + $op_sigil = $this->is_tag_closer() ? '-' : '+'; + $op = "{$op_sigil}{$tag_name}"; + + switch ( $op ) { + /* + * > A start tag whose tag name is "tr" + */ + case '+TR': + $this->clear_stack_to_table_body_context(); + $this->insert_html_element( $this->state->current_token ); + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; + return true; + + /* + * > A start tag whose tag name is one of: "th", "td" + */ + case '+TH': + case '+TD': + // parse error + $this->clear_stack_to_table_body_context(); + $this->insert_html_element( + new WP_HTML_Token( null, 'TR', false ) + ); + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; + return $this->step( self::REPROCESS_CURRENT_NODE ); + + /* + * > An end tag whose tag name is one of: "tbody", "tfoot", "thead" + */ + case '-TBODY': + case '-TFOOT': + case '-THEAD': + if ( + ! $this->state->stack_of_open_elements->has_element_in_table_scope( $tag_name ) + ) { + // parse error + return $this->step(); + } + $this->state->stack_of_open_elements->pop(); + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; + return true; + + /* + * > A start tag whose tag name is one of: "caption", "col", "colgroup", "tbody", "tfoot", "thead" + * > An end tag whose tag name is "table" + */ + case '+CAPTION': + case '+COL': + case '+COLGROUP': + case '+TBODY': + case '+TFOOT': + case '+THEAD': + case '-TABLE': + if ( + ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TBODY' ) && + ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'THEAD' ) && + ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TFOOT' ) + ) { + // parse error + return $this->step(); + } + $this->clear_stack_to_table_body_context(); + $this->state->stack_of_open_elements->pop(); + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; + return $this->step( self::REPROCESS_CURRENT_NODE ); + + /* + * > An end tag whose tag name is one of: "body", "caption", "col", "colgroup", "html", "td", "th", "tr" + */ + case '-BODY': + case '-CAPTION': + case '-COL': + case '-COLGROUP': + case '-HTML': + case '-TD': + case '-TH': + case '-TR': + // parse error + return $this->step(); + } + + /* + * > Anything else + * > Process the token using the rules for the "in table" insertion mode. + */ + return $this->step_in_table(); } /* @@ -1841,10 +1948,11 @@ private function bookmark_token() { * > that the UA must, while the current node is not a table, template, or html element, pop * > elements from the stack of open elements. * + * @todo move this to open elements class. + * * @see https://html.spec.whatwg.org/multipage/parsing.html#clear-the-stack-back-to-a-table-context */ private function clear_stack_to_table_context() { - // @todo we could add saftey here checking insertion modes… foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { if ( $item->node_name === 'TABLE' || @@ -1857,6 +1965,32 @@ private function clear_stack_to_table_context() { } } + /** + * Clear the stack back to a table body context. + * + * > When the steps above require the UA to clear the stack back to a table body context, it + * > means that the UA must, while the current node is not a tbody, tfoot, thead, template, or + * > html element, pop elements from the stack of open elements. + * + * @todo move this to open elements class. + * + * @see https://html.spec.whatwg.org/multipage/parsing.html#clear-the-stack-back-to-a-table-body-context + */ + private function clear_stack_to_table_body_context() { + foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { + if ( + $item->node_name === 'TBODY' || + $item->node_name === 'TFOOT' || + $item->node_name === 'THEAD' || + $item->node_name === 'TEMPLATE' || + $item->node_name === 'HTML' + ) { + break; + } + $this->state->stack_of_open_elements->remove_node( $item ); + } + } + /* * HTML semantic overrides for Tag Processor */ From afb35bc5586e7e5cd5dbd1223df3b1df6d873f90 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 6 Feb 2024 07:50:39 +0100 Subject: [PATCH 41/53] prep step_in_row --- .../html-api/class-wp-html-processor.php | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 3ee2a0bdeda2f..516614a14347d 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -766,6 +766,9 @@ public function step( $node_to_process = self::PROCESS_NEXT_NODE ) { case WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY: return $this->step_in_table_body(); + case WP_HTML_Processor_State::INSERTION_MODE_IN_ROW: + return $this->step_in_row(); + default: echo "\n MODE: " . $this->state->insertion_mode . "\n"; @@ -1918,6 +1921,78 @@ private function step_in_table_body() { return $this->step_in_table(); } + /** + * Parses next element in the 'in row' insertion mode. + * + * This internal function performs the 'in row' insertion mode + * logic for the generalized WP_HTML_Processor::step() function. + * + * @since 6.5.0 + * + * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. + * + * @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-intr + * @see WP_HTML_Processor::step + * + * @return bool Whether an element was found. + */ + private function step_in_row() { + $tag_name = $this->get_tag(); + $op_sigil = $this->is_tag_closer() ? '-' : '+'; + $op = "{$op_sigil}{$tag_name}"; + + switch ( $op ) { + /* + * > A start tag whose tag name is one of: "th", "td" + */ + case '+TH': + case '+TD': + + /* + * > An end tag whose tag name is "tr" + */ + case '-TR': + + /* + * > A start tag whose tag name is one of: "caption", "col", "colgroup", "tbody", "tfoot", "thead", "tr" + */ + case '+CAPTION': + case '+COL': + case '+COLGROUP': + case '+TBODY': + case '+TFOOT': + case '+THEAD': + case '+TR': + + /* + * > An end tag whose tag name is "table" + */ + case '-TABLE': + + /* + * > An end tag whose tag name is one of: "tbody", "tfoot", "thead" + */ + case '-TBODY': + case '-TFOOT': + case '-THEAD': + + /* + * > An end tag whose tag name is one of: "body", "caption", "col", "colgroup", "html", "td", "th" + */ + case '-BODY': + case '-CAPTION': + case '-COL': + case '-COLGROUP': + case '-HTML': + case '-TD': + case '-TH': + } + + /* + * > Anything else + */ + } + /* * Internal helpers */ From a596326768b49c7d3b8ef7319dba4ea0759c491e Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 3 Jul 2024 21:04:54 +0200 Subject: [PATCH 42/53] Remove unsupported table element tests --- .../tests/html-api/wpHtmlProcessor.php | 10 ----- .../html-api/wpHtmlProcessorBreadcrumbs.php | 10 ----- .../wpHtmlSupportRequiredHtmlProcessor.php | 7 ---- .../wpHtmlSupportRequiredOpenElements.php | 40 ------------------- 4 files changed, 67 deletions(-) diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessor.php b/tests/phpunit/tests/html-api/wpHtmlProcessor.php index b842703a7a135..3faf1b201cad2 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessor.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessor.php @@ -388,9 +388,6 @@ public static function data_unsupported_special_in_body_tags() { 'BASEFONT' => array( 'BASEFONT' ), 'BGSOUND' => array( 'BGSOUND' ), 'BODY' => array( 'BODY' ), - 'CAPTION' => array( 'CAPTION' ), - 'COL' => array( 'COL' ), - 'COLGROUP' => array( 'COLGROUP' ), 'FORM' => array( 'FORM' ), 'FRAME' => array( 'FRAME' ), 'FRAMESET' => array( 'FRAMESET' ), @@ -415,16 +412,9 @@ public static function data_unsupported_special_in_body_tags() { 'SCRIPT' => array( 'SCRIPT' ), 'STYLE' => array( 'STYLE' ), 'SVG' => array( 'SVG' ), - 'TABLE' => array( 'TABLE' ), - 'TBODY' => array( 'TBODY' ), - 'TD' => array( 'TD' ), 'TEMPLATE' => array( 'TEMPLATE' ), 'TEXTAREA' => array( 'TEXTAREA' ), - 'TFOOT' => array( 'TFOOT' ), - 'TH' => array( 'TH' ), - 'THEAD' => array( 'THEAD' ), 'TITLE' => array( 'TITLE' ), - 'TR' => array( 'TR' ), 'XMP' => array( 'XMP' ), ); } diff --git a/tests/phpunit/tests/html-api/wpHtmlProcessorBreadcrumbs.php b/tests/phpunit/tests/html-api/wpHtmlProcessorBreadcrumbs.php index 403f40a1da032..cc094e30372bd 100644 --- a/tests/phpunit/tests/html-api/wpHtmlProcessorBreadcrumbs.php +++ b/tests/phpunit/tests/html-api/wpHtmlProcessorBreadcrumbs.php @@ -171,9 +171,6 @@ public static function data_unsupported_elements() { 'BASE', 'BGSOUND', // Deprecated; self-closing if self-closing flag provided, otherwise normal. 'BODY', - 'CAPTION', - 'COL', - 'COLGROUP', 'FORM', 'FRAME', 'FRAMESET', @@ -197,16 +194,9 @@ public static function data_unsupported_elements() { 'SCRIPT', 'STYLE', 'SVG', - 'TABLE', - 'TBODY', - 'TD', 'TEMPLATE', 'TEXTAREA', - 'TFOOT', - 'TH', - 'THEAD', 'TITLE', - 'TR', 'XMP', // Deprecated, use PRE instead. ); diff --git a/tests/phpunit/tests/html-api/wpHtmlSupportRequiredHtmlProcessor.php b/tests/phpunit/tests/html-api/wpHtmlSupportRequiredHtmlProcessor.php index 07943cd62a2f4..fc2d3f9245408 100644 --- a/tests/phpunit/tests/html-api/wpHtmlSupportRequiredHtmlProcessor.php +++ b/tests/phpunit/tests/html-api/wpHtmlSupportRequiredHtmlProcessor.php @@ -75,17 +75,10 @@ public function test_generate_implied_end_tags_needs_support() { * @covers WP_HTML_Processor::generate_implied_end_tags_thoroughly */ public function test_generate_implied_end_tags_thoroughly_needs_support() { - $this->ensure_support_is_added_everywhere( 'CAPTION' ); - $this->ensure_support_is_added_everywhere( 'COLGROUP' ); $this->ensure_support_is_added_everywhere( 'RB' ); $this->ensure_support_is_added_everywhere( 'RP' ); $this->ensure_support_is_added_everywhere( 'RT' ); $this->ensure_support_is_added_everywhere( 'RTC' ); - $this->ensure_support_is_added_everywhere( 'TBODY' ); - $this->ensure_support_is_added_everywhere( 'TD' ); - $this->ensure_support_is_added_everywhere( 'TFOOT' ); - $this->ensure_support_is_added_everywhere( 'TH' ); $this->ensure_support_is_added_everywhere( 'HEAD' ); - $this->ensure_support_is_added_everywhere( 'TR' ); } } diff --git a/tests/phpunit/tests/html-api/wpHtmlSupportRequiredOpenElements.php b/tests/phpunit/tests/html-api/wpHtmlSupportRequiredOpenElements.php index 48255190ad50c..7e6b75466dbe2 100644 --- a/tests/phpunit/tests/html-api/wpHtmlSupportRequiredOpenElements.php +++ b/tests/phpunit/tests/html-api/wpHtmlSupportRequiredOpenElements.php @@ -63,11 +63,7 @@ private function ensure_support_is_added_everywhere( $tag_name ) { public function test_has_element_in_scope_needs_support() { // These elements impact all scopes. $this->ensure_support_is_added_everywhere( 'APPLET' ); - $this->ensure_support_is_added_everywhere( 'CAPTION' ); $this->ensure_support_is_added_everywhere( 'HTML' ); - $this->ensure_support_is_added_everywhere( 'TABLE' ); - $this->ensure_support_is_added_everywhere( 'TD' ); - $this->ensure_support_is_added_everywhere( 'TH' ); $this->ensure_support_is_added_everywhere( 'MARQUEE' ); $this->ensure_support_is_added_everywhere( 'OBJECT' ); $this->ensure_support_is_added_everywhere( 'TEMPLATE' ); @@ -101,11 +97,7 @@ public function test_has_element_in_scope_needs_support() { public function test_has_element_in_list_item_scope_needs_support() { // These elements impact all scopes. $this->ensure_support_is_added_everywhere( 'APPLET' ); - $this->ensure_support_is_added_everywhere( 'CAPTION' ); $this->ensure_support_is_added_everywhere( 'HTML' ); - $this->ensure_support_is_added_everywhere( 'TABLE' ); - $this->ensure_support_is_added_everywhere( 'TD' ); - $this->ensure_support_is_added_everywhere( 'TH' ); $this->ensure_support_is_added_everywhere( 'MARQUEE' ); $this->ensure_support_is_added_everywhere( 'OBJECT' ); $this->ensure_support_is_added_everywhere( 'TEMPLATE' ); @@ -135,11 +127,7 @@ public function test_has_element_in_list_item_scope_needs_support() { public function test_has_element_in_button_scope_needs_support() { // These elements impact all scopes. $this->ensure_support_is_added_everywhere( 'APPLET' ); - $this->ensure_support_is_added_everywhere( 'CAPTION' ); $this->ensure_support_is_added_everywhere( 'HTML' ); - $this->ensure_support_is_added_everywhere( 'TABLE' ); - $this->ensure_support_is_added_everywhere( 'TD' ); - $this->ensure_support_is_added_everywhere( 'TH' ); $this->ensure_support_is_added_everywhere( 'MARQUEE' ); $this->ensure_support_is_added_everywhere( 'OBJECT' ); $this->ensure_support_is_added_everywhere( 'TEMPLATE' ); @@ -170,11 +158,7 @@ public function test_has_element_in_button_scope_needs_support() { public function test_after_element_pop_must_maintain_p_in_button_scope_flag() { // These elements impact all scopes. $this->ensure_support_is_added_everywhere( 'APPLET' ); - $this->ensure_support_is_added_everywhere( 'CAPTION' ); $this->ensure_support_is_added_everywhere( 'HTML' ); - $this->ensure_support_is_added_everywhere( 'TABLE' ); - $this->ensure_support_is_added_everywhere( 'TD' ); - $this->ensure_support_is_added_everywhere( 'TH' ); $this->ensure_support_is_added_everywhere( 'MARQUEE' ); $this->ensure_support_is_added_everywhere( 'OBJECT' ); $this->ensure_support_is_added_everywhere( 'TEMPLATE' ); @@ -205,11 +189,7 @@ public function test_after_element_pop_must_maintain_p_in_button_scope_flag() { public function test_after_element_push_must_maintain_p_in_button_scope_flag() { // These elements impact all scopes. $this->ensure_support_is_added_everywhere( 'APPLET' ); - $this->ensure_support_is_added_everywhere( 'CAPTION' ); $this->ensure_support_is_added_everywhere( 'HTML' ); - $this->ensure_support_is_added_everywhere( 'TABLE' ); - $this->ensure_support_is_added_everywhere( 'TD' ); - $this->ensure_support_is_added_everywhere( 'TH' ); $this->ensure_support_is_added_everywhere( 'MARQUEE' ); $this->ensure_support_is_added_everywhere( 'OBJECT' ); $this->ensure_support_is_added_everywhere( 'TEMPLATE' ); @@ -239,11 +219,7 @@ public function test_after_element_push_must_maintain_p_in_button_scope_flag() { public function test_has_element_in_table_scope_needs_support() { // These elements impact all scopes. $this->ensure_support_is_added_everywhere( 'APPLET' ); - $this->ensure_support_is_added_everywhere( 'CAPTION' ); $this->ensure_support_is_added_everywhere( 'HTML' ); - $this->ensure_support_is_added_everywhere( 'TABLE' ); - $this->ensure_support_is_added_everywhere( 'TD' ); - $this->ensure_support_is_added_everywhere( 'TH' ); $this->ensure_support_is_added_everywhere( 'MARQUEE' ); $this->ensure_support_is_added_everywhere( 'OBJECT' ); $this->ensure_support_is_added_everywhere( 'TEMPLATE' ); @@ -261,19 +237,7 @@ public function test_has_element_in_table_scope_needs_support() { // These elements are specific to TABLE scope. $this->ensure_support_is_added_everywhere( 'HTML' ); - $this->ensure_support_is_added_everywhere( 'TABLE' ); $this->ensure_support_is_added_everywhere( 'TEMPLATE' ); - - // These elements depend on table scope. - $this->ensure_support_is_added_everywhere( 'CAPTION' ); - $this->ensure_support_is_added_everywhere( 'COL' ); - $this->ensure_support_is_added_everywhere( 'COLGROUP' ); - $this->ensure_support_is_added_everywhere( 'TBODY' ); - $this->ensure_support_is_added_everywhere( 'TD' ); - $this->ensure_support_is_added_everywhere( 'TFOOT' ); - $this->ensure_support_is_added_everywhere( 'TH' ); - $this->ensure_support_is_added_everywhere( 'THEAD' ); - $this->ensure_support_is_added_everywhere( 'TR' ); } /** @@ -289,11 +253,7 @@ public function test_has_element_in_table_scope_needs_support() { public function test_has_element_in_select_scope_needs_support() { // These elements impact all scopes. $this->ensure_support_is_added_everywhere( 'APPLET' ); - $this->ensure_support_is_added_everywhere( 'CAPTION' ); $this->ensure_support_is_added_everywhere( 'HTML' ); - $this->ensure_support_is_added_everywhere( 'TABLE' ); - $this->ensure_support_is_added_everywhere( 'TD' ); - $this->ensure_support_is_added_everywhere( 'TH' ); $this->ensure_support_is_added_everywhere( 'MARQUEE' ); $this->ensure_support_is_added_everywhere( 'OBJECT' ); $this->ensure_support_is_added_everywhere( 'TEMPLATE' ); From 376be8d7f6ff1adcb2c69da9f9e83c7ffd8d9f3b Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 4 Jul 2024 10:02:37 +0200 Subject: [PATCH 43/53] phpcbf and implement in row --- .../html-api/class-wp-html-processor.php | 139 ++++++++++++------ 1 file changed, 98 insertions(+), 41 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 516614a14347d..f4afa20baec48 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -1298,7 +1298,7 @@ private function step_in_body() { $this->close_a_p_element(); } $this->insert_html_element( $this->state->current_token ); - $this->state->frameset_ok = false; + $this->state->frameset_ok = false; $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE; return true; @@ -1666,7 +1666,7 @@ private function step_in_table() { /* * > A start tag whose tag name is "caption" */ - case "+CAPTION": + case '+CAPTION': $this->clear_stack_to_table_context(); $this->state->active_formatting_elements->set_marker(); $this->insert_html_element( $this->state->current_token ); @@ -1676,7 +1676,7 @@ private function step_in_table() { /* * > A start tag whose tag name is "colgroup" */ - case "+COLGROUP": + case '+COLGROUP': $this->clear_stack_to_table_context(); $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP; @@ -1685,7 +1685,7 @@ private function step_in_table() { /* * > A start tag whose tag name is "col" */ - case "+COL": + case '+COL': $this->clear_stack_to_table_context(); $this->insert_html_element( new WP_HTML_Token( null, 'COLGROUP', false ) @@ -1696,9 +1696,9 @@ private function step_in_table() { /* * > A start tag whose tag name is one of: "tbody", "tfoot", "thead" */ - case "+TBODY": - case "+TFOOT": - case "+THEAD": + case '+TBODY': + case '+TFOOT': + case '+THEAD': $this->clear_stack_to_table_context(); $this->insert_html_element( $this->state->current_token ); $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; @@ -1707,9 +1707,9 @@ private function step_in_table() { /* * > A start tag whose tag name is one of: "td", "th", "tr" */ - case "+TD": - case "+TH": - case "+TR": + case '+TD': + case '+TH': + case '+TR': $this->clear_stack_to_table_context(); $this->insert_html_element( new WP_HTML_Token( null, 'TBODY', false ) @@ -1720,7 +1720,7 @@ private function step_in_table() { /* * > A start tag whose tag name is "table" */ - case "+TABLE": + case '+TABLE': // pase error if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TABLE' ) ) { return $this->step(); @@ -1732,7 +1732,7 @@ private function step_in_table() { /* * > An end tag whose tag name is "table" */ - case "-TABLE": + case '-TABLE': if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TABLE' ) ) { // parse error return $this->step(); @@ -1744,17 +1744,17 @@ private function step_in_table() { /* * > An end tag whose tag name is one of: "body", "caption", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr" */ - case "-BODY": - case "-CAPTION": - case "-COL": - case "-COLGROUP": - case "-HTML": - case "-TBODY": - case "-TD": - case "-TFOOT": - case "-TH": - case "-THEAD": - case "-TR": + case '-BODY': + case '-CAPTION': + case '-COL': + case '-COLGROUP': + case '-HTML': + case '-TBODY': + case '-TD': + case '-TFOOT': + case '-TH': + case '-THEAD': + case '-TR': // parse error return $this->step(); @@ -1762,10 +1762,10 @@ private function step_in_table() { * > A start tag whose tag name is one of: "style", "script", "template" * > An end tag whose tag name is "template" */ - case "+STYLE": - case "+SCRIPT": - case "+TEMPLATE": - case "-TEMPLATE": + case '+STYLE': + case '+SCRIPT': + case '+TEMPLATE': + case '-TEMPLATE': // > Process the token using the rules for the "in head" insertion mode. $this->last_error = self::ERROR_UNSUPPORTED; throw new WP_HTML_Unsupported_Exception( "Cannot process {$tag_name} element." ); @@ -1777,7 +1777,7 @@ private function step_in_table() { * > that attribute's value is not an ASCII case-insensitive match for the string * > "hidden", then: act as described in the "anything else" entry below. */ - case "+INPUT": + case '+INPUT': $type_attribute = $this->get_attribute( 'type' ); if ( ! is_string( $type_attribute ) || 'hidden' !== strtolower( $type_attribute ) ) { goto in_table_anything_else; @@ -1789,7 +1789,7 @@ private function step_in_table() { /* * > A start tag whose tag name is "form" */ - case "+FORM": + case '+FORM': if ( $this->state->stack_of_open_elements->has_element_in_scope( 'TEMPLATE' ) || $this->has_element_pointer( 'FORM' ) @@ -1947,14 +1947,27 @@ private function step_in_row() { */ case '+TH': case '+TD': + $this->clear_stack_to_table_row_context(); + $this->insert_html_element( $this->state->current_token ); + $this->state->active_formatting_elements->set_marker(); + return true; /* * > An end tag whose tag name is "tr" */ case '-TR': + if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TR' ) ) { + // this is a parse error; ignore the token. + return $this->step(); + } + $this->clear_stack_to_table_row_context(); + $this->state->stack_of_open_elements->pop(); + $this->state->insertion_mode = $this->state::INSERTION_MODE_IN_TABLE_BODY; + return true; /* * > A start tag whose tag name is one of: "caption", "col", "colgroup", "tbody", "tfoot", "thead", "tr" + * > An end tag whose tag name is "table" */ case '+CAPTION': case '+COL': @@ -1963,11 +1976,15 @@ private function step_in_row() { case '+TFOOT': case '+THEAD': case '+TR': - - /* - * > An end tag whose tag name is "table" - */ case '-TABLE': + if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TR' ) ) { + // this is a parse error; ignore the token. + return $this->step(); + } + $this->clear_stack_to_table_row_context(); + $this->state->stack_of_open_elements->pop(); + $this->state->insertion_mode = $this->state::INSERTION_MODE_IN_TABLE_BODY; + return $this->step( self::REPROCESS_CURRENT_NODE ); /* * > An end tag whose tag name is one of: "tbody", "tfoot", "thead" @@ -1975,6 +1992,18 @@ private function step_in_row() { case '-TBODY': case '-TFOOT': case '-THEAD': + if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( $tag_name ) ) { + // this is a parse error; ignore the token. + return $this->step(); + } + if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TR' ) ) { + // ignore the token. + return $this->step(); + } + $this->clear_stack_to_table_row_context(); + $this->state->stack_of_open_elements->pop(); + $this->state->insertion_mode = $this->state::INSERTION_MODE_IN_TABLE_BODY; + return $this->step( self::REPROCESS_CURRENT_NODE ); /* * > An end tag whose tag name is one of: "body", "caption", "col", "colgroup", "html", "td", "th" @@ -1986,11 +2015,15 @@ private function step_in_row() { case '-HTML': case '-TD': case '-TH': + // this is a parse error; ignore the token. + return $this->step(); } /* * > Anything else + * > Process the token using the rules for the "in table" insertion mode. */ + return $this->step_in_table(); } /* @@ -2030,9 +2063,9 @@ private function bookmark_token() { private function clear_stack_to_table_context() { foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { if ( - $item->node_name === 'TABLE' || - $item->node_name === 'TEMPLATE' || - $item->node_name === 'HTML' + 'TABLE' === $item->node_name || + 'TEMPLATE' === $item->node_name || + 'HTML' === $item->node_name ) { break; } @@ -2054,11 +2087,35 @@ private function clear_stack_to_table_context() { private function clear_stack_to_table_body_context() { foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { if ( - $item->node_name === 'TBODY' || - $item->node_name === 'TFOOT' || - $item->node_name === 'THEAD' || - $item->node_name === 'TEMPLATE' || - $item->node_name === 'HTML' + 'TBODY' === $item->node_name || + 'TFOOT' === $item->node_name || + 'THEAD' === $item->node_name || + 'TEMPLATE' === $item->node_name || + 'HTML' === $item->node_name + ) { + break; + } + $this->state->stack_of_open_elements->remove_node( $item ); + } + } + + /** + * Clear the stack back to a table row context. + * + * > When the steps above require the UA to clear the stack back to a table row context, it + * > means that the UA must, while the current node is not a tr, template, or html element, pop + * > elements from the stack of open elements. + * + * @todo move this to open elements class. + * + * @see https://html.spec.whatwg.org/multipage/parsing.html#clear-the-stack-back-to-a-table-row-context + */ + private function clear_stack_to_table_row_context() { + foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) { + if ( + 'TR' === $item->node_name || + 'TEMPLATE' === $item->node_name || + 'HTML' === $item->node_name ) { break; } From 4d6f1e5c1fb52fe316d5e45fe6a054022288371e Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 4 Jul 2024 13:23:29 +0200 Subject: [PATCH 44/53] Add clear_up_to_last_marker to active formatting This is an algorithm defined in the standard: https://html.spec.whatwg.org/multipage/parsing.html#clear-the-list-of-active-formatting-elements-up-to-the-last-marker --- ...ass-wp-html-active-formatting-elements.php | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-html-active-formatting-elements.php b/src/wp-includes/html-api/class-wp-html-active-formatting-elements.php index 0f71d9d70fc0e..3048e6d2ca3fd 100644 --- a/src/wp-includes/html-api/class-wp-html-active-formatting-elements.php +++ b/src/wp-includes/html-api/class-wp-html-active-formatting-elements.php @@ -188,4 +188,31 @@ public function walk_up() { public function set_marker() { $this->push( new WP_HTML_Token( null, 'marker', false ) ); } + + /** + * Clears the list of active formatting elements up to the last marker. + * + * > When the steps below require the UA to clear the list of active formatting elements up to + * > the last marker, the UA must perform the following steps: + * > + * > 1. Let entry be the last (most recently added) entry in the list of active + * > formatting elements. + * > 2. Remove entry from the list of active formatting elements. + * > 3. If entry was a marker, then stop the algorithm at this point. + * > The list has been cleared up to the last marker. + * > 4. Go to step 1. + * + * @see https://html.spec.whatwg.org/multipage/parsing.html#clear-the-list-of-active-formatting-elements-up-to-the-last-marker + * + * @since 6.7.0 + */ + public function clear_up_to_last_marker(): void { + foreach ( $this->walk_up() as $item ) { + $is_marker = 'marker' === $item->node_name; + array_pop( $this->stack ); + if ( $is_marker ) { + break; + } + } + } } From 963390eb3a9c910df7b904b320698bcc417c78f6 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 4 Jul 2024 13:24:01 +0200 Subject: [PATCH 45/53] Add step_in_cell method --- .../html-api/class-wp-html-processor.php | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index f4afa20baec48..0cc5d36982510 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -769,6 +769,9 @@ public function step( $node_to_process = self::PROCESS_NEXT_NODE ) { case WP_HTML_Processor_State::INSERTION_MODE_IN_ROW: return $this->step_in_row(); + case WP_HTML_Processor_State::INSERTION_MODE_IN_CELL: + return $this->step_in_cell(); + default: echo "\n MODE: " . $this->state->insertion_mode . "\n"; @@ -2026,6 +2029,105 @@ private function step_in_row() { return $this->step_in_table(); } + /** + * Parses next element in the 'in cell' insertion mode. + * + * This internal function performs the 'in cell' insertion mode + * logic for the generalized WP_HTML_Processor::step() function. + * + * @since 6.7.0 + * + * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. + * + * @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-intd + * @see WP_HTML_Processor::step + * + * @return bool Whether an element was found. + */ + private function step_in_cell() { + $tag_name = $this->get_tag(); + $op_sigil = $this->is_tag_closer() ? '-' : '+'; + $op = "{$op_sigil}{$tag_name}"; + + switch ( $op ) { + /* + * > An end tag whose tag name is one of: "td", "th" + */ + case '-TD': + case '-TH': + if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( $tag_name ) ) { + // this is a parse error; ignore the token. + return $this->step(); + } + $this->generate_implied_end_tags(); + /* + * @todo report a parse error when supported. + * + * if ( ! $this->state->stack_of_open_elements->current_node()->node_name ) {} + */ + $this->state->stack_of_open_elements->pop_until( $tag_name ); + $this->state->active_formatting_elements->clear_up_to_last_marker(); + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; + return true; + + /* + * > A start tag whose tag name is one of: "caption", "col", "colgroup", "tbody", "td", + * > "tfoot", "th", "thead", "tr" + */ + case '+CAPTION': + case '+COL': + case '+COLGROUP': + case '+TBODY': + case '+TD': + case '+TFOOT': + case '+TH': + case '+THEAD': + case '+TR': + // Assert: The stack of open elements has a td or th element in table scope. + if ( + ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TD' ) && + ! $this->state->stack_of_open_elements->has_element_in_table_scope( 'TH' ) + ) { + throw new Exception( 'Assertion failed @todo better message' ); + } + + $this->close_cell(); + return $this->step( self::REPROCESS_CURRENT_NODE ); + + /* + * > An end tag whose tag name is one of: "body", "caption", "col", "colgroup", "html" + */ + case '-BODY': + case '-CAPTION': + case '-COL': + case '-COLGROUP': + case '-HTML': + // Parse error. Ignore the token. + return $this->step(); + + /* + * > An end tag whose tag name is one of: "table", "tbody", "tfoot", "thead", "tr" + */ + case '-TABLE': + case '-TBODY': + case '-TFOOT': + case '-THEAD': + case '-TR': + if ( ! $this->state->stack_of_open_elements->has_element_in_table_scope( $tag_name ) ) { + // Parse error. Ignore the token. + return $this->step(); + } + $this->close_cell(); + return $this->step( self::REPROCESS_CURRENT_NODE ); + } + + /* + * > Anything else + * > Process the token using the rules for the "in body" insertion mode. + */ + return $this->step_in_body(); + } + /* * Internal helpers */ From b72f6d91b03ed725fe663784a2318f9523ca7d38 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 4 Jul 2024 13:24:50 +0200 Subject: [PATCH 46/53] Use class name for processor state constants access --- src/wp-includes/html-api/class-wp-html-processor.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 0cc5d36982510..f6569e215569d 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -1965,7 +1965,7 @@ private function step_in_row() { } $this->clear_stack_to_table_row_context(); $this->state->stack_of_open_elements->pop(); - $this->state->insertion_mode = $this->state::INSERTION_MODE_IN_TABLE_BODY; + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return true; /* @@ -1986,7 +1986,7 @@ private function step_in_row() { } $this->clear_stack_to_table_row_context(); $this->state->stack_of_open_elements->pop(); - $this->state->insertion_mode = $this->state::INSERTION_MODE_IN_TABLE_BODY; + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); /* @@ -2005,7 +2005,7 @@ private function step_in_row() { } $this->clear_stack_to_table_row_context(); $this->state->stack_of_open_elements->pop(); - $this->state->insertion_mode = $this->state::INSERTION_MODE_IN_TABLE_BODY; + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY; return $this->step( self::REPROCESS_CURRENT_NODE ); /* From 8a416581eefa708fe21fd90a417a2747d2c9e226 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 4 Jul 2024 13:40:15 +0200 Subject: [PATCH 47/53] Add to generate-implied-end-tags-thoroughly --- src/wp-includes/html-api/class-wp-html-processor.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index f6569e215569d..9c9ab8ecc7869 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -2830,18 +2830,27 @@ private function generate_implied_end_tags( $except_for_this_element = null ) { * different from generating end tags in the normal sense. * * @since 6.4.0 + * @since 6.7.0 Support "option", "optgroup", and table-structure elements. * * @see WP_HTML_Processor::generate_implied_end_tags * @see https://html.spec.whatwg.org/#generate-implied-end-tags */ private function generate_implied_end_tags_thoroughly() { $elements_with_implied_end_tags = array( + 'CAPTION', + 'COLGROUP', 'DD', 'DT', 'LI', 'OPTGROUP', 'OPTION', 'P', + 'TBODY', + 'TD', + 'TFOOT', + 'TH', + 'THEAD', + 'TR', ); while ( in_array( $this->state->stack_of_open_elements->current_node(), $elements_with_implied_end_tags, true ) ) { From 164d81ff99ab59672b74d20120327529298b9507 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 4 Jul 2024 13:44:49 +0200 Subject: [PATCH 48/53] Update since tags --- src/wp-includes/html-api/class-wp-html-processor.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 9c9ab8ecc7869..fc71209b347bf 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -1642,7 +1642,7 @@ private function step_in_select() { * This internal function performs the 'in table' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * - * @since 6.5.0 + * @since 6.7.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * @@ -1825,7 +1825,7 @@ private function step_in_table() { * This internal function performs the 'in table body' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * - * @since 6.5.0 + * @since 6.7.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * @@ -1930,7 +1930,7 @@ private function step_in_table_body() { * This internal function performs the 'in row' insertion mode * logic for the generalized WP_HTML_Processor::step() function. * - * @since 6.5.0 + * @since 6.7.0 * * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input. * From 57f5d6dae01e8ac9fc87e4b9876b93d1e5c7376e Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 4 Jul 2024 13:55:48 +0200 Subject: [PATCH 49/53] Add close_cell method --- .../html-api/class-wp-html-processor.php | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index fc71209b347bf..79aaa724f1b48 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -3199,6 +3199,34 @@ private function run_adoption_agency_algorithm() { throw new WP_HTML_Unsupported_Exception( 'Cannot run adoption agency when looping required.' ); } + /** + * Runs the close cell algorithm. + * + * @see https://html.spec.whatwg.org/multipage/parsing.html#close-the-cell + * + * Where the steps above say to close the cell, they mean to run the following algorithm: + + * > 1. Generate implied end tags. + * > 2. If the current node is not now a td element or a th element, then this is a parse error. + * > 3. Pop elements from the stack of open elements stack until a td element or a th element has been popped from the stack. + * > 4. Clear the list of active formatting elements up to the last marker. + * > 5. Switch the insertion mode to "in row". + * + * @since 6.7.0 + */ + private function close_cell(): void { + $this->generate_implied_end_tags(); + // @todo Parse error if the current node is a "td" or "th" element. + foreach ( $this->state->stack_of_open_elements->walk_up() as $element ) { + $this->state->stack_of_open_elements->pop(); + if ( 'TD' === $element->node_name || 'TH' === $element->node_name ) { + break; + } + } + $this->state->active_formatting_elements->clear_up_to_last_marker(); + $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW; + } + /** * Inserts an HTML element on the stack of open elements. * From c0781600696a3ceafce7967b8aa677102a8d532a Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 4 Jul 2024 13:56:10 +0200 Subject: [PATCH 50/53] Pop from open elements instead of removing items --- src/wp-includes/html-api/class-wp-html-processor.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index 79aaa724f1b48..f8781c8a40db6 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -2171,7 +2171,7 @@ private function clear_stack_to_table_context() { ) { break; } - $this->state->stack_of_open_elements->remove_node( $item ); + $this->state->stack_of_open_elements->pop(); } } @@ -2197,7 +2197,7 @@ private function clear_stack_to_table_body_context() { ) { break; } - $this->state->stack_of_open_elements->remove_node( $item ); + $this->state->stack_of_open_elements->pop(); } } @@ -2221,7 +2221,7 @@ private function clear_stack_to_table_row_context() { ) { break; } - $this->state->stack_of_open_elements->remove_node( $item ); + $this->state->stack_of_open_elements->pop(); } } From 41320ac0ebdcbdde6de68922b7e96c7a1761df67 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 4 Jul 2024 15:35:03 +0200 Subject: [PATCH 51/53] Complete cases in step_in_table --- .../html-api/class-wp-html-processor.php | 41 +++++++++++++------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-processor.php b/src/wp-includes/html-api/class-wp-html-processor.php index f8781c8a40db6..2bdba7c002eb5 100644 --- a/src/wp-includes/html-api/class-wp-html-processor.php +++ b/src/wp-includes/html-api/class-wp-html-processor.php @@ -1652,20 +1652,36 @@ private function step_in_select() { * @return bool Whether an element was found. */ private function step_in_table() { - $tag_name = $this->get_tag(); - $op_sigil = $this->is_tag_closer() ? '-' : '+'; - $op = "{$op_sigil}{$tag_name}"; + $token_name = $this->get_token_name(); + $token_type = $this->get_token_type(); + $op_sigil = '#tag' === $token_type ? ( parent::is_tag_closer() ? '-' : '+' ) : ''; + $op = "{$op_sigil}{$token_name}"; + switch ( $op ) { /* * > A character token, if the current node is table, tbody, template, tfoot, thead, or tr element */ + case '#text': + $this->last_error = self::ERROR_UNSUPPORTED; + throw new WP_HTML_Unsupported_Exception( "Text in tables is not supported." ); + /* * > A comment token */ + case '#comment': + case '#funky-comment': + $this->insert_html_element( $this->state->current_token ); + return true; + + /* * > A DOCTYPE token */ + case 'html': + // Parse error. Ignore the token. + return $this->step(); + /* * > A start tag whose tag name is "caption" */ @@ -1783,7 +1799,7 @@ private function step_in_table() { case '+INPUT': $type_attribute = $this->get_attribute( 'type' ); if ( ! is_string( $type_attribute ) || 'hidden' !== strtolower( $type_attribute ) ) { - goto in_table_anything_else; + break; } // parse error $this->insert_html_element( $this->state->current_token ); @@ -1807,16 +1823,15 @@ private function step_in_table() { * > An end-of-file token */ - /* - * > Anything else - * > Parse error. Enable foster parenting, process the token using the rules for the - * > "in body" insertion mode, and then disable foster parenting. - */ - default: - in_table_anything_else: - $this->last_error = self::ERROR_UNSUPPORTED; - throw new WP_HTML_Unsupported_Exception( "Cannot process {$tag_name} element." ); } + + /* + * > Anything else + * > Parse error. Enable foster parenting, process the token using the rules for the + * > "in body" insertion mode, and then disable foster parenting. + */ + $this->last_error = self::ERROR_UNSUPPORTED; + throw new WP_HTML_Unsupported_Exception( "Cannot process {$tag_name} element." ); } /** From 33ffc836c8e42f38dbb5033c3d98a0d09f7fa757 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 4 Jul 2024 16:04:22 +0200 Subject: [PATCH 52/53] Implement in_table_scope --- .../html-api/class-wp-html-open-elements.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-open-elements.php b/src/wp-includes/html-api/class-wp-html-open-elements.php index 0fd8ae43b0c42..4e8debf1ba1ca 100644 --- a/src/wp-includes/html-api/class-wp-html-open-elements.php +++ b/src/wp-includes/html-api/class-wp-html-open-elements.php @@ -258,19 +258,19 @@ public function has_element_in_button_scope( $tag_name ) { /** * Returns whether a particular element is in table scope. * - * @since 6.4.0 + * @since 6.4.0 Stub implementation (throws). + * @since 6.7.0 Full implementation. * * @see https://html.spec.whatwg.org/#has-an-element-in-table-scope * - * @throws WP_HTML_Unsupported_Exception Always until this function is implemented. - * * @param string $tag_name Name of tag to check. * @return bool Whether given element is in scope. */ public function has_element_in_table_scope( $tag_name ) { - throw new WP_HTML_Unsupported_Exception( 'Cannot process elements depending on table scope.' ); - - return false; // The linter requires this unreachable code until the function is implemented and can return. + return $this->has_element_in_specific_scope( + $tag_name, + array( 'HTML', 'TABLE', 'TEMPLATE' ) + ); } /** From 759ca17b398c05ebf20d518b1c159a06c4b5d612 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 4 Jul 2024 16:12:09 +0200 Subject: [PATCH 53/53] Add HTML elements to has_element_in_scope handling --- .../html-api/class-wp-html-open-elements.php | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/html-api/class-wp-html-open-elements.php b/src/wp-includes/html-api/class-wp-html-open-elements.php index 4e8debf1ba1ca..766c20fd12d78 100644 --- a/src/wp-includes/html-api/class-wp-html-open-elements.php +++ b/src/wp-includes/html-api/class-wp-html-open-elements.php @@ -197,6 +197,7 @@ public function has_element_in_specific_scope( $tag_name, $termination_list, $te * Returns whether a particular element is in scope. * * @since 6.4.0 + * @since 6.7.0 Add handling for all HTML elements. * * @see https://html.spec.whatwg.org/#has-an-element-in-scope * @@ -207,13 +208,27 @@ public function has_element_in_scope( $tag_name ) { return $this->has_element_in_specific_scope( $tag_name, array( - + 'APPLET', + 'CAPTION', + 'HTML', + 'TABLE', + 'TD', + 'TH', + 'MARQUEE', + 'OBJECT', + 'TEMPLATE', /* - * Because it's not currently possible to encounter - * one of the termination elements, they don't need - * to be listed here. If they were, they would be - * unreachable and only waste CPU cycles while - * scanning through HTML. + * Foreign content not yet supported + * + * - MathML mi + * - MathML mo + * - MathML mn + * - MathML ms + * - MathML mtext + * - MathML annotation-xml + * - SVG foreignObject + * - SVG desc + * - SVG title */ ) );