Last week, WordPress 6.8 was released. This release includes a new default theme, a new block editor experience, and a new block library. It also includes a new block editor experience, and a new block library.
HTML;
- $consumer = new MarkupProcessorConsumer( new WP_HTML_Processor( $html ) );
+ $consumer = new MarkupProcessorConsumer( \WordPress\HTML\WP_HTML_Processor::create_fragment( $html ) );
$blocks_with_meta = $consumer->consume();
$metadata = $blocks_with_meta->get_all_metadata();
$expected_metadata = array(
@@ -37,14 +37,14 @@ public function test_metadata_extraction() {
* @dataProvider provider_test_conversion
*/
public function test_html_to_blocks_conversion( $html, $expected ) {
- $consumer = new MarkupProcessorConsumer( new WP_HTML_Processor( $html ) );
+ $consumer = new MarkupProcessorConsumer( \WordPress\HTML\WP_HTML_Processor::create_fragment( $html ) );
$blocks_with_meta = $consumer->consume();
$this->assertEquals( $this->normalize_markup( $expected ), $this->normalize_markup( $blocks_with_meta->get_block_markup() ) );
}
private function normalize_markup( $markup ) {
- $processor = WP_HTML_Processor::create_fragment( $markup );
+ $processor = \WordPress\HTML\WP_HTML_Processor::create_fragment( $markup );
$serialized = $processor->serialize();
$serialized = trim(
str_replace(
@@ -137,7 +137,7 @@ public static function provider_test_conversion() {
public function test_html_to_blocks_excerpt() {
$this->markTestSkipped( 'Skipping this test because of outdated fixture.' );
- // $consumer = new MarkupProcessorConsumer( WP_HTML_Processor::create_fragment( $input ) );
+ // $consumer = new MarkupProcessorConsumer( \WordPress\HTML\WP_HTML_Processor::create_fragment( $input ) );
// $blocks_with_meta = $consumer->consume();
// $blocks = $blocks_with_meta->get_block_markup();
diff --git a/components/DataLiberation/URL/URLInTextProcessor.php b/components/DataLiberation/URL/URLInTextProcessor.php
index 3311cf07..76faaaea 100644
--- a/components/DataLiberation/URL/URLInTextProcessor.php
+++ b/components/DataLiberation/URL/URLInTextProcessor.php
@@ -3,7 +3,7 @@
namespace WordPress\DataLiberation\URL;
use WordPress\DataLiberation\BlockMarkup\URL;
-use WP_HTML_Text_Replacement;
+use WordPress\HTML\WP_HTML_Text_Replacement;
/**
* Finds string fragments that look like URLs and allow replacing them.
@@ -278,7 +278,7 @@ public function set_raw_url( $new_url ) {
$new_url = substr( $new_url, strpos( $new_url, '://' ) + 3 );
}
$this->raw_url = $new_url;
- $this->lexical_updates[ $this->url_starts_at ] = new WP_HTML_Text_Replacement(
+ $this->lexical_updates[ $this->url_starts_at ] = new \WordPress\HTML\WP_HTML_Text_Replacement(
$this->url_starts_at,
$this->url_length,
$new_url
diff --git a/components/Filesystem/Tests/FunctionsTest.php b/components/Filesystem/Tests/FunctionsTest.php
index 05431e97..1b0f9a81 100644
--- a/components/Filesystem/Tests/FunctionsTest.php
+++ b/components/Filesystem/Tests/FunctionsTest.php
@@ -4,7 +4,6 @@
use function WordPress\Filesystem\wp_join_unix_paths;
use function WordPress\Filesystem\wp_unix_dirname;
-use ValueError;
class FunctionsTest extends TestCase {
public function testBasicPathJoining() {
diff --git a/components/Git/GitRemote.php b/components/Git/GitRemote.php
index e5677534..af08935e 100644
--- a/components/Git/GitRemote.php
+++ b/components/Git/GitRemote.php
@@ -242,10 +242,42 @@ private function resolve_missing_blobs_oids( $remote_commit_hash, $options ) {
$commit = $this->repository->read_object( $remote_commit_hash )->as_commit();
$subpath = trim( $path, '/' );
- $requested_tree_oid = $this->repository->find_hash_by_path( $subpath, $commit->hash );
+ $parent_path = dirname( $subpath );
+ if( $parent_path === '.' || $parent_path === '' ) {
+ $parent_path = '/';
+ }
+
+ $descentant_blobs_oids = [];
+ if( $parent_path !== '/' ) {
+ $parent_tree_oid = $this->repository->find_hash_by_path( $parent_path, $commit->hash );
+ $parent_tree = $this->repository->read_object( $parent_tree_oid )->as_tree();
+ $parent_tree_entries = $parent_tree->entries;
+ $object_name = basename( $subpath );
+ foreach( $parent_tree_entries as $entry ) {
+ if( $entry->name === $object_name ) {
+ $requested_object_oid = $entry->hash;
+ break;
+ }
+ }
+
+ // If the object is not found, it is a blob. Trees are always fetched.
+ if ( ! $this->repository->has_object( $requested_object_oid ) ) {
+ return [$requested_object_oid];
+ }
+
+ $object = $this->repository->read_object( $requested_object_oid );
+ if( $object->get_object_type_name() === 'blob' ) {
+ // Requested object is a blob and, since we've just read it, it isn't
+ // missing. We're done.
+ return [];
+ }
+ }
+
+ // Requested object is a tree, we need to compute all its descendants
+ $requested_object_oid = $this->repository->find_hash_by_path( $subpath, $commit->hash );
$descentant_blobs_oids = get_all_descendant_oids_in_tree(
$this->repository,
- $requested_tree_oid,
+ $requested_object_oid,
array(
'object_types' => array(
TreeEntry::FILE_MODE_REGULAR_EXECUTABLE,
@@ -365,7 +397,7 @@ public function fetch( $full_branch_name, $options = array() ) {
// Make double sure we have all the relevant objects from the remote commit.
// @TODO: investigate why sometimes the root tree is missing and address the
// root cause instead of plugging the hole with a bandaid.
- if ( ! isset( $options['path'] ) || $options['path'] === '/' || $options['path'] === '' ) {
+ if ( ! isset( $options['path'] ) || $options['path'] === '/' || $options['path'] === '' ) {
if ( ! $this->repository->has_all_objects_from_commit( $remote_head ) ) {
$this->git_upload_pack(
array(
diff --git a/components/Git/GitRepository.php b/components/Git/GitRepository.php
index 3efb4b1d..089bc484 100644
--- a/components/Git/GitRepository.php
+++ b/components/Git/GitRepository.php
@@ -14,6 +14,7 @@
use function WordPress\Filesystem\wp_unix_dirname;
use function WordPress\Filesystem\wp_join_unix_paths;
use function WordPress\Filesystem\wp_unix_path_resolve_dots;
+use function WordPress\Polyfill\_doing_it_wrong;
class GitRepository {
@@ -356,6 +357,7 @@ private function resolve_branch_file_path( $branch_name ) {
if (
strpos( $branch_name, '/' ) !== false &&
strncmp( $branch_name, 'refs/heads/', strlen( 'refs/heads/' ) ) !== 0 &&
+ strncmp( $branch_name, 'refs/tags/', strlen( 'refs/tags/' ) ) !== 0 &&
strncmp( $branch_name, 'refs/remotes/', strlen( 'refs/remotes/' ) ) !== 0
) {
_doing_it_wrong( __METHOD__, 'Invalid ref name: ' . $branch_name, '1.0.0' );
diff --git a/components/HTML/class-wp-html-active-formatting-elements.php b/components/HTML/class-wp-html-active-formatting-elements.php
index 317f4089..2bbed0c1 100644
--- a/components/HTML/class-wp-html-active-formatting-elements.php
+++ b/components/HTML/class-wp-html-active-formatting-elements.php
@@ -1,4 +1,6 @@
walk_up() as $item ) {
@@ -65,9 +66,9 @@ public function contains_node( WP_HTML_Token $token ) {
/**
* Returns how many nodes are currently in the stack of active formatting elements.
*
- * @return int How many node are in the stack of active formatting elements.
* @since 6.4.0
*
+ * @return int How many node are in the stack of active formatting elements.
*/
public function count() {
return count( $this->stack );
@@ -77,9 +78,9 @@ public function count() {
* Returns the node at the end of the stack of active formatting elements,
* if one exists. If the stack is empty, returns null.
*
- * @return WP_HTML_Token|null Last node in the stack of active formatting elements, if one exists, otherwise null.
* @since 6.4.0
*
+ * @return WP_HTML_Token|null Last node in the stack of active formatting elements, if one exists, otherwise null.
*/
public function current_node() {
$current_node = end( $this->stack );
@@ -106,12 +107,11 @@ public function insert_marker(): void {
/**
* Pushes a node onto the stack of active formatting elements.
*
- * @param WP_HTML_Token $token Push this node onto the stack.
+ * @since 6.4.0
*
* @see https://html.spec.whatwg.org/#push-onto-the-list-of-active-formatting-elements
*
- * @since 6.4.0
- *
+ * @param WP_HTML_Token $token Push this node onto the stack.
*/
public function push( WP_HTML_Token $token ) {
/*
@@ -132,11 +132,10 @@ public function push( WP_HTML_Token $token ) {
/**
* Removes a node from the stack of active formatting elements.
*
- * @param WP_HTML_Token $token Remove this node from the stack, if it's there already.
- *
- * @return bool Whether the node was found and removed from the stack of active formatting elements.
* @since 6.4.0
*
+ * @param WP_HTML_Token $token Remove this node from the stack, if it's there already.
+ * @return bool Whether the node was found and removed from the stack of active formatting elements.
*/
public function remove_node( WP_HTML_Token $token ) {
foreach ( $this->walk_up() as $position_from_end => $item ) {
@@ -146,7 +145,6 @@ public function remove_node( WP_HTML_Token $token ) {
$position_from_start = $this->count() - $position_from_end - 1;
array_splice( $this->stack, $position_from_start, 1 );
-
return true;
}
@@ -175,7 +173,7 @@ public function remove_node( WP_HTML_Token $token ) {
public function walk_down() {
$count = count( $this->stack );
- for ( $i = 0; $i < $count; $i ++ ) {
+ for ( $i = 0; $i < $count; $i++ ) {
yield $this->stack[ $i ];
}
}
@@ -200,7 +198,7 @@ public function walk_down() {
* @since 6.4.0
*/
public function walk_up() {
- for ( $i = count( $this->stack ) - 1; $i >= 0; $i -- ) {
+ for ( $i = count( $this->stack ) - 1; $i >= 0; $i-- ) {
yield $this->stack[ $i ];
}
}
diff --git a/components/HTML/class-wp-html-attribute-token.php b/components/HTML/class-wp-html-attribute-token.php
index 4bb582cf..ccd92175 100644
--- a/components/HTML/class-wp-html-attribute-token.php
+++ b/components/HTML/class-wp-html-attribute-token.php
@@ -1,4 +1,6 @@
name = $name;
diff --git a/components/HTML/class-wp-html-decoder.php b/components/HTML/class-wp-html-decoder.php
index 6f6f2e53..f03d0a15 100644
--- a/components/HTML/class-wp-html-decoder.php
+++ b/components/HTML/class-wp-html-decoder.php
@@ -1,5 +1,7 @@
$max_digits ) {
$match_byte_length = $end_of_span - $at;
-
return 'οΏ½';
}
@@ -356,7 +351,6 @@ public static function read_character_reference( $context, $text, $at = 0, &$mat
}
$match_byte_length = $end_of_span - $at;
-
return self::code_point_to_utf8_bytes( $code_point );
}
@@ -378,7 +372,6 @@ public static function read_character_reference( $context, $text, $at = 0, &$mat
// If the match ended with a semicolon then it should always be decoded.
if ( ';' === $text[ $name_at + $name_length - 1 ] ) {
$match_byte_length = $after_name - $at;
-
return $replacement;
}
@@ -399,7 +392,6 @@ public static function read_character_reference( $context, $text, $at = 0, &$mat
// It's non-ambiguous, safe to leave it in.
if ( ! $ambiguous_follower ) {
$match_byte_length = $after_name - $at;
-
return $replacement;
}
@@ -409,7 +401,6 @@ public static function read_character_reference( $context, $text, $at = 0, &$mat
}
$match_byte_length = $after_name - $at;
-
return $replacement;
}
@@ -427,13 +418,12 @@ public static function read_character_reference( $context, $text, $at = 0, &$mat
* // Half of a surrogate pair is an invalid code point.
* 'οΏ½' === WP_HTML_Decoder::code_point_to_utf8_bytes( 0xd83c );
*
- * @param int $code_point Which code point to convert.
- *
- * @return string Converted code point, or `οΏ½` if invalid.
* @since 6.6.0
*
* @see https://www.rfc-editor.org/rfc/rfc3629 For the UTF-8 standard.
*
+ * @param int $code_point Which code point to convert.
+ * @return string Converted code point, or `οΏ½` if invalid.
*/
public static function code_point_to_utf8_bytes( $code_point ): string {
// Pre-check to ensure a valid code point.
diff --git a/components/HTML/class-wp-html-doctype-info.php b/components/HTML/class-wp-html-doctype-info.php
index 33099400..42211eff 100644
--- a/components/HTML/class-wp-html-doctype-info.php
+++ b/components/HTML/class-wp-html-doctype-info.php
@@ -1,4 +1,6 @@
indicated_compatability_mode = 'quirks';
-
return;
}
@@ -203,7 +204,6 @@ private function __construct(
*/
if ( 'html' === $name && null === $public_identifier && null === $system_identifier ) {
$this->indicated_compatability_mode = 'no-quirks';
-
return;
}
@@ -215,7 +215,6 @@ private function __construct(
*/
if ( 'html' !== $name ) {
$this->indicated_compatability_mode = 'quirks';
-
return;
}
@@ -244,7 +243,6 @@ private function __construct(
'html' === $public_identifier
) {
$this->indicated_compatability_mode = 'quirks';
-
return;
}
@@ -253,7 +251,6 @@ private function __construct(
*/
if ( 'http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd' === $system_identifier ) {
$this->indicated_compatability_mode = 'quirks';
-
return;
}
@@ -263,7 +260,6 @@ private function __construct(
*/
if ( '' === $public_identifier ) {
$this->indicated_compatability_mode = 'no-quirks';
-
return;
}
@@ -275,87 +271,63 @@ private function __construct(
* and normative documents will have exited before reaching this condition.
*/
if (
- strncmp( $public_identifier, '+//silmaril//dtd html pro v0r11 19970101//',
- strlen( '+//silmaril//dtd html pro v0r11 19970101//' ) ) === 0 ||
- strncmp( $public_identifier, '-//as//dtd html 3.0 aswedit + extensions//',
- strlen( '-//as//dtd html 3.0 aswedit + extensions//' ) ) === 0 ||
- strncmp( $public_identifier, '-//advasoft ltd//dtd html 3.0 aswedit + extensions//',
- strlen( '-//advasoft ltd//dtd html 3.0 aswedit + extensions//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html 2.0 level 1//', strlen( '-//ietf//dtd html 2.0 level 1//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html 2.0 level 2//', strlen( '-//ietf//dtd html 2.0 level 2//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html 2.0 strict level 1//',
- strlen( '-//ietf//dtd html 2.0 strict level 1//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html 2.0 strict level 2//',
- strlen( '-//ietf//dtd html 2.0 strict level 2//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html 2.0 strict//', strlen( '-//ietf//dtd html 2.0 strict//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html 2.0//', strlen( '-//ietf//dtd html 2.0//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html 2.1e//', strlen( '-//ietf//dtd html 2.1e//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html 3.0//', strlen( '-//ietf//dtd html 3.0//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html 3.2 final//', strlen( '-//ietf//dtd html 3.2 final//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html 3.2//', strlen( '-//ietf//dtd html 3.2//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html 3//', strlen( '-//ietf//dtd html 3//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html level 0//', strlen( '-//ietf//dtd html level 0//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html level 1//', strlen( '-//ietf//dtd html level 1//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html level 2//', strlen( '-//ietf//dtd html level 2//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html level 3//', strlen( '-//ietf//dtd html level 3//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html strict level 0//', strlen( '-//ietf//dtd html strict level 0//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html strict level 1//', strlen( '-//ietf//dtd html strict level 1//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html strict level 2//', strlen( '-//ietf//dtd html strict level 2//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html strict level 3//', strlen( '-//ietf//dtd html strict level 3//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html strict//', strlen( '-//ietf//dtd html strict//' ) ) === 0 ||
- strncmp( $public_identifier, '-//ietf//dtd html//', strlen( '-//ietf//dtd html//' ) ) === 0 ||
- strncmp( $public_identifier, '-//metrius//dtd metrius presentational//',
- strlen( '-//metrius//dtd metrius presentational//' ) ) === 0 ||
- strncmp( $public_identifier, '-//microsoft//dtd internet explorer 2.0 html strict//',
- strlen( '-//microsoft//dtd internet explorer 2.0 html strict//' ) ) === 0 ||
- strncmp( $public_identifier, '-//microsoft//dtd internet explorer 2.0 html//',
- strlen( '-//microsoft//dtd internet explorer 2.0 html//' ) ) === 0 ||
- strncmp( $public_identifier, '-//microsoft//dtd internet explorer 2.0 tables//',
- strlen( '-//microsoft//dtd internet explorer 2.0 tables//' ) ) === 0 ||
- strncmp( $public_identifier, '-//microsoft//dtd internet explorer 3.0 html strict//',
- strlen( '-//microsoft//dtd internet explorer 3.0 html strict//' ) ) === 0 ||
- strncmp( $public_identifier, '-//microsoft//dtd internet explorer 3.0 html//',
- strlen( '-//microsoft//dtd internet explorer 3.0 html//' ) ) === 0 ||
- strncmp( $public_identifier, '-//microsoft//dtd internet explorer 3.0 tables//',
- strlen( '-//microsoft//dtd internet explorer 3.0 tables//' ) ) === 0 ||
- strncmp( $public_identifier, '-//netscape comm. corp.//dtd html//', strlen( '-//netscape comm. corp.//dtd html//' ) ) === 0 ||
- strncmp( $public_identifier, '-//netscape comm. corp.//dtd strict html//',
- strlen( '-//netscape comm. corp.//dtd strict html//' ) ) === 0 ||
- strncmp( $public_identifier, "-//o'reilly and associates//dtd html 2.0//",
- strlen( "-//o'reilly and associates//dtd html 2.0//" ) ) === 0 ||
- strncmp( $public_identifier, "-//o'reilly and associates//dtd html extended 1.0//",
- strlen( "-//o'reilly and associates//dtd html extended 1.0//" ) ) === 0 ||
- strncmp( $public_identifier, "-//o'reilly and associates//dtd html extended relaxed 1.0//",
- strlen( "-//o'reilly and associates//dtd html extended relaxed 1.0//" ) ) === 0 ||
- strncmp( $public_identifier, '-//sq//dtd html 2.0 hotmetal + extensions//',
- strlen( '-//sq//dtd html 2.0 hotmetal + extensions//' ) ) === 0 ||
- strncmp( $public_identifier, '-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//',
- strlen( '-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//' ) ) === 0 ||
- strncmp( $public_identifier, '-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//',
- strlen( '-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//' ) ) === 0 ||
- strncmp( $public_identifier, '-//spyglass//dtd html 2.0 extended//', strlen( '-//spyglass//dtd html 2.0 extended//' ) ) === 0 ||
- strncmp( $public_identifier, '-//sun microsystems corp.//dtd hotjava html//',
- strlen( '-//sun microsystems corp.//dtd hotjava html//' ) ) === 0 ||
- strncmp( $public_identifier, '-//sun microsystems corp.//dtd hotjava strict html//',
- strlen( '-//sun microsystems corp.//dtd hotjava strict html//' ) ) === 0 ||
- strncmp( $public_identifier, '-//w3c//dtd html 3 1995-03-24//', strlen( '-//w3c//dtd html 3 1995-03-24//' ) ) === 0 ||
- strncmp( $public_identifier, '-//w3c//dtd html 3.2 draft//', strlen( '-//w3c//dtd html 3.2 draft//' ) ) === 0 ||
- strncmp( $public_identifier, '-//w3c//dtd html 3.2 final//', strlen( '-//w3c//dtd html 3.2 final//' ) ) === 0 ||
- strncmp( $public_identifier, '-//w3c//dtd html 3.2//', strlen( '-//w3c//dtd html 3.2//' ) ) === 0 ||
- strncmp( $public_identifier, '-//w3c//dtd html 3.2s draft//', strlen( '-//w3c//dtd html 3.2s draft//' ) ) === 0 ||
- strncmp( $public_identifier, '-//w3c//dtd html 4.0 frameset//', strlen( '-//w3c//dtd html 4.0 frameset//' ) ) === 0 ||
- strncmp( $public_identifier, '-//w3c//dtd html 4.0 transitional//', strlen( '-//w3c//dtd html 4.0 transitional//' ) ) === 0 ||
- strncmp( $public_identifier, '-//w3c//dtd html experimental 19960712//',
- strlen( '-//w3c//dtd html experimental 19960712//' ) ) === 0 ||
- strncmp( $public_identifier, '-//w3c//dtd html experimental 970421//',
- strlen( '-//w3c//dtd html experimental 970421//' ) ) === 0 ||
- strncmp( $public_identifier, '-//w3c//dtd w3 html//', strlen( '-//w3c//dtd w3 html//' ) ) === 0 ||
- strncmp( $public_identifier, '-//w3o//dtd w3 html 3.0//', strlen( '-//w3o//dtd w3 html 3.0//' ) ) === 0 ||
- strncmp( $public_identifier, '-//webtechs//dtd mozilla html 2.0//', strlen( '-//webtechs//dtd mozilla html 2.0//' ) ) === 0 ||
- strncmp( $public_identifier, '-//webtechs//dtd mozilla html//', strlen( '-//webtechs//dtd mozilla html//' ) ) === 0
+ str_starts_with( $public_identifier, '+//silmaril//dtd html pro v0r11 19970101//' ) ||
+ str_starts_with( $public_identifier, '-//as//dtd html 3.0 aswedit + extensions//' ) ||
+ str_starts_with( $public_identifier, '-//advasoft ltd//dtd html 3.0 aswedit + extensions//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html 2.0 level 1//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html 2.0 level 2//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html 2.0 strict level 1//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html 2.0 strict level 2//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html 2.0 strict//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html 2.0//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html 2.1e//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html 3.0//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html 3.2 final//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html 3.2//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html 3//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html level 0//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html level 1//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html level 2//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html level 3//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html strict level 0//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html strict level 1//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html strict level 2//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html strict level 3//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html strict//' ) ||
+ str_starts_with( $public_identifier, '-//ietf//dtd html//' ) ||
+ str_starts_with( $public_identifier, '-//metrius//dtd metrius presentational//' ) ||
+ str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 2.0 html strict//' ) ||
+ str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 2.0 html//' ) ||
+ str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 2.0 tables//' ) ||
+ str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 3.0 html strict//' ) ||
+ str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 3.0 html//' ) ||
+ str_starts_with( $public_identifier, '-//microsoft//dtd internet explorer 3.0 tables//' ) ||
+ str_starts_with( $public_identifier, '-//netscape comm. corp.//dtd html//' ) ||
+ str_starts_with( $public_identifier, '-//netscape comm. corp.//dtd strict html//' ) ||
+ str_starts_with( $public_identifier, "-//o'reilly and associates//dtd html 2.0//" ) ||
+ str_starts_with( $public_identifier, "-//o'reilly and associates//dtd html extended 1.0//" ) ||
+ str_starts_with( $public_identifier, "-//o'reilly and associates//dtd html extended relaxed 1.0//" ) ||
+ str_starts_with( $public_identifier, '-//sq//dtd html 2.0 hotmetal + extensions//' ) ||
+ str_starts_with( $public_identifier, '-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//' ) ||
+ str_starts_with( $public_identifier, '-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//' ) ||
+ str_starts_with( $public_identifier, '-//spyglass//dtd html 2.0 extended//' ) ||
+ str_starts_with( $public_identifier, '-//sun microsystems corp.//dtd hotjava html//' ) ||
+ str_starts_with( $public_identifier, '-//sun microsystems corp.//dtd hotjava strict html//' ) ||
+ str_starts_with( $public_identifier, '-//w3c//dtd html 3 1995-03-24//' ) ||
+ str_starts_with( $public_identifier, '-//w3c//dtd html 3.2 draft//' ) ||
+ str_starts_with( $public_identifier, '-//w3c//dtd html 3.2 final//' ) ||
+ str_starts_with( $public_identifier, '-//w3c//dtd html 3.2//' ) ||
+ str_starts_with( $public_identifier, '-//w3c//dtd html 3.2s draft//' ) ||
+ str_starts_with( $public_identifier, '-//w3c//dtd html 4.0 frameset//' ) ||
+ str_starts_with( $public_identifier, '-//w3c//dtd html 4.0 transitional//' ) ||
+ str_starts_with( $public_identifier, '-//w3c//dtd html experimental 19960712//' ) ||
+ str_starts_with( $public_identifier, '-//w3c//dtd html experimental 970421//' ) ||
+ str_starts_with( $public_identifier, '-//w3c//dtd w3 html//' ) ||
+ str_starts_with( $public_identifier, '-//w3o//dtd w3 html 3.0//' ) ||
+ str_starts_with( $public_identifier, '-//webtechs//dtd mozilla html 2.0//' ) ||
+ str_starts_with( $public_identifier, '-//webtechs//dtd mozilla html//' )
) {
$this->indicated_compatability_mode = 'quirks';
-
return;
}
@@ -364,13 +336,11 @@ private function __construct(
*/
if (
$system_identifier_is_missing && (
- strncmp( $public_identifier, '-//w3c//dtd html 4.01 frameset//', strlen( '-//w3c//dtd html 4.01 frameset//' ) ) === 0 ||
- strncmp( $public_identifier, '-//w3c//dtd html 4.01 transitional//',
- strlen( '-//w3c//dtd html 4.01 transitional//' ) ) === 0
+ str_starts_with( $public_identifier, '-//w3c//dtd html 4.01 frameset//' ) ||
+ str_starts_with( $public_identifier, '-//w3c//dtd html 4.01 transitional//' )
)
) {
$this->indicated_compatability_mode = 'quirks';
-
return;
}
@@ -383,11 +353,10 @@ private function __construct(
* > The public identifier starts withβ¦
*/
if (
- strncmp( $public_identifier, '-//w3c//dtd xhtml 1.0 frameset//', strlen( '-//w3c//dtd xhtml 1.0 frameset//' ) ) === 0 ||
- strncmp( $public_identifier, '-//w3c//dtd xhtml 1.0 transitional//', strlen( '-//w3c//dtd xhtml 1.0 transitional//' ) ) === 0
+ str_starts_with( $public_identifier, '-//w3c//dtd xhtml 1.0 frameset//' ) ||
+ str_starts_with( $public_identifier, '-//w3c//dtd xhtml 1.0 transitional//' )
) {
$this->indicated_compatability_mode = 'limited-quirks';
-
return;
}
@@ -396,13 +365,11 @@ private function __construct(
*/
if (
! $system_identifier_is_missing && (
- strncmp( $public_identifier, '-//w3c//dtd html 4.01 frameset//', strlen( '-//w3c//dtd html 4.01 frameset//' ) ) === 0 ||
- strncmp( $public_identifier, '-//w3c//dtd html 4.01 transitional//',
- strlen( '-//w3c//dtd html 4.01 transitional//' ) ) === 0
+ str_starts_with( $public_identifier, '-//w3c//dtd html 4.01 frameset//' ) ||
+ str_starts_with( $public_identifier, '-//w3c//dtd html 4.01 transitional//' )
)
) {
$this->indicated_compatability_mode = 'limited-quirks';
-
return;
}
@@ -437,12 +404,12 @@ private function __construct(
* null === WP_HTML_Doctype_Info::from_doctype_token( 'html' );
* null === WP_HTML_Doctype_Info::from_doctype_token( '' );
*
- * @param string $doctype_html The complete raw DOCTYPE HTML string, e.g. ``.
+ * @since 6.7.0
+ *
+ * @param string $doctype_html The complete raw DOCTYPE HTML string, e.g. ``.
*
* @return WP_HTML_Doctype_Info|null A WP_HTML_Doctype_Info instance will be returned if the
* provided DOCTYPE HTML is a valid DOCTYPE. Otherwise, null.
- * @since 6.7.0
- *
*/
public static function from_doctype_token( string $doctype_html ): ?self {
$doctype_name = null;
@@ -572,7 +539,6 @@ public static function from_doctype_token( string $doctype_html ): ?self {
* > Set the current DOCTYPE token's force-quirks flag to on. Reconsume in the bogus
* > DOCTYPE state.
*/
-
return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true );
parse_doctype_public_identifier:
@@ -594,7 +560,7 @@ public static function from_doctype_token( string $doctype_html ): ?self {
return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true );
}
- ++ $at;
+ ++$at;
$identifier_length = strcspn( $doctype_html, $closer_quote, $at, $end - $at );
$doctype_public_id = str_replace( "\0", "\u{FFFD}", substr( $doctype_html, $at, $identifier_length ) );
@@ -604,7 +570,7 @@ public static function from_doctype_token( string $doctype_html ): ?self {
return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true );
}
- ++ $at;
+ ++$at;
/*
* "Between DOCTYPE public and system identifiers state"
@@ -637,7 +603,7 @@ public static function from_doctype_token( string $doctype_html ): ?self {
return new self( $doctype_name, $doctype_public_id, $doctype_system_id, true );
}
- ++ $at;
+ ++$at;
$identifier_length = strcspn( $doctype_html, $closer_quote, $at, $end - $at );
$doctype_system_id = str_replace( "\0", "\u{FFFD}", substr( $doctype_html, $at, $identifier_length ) );
diff --git a/components/HTML/class-wp-html-open-elements.php b/components/HTML/class-wp-html-open-elements.php
index ad5d34f9..05c01fca 100644
--- a/components/HTML/class-wp-html-open-elements.php
+++ b/components/HTML/class-wp-html-open-elements.php
@@ -1,4 +1,7 @@
pop_handler = $handler;
@@ -94,10 +96,9 @@ public function set_pop_handler( Closure $handler ): void {
*
* The function will be called with the pushed item as its argument.
*
- * @param Closure $handler The handler function.
- *
* @since 6.6.0
*
+ * @param Closure $handler The handler function.
*/
public function set_push_handler( Closure $handler ): void {
$this->push_handler = $handler;
@@ -111,17 +112,16 @@ public function set_push_handler( Closure $handler ): void {
* "nth item" on the stack, counting from the top, where the
* top-most element is the 1st, the second is the 2nd, etc...
*
- * @param int $nth Retrieve the nth item on the stack, with 1 being
- * the top element, 2 being the second, etc...
+ * @since 6.7.0
*
+ * @param int $nth Retrieve the nth item on the stack, with 1 being
+ * the top element, 2 being the second, etc...
* @return WP_HTML_Token|null Name of the node on the stack at the given location,
* or `null` if the location isn't on the stack.
- * @since 6.7.0
- *
*/
public function at( int $nth ): ?WP_HTML_Token {
foreach ( $this->walk_down() as $item ) {
- if ( 0 === -- $nth ) {
+ if ( 0 === --$nth ) {
return $item;
}
}
@@ -132,11 +132,10 @@ public function at( int $nth ): ?WP_HTML_Token {
/**
* Reports if a node of a given name is in the stack of open elements.
*
- * @param string $node_name Name of node for which to check.
- *
- * @return bool Whether a node of the given name is in the stack of open elements.
* @since 6.7.0
*
+ * @param string $node_name Name of node for which to check.
+ * @return bool Whether a node of the given name is in the stack of open elements.
*/
public function contains( string $node_name ): bool {
foreach ( $this->walk_up() as $item ) {
@@ -151,11 +150,10 @@ public function contains( string $node_name ): bool {
/**
* Reports if a specific node is in the stack of open elements.
*
- * @param WP_HTML_Token $token Look for this node in the stack.
- *
- * @return bool Whether the referenced node is in the stack of open elements.
* @since 6.4.0
*
+ * @param WP_HTML_Token $token Look for this node in the stack.
+ * @return bool Whether the referenced node is in the stack of open elements.
*/
public function contains_node( WP_HTML_Token $token ): bool {
foreach ( $this->walk_up() as $item ) {
@@ -170,9 +168,9 @@ public function contains_node( WP_HTML_Token $token ): bool {
/**
* Returns how many nodes are currently in the stack of open elements.
*
- * @return int How many node are in the stack of open elements.
* @since 6.4.0
*
+ * @return int How many node are in the stack of open elements.
*/
public function count(): int {
return count( $this->stack );
@@ -182,9 +180,9 @@ public function count(): int {
* Returns the node at the end of the stack of open elements,
* if one exists. If the stack is empty, returns null.
*
- * @return WP_HTML_Token|null Last node in the stack of open elements, if one exists, otherwise null.
* @since 6.4.0
*
+ * @return WP_HTML_Token|null Last node in the stack of open elements, if one exists, otherwise null.
*/
public function current_node(): ?WP_HTML_Token {
$current_node = end( $this->stack );
@@ -209,16 +207,15 @@ public function current_node(): ?WP_HTML_Token {
* // Is the current node any element/tag?
* $stack->current_node_is( '#tag' );
*
- * @param string $identity Check if the current node has this name or type (depending on what is provided).
+ * @see WP_HTML_Tag_Processor::get_token_type
+ * @see WP_HTML_Tag_Processor::get_token_name
*
- * @return bool Whether there is a current element that matches the given identity, whether a token name or type.
* @since 6.7.0
*
* @access private
*
- * @see WP_HTML_Tag_Processor::get_token_type
- * @see WP_HTML_Tag_Processor::get_token_name
- *
+ * @param string $identity Check if the current node has this name or type (depending on what is provided).
+ * @return bool Whether there is a current element that matches the given identity, whether a token name or type.
*/
public function current_node_is( string $identity ): bool {
$current_node = end( $this->stack );
@@ -238,14 +235,13 @@ public function current_node_is( string $identity ): bool {
/**
* Returns whether an element is in a specific scope.
*
- * @param string $tag_name Name of tag check.
- * @param string[] $termination_list List of elements that terminate the search.
+ * @since 6.4.0
*
- * @return bool Whether the element was found in a specific scope.
* @see https://html.spec.whatwg.org/#has-an-element-in-the-specific-scope
*
- * @since 6.4.0
- *
+ * @param string $tag_name Name of tag check.
+ * @param string[] $termination_list List of elements that terminate the search.
+ * @return bool Whether the element was found in a specific scope.
*/
public function has_element_in_specific_scope( string $tag_name, $termination_list ): bool {
foreach ( $this->walk_up() as $node ) {
@@ -298,14 +294,13 @@ public function has_element_in_specific_scope( string $tag_name, $termination_li
* > - SVG desc
* > - SVG title
*
- * @param string $tag_name Name of tag to check.
- *
- * @return bool Whether given element is in scope.
- * @see https://html.spec.whatwg.org/#has-an-element-in-scope
- *
* @since 6.4.0
* @since 6.7.0 Full support.
*
+ * @see https://html.spec.whatwg.org/#has-an-element-in-scope
+ *
+ * @param string $tag_name Name of tag to check.
+ * @return bool Whether given element is in scope.
*/
public function has_element_in_scope( string $tag_name ): bool {
return $this->has_element_in_specific_scope(
@@ -346,15 +341,14 @@ public function has_element_in_scope( string $tag_name ): bool {
* > - ol in the HTML namespace
* > - ul in the HTML namespace
*
- * @param string $tag_name Name of tag to check.
- *
- * @return bool Whether given element is in scope.
+ * @since 6.4.0
+ * @since 6.5.0 Implemented: no longer throws on every invocation.
* @since 6.7.0 Supports all required HTML elements.
*
* @see https://html.spec.whatwg.org/#has-an-element-in-list-item-scope
*
- * @since 6.4.0
- * @since 6.5.0 Implemented: no longer throws on every invocation.
+ * @param string $tag_name Name of tag to check.
+ * @return bool Whether given element is in scope.
*/
public function has_element_in_list_item_scope( string $tag_name ): bool {
return $this->has_element_in_specific_scope(
@@ -397,14 +391,13 @@ public function has_element_in_list_item_scope( string $tag_name ): bool {
* > - All the element types listed above for the has an element in scope algorithm.
* > - button in the HTML namespace
*
- * @param string $tag_name Name of tag to check.
- *
- * @return bool Whether given element is in scope.
- * @see https://html.spec.whatwg.org/#has-an-element-in-button-scope
- *
* @since 6.4.0
* @since 6.7.0 Supports all required HTML elements.
*
+ * @see https://html.spec.whatwg.org/#has-an-element-in-button-scope
+ *
+ * @param string $tag_name Name of tag to check.
+ * @return bool Whether given element is in scope.
*/
public function has_element_in_button_scope( string $tag_name ): bool {
return $this->has_element_in_specific_scope(
@@ -446,14 +439,13 @@ public function has_element_in_button_scope( string $tag_name ): bool {
* > - table in the HTML namespace
* > - template in the HTML namespace
*
- * @param string $tag_name Name of tag to check.
- *
- * @return bool Whether given element is in scope.
- * @see https://html.spec.whatwg.org/#has-an-element-in-table-scope
- *
* @since 6.4.0
* @since 6.7.0 Full implementation.
*
+ * @see https://html.spec.whatwg.org/#has-an-element-in-table-scope
+ *
+ * @param string $tag_name Name of tag to check.
+ * @return bool Whether given element is in scope.
*/
public function has_element_in_table_scope( string $tag_name ): bool {
return $this->has_element_in_specific_scope(
@@ -478,14 +470,13 @@ public function has_element_in_table_scope( string $tag_name ): bool {
* > - optgroup in the HTML namespace
* > - option in the HTML namespace
*
- * @param string $tag_name Name of tag to check.
- *
- * @return bool Whether the given element is in SELECT scope.
- * @see https://html.spec.whatwg.org/#has-an-element-in-select-scope
- *
* @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
+ *
+ * @param string $tag_name Name of tag to check.
+ * @return bool Whether the given element is in SELECT scope.
*/
public function has_element_in_select_scope( string $tag_name ): bool {
foreach ( $this->walk_up() as $node ) {
@@ -507,11 +498,11 @@ public function has_element_in_select_scope( string $tag_name ): bool {
/**
* Returns whether a P is in BUTTON scope.
*
- * @return bool Whether a P is in BUTTON scope.
- * @see https://html.spec.whatwg.org/#has-an-element-in-button-scope
- *
* @since 6.4.0
*
+ * @see https://html.spec.whatwg.org/#has-an-element-in-button-scope
+ *
+ * @return bool Whether a P is in BUTTON scope.
*/
public function has_p_in_button_scope(): bool {
return $this->has_p_in_button_scope;
@@ -520,11 +511,11 @@ public function has_p_in_button_scope(): bool {
/**
* Pops a node off of the stack of open elements.
*
- * @return bool Whether a node was popped off of the stack.
- * @see https://html.spec.whatwg.org/#stack-of-open-elements
- *
* @since 6.4.0
*
+ * @see https://html.spec.whatwg.org/#stack-of-open-elements
+ *
+ * @return bool Whether a node was popped off of the stack.
*/
public function pop(): bool {
$item = array_pop( $this->stack );
@@ -532,27 +523,19 @@ public function pop(): bool {
return false;
}
- if ( 'context-node' === $item->bookmark_name ) {
- $this->stack[] = $item;
-
- return false;
- }
-
$this->after_element_pop( $item );
-
return true;
}
/**
* Pops nodes off of the stack of open elements until an HTML tag with the given name has been popped.
*
- * @param string $html_tag_name Name of tag that needs to be popped off of the stack of open elements.
- *
- * @return bool Whether a tag of the given name was found and popped off of the stack of open elements.
* @since 6.4.0
*
* @see WP_HTML_Open_Elements::pop
*
+ * @param string $html_tag_name Name of tag that needs to be popped off of the stack of open elements.
+ * @return bool Whether a tag of the given name was found and popped off of the stack of open elements.
*/
public function pop_until( string $html_tag_name ): bool {
foreach ( $this->walk_up() as $item ) {
@@ -580,12 +563,11 @@ public function pop_until( string $html_tag_name ): bool {
/**
* Pushes a node onto the stack of open elements.
*
- * @param WP_HTML_Token $stack_item Item to add onto stack.
+ * @since 6.4.0
*
* @see https://html.spec.whatwg.org/#stack-of-open-elements
*
- * @since 6.4.0
- *
+ * @param WP_HTML_Token $stack_item Item to add onto stack.
*/
public function push( WP_HTML_Token $stack_item ): void {
$this->stack[] = $stack_item;
@@ -595,17 +577,12 @@ public function push( WP_HTML_Token $stack_item ): void {
/**
* Removes a specific node from the stack of open elements.
*
- * @param WP_HTML_Token $token The node to remove from the stack of open elements.
- *
- * @return bool Whether the node was found and removed from the stack of open elements.
* @since 6.4.0
*
+ * @param WP_HTML_Token $token The node to remove from the stack of open elements.
+ * @return bool Whether the node was found and removed from the stack of open elements.
*/
public function remove_node( WP_HTML_Token $token ): bool {
- if ( 'context-node' === $token->bookmark_name ) {
- return false;
- }
-
foreach ( $this->walk_up() as $position_from_end => $item ) {
if ( $token->bookmark_name !== $item->bookmark_name ) {
continue;
@@ -614,7 +591,6 @@ public function remove_node( WP_HTML_Token $token ): bool {
$position_from_start = $this->count() - $position_from_end - 1;
array_splice( $this->stack, $position_from_start, 1 );
$this->after_element_pop( $item );
-
return true;
}
@@ -644,7 +620,7 @@ public function remove_node( WP_HTML_Token $token ): bool {
public function walk_down() {
$count = count( $this->stack );
- for ( $i = 0; $i < $count; $i ++ ) {
+ for ( $i = 0; $i < $count; $i++ ) {
yield $this->stack[ $i ];
}
}
@@ -666,17 +642,16 @@ public function walk_down() {
* To start with the first added element and walk towards the bottom,
* see WP_HTML_Open_Elements::walk_down().
*
- * @param WP_HTML_Token|null $above_this_node Optional. Start traversing above this node,
- * if provided and if the node exists.
- *
+ * @since 6.4.0
* @since 6.5.0 Accepts $above_this_node to start traversal above a given node, if it exists.
*
- * @since 6.4.0
+ * @param WP_HTML_Token|null $above_this_node Optional. Start traversing above this node,
+ * if provided and if the node exists.
*/
public function walk_up( ?WP_HTML_Token $above_this_node = null ) {
$has_found_node = null === $above_this_node;
- for ( $i = count( $this->stack ) - 1; $i >= 0; $i -- ) {
+ for ( $i = count( $this->stack ) - 1; $i >= 0; $i-- ) {
$node = $this->stack[ $i ];
if ( ! $has_found_node ) {
@@ -701,10 +676,9 @@ public function walk_up( ?WP_HTML_Token $above_this_node = null ) {
* over the open stack elements upon each new tag it encounters. These flags,
* however, need to be maintained as items are added and removed from the stack.
*
- * @param WP_HTML_Token $item Element that was added to the stack of open elements.
- *
* @since 6.4.0
*
+ * @param WP_HTML_Token $item Element that was added to the stack of open elements.
*/
public function after_element_push( WP_HTML_Token $item ): void {
$namespaced_name = 'html' === $item->namespace
@@ -757,10 +731,9 @@ public function after_element_push( WP_HTML_Token $item ): void {
* over the open stack elements upon each new tag it encounters. These flags,
* however, need to be maintained as items are added and removed from the stack.
*
- * @param WP_HTML_Token $item Element that was removed from the stack of open elements.
- *
* @since 6.4.0
*
+ * @param WP_HTML_Token $item Element that was removed from the stack of open elements.
*/
public function after_element_pop( WP_HTML_Token $item ): void {
/*
@@ -877,6 +850,6 @@ public function clear_to_table_row_context(): void {
* @since 6.6.0
*/
public function __wakeup() {
- throw new LogicException( __CLASS__ . ' should never be unserialized' );
+ throw new \LogicException( __CLASS__ . ' should never be unserialized' );
}
}
diff --git a/components/HTML/class-wp-html-processor-state.php b/components/HTML/class-wp-html-processor-state.php
index b7cdd347..b61064e6 100644
--- a/components/HTML/class-wp-html-processor-state.php
+++ b/components/HTML/class-wp-html-processor-state.php
@@ -1,4 +1,6 @@
`, which is the default value.
* - The only supported document encoding is `UTF-8`, which is the default value.
*
- * @param string $html Input HTML fragment to process.
- * @param string $context Context element for the fragment, must be default of ``.
- * @param string $encoding Text encoding of the document; must be default of 'UTF-8'.
- *
- * @return static|null The created processor if successful, otherwise null.
* @since 6.4.0
* @since 6.6.0 Returns `static` instead of `self` so it can create subclass instances.
*
+ * @param string $html Input HTML fragment to process.
+ * @param string $context Context element for the fragment, must be default of ``.
+ * @param string $encoding Text encoding of the document; must be default of 'UTF-8'.
+ * @return static|null The created processor if successful, otherwise null.
*/
public static function create_fragment( $html, $context = '', $encoding = 'UTF-8' ) {
if ( '' !== $context || 'UTF-8' !== $encoding ) {
return null;
}
- $processor = new static( $html, self::CONSTRUCTOR_UNLOCK_CODE );
- $processor->state->context_node = array( 'BODY', array() );
- $processor->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY;
- $processor->state->encoding = $encoding;
- $processor->state->encoding_confidence = 'certain';
-
- // @todo Create "fake" bookmarks for non-existent but implied nodes.
- $processor->bookmarks['root-node'] = new WP_HTML_Span( 0, 0 );
- $processor->bookmarks['context-node'] = new WP_HTML_Span( 0, 0 );
-
- $root_node = new WP_HTML_Token(
- 'root-node',
- 'HTML',
- false
- );
-
- $processor->state->stack_of_open_elements->push( $root_node );
+ $context_processor = static::create_full_parser( "{$context}", $encoding );
+ if ( null === $context_processor ) {
+ return null;
+ }
- $context_node = new WP_HTML_Token(
- 'context-node',
- $processor->state->context_node[0],
- false
- );
+ while ( $context_processor->next_tag() ) {
+ if ( ! $context_processor->is_virtual() ) {
+ $context_processor->set_bookmark( 'final_node' );
+ }
+ }
- $processor->context_node = $context_node;
- $processor->breadcrumbs = array( 'HTML', $context_node->node_name );
+ if (
+ ! $context_processor->has_bookmark( 'final_node' ) ||
+ ! $context_processor->seek( 'final_node' )
+ ) {
+ _doing_it_wrong( __METHOD__, __( 'No valid context element was detected.' ), '6.8.0' );
+ return null;
+ }
- return $processor;
+ return $context_processor->create_fragment_at_current_node( $html );
}
/**
@@ -335,14 +333,13 @@ public static function create_fragment( $html, $context = '', $encoding =
* entire HTML document from start to finish. Consider a fragment parser with
* a context node of ``.
*
- * Since UTF-8 is the only currently-accepted charset, if working with a
- * document that isn't UTF-8, it's important to convert the document before
- * creating the processor: pass in the converted HTML.
+ * UTF-8 is the only allowed encoding. If working with a document that
+ * isn't UTF-8, first convert the document to UTF-8, then pass in the
+ * converted HTML.
*
- * @param string $html Input HTML document to process.
- * @param string|null $known_definite_encoding Optional. If provided, specifies the charset used
+ * @param string $html Input HTML document to process.
+ * @param string|null $known_definite_encoding Optional. If provided, specifies the charset used
* in the input byte stream. Currently must be UTF-8.
- *
* @return static|null The created processor if successful, otherwise null.
*/
public static function create_full_parser( $html, $known_definite_encoding = 'UTF-8' ) {
@@ -364,13 +361,12 @@ public static function create_full_parser( $html, $known_definite_encoding = 'UT
*
* @access private
*
- * @param string $html HTML to process.
- * @param string|null $use_the_static_create_methods_instead This constructor should not be called manually.
- *
* @since 6.4.0
*
* @see WP_HTML_Processor::create_fragment()
*
+ * @param string $html HTML to process.
+ * @param string|null $use_the_static_create_methods_instead This constructor should not be called manually.
*/
public function __construct( $html, $use_the_static_create_methods_instead = null ) {
parent::__construct( $html );
@@ -379,7 +375,7 @@ public function __construct( $html, $use_the_static_create_methods_instead = nul
_doing_it_wrong(
__METHOD__,
sprintf(
- /* translators: %s: WP_HTML_Processor::create_fragment(). */
+ /* translators: %s: WP_HTML_Processor::create_fragment(). */
__( 'Call %s to create an HTML Processor instead of calling the constructor directly.' ),
'WP_HTML_Processor::create_fragment()'
),
@@ -428,14 +424,155 @@ function ( WP_HTML_Token $token ): void {
}
/**
- * Stops the parser and terminates its execution when encountering unsupported markup.
+ * Creates a fragment processor at the current node.
+ *
+ * HTML Fragment parsing always happens with a context node. HTML Fragment Processors can be
+ * instantiated with a `BODY` context node via `WP_HTML_Processor::create_fragment( $html )`.
+ *
+ * The context node may impact how a fragment of HTML is parsed. For example, consider the HTML
+ * fragment `
Inside TD?`.
+ *
+ * A BODY context node will produce the following tree:
+ *
+ * ββ#text Inside TD?
+ *
+ * Notice that the `
` tags are completely ignored.
+ *
+ * Compare that with an SVG context node that produces the following tree:
+ *
+ * ββsvg:td
+ * ββ#text Inside TD?
+ *
+ * Here, a `td` node in the `svg` namespace is created, and its self-closing flag is respected.
+ * This is a peculiarity of parsing HTML in foreign content like SVG.
*
- * @param string $message Explains support is missing in order to parse the current node.
+ * Finally, consider the tree produced with a TABLE context node:
+ *
+ * ββTBODY
+ * ββTR
+ * ββTD
+ * ββ#text Inside TD?
+ *
+ * These examples demonstrate how important the context node may be when processing an HTML
+ * fragment. Special care must be taken when processing fragments that are expected to appear
+ * in specific contexts. SVG and TABLE are good examples, but there are others.
+ *
+ * @see https://html.spec.whatwg.org/multipage/parsing.html#html-fragment-parsing-algorithm
+ *
+ * @since 6.8.0
+ *
+ * @param string $html Input HTML fragment to process.
+ * @return static|null The created processor if successful, otherwise null.
+ */
+ private function create_fragment_at_current_node( string $html ) {
+ if ( $this->get_token_type() !== '#tag' || $this->is_tag_closer() ) {
+ _doing_it_wrong(
+ __METHOD__,
+ __( 'The context element must be a start tag.' ),
+ '6.8.0'
+ );
+ return null;
+ }
+
+ $tag_name = $this->current_element->token->node_name;
+ $namespace = $this->current_element->token->namespace;
+
+ if ( 'html' === $namespace && self::is_void( $tag_name ) ) {
+ _doing_it_wrong(
+ __METHOD__,
+ sprintf(
+ // translators: %s: A tag name like INPUT or BR.
+ __( 'The context element cannot be a void element, found "%s".' ),
+ $tag_name
+ ),
+ '6.8.0'
+ );
+ return null;
+ }
+
+ /*
+ * Prevent creating fragments at nodes that require a special tokenizer state.
+ * This is unsupported by the HTML Processor.
+ */
+ if (
+ 'html' === $namespace &&
+ in_array( $tag_name, array( 'IFRAME', 'NOEMBED', 'NOFRAMES', 'SCRIPT', 'STYLE', 'TEXTAREA', 'TITLE', 'XMP', 'PLAINTEXT' ), true )
+ ) {
+ _doing_it_wrong(
+ __METHOD__,
+ sprintf(
+ // translators: %s: A tag name like IFRAME or TEXTAREA.
+ __( 'The context element "%s" is not supported.' ),
+ $tag_name
+ ),
+ '6.8.0'
+ );
+ return null;
+ }
+
+ $fragment_processor = new static( $html, self::CONSTRUCTOR_UNLOCK_CODE );
+
+ $fragment_processor->compat_mode = $this->compat_mode;
+
+ // @todo Create "fake" bookmarks for non-existent but implied nodes.
+ $fragment_processor->bookmarks['root-node'] = new WP_HTML_Span( 0, 0 );
+ $root_node = new WP_HTML_Token(
+ 'root-node',
+ 'HTML',
+ false
+ );
+ $fragment_processor->state->stack_of_open_elements->push( $root_node );
+
+ $fragment_processor->bookmarks['context-node'] = new WP_HTML_Span( 0, 0 );
+ $fragment_processor->context_node = clone $this->current_element->token;
+ $fragment_processor->context_node->bookmark_name = 'context-node';
+ $fragment_processor->context_node->on_destroy = null;
+
+ $fragment_processor->breadcrumbs = array( 'HTML', $fragment_processor->context_node->node_name );
+
+ if ( 'TEMPLATE' === $fragment_processor->context_node->node_name ) {
+ $fragment_processor->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE;
+ }
+
+ $fragment_processor->reset_insertion_mode_appropriately();
+
+ /*
+ * > Set the parser's form element pointer to the nearest node to the context element that
+ * > is a form element (going straight up the ancestor chain, and including the element
+ * > itself, if it is a form element), if any. (If there is no such form element, the
+ * > form element pointer keeps its initial value, null.)
+ */
+ foreach ( $this->state->stack_of_open_elements->walk_up() as $element ) {
+ if ( 'FORM' === $element->node_name && 'html' === $element->namespace ) {
+ $fragment_processor->state->form_element = clone $element;
+ $fragment_processor->state->form_element->bookmark_name = null;
+ $fragment_processor->state->form_element->on_destroy = null;
+ break;
+ }
+ }
+
+ $fragment_processor->state->encoding_confidence = 'irrelevant';
+
+ /*
+ * Update the parsing namespace near the end of the process.
+ * This is important so that any push/pop from the stack of open
+ * elements does not change the parsing namespace.
+ */
+ $fragment_processor->change_parsing_namespace(
+ $this->current_element->token->integration_node_type ? 'html' : $namespace
+ );
+
+ return $fragment_processor;
+ }
+
+ /**
+ * Stops the parser and terminates its execution when encountering unsupported markup.
*
* @throws WP_HTML_Unsupported_Exception Halts execution of the parser.
*
* @since 6.7.0
*
+ * @param string $message Explains support is missing in order to parse the current node.
*/
private function bail( string $message ) {
$here = $this->bookmarks[ $this->state->current_token->bookmark_name ];
@@ -481,12 +618,12 @@ private function bail( string $message ) {
* false === $processor->next_tag();
* WP_HTML_Processor::ERROR_UNSUPPORTED === $processor->get_last_error();
*
- * @return string|null The last error, if one exists, otherwise null.
+ * @since 6.4.0
+ *
* @see self::ERROR_UNSUPPORTED
* @see self::ERROR_EXCEEDED_MAX_BOOKMARKS
*
- * @since 6.4.0
- *
+ * @return string|null The last error, if one exists, otherwise null.
*/
public function get_last_error(): ?string {
return $this->last_error;
@@ -497,11 +634,11 @@ public function get_last_error(): ?string {
*
* This is meant for debugging purposes, not for production use.
*
- * @return WP_HTML_Unsupported_Exception|null
- * @see self::$unsupported_exception
- *
* @since 6.7.0
*
+ * @see self::$unsupported_exception
+ *
+ * @return WP_HTML_Unsupported_Exception|null
*/
public function get_unsupported_exception() {
return $this->unsupported_exception;
@@ -510,26 +647,26 @@ public function get_unsupported_exception() {
/**
* Finds the next tag matching the $query.
*
- * @param array|string|null $query {
+ * @todo Support matching the class name and tag name.
+ *
+ * @since 6.4.0
+ * @since 6.6.0 Visits all tokens, including virtual ones.
+ *
+ * @throws Exception When unable to allocate a bookmark for the next token in the input HTML document.
+ *
+ * @param array|string|null $query {
* Optional. Which tag name to find, having which class, etc. Default is to find any tag.
*
- * @type string|null $tag_name Which tag to find, or `null` for "any tag."
- * @type string $tag_closers 'visit' to pause at tag closers, 'skip' or unset to only visit openers.
- * @type int|null $match_offset Find the Nth tag matching all search criteria.
+ * @type string|null $tag_name Which tag to find, or `null` for "any tag."
+ * @type string $tag_closers 'visit' to pause at tag closers, 'skip' or unset to only visit openers.
+ * @type int|null $match_offset Find the Nth tag matching all search criteria.
* 1 for "first" tag, 3 for "third," etc.
* Defaults to first tag.
- * @type string|null $class_name Tag must contain this whole class name to match.
- * @type string[] $breadcrumbs DOM sub-path at which element is found, e.g. `array( 'FIGURE', 'IMG' )`.
+ * @type string|null $class_name Tag must contain this whole class name to match.
+ * @type string[] $breadcrumbs DOM sub-path at which element is found, e.g. `array( 'FIGURE', 'IMG' )`.
* May also contain the wildcard `*` which matches a single element, e.g. `array( 'SECTION', '*' )`.
* }
* @return bool Whether a tag was matched.
- * @throws Exception When unable to allocate a bookmark for the next token in the input HTML document.
- *
- * @todo Support matching the class name and tag name.
- *
- * @since 6.4.0
- * @since 6.6.0 Visits all tokens, including virtual ones.
- *
*/
public function next_tag( $query = null ): bool {
$visit_closers = isset( $query['tag_closers'] ) && 'visit' === $query['tag_closers'];
@@ -558,10 +695,13 @@ public function next_tag( $query = null ): bool {
__( 'Please pass a query array to this function.' ),
'6.4.0'
);
-
return false;
}
+ if ( isset( $query['tag_name'] ) ) {
+ $query['tag_name'] = strtoupper( $query['tag_name'] );
+ }
+
$needs_class = ( isset( $query['class_name'] ) && is_string( $query['class_name'] ) )
? $query['class_name']
: null;
@@ -600,7 +740,7 @@ public function next_tag( $query = null ): bool {
continue;
}
- if ( $this->matches_breadcrumbs( $breadcrumbs ) && 0 === -- $match_offset ) {
+ if ( $this->matches_breadcrumbs( $breadcrumbs ) && 0 === --$match_offset ) {
return true;
}
}
@@ -608,6 +748,22 @@ public function next_tag( $query = null ): bool {
return false;
}
+ /**
+ * Finds the next token in the HTML document.
+ *
+ * This doesn't currently have a way to represent non-tags and doesn't process
+ * semantic rules for text nodes. For access to the raw tokens consider using
+ * WP_HTML_Tag_Processor instead.
+ *
+ * @since 6.5.0 Added for internal support; do not use.
+ * @since 6.7.2 Refactored so subclasses may extend.
+ *
+ * @return bool Whether a token was parsed.
+ */
+ public function next_token(): bool {
+ return $this->next_visitable_token();
+ }
+
/**
* Ensures internal accounting is maintained for HTML semantic rules while
* the underlying Tag Processor class is seeking to a bookmark.
@@ -616,13 +772,18 @@ public function next_tag( $query = null ): bool {
* semantic rules for text nodes. For access to the raw tokens consider using
* WP_HTML_Tag_Processor instead.
*
- * @return bool
- * @since 6.5.0 Added for internal support; do not use.
+ * Note that this method may call itself recursively. This is why it is not
+ * implemented as {@see WP_HTML_Processor::next_token()}, which instead calls
+ * this method similarly to how {@see WP_HTML_Tag_Processor::next_token()}
+ * calls the {@see WP_HTML_Tag_Processor::base_class_next_token()} method.
+ *
+ * @since 6.7.2 Added for internal support.
*
* @access private
*
+ * @return bool
*/
- public function next_token(): bool {
+ private function next_visitable_token(): bool {
$this->current_element = null;
if ( isset( $this->last_error ) ) {
@@ -640,7 +801,7 @@ public function next_token(): bool {
* tokens works in the meantime and isn't obviously wrong.
*/
if ( empty( $this->element_queue ) && $this->step() ) {
- return $this->next_token();
+ return $this->next_visitable_token();
}
// Process the next event on the queue.
@@ -651,7 +812,7 @@ public function next_token(): bool {
continue;
}
- return empty( $this->element_queue ) ? false : $this->next_token();
+ return empty( $this->element_queue ) ? false : $this->next_visitable_token();
}
$is_pop = WP_HTML_Stack_Event::POP === $this->current_element->operation;
@@ -662,7 +823,7 @@ public function next_token(): bool {
* the breadcrumbs.
*/
if ( 'root-node' === $this->current_element->token->bookmark_name ) {
- return $this->next_token();
+ return $this->next_visitable_token();
}
// Adjust the breadcrumbs for this event.
@@ -674,7 +835,7 @@ public function next_token(): bool {
// Avoid sending close events for elements which don't expect a closing.
if ( $is_pop && ! $this->expects_closer( $this->current_element->token ) ) {
- return $this->next_token();
+ return $this->next_visitable_token();
}
return true;
@@ -692,9 +853,9 @@ public function next_token(): bool {
* $p->next_tag( array( 'tag_name' => 'div', 'tag_closers' => 'visit' ) );
* $p->is_tag_closer() === true;
*
- * @return bool Whether the current tag is a tag closer.
* @since 6.6.0 Subclassed for HTML Processor.
*
+ * @return bool Whether the current tag is a tag closer.
*/
public function is_tag_closer(): bool {
return $this->is_virtual()
@@ -706,11 +867,11 @@ public function is_tag_closer(): bool {
* Indicates if the currently-matched token is virtual, created by a stack operation
* while processing HTML, rather than a token found in the HTML text itself.
*
- * @return bool Whether the current token is virtual.
* @since 6.6.0
*
+ * @return bool Whether the current token is virtual.
*/
- public function is_virtual(): bool {
+ private function is_virtual(): bool {
return (
isset( $this->current_element->provenance ) &&
'virtual' === $this->current_element->provenance
@@ -736,12 +897,11 @@ public function is_virtual(): bool {
* false === $processor->matches_breadcrumbs( array( 'span', 'img' ) );
* true === $processor->matches_breadcrumbs( array( 'span', '*', 'img' ) );
*
- * @param string[] $breadcrumbs DOM sub-path at which element is found, e.g. `array( 'FIGURE', 'IMG' )`.
- * May also contain the wildcard `*` which matches a single element, e.g. `array( 'SECTION', '*' )`.
- *
- * @return bool Whether the currently-matched tag is found at the given nested structure.
* @since 6.4.0
*
+ * @param string[] $breadcrumbs DOM sub-path at which element is found, e.g. `array( 'FIGURE', 'IMG' )`.
+ * May also contain the wildcard `*` which matches a single element, e.g. `array( 'SECTION', '*' )`.
+ * @return bool Whether the currently-matched tag is found at the given nested structure.
*/
public function matches_breadcrumbs( $breadcrumbs ): bool {
// Everything matches when there are zero constraints.
@@ -756,7 +916,7 @@ public function matches_breadcrumbs( $breadcrumbs ): bool {
return false;
}
- for ( $i = count( $this->breadcrumbs ) - 1; $i >= 0; $i -- ) {
+ for ( $i = count( $this->breadcrumbs ) - 1; $i >= 0; $i-- ) {
$node = $this->breadcrumbs[ $i ];
$crumb = strtoupper( current( $breadcrumbs ) );
@@ -783,13 +943,12 @@ public function matches_breadcrumbs( $breadcrumbs ): bool {
* foreign content will also act just like a void tag, immediately
* closing as soon as the processor advances to the next token.
*
- * @param WP_HTML_Token|null $node Optional. Node to examine, if provided.
- * Default is to examine current node.
+ * @since 6.6.0
*
+ * @param WP_HTML_Token|null $node Optional. Node to examine, if provided.
+ * Default is to examine current node.
* @return bool|null Whether to expect a closer for the currently-matched node,
* or `null` if not matched on any token.
- * @since 6.6.0
- *
*/
public function expects_closer( ?WP_HTML_Token $node = null ): ?bool {
$token_name = $node->node_name ?? $this->get_token_name();
@@ -807,10 +966,9 @@ public function expects_closer( ?WP_HTML_Token $node = null ): ?bool {
// Doctype declarations.
'html' === $token_name ||
// Void elements.
- self::is_void( $token_name ) ||
+ ( 'html' === $token_namespace && self::is_void( $token_name ) ) ||
// Special atomic elements.
- ( 'html' === $token_namespace && in_array( $token_name,
- array( 'IFRAME', 'NOEMBED', 'NOFRAMES', 'SCRIPT', 'STYLE', 'TEXTAREA', 'TITLE', 'XMP' ), true ) ) ||
+ ( 'html' === $token_namespace && in_array( $token_name, array( 'IFRAME', 'NOEMBED', 'NOFRAMES', 'SCRIPT', 'STYLE', 'TEXTAREA', 'TITLE', 'XMP' ), true ) ) ||
// Self-closing elements in foreign content.
( 'html' !== $token_namespace && $token_has_self_closing )
);
@@ -819,16 +977,15 @@ public function expects_closer( ?WP_HTML_Token $node = null ): ?bool {
/**
* Steps through the HTML document and stop at the next tag, if any.
*
- * @param string $node_to_process Whether to parse the next node or reprocess the current node.
+ * @since 6.4.0
*
- * @return bool Whether a tag was matched.
* @throws Exception When unable to allocate a bookmark for the next token in the input HTML document.
*
+ * @see self::PROCESS_NEXT_NODE
* @see self::REPROCESS_CURRENT_NODE
*
- * @since 6.4.0
- *
- * @see self::PROCESS_NEXT_NODE
+ * @param string $node_to_process Whether to parse the next node or reprocess the current node.
+ * @return bool Whether a tag was matched.
*/
public function step( $node_to_process = self::PROCESS_NEXT_NODE ): bool {
// Refuse to proceed if there was a previous error.
@@ -993,21 +1150,17 @@ public function step( $node_to_process = self::PROCESS_NEXT_NODE ): bool {
* Breadcrumbs start at the outermost parent and descend toward the matched element.
* They always include the entire path from the root HTML node to the matched element.
*
- * @return string[]|null Array of tag names representing path to matched node, if matched, otherwise NULL.
- * @since 6.4.0
- *
- * @todo It could be more efficient to expose a generator-based version of this function
- * to avoid creating the array copy on tag iteration. If this is done, it would likely
- * be more useful to walk up the stack when yielding instead of starting at the top.
- *
- * Example
+ * Example:
*
* $processor = WP_HTML_Processor::create_fragment( '
' );
* $processor->next_tag( 'IMG' );
* $processor->get_breadcrumbs() === array( 'HTML', 'BODY', 'P', 'STRONG', 'EM', 'IMG' );
*
+ * @since 6.4.0
+ *
+ * @return string[] Array of tag names representing path to matched node.
*/
- public function get_breadcrumbs(): ?array {
+ public function get_breadcrumbs(): array {
return $this->breadcrumbs;
}
@@ -1032,9 +1185,9 @@ public function get_breadcrumbs(): ?array {
* $processor->next_token();
* 3 === $processor->get_current_depth();
*
- * @return int Nesting-depth of current location in the document.
* @since 6.6.0
*
+ * @return int Nesting-depth of current location in the document.
*/
public function get_current_depth(): int {
return count( $this->breadcrumbs );
@@ -1072,11 +1225,11 @@ public function get_current_depth(): int {
* echo WP_HTML_Processor::normalize( ' syntax < <> "oddities"' );
* // syntax < <> "oddities"
*
- * @param string $html Input HTML to normalize.
- *
- * @return string|null Normalized output, or `null` if unable to normalize.
* @since 6.7.0
*
+ * @param string $html Input HTML to normalize.
+ *
+ * @return string|null Normalized output, or `null` if unable to normalize.
*/
public static function normalize( string $html ): ?string {
return static::create_fragment( $html )->serialize();
@@ -1116,10 +1269,10 @@ public static function normalize( string $html ): ?string {
* echo $processor->serialize();
* // syntax < <> "oddities"
*
- * @return string|null Normalized HTML markup represented by processor,
- * or `null` if unable to generate serialization.
* @since 6.7.0
*
+ * @return string|null Normalized HTML markup represented by processor,
+ * or `null` if unable to generate serialization.
*/
public function serialize(): ?string {
if ( WP_HTML_Tag_Processor::STATE_READY !== $this->parser_state ) {
@@ -1128,7 +1281,6 @@ public function serialize(): ?string {
'An HTML Processor which has already started processing cannot serialize its contents. Serialize immediately after creating the instance.',
E_USER_WARNING
);
-
return null;
}
@@ -1143,7 +1295,6 @@ public function serialize(): ?string {
"Cannot serialize HTML Processor with parsing error: {$this->get_last_error()}.",
E_USER_WARNING
);
-
return null;
}
@@ -1157,11 +1308,11 @@ public function serialize(): ?string {
* if able. If not matched at any token or if the token doesn't correspond to any HTML
* it will return an empty string (for example, presumptuous end tags are ignored).
*
- * @return string Serialization of token, or empty string if no serialization exists.
- * @since 6.7.0
- *
* @see static::serialize()
*
+ * @since 6.7.0
+ *
+ * @return string Serialization of token, or empty string if no serialization exists.
*/
protected function serialize_token(): string {
$html = '';
@@ -1181,15 +1332,15 @@ protected function serialize_token(): string {
}
if ( null !== $doctype->public_identifier ) {
- $quote = strpos( $doctype->public_identifier, '"' ) !== false ? "'" : '"';
- $html .= " PUBLIC {$quote}{$doctype->public_identifier}{$quote}";
+ $quote = str_contains( $doctype->public_identifier, '"' ) ? "'" : '"';
+ $html .= " PUBLIC {$quote}{$doctype->public_identifier}{$quote}";
}
if ( null !== $doctype->system_identifier ) {
if ( null === $doctype->public_identifier ) {
$html .= ' SYSTEM';
}
- $quote = strpos( $doctype->system_identifier, '"' ) !== false ? "'" : '"';
- $html .= " {$quote}{$doctype->system_identifier}{$quote}";
+ $quote = str_contains( $doctype->system_identifier, '"' ) ? "'" : '"';
+ $html .= " {$quote}{$doctype->system_identifier}{$quote}";
}
$html .= '>';
@@ -1223,20 +1374,18 @@ protected function serialize_token(): string {
if ( $this->is_tag_closer() ) {
$html .= "{$qualified_name}>";
-
return $html;
}
$attribute_names = $this->get_attribute_names_with_prefix( '' );
if ( ! isset( $attribute_names ) ) {
$html .= "<{$qualified_name}>";
-
return $html;
}
$html .= "<{$qualified_name}";
foreach ( $attribute_names as $attribute_name ) {
- $html .= " {$this->get_qualified_attribute_name( $attribute_name )}";
+ $html .= " {$this->get_qualified_attribute_name( $attribute_name )}";
$value = $this->get_attribute( $attribute_name );
if ( is_string( $value ) ) {
@@ -1253,8 +1402,7 @@ protected function serialize_token(): string {
$html .= '>';
// Flush out self-contained elements.
- if ( $in_html && in_array( $tag_name, array( 'IFRAME', 'NOEMBED', 'NOFRAMES', 'SCRIPT', 'STYLE', 'TEXTAREA', 'TITLE', 'XMP' ),
- true ) ) {
+ if ( $in_html && in_array( $tag_name, array( 'IFRAME', 'NOEMBED', 'NOFRAMES', 'SCRIPT', 'STYLE', 'TEXTAREA', 'TITLE', 'XMP' ), true ) ) {
$text = $this->get_modifiable_text();
switch ( $tag_name ) {
@@ -1284,14 +1432,14 @@ protected function serialize_token(): string {
* This internal function performs the 'initial' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#the-initial-insertion-mode
* @see WP_HTML_Processor::step
*
- * @since 6.7.0
- *
+ * @return bool Whether an element was found.
*/
private function step_initial(): bool {
$token_name = $this->get_token_name();
@@ -1321,7 +1469,6 @@ private function step_initial(): bool {
case '#funky-comment':
case '#presumptuous-tag':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -1338,7 +1485,6 @@ private function step_initial(): bool {
*/
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HTML;
$this->insert_html_element( $this->state->current_token );
-
return true;
}
@@ -1348,7 +1494,6 @@ private function step_initial(): bool {
initial_anything_else:
$this->compat_mode = WP_HTML_Tag_Processor::QUIRKS_MODE;
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HTML;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
}
@@ -1358,14 +1503,14 @@ private function step_initial(): bool {
* This internal function performs the 'before html' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#the-before-html-insertion-mode
* @see WP_HTML_Processor::step
*
- * @since 6.7.0
- *
+ * @return bool Whether an element was found.
*/
private function step_before_html(): bool {
$token_name = $this->get_token_name();
@@ -1389,7 +1534,6 @@ private function step_before_html(): bool {
case '#funky-comment':
case '#presumptuous-tag':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -1412,7 +1556,6 @@ private function step_before_html(): bool {
case '+HTML':
$this->insert_html_element( $this->state->current_token );
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HEAD;
-
return true;
/*
@@ -1448,7 +1591,6 @@ private function step_before_html(): bool {
before_html_anything_else:
$this->insert_virtual_node( 'HTML' );
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_BEFORE_HEAD;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
}
@@ -1458,14 +1600,14 @@ private function step_before_html(): bool {
* This internal function performs the 'before head' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0 Stub implementation.
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#the-before-head-insertion-mode
* @see WP_HTML_Processor::step
*
- * @since 6.7.0 Stub implementation.
- *
+ * @return bool Whether an element was found.
*/
private function step_before_head(): bool {
$token_name = $this->get_token_name();
@@ -1496,7 +1638,6 @@ private function step_before_head(): bool {
case '#funky-comment':
case '#presumptuous-tag':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -1519,7 +1660,6 @@ private function step_before_head(): bool {
$this->insert_html_element( $this->state->current_token );
$this->state->head_element = $this->state->current_token;
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD;
-
return true;
/*
@@ -1548,7 +1688,6 @@ private function step_before_head(): bool {
before_head_anything_else:
$this->state->head_element = $this->insert_virtual_node( 'HEAD' );
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
}
@@ -1558,14 +1697,14 @@ private function step_before_head(): bool {
* This internal function performs the 'in head' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @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-inhead
* @see WP_HTML_Processor::step
*
- * @since 6.7.0
- *
+ * @return bool Whether an element was found.
*/
private function step_in_head(): bool {
$token_name = $this->get_token_name();
@@ -1584,7 +1723,6 @@ private function step_in_head(): bool {
if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) {
// Insert the character.
$this->insert_html_element( $this->state->current_token );
-
return true;
}
@@ -1598,7 +1736,6 @@ private function step_in_head(): bool {
case '#funky-comment':
case '#presumptuous-tag':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -1622,7 +1759,6 @@ private function step_in_head(): bool {
case '+BGSOUND':
case '+LINK':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -1668,7 +1804,6 @@ private function step_in_head(): bool {
*/
case '+TITLE':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -1680,7 +1815,6 @@ private function step_in_head(): bool {
case '+NOFRAMES':
case '+STYLE':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -1689,7 +1823,6 @@ private function step_in_head(): bool {
case '+NOSCRIPT':
$this->insert_html_element( $this->state->current_token );
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD_NOSCRIPT;
-
return true;
/*
@@ -1699,7 +1832,6 @@ private function step_in_head(): bool {
*/
case '+SCRIPT':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -1708,7 +1840,6 @@ private function step_in_head(): bool {
case '-HEAD':
$this->state->stack_of_open_elements->pop();
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_HEAD;
-
return true;
/*
@@ -1737,7 +1868,6 @@ private function step_in_head(): bool {
$this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE;
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -1758,7 +1888,6 @@ private function step_in_head(): bool {
$this->state->active_formatting_elements->clear_up_to_last_marker();
array_pop( $this->state->stack_of_template_insertion_modes );
$this->reset_insertion_mode_appropriately();
-
return true;
}
@@ -1777,7 +1906,6 @@ private function step_in_head(): bool {
in_head_anything_else:
$this->state->stack_of_open_elements->pop();
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_HEAD;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
}
@@ -1787,14 +1915,14 @@ private function step_in_head(): bool {
* This internal function performs the 'in head noscript' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0 Stub implementation.
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#parsing-main-inheadnoscript
* @see WP_HTML_Processor::step
*
- * @since 6.7.0 Stub implementation.
- *
+ * @return bool Whether an element was found.
*/
private function step_in_head_noscript(): bool {
$token_name = $this->get_token_name();
@@ -1838,7 +1966,6 @@ private function step_in_head_noscript(): bool {
case '-NOSCRIPT':
$this->state->stack_of_open_elements->pop();
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD;
-
return true;
/*
@@ -1857,6 +1984,7 @@ private function step_in_head_noscript(): bool {
case '+NOFRAMES':
case '+STYLE':
return $this->step_in_head();
+
/*
* > An end tag whose tag name is "br"
*
@@ -1881,7 +2009,6 @@ private function step_in_head_noscript(): bool {
in_head_noscript_anything_else:
$this->state->stack_of_open_elements->pop();
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
}
@@ -1891,14 +2018,14 @@ private function step_in_head_noscript(): bool {
* This internal function performs the 'after head' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0 Stub implementation.
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#the-after-head-insertion-mode
* @see WP_HTML_Processor::step
*
- * @since 6.7.0 Stub implementation.
- *
+ * @return bool Whether an element was found.
*/
private function step_after_head(): bool {
$token_name = $this->get_token_name();
@@ -1917,7 +2044,6 @@ private function step_after_head(): bool {
if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) {
// Insert the character.
$this->insert_html_element( $this->state->current_token );
-
return true;
}
goto after_head_anything_else;
@@ -1930,7 +2056,6 @@ private function step_after_head(): bool {
case '#funky-comment':
case '#presumptuous-tag':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -1953,7 +2078,6 @@ private function step_after_head(): bool {
$this->insert_html_element( $this->state->current_token );
$this->state->frameset_ok = false;
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY;
-
return true;
/*
@@ -1962,7 +2086,6 @@ private function step_after_head(): bool {
case '+FRAMESET':
$this->insert_html_element( $this->state->current_token );
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_FRAMESET;
-
return true;
/*
@@ -2030,7 +2153,6 @@ private function step_after_head(): bool {
after_head_anything_else:
$this->insert_virtual_node( 'BODY' );
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
}
@@ -2040,14 +2162,14 @@ private function step_after_head(): bool {
* This internal function performs the 'in body' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.4.0
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#parsing-main-inbody
* @see WP_HTML_Processor::step
*
- * @since 6.4.0
- *
+ * @return bool Whether an element was found.
*/
private function step_in_body(): bool {
$token_name = $this->get_token_name();
@@ -2083,14 +2205,12 @@ private function step_in_body(): bool {
}
$this->insert_html_element( $this->state->current_token );
-
return true;
case '#comment':
case '#funky-comment':
case '#presumptuous-tag':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -2160,7 +2280,6 @@ private function step_in_body(): bool {
* This parser does not currently support this behavior: ignore the token.
*/
$this->state->frameset_ok = false;
-
return $this->step();
/*
@@ -2204,8 +2323,14 @@ private function step_in_body(): bool {
*/
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_BODY;
-
- return true;
+ /*
+ * The BODY element is not removed from the stack of open elements.
+ * Only internal state has changed, this does not qualify as a "step"
+ * in terms of advancing through the document to another token.
+ * Nothing has been pushed or popped.
+ * Proceed to parse the next item.
+ */
+ return $this->step();
/*
* > An end tag whose tag name is "html"
@@ -2227,7 +2352,6 @@ private function step_in_body(): bool {
*/
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_BODY;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
/*
@@ -2266,7 +2390,6 @@ private function step_in_body(): bool {
}
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -2294,7 +2417,6 @@ private function step_in_body(): bool {
}
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -2316,7 +2438,6 @@ private function step_in_body(): bool {
$this->insert_html_element( $this->state->current_token );
$this->state->frameset_ok = false;
-
return true;
/*
@@ -2397,7 +2518,6 @@ private function step_in_body(): bool {
}
$this->insert_html_element( $this->state->current_token );
-
return true;
case '+PLAINTEXT':
@@ -2473,7 +2593,6 @@ private function step_in_body(): bool {
// @todo Record parse error: this error doesn't impact parsing.
}
$this->state->stack_of_open_elements->pop_until( $token_name );
-
return true;
/*
@@ -2506,7 +2625,6 @@ private function step_in_body(): bool {
}
$this->state->stack_of_open_elements->remove_node( $node );
-
return true;
} else {
/*
@@ -2527,7 +2645,6 @@ private function step_in_body(): bool {
}
$this->state->stack_of_open_elements->pop_until( 'FORM' );
-
return true;
}
break;
@@ -2541,7 +2658,6 @@ private function step_in_body(): bool {
}
$this->close_a_p_element();
-
return true;
/*
@@ -2587,7 +2703,6 @@ private function step_in_body(): bool {
}
$this->state->stack_of_open_elements->pop_until( $token_name );
-
return true;
/*
@@ -2615,7 +2730,6 @@ private function step_in_body(): bool {
}
$this->state->stack_of_open_elements->pop_until( '(internal: H1 through H6 - do not use)' );
-
return true;
/*
@@ -2638,7 +2752,6 @@ private function step_in_body(): bool {
$this->reconstruct_active_formatting_elements();
$this->insert_html_element( $this->state->current_token );
$this->state->active_formatting_elements->push( $this->state->current_token );
-
return true;
/*
@@ -2660,7 +2773,6 @@ private function step_in_body(): bool {
$this->reconstruct_active_formatting_elements();
$this->insert_html_element( $this->state->current_token );
$this->state->active_formatting_elements->push( $this->state->current_token );
-
return true;
/*
@@ -2677,7 +2789,6 @@ private function step_in_body(): bool {
$this->insert_html_element( $this->state->current_token );
$this->state->active_formatting_elements->push( $this->state->current_token );
-
return true;
/*
@@ -2699,7 +2810,6 @@ private function step_in_body(): bool {
case '-TT':
case '-U':
$this->run_adoption_agency_algorithm();
-
return true;
/*
@@ -2712,7 +2822,6 @@ private function step_in_body(): bool {
$this->insert_html_element( $this->state->current_token );
$this->state->active_formatting_elements->insert_marker();
$this->state->frameset_ok = false;
-
return true;
/*
@@ -2733,7 +2842,6 @@ private function step_in_body(): bool {
$this->state->stack_of_open_elements->pop_until( $token_name );
$this->state->active_formatting_elements->clear_up_to_last_marker();
-
return true;
/*
@@ -2754,7 +2862,6 @@ private function step_in_body(): bool {
$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;
/*
@@ -2776,7 +2883,6 @@ private function step_in_body(): bool {
$this->reconstruct_active_formatting_elements();
$this->insert_html_element( $this->state->current_token );
$this->state->frameset_ok = false;
-
return true;
/*
@@ -2805,7 +2911,6 @@ private function step_in_body(): bool {
case '+SOURCE':
case '+TRACK':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -2817,7 +2922,6 @@ private function step_in_body(): bool {
}
$this->insert_html_element( $this->state->current_token );
$this->state->frameset_ok = false;
-
return true;
/*
@@ -2853,7 +2957,6 @@ private function step_in_body(): bool {
*
* As a self-contained node, this behavior is handled in the Tag Processor.
*/
-
return true;
/*
@@ -2873,7 +2976,6 @@ private function step_in_body(): bool {
* As a self-contained node, this behavior is handled in the Tag Processor.
*/
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -2888,7 +2990,6 @@ private function step_in_body(): bool {
* As a self-contained node, this behavior is handled in the Tag Processor.
*/
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -2899,7 +3000,6 @@ private function step_in_body(): bool {
*/
case '+NOEMBED':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -2930,7 +3030,6 @@ private function step_in_body(): bool {
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_SELECT;
break;
}
-
return true;
/*
@@ -2943,7 +3042,6 @@ private function step_in_body(): bool {
}
$this->reconstruct_active_formatting_elements();
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -2960,7 +3058,6 @@ private function step_in_body(): bool {
}
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -2978,7 +3075,6 @@ private function step_in_body(): bool {
}
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -2998,7 +3094,6 @@ private function step_in_body(): bool {
if ( $this->state->current_token->has_self_closing_flag ) {
$this->state->stack_of_open_elements->pop();
}
-
return true;
/*
@@ -3018,7 +3113,6 @@ private function step_in_body(): bool {
if ( $this->state->current_token->has_self_closing_flag ) {
$this->state->stack_of_open_elements->pop();
}
-
return true;
/*
@@ -3046,7 +3140,6 @@ private function step_in_body(): bool {
*/
$this->reconstruct_active_formatting_elements();
$this->insert_html_element( $this->state->current_token );
-
return true;
} else {
/*
@@ -3084,7 +3177,6 @@ private function step_in_body(): bool {
}
$this->bail( 'Should not have been able to reach end of IN BODY processing. Check HTML API code.' );
-
// This unnecessary return prevents tools from inaccurately reporting type errors.
return false;
}
@@ -3095,14 +3187,14 @@ private function step_in_body(): bool {
* This internal function performs the 'in table' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#parsing-main-intable
* @see WP_HTML_Processor::step
*
- * @since 6.7.0
- *
+ * @return bool Whether an element was found.
*/
private function step_in_table(): bool {
$token_name = $this->get_token_name();
@@ -3157,7 +3249,6 @@ private function step_in_table(): bool {
*/
if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) {
$this->insert_html_element( $this->state->current_token );
-
return true;
}
@@ -3174,7 +3265,6 @@ private function step_in_table(): bool {
case '#funky-comment':
case '#presumptuous-tag':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -3192,7 +3282,6 @@ private function step_in_table(): bool {
$this->state->active_formatting_elements->insert_marker();
$this->insert_html_element( $this->state->current_token );
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION;
-
return true;
/*
@@ -3202,7 +3291,6 @@ private function step_in_table(): bool {
$this->state->stack_of_open_elements->clear_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;
/*
@@ -3217,7 +3305,6 @@ private function step_in_table(): bool {
*/
$this->insert_virtual_node( 'COLGROUP' );
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
/*
@@ -3229,7 +3316,6 @@ private function step_in_table(): bool {
$this->state->stack_of_open_elements->clear_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;
/*
@@ -3245,7 +3331,6 @@ private function step_in_table(): bool {
*/
$this->insert_virtual_node( 'TBODY' );
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
/*
@@ -3260,7 +3345,6 @@ private function step_in_table(): bool {
$this->state->stack_of_open_elements->pop_until( 'TABLE' );
$this->reset_insertion_mode_appropriately();
-
return $this->step( self::REPROCESS_CURRENT_NODE );
/*
@@ -3274,7 +3358,6 @@ private function step_in_table(): bool {
$this->state->stack_of_open_elements->pop_until( 'TABLE' );
$this->reset_insertion_mode_appropriately();
-
return true;
/*
@@ -3321,7 +3404,6 @@ private function step_in_table(): bool {
}
// @todo Indicate a parse error once it's possible.
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -3341,7 +3423,6 @@ private function step_in_table(): bool {
$this->insert_html_element( $this->state->current_token );
$this->state->form_element = $this->state->current_token;
$this->state->stack_of_open_elements->pop();
-
return true;
}
@@ -3362,14 +3443,14 @@ private function step_in_table(): bool {
* This internal function performs the 'in table text' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0 Stub implementation.
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#parsing-main-intabletext
* @see WP_HTML_Processor::step
*
- * @since 6.7.0 Stub implementation.
- *
+ * @return bool Whether an element was found.
*/
private function step_in_table_text(): bool {
$this->bail( 'No support for parsing in the ' . WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_TEXT . ' state.' );
@@ -3381,14 +3462,14 @@ private function step_in_table_text(): bool {
* This internal function performs the 'in caption' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#parsing-main-incaption
* @see WP_HTML_Processor::step
*
- * @since 6.7.0
- *
+ * @return bool Whether an element was found.
*/
private function step_in_caption(): bool {
$tag_name = $this->get_tag();
@@ -3433,7 +3514,6 @@ private function step_in_caption(): bool {
if ( '-CAPTION' === $op ) {
return true;
}
-
return $this->step( self::REPROCESS_CURRENT_NODE );
/**
@@ -3466,14 +3546,14 @@ private function step_in_caption(): bool {
* This internal function performs the 'in column group' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#parsing-main-incolgroup
* @see WP_HTML_Processor::step
*
- * @since 6.7.0
- *
+ * @return bool Whether an element was found.
*/
private function step_in_column_group(): bool {
$token_name = $this->get_token_name();
@@ -3490,7 +3570,6 @@ private function step_in_column_group(): bool {
if ( parent::TEXT_IS_WHITESPACE === $this->text_node_classification ) {
// Insert the character.
$this->insert_html_element( $this->state->current_token );
-
return true;
}
@@ -3504,7 +3583,6 @@ private function step_in_column_group(): bool {
case '#funky-comment':
case '#presumptuous-tag':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -3526,7 +3604,6 @@ private function step_in_column_group(): bool {
case '+COL':
$this->insert_html_element( $this->state->current_token );
$this->state->stack_of_open_elements->pop();
-
return true;
/*
@@ -3539,7 +3616,6 @@ private function step_in_column_group(): bool {
}
$this->state->stack_of_open_elements->pop();
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE;
-
return true;
/*
@@ -3568,7 +3644,6 @@ private function step_in_column_group(): bool {
}
$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 );
}
@@ -3578,14 +3653,14 @@ private function step_in_column_group(): bool {
* This internal function performs the 'in table body' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#parsing-main-intbody
* @see WP_HTML_Processor::step
*
- * @since 6.7.0
- *
+ * @return bool Whether an element was found.
*/
private function step_in_table_body(): bool {
$tag_name = $this->get_tag();
@@ -3600,7 +3675,6 @@ private function step_in_table_body(): bool {
$this->state->stack_of_open_elements->clear_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;
/*
@@ -3612,7 +3686,6 @@ private function step_in_table_body(): bool {
$this->state->stack_of_open_elements->clear_to_table_body_context();
$this->insert_virtual_node( 'TR' );
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
/*
@@ -3629,7 +3702,6 @@ private function step_in_table_body(): bool {
$this->state->stack_of_open_elements->clear_to_table_body_context();
$this->state->stack_of_open_elements->pop();
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE;
-
return true;
/*
@@ -3654,7 +3726,6 @@ private function step_in_table_body(): bool {
$this->state->stack_of_open_elements->clear_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 );
/*
@@ -3676,7 +3747,6 @@ private function step_in_table_body(): bool {
* > Anything else
* > Process the token using the rules for the "in table" insertion mode.
*/
-
return $this->step_in_table();
}
@@ -3686,14 +3756,14 @@ private function step_in_table_body(): bool {
* This internal function performs the 'in row' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#parsing-main-intr
* @see WP_HTML_Processor::step
*
- * @since 6.7.0
- *
+ * @return bool Whether an element was found.
*/
private function step_in_row(): bool {
$tag_name = $this->get_tag();
@@ -3710,7 +3780,6 @@ private function step_in_row(): bool {
$this->insert_html_element( $this->state->current_token );
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_CELL;
$this->state->active_formatting_elements->insert_marker();
-
return true;
/*
@@ -3725,7 +3794,6 @@ private function step_in_row(): bool {
$this->state->stack_of_open_elements->clear_to_table_row_context();
$this->state->stack_of_open_elements->pop();
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY;
-
return true;
/*
@@ -3748,7 +3816,6 @@ private function step_in_row(): bool {
$this->state->stack_of_open_elements->clear_to_table_row_context();
$this->state->stack_of_open_elements->pop();
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
/*
@@ -3770,7 +3837,6 @@ private function step_in_row(): bool {
$this->state->stack_of_open_elements->clear_to_table_row_context();
$this->state->stack_of_open_elements->pop();
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
/*
@@ -3791,7 +3857,6 @@ private function step_in_row(): bool {
* > Anything else
* > Process the token using the rules for the "in table" insertion mode.
*/
-
return $this->step_in_table();
}
@@ -3801,14 +3866,14 @@ private function step_in_row(): bool {
* This internal function performs the 'in cell' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#parsing-main-intd
* @see WP_HTML_Processor::step
*
- * @since 6.7.0
- *
+ * @return bool Whether an element was found.
*/
private function step_in_cell(): bool {
$tag_name = $this->get_tag();
@@ -3841,7 +3906,6 @@ private function step_in_cell(): bool {
$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;
/*
@@ -3864,7 +3928,6 @@ private function step_in_cell(): bool {
*/
$this->close_cell();
-
return $this->step( self::REPROCESS_CURRENT_NODE );
/*
@@ -3891,7 +3954,6 @@ private function step_in_cell(): bool {
return $this->step();
}
$this->close_cell();
-
return $this->step( self::REPROCESS_CURRENT_NODE );
}
@@ -3899,7 +3961,6 @@ private function step_in_cell(): bool {
* > Anything else
* > Process the token using the rules for the "in body" insertion mode.
*/
-
return $this->step_in_body();
}
@@ -3909,14 +3970,14 @@ private function step_in_cell(): bool {
* This internal function performs the 'in select' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @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-inselect
* @see WP_HTML_Processor::step
*
- * @since 6.7.0
- *
+ * @return bool Whether an element was found.
*/
private function step_in_select(): bool {
$token_name = $this->get_token_name();
@@ -3941,7 +4002,6 @@ private function step_in_select(): bool {
}
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -3951,7 +4011,6 @@ private function step_in_select(): bool {
case '#funky-comment':
case '#presumptuous-tag':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -3975,7 +4034,6 @@ private function step_in_select(): bool {
$this->state->stack_of_open_elements->pop();
}
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -3996,7 +4054,6 @@ private function step_in_select(): bool {
}
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -4015,7 +4072,6 @@ private function step_in_select(): bool {
if ( $this->state->stack_of_open_elements->current_node_is( 'OPTGROUP' ) ) {
$this->state->stack_of_open_elements->pop();
-
return true;
}
@@ -4028,7 +4084,6 @@ private function step_in_select(): bool {
case '-OPTION':
if ( $this->state->stack_of_open_elements->current_node_is( 'OPTION' ) ) {
$this->state->stack_of_open_elements->pop();
-
return true;
}
@@ -4049,7 +4104,6 @@ private function step_in_select(): bool {
}
$this->state->stack_of_open_elements->pop_until( 'SELECT' );
$this->reset_insertion_mode_appropriately();
-
return true;
/*
@@ -4066,7 +4120,6 @@ private function step_in_select(): bool {
}
$this->state->stack_of_open_elements->pop_until( 'SELECT' );
$this->reset_insertion_mode_appropriately();
-
return $this->step( self::REPROCESS_CURRENT_NODE );
/*
@@ -4083,7 +4136,6 @@ private function step_in_select(): bool {
* > Anything else
* > Parse error: ignore the token.
*/
-
return $this->step();
}
@@ -4093,14 +4145,14 @@ private function step_in_select(): bool {
* This internal function performs the 'in select in table' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#parsing-main-inselectintable
* @see WP_HTML_Processor::step
*
- * @since 6.7.0
- *
+ * @return bool Whether an element was found.
*/
private function step_in_select_in_table(): bool {
$token_name = $this->get_token_name();
@@ -4123,7 +4175,6 @@ private function step_in_select_in_table(): bool {
// @todo Indicate a parse error once it's possible.
$this->state->stack_of_open_elements->pop_until( 'SELECT' );
$this->reset_insertion_mode_appropriately();
-
return $this->step( self::REPROCESS_CURRENT_NODE );
/*
@@ -4143,14 +4194,12 @@ private function step_in_select_in_table(): bool {
}
$this->state->stack_of_open_elements->pop_until( 'SELECT' );
$this->reset_insertion_mode_appropriately();
-
return $this->step( self::REPROCESS_CURRENT_NODE );
}
/*
* > Anything else
*/
-
return $this->step_in_select();
}
@@ -4160,14 +4209,14 @@ private function step_in_select_in_table(): bool {
* This internal function performs the 'in template' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0 Stub implementation.
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#parsing-main-intemplate
* @see WP_HTML_Processor::step
*
- * @since 6.7.0 Stub implementation.
- *
+ * @return bool Whether an element was found.
*/
private function step_in_template(): bool {
$token_name = $this->get_token_name();
@@ -4218,7 +4267,6 @@ private function step_in_template(): bool {
array_pop( $this->state->stack_of_template_insertion_modes );
$this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE;
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
/*
@@ -4228,7 +4276,6 @@ private function step_in_template(): bool {
array_pop( $this->state->stack_of_template_insertion_modes );
$this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP;
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
/*
@@ -4238,7 +4285,6 @@ private function step_in_template(): bool {
array_pop( $this->state->stack_of_template_insertion_modes );
$this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_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 );
/*
@@ -4249,7 +4295,6 @@ private function step_in_template(): bool {
array_pop( $this->state->stack_of_template_insertion_modes );
$this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW;
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_ROW;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
}
@@ -4260,7 +4305,6 @@ private function step_in_template(): bool {
array_pop( $this->state->stack_of_template_insertion_modes );
$this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY;
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
}
@@ -4285,7 +4329,6 @@ private function step_in_template(): bool {
$this->state->active_formatting_elements->clear_up_to_last_marker();
array_pop( $this->state->stack_of_template_insertion_modes );
$this->reset_insertion_mode_appropriately();
-
return $this->step( self::REPROCESS_CURRENT_NODE );
}
@@ -4295,14 +4338,14 @@ private function step_in_template(): bool {
* This internal function performs the 'after body' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0 Stub implementation.
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#parsing-main-afterbody
* @see WP_HTML_Processor::step
*
- * @since 6.7.0 Stub implementation.
- *
+ * @return bool Whether an element was found.
*/
private function step_after_body(): bool {
$tag_name = $this->get_token_name();
@@ -4360,8 +4403,14 @@ private function step_after_body(): bool {
}
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_AFTER_BODY;
-
- return true;
+ /*
+ * The HTML element is not removed from the stack of open elements.
+ * Only internal state has changed, this does not qualify as a "step"
+ * in terms of advancing through the document to another token.
+ * Nothing has been pushed or popped.
+ * Proceed to parse the next item.
+ */
+ return $this->step();
}
/*
@@ -4369,7 +4418,6 @@ private function step_after_body(): bool {
*/
after_body_anything_else:
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
}
@@ -4379,14 +4427,14 @@ private function step_after_body(): bool {
* This internal function performs the 'in frameset' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0 Stub implementation.
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#parsing-main-inframeset
* @see WP_HTML_Processor::step
*
- * @since 6.7.0 Stub implementation.
- *
+ * @return bool Whether an element was found.
*/
private function step_in_frameset(): bool {
$tag_name = $this->get_token_name();
@@ -4418,7 +4466,6 @@ private function step_in_frameset(): bool {
case '#funky-comment':
case '#presumptuous-tag':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -4439,7 +4486,6 @@ private function step_in_frameset(): bool {
*/
case '+FRAMESET':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -4481,7 +4527,6 @@ private function step_in_frameset(): bool {
case '+FRAME':
$this->insert_html_element( $this->state->current_token );
$this->state->stack_of_open_elements->pop();
-
return true;
/*
@@ -4501,14 +4546,14 @@ private function step_in_frameset(): bool {
* This internal function performs the 'after frameset' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0 Stub implementation.
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#parsing-main-afterframeset
* @see WP_HTML_Processor::step
*
- * @since 6.7.0 Stub implementation.
- *
+ * @return bool Whether an element was found.
*/
private function step_after_frameset(): bool {
$tag_name = $this->get_token_name();
@@ -4540,7 +4585,6 @@ private function step_after_frameset(): bool {
case '#funky-comment':
case '#presumptuous-tag':
$this->insert_html_element( $this->state->current_token );
-
return true;
/*
@@ -4561,8 +4605,14 @@ private function step_after_frameset(): bool {
*/
case '-HTML':
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_AFTER_AFTER_FRAMESET;
-
- return true;
+ /*
+ * The HTML element is not removed from the stack of open elements.
+ * Only internal state has changed, this does not qualify as a "step"
+ * in terms of advancing through the document to another token.
+ * Nothing has been pushed or popped.
+ * Proceed to parse the next item.
+ */
+ return $this->step();
/*
* > A start tag whose tag name is "noframes"
@@ -4581,14 +4631,14 @@ private function step_after_frameset(): bool {
* This internal function performs the 'after after body' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0 Stub implementation.
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#the-after-after-body-insertion-mode
* @see WP_HTML_Processor::step
*
- * @since 6.7.0 Stub implementation.
- *
+ * @return bool Whether an element was found.
*/
private function step_after_after_body(): bool {
$tag_name = $this->get_token_name();
@@ -4635,7 +4685,6 @@ private function step_after_after_body(): bool {
*/
after_after_body_anything_else:
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY;
-
return $this->step( self::REPROCESS_CURRENT_NODE );
}
@@ -4645,14 +4694,14 @@ private function step_after_after_body(): bool {
* This internal function performs the 'after after frameset' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0 Stub implementation.
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#the-after-after-frameset-insertion-mode
* @see WP_HTML_Processor::step
*
- * @since 6.7.0 Stub implementation.
- *
+ * @return bool Whether an element was found.
*/
private function step_after_after_frameset(): bool {
$tag_name = $this->get_token_name();
@@ -4713,14 +4762,14 @@ private function step_after_after_frameset(): bool {
* This internal function performs the 'in foreign content' insertion mode
* logic for the generalized WP_HTML_Processor::step() function.
*
- * @return bool Whether an element was found.
+ * @since 6.7.0 Stub implementation.
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#parsing-main-inforeign
* @see WP_HTML_Processor::step
*
- * @since 6.7.0 Stub implementation.
- *
+ * @return bool Whether an element was found.
*/
private function step_in_foreign_content(): bool {
$tag_name = $this->get_token_name();
@@ -4763,7 +4812,6 @@ private function step_in_foreign_content(): bool {
}
$this->insert_foreign_element( $this->state->current_token, false );
-
return true;
/*
@@ -4782,7 +4830,6 @@ private function step_in_foreign_content(): bool {
}
$this->insert_foreign_element( $this->state->current_token, false );
-
return true;
/*
@@ -4792,7 +4839,6 @@ private function step_in_foreign_content(): bool {
case '#funky-comment':
case '#presumptuous-tag':
$this->insert_foreign_element( $this->state->current_token, false );
-
return true;
/*
@@ -4903,7 +4949,6 @@ private function step_in_foreign_content(): bool {
if ( $this->state->current_token->has_self_closing_flag ) {
$this->state->stack_of_open_elements->pop();
}
-
return true;
}
@@ -4912,7 +4957,6 @@ private function step_in_foreign_content(): bool {
*/
if ( $this->is_tag_closer() && 'SCRIPT' === $this->state->current_token->node_name && 'svg' === $this->state->current_token->namespace ) {
$this->state->stack_of_open_elements->pop();
-
return true;
}
@@ -5027,7 +5071,6 @@ private function step_in_foreign_content(): bool {
}
$this->bail( 'Should not have been able to reach end of IN FOREIGN CONTENT processing. Check HTML API code.' );
-
// This unnecessary return prevents tools from inaccurately reporting type errors.
return false;
}
@@ -5039,15 +5082,15 @@ private function step_in_foreign_content(): bool {
/**
* Creates a new bookmark for the currently-matched token and returns the generated name.
*
- * @return string|false Name of created bookmark, or false if unable to create.
- * @throws Exception When unable to allocate requested bookmark.
- *
* @since 6.4.0
* @since 6.5.0 Renamed from bookmark_tag() to bookmark_token().
*
+ * @throws Exception When unable to allocate requested bookmark.
+ *
+ * @return string|false Name of created bookmark, or false if unable to create.
*/
private function bookmark_token() {
- if ( ! parent::set_bookmark( ++ $this->bookmark_counter ) ) {
+ if ( ! parent::set_bookmark( ++$this->bookmark_counter ) ) {
$this->last_error = self::ERROR_EXCEEDED_MAX_BOOKMARKS;
throw new Exception( 'could not allocate bookmark' );
}
@@ -5089,9 +5132,9 @@ public function get_namespace(): string {
* $processor->next_tag() === false;
* $processor->get_tag() === null;
*
- * @return string|null Name of currently matched tag in input HTML, or `null` if none found.
* @since 6.4.0
*
+ * @return string|null Name of currently matched tag in input HTML, or `null` if none found.
*/
public function get_tag(): ?string {
if ( null !== $this->last_error ) {
@@ -5108,7 +5151,6 @@ public function get_tag(): ?string {
* > A start tag whose tag name is "image"
* > Change the token's tag name to "img" and reprocess it. (Don't ask.)
*/
-
return ( 'IMAGE' === $tag_name && 'html' === $this->get_namespace() )
? 'IMG'
: $tag_name;
@@ -5127,9 +5169,9 @@ public function get_tag(): ?string {
* This function does not determine if a tag is self-closing,
* but only if the self-closing flag is present in the syntax.
*
- * @return bool Whether the currently matched tag contains the self-closing flag.
* @since 6.6.0 Subclassed for the HTML Processor.
*
+ * @return bool Whether the currently matched tag contains the self-closing flag.
*/
public function has_self_closing_flag(): bool {
return $this->is_virtual() ? false : parent::has_self_closing_flag();
@@ -5151,9 +5193,9 @@ public function has_self_closing_flag(): bool {
* hasn't yet found a token or because it reached the end
* of the document without matching a token.
*
- * @return string|null Name of the matched token.
* @since 6.6.0 Subclassed for the HTML Processor.
*
+ * @return string|null Name of the matched token.
*/
public function get_token_name(): ?string {
return $this->is_virtual()
@@ -5179,9 +5221,9 @@ public function get_token_name(): ?string {
* - `#presumptuous-tag` when matched on an empty tag closer.
* - `#funky-comment` when matched on a funky comment.
*
- * @return string|null What kind of token is matched, or null.
* @since 6.6.0 Subclassed for the HTML Processor.
*
+ * @return string|null What kind of token is matched, or null.
*/
public function get_token_type(): ?string {
if ( $this->is_virtual() ) {
@@ -5221,11 +5263,10 @@ public function get_token_type(): ?string {
* $p->next_tag() === false;
* $p->get_attribute( 'class' ) === null;
*
- * @param string $name Name of attribute whose value is requested.
- *
- * @return string|true|null Value of attribute or `null` if not available. Boolean attributes return `true`.
* @since 6.6.0 Subclassed for HTML Processor.
*
+ * @param string $name Name of attribute whose value is requested.
+ * @return string|true|null Value of attribute or `null` if not available. Boolean attributes return `true`.
*/
public function get_attribute( $name ) {
return $this->is_virtual() ? null : parent::get_attribute( $name );
@@ -5240,12 +5281,11 @@ public function get_attribute( $name ) {
*
* For string attributes, the value is escaped using the `esc_attr` function.
*
- * @param string $name The attribute name to target.
- * @param string|bool $value The new attribute value.
- *
- * @return bool Whether an attribute value was set.
* @since 6.6.0 Subclassed for the HTML Processor.
*
+ * @param string $name The attribute name to target.
+ * @param string|bool $value The new attribute value.
+ * @return bool Whether an attribute value was set.
*/
public function set_attribute( $name, $value ): bool {
return $this->is_virtual() ? false : parent::set_attribute( $name, $value );
@@ -5254,11 +5294,10 @@ public function set_attribute( $name, $value ): bool {
/**
* Remove an attribute from the currently-matched tag.
*
- * @param string $name The attribute name to remove.
- *
- * @return bool Whether an attribute was removed.
* @since 6.6.0 Subclassed for HTML Processor.
*
+ * @param string $name The attribute name to remove.
+ * @return bool Whether an attribute was removed.
*/
public function remove_attribute( $name ): bool {
return $this->is_virtual() ? false : parent::remove_attribute( $name );
@@ -5283,13 +5322,12 @@ public function remove_attribute( $name ): bool {
* $p->next_tag() === false;
* $p->get_attribute_names_with_prefix( 'data-' ) === null;
*
- * @param string $prefix Prefix of requested attribute names.
- *
- * @return array|null List of attribute names, or `null` when no tag opener is matched.
* @since 6.6.0 Subclassed for the HTML Processor.
*
* @see https://html.spec.whatwg.org/multipage/syntax.html#attributes-2:ascii-case-insensitive
*
+ * @param string $prefix Prefix of requested attribute names.
+ * @return array|null List of attribute names, or `null` when no tag opener is matched.
*/
public function get_attribute_names_with_prefix( $prefix ): ?array {
return $this->is_virtual() ? null : parent::get_attribute_names_with_prefix( $prefix );
@@ -5298,11 +5336,10 @@ public function get_attribute_names_with_prefix( $prefix ): ?array {
/**
* Adds a new class name to the currently matched tag.
*
- * @param string $class_name The class name to add.
- *
- * @return bool Whether the class was set to be added.
* @since 6.6.0 Subclassed for the HTML Processor.
*
+ * @param string $class_name The class name to add.
+ * @return bool Whether the class was set to be added.
*/
public function add_class( $class_name ): bool {
return $this->is_virtual() ? false : parent::add_class( $class_name );
@@ -5311,11 +5348,10 @@ public function add_class( $class_name ): bool {
/**
* Removes a class name from the currently matched tag.
*
- * @param string $class_name The class name to remove.
- *
- * @return bool Whether the class was set to be removed.
* @since 6.6.0 Subclassed for the HTML Processor.
*
+ * @param string $class_name The class name to remove.
+ * @return bool Whether the class was set to be removed.
*/
public function remove_class( $class_name ): bool {
return $this->is_virtual() ? false : parent::remove_class( $class_name );
@@ -5324,15 +5360,14 @@ public function remove_class( $class_name ): bool {
/**
* Returns if a matched tag contains the given ASCII case-insensitive class name.
*
- * @param string $wanted_class Look for this CSS class name, ASCII case-insensitive.
- *
- * @return bool|null Whether the matched tag contains the given class name, or null if not matched.
* @since 6.6.0 Subclassed for the HTML Processor.
*
* @todo When reconstructing active formatting elements with attributes, find a way
* to indicate if the virtually-reconstructed formatting elements contain the
* wanted class name.
*
+ * @param string $wanted_class Look for this CSS class name, ASCII case-insensitive.
+ * @return bool|null Whether the matched tag contains the given class name, or null if not matched.
*/
public function has_class( $wanted_class ): ?bool {
return $this->is_virtual() ? null : parent::has_class( $wanted_class );
@@ -5374,9 +5409,9 @@ public function class_list() {
* that a token has modifiable text, and a token with modifiable text may
* have an empty string (e.g. a comment with no contents).
*
- * @return string
* @since 6.6.0 Subclassed for the HTML Processor.
*
+ * @return string
*/
public function get_modifiable_text(): string {
return $this->is_virtual() ? '' : parent::get_modifiable_text();
@@ -5391,7 +5426,7 @@ public function get_modifiable_text(): string {
* they are commonly known, but a number of unrelated syntax errors
* also produce comments.
*
- * @return string|null
+ * @see self::COMMENT_AS_ABRUPTLY_CLOSED_COMMENT
* @see self::COMMENT_AS_CDATA_LOOKALIKE
* @see self::COMMENT_AS_INVALID_HTML
* @see self::COMMENT_AS_HTML_COMMENT
@@ -5399,7 +5434,7 @@ public function get_modifiable_text(): string {
*
* @since 6.6.0 Subclassed for the HTML Processor.
*
- * @see self::COMMENT_AS_ABRUPTLY_CLOSED_COMMENT
+ * @return string|null
*/
public function get_comment_type(): ?string {
return $this->is_virtual() ? null : parent::get_comment_type();
@@ -5411,11 +5446,10 @@ public function get_comment_type(): ?string {
* Releasing a bookmark frees up the small
* performance overhead it requires.
*
- * @param string $bookmark_name Name of the bookmark to remove.
- *
- * @return bool Whether the bookmark already existed before removal.
* @since 6.4.0
*
+ * @param string $bookmark_name Name of the bookmark to remove.
+ * @return bool Whether the bookmark already existed before removal.
*/
public function release_bookmark( $bookmark_name ): bool {
return parent::release_bookmark( "_{$bookmark_name}" );
@@ -5431,13 +5465,12 @@ public function release_bookmark( $bookmark_name ): bool {
* In order to prevent accidental infinite loops, there's a
* maximum limit on the number of times seek() can be called.
*
- * @param string $bookmark_name Jump to the place in the document identified by this bookmark name.
- *
- * @return bool Whether the internal cursor was successfully moved to the bookmark's location.
* @throws Exception When unable to allocate a bookmark for the next token in the input HTML document.
*
* @since 6.4.0
*
+ * @param string $bookmark_name Jump to the place in the document identified by this bookmark name.
+ * @return bool Whether the internal cursor was successfully moved to the bookmark's location.
*/
public function seek( $bookmark_name ): bool {
// Flush any pending updates to the document before beginning.
@@ -5480,54 +5513,93 @@ public function seek( $bookmark_name ): bool {
* and computation time.
*/
if ( 'backward' === $direction ) {
+
/*
- * Instead of clearing the parser state and starting fresh, calling the stack methods
- * maintains the proper flags in the parser.
+ * When moving backward, stateful stacks should be cleared.
*/
foreach ( $this->state->stack_of_open_elements->walk_up() as $item ) {
- if ( 'context-node' === $item->bookmark_name ) {
- break;
- }
-
$this->state->stack_of_open_elements->remove_node( $item );
}
foreach ( $this->state->active_formatting_elements->walk_up() as $item ) {
- if ( 'context-node' === $item->bookmark_name ) {
- break;
- }
-
$this->state->active_formatting_elements->remove_node( $item );
}
- parent::seek( 'context-node' );
- $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY;
- $this->state->frameset_ok = true;
- $this->element_queue = array();
- $this->current_element = null;
+ /*
+ * **After** clearing stacks, more processor state can be reset.
+ * This must be done after clearing the stack because those stacks generate events that
+ * would appear on a subsequent call to `next_token()`.
+ */
+ $this->state->frameset_ok = true;
+ $this->state->stack_of_template_insertion_modes = array();
+ $this->state->head_element = null;
+ $this->state->form_element = null;
+ $this->state->current_token = null;
+ $this->current_element = null;
+ $this->element_queue = array();
+
+ /*
+ * The absence of a context node indicates a full parse.
+ * The presence of a context node indicates a fragment parser.
+ */
+ if ( null === $this->context_node ) {
+ $this->change_parsing_namespace( 'html' );
+ $this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_INITIAL;
+ $this->breadcrumbs = array();
- if ( isset( $this->context_node ) ) {
- $this->breadcrumbs = array_slice( $this->breadcrumbs, 0, 2 );
+ $this->bookmarks['initial'] = new WP_HTML_Span( 0, 0 );
+ parent::seek( 'initial' );
+ unset( $this->bookmarks['initial'] );
} else {
- $this->breadcrumbs = array();
- }
- }
- // When moving forwards, reparse the document until reaching the same location as the original bookmark.
- if ( $bookmark_starts_at === $this->bookmarks[ $this->state->current_token->bookmark_name ]->start ) {
- return true;
- }
+ /*
+ * Push the root-node (HTML) back onto the stack of open elements.
+ *
+ * Fragment parsers require this extra bit of setup.
+ * It's handled in full parsers by advancing the processor state.
+ */
+ $this->state->stack_of_open_elements->push(
+ new WP_HTML_Token(
+ 'root-node',
+ 'HTML',
+ false
+ )
+ );
- while ( $this->next_token() ) {
- if ( $bookmark_starts_at === $this->bookmarks[ $this->state->current_token->bookmark_name ]->start ) {
- while ( isset( $this->current_element ) && WP_HTML_Stack_Event::POP === $this->current_element->operation ) {
- $this->current_element = array_shift( $this->element_queue );
+ $this->change_parsing_namespace(
+ $this->context_node->integration_node_type
+ ? 'html'
+ : $this->context_node->namespace
+ );
+
+ if ( 'TEMPLATE' === $this->context_node->node_name ) {
+ $this->state->stack_of_template_insertion_modes[] = WP_HTML_Processor_State::INSERTION_MODE_IN_TEMPLATE;
}
- return true;
+ $this->reset_insertion_mode_appropriately();
+ $this->breadcrumbs = array_slice( $this->breadcrumbs, 0, 2 );
+ parent::seek( $this->context_node->bookmark_name );
}
}
+ /*
+ * Here, the processor moves forward through the document until it matches the bookmark.
+ * do-while is used here because the processor is expected to already be stopped on
+ * a token than may match the bookmarked location.
+ */
+ do {
+ /*
+ * The processor will stop on virtual tokens, but bookmarks may not be set on them.
+ * They should not be matched when seeking a bookmark, skip them.
+ */
+ if ( $this->is_virtual() ) {
+ continue;
+ }
+ if ( $bookmark_starts_at === $this->bookmarks[ $this->state->current_token->bookmark_name ]->start ) {
+ return true;
+ }
+ } while ( $this->next_token() );
+
return false;
}
@@ -5606,24 +5678,35 @@ public function seek( $bookmark_name ): bool {
* reaching for it, as inappropriate use could lead to broken
* HTML structure or unwanted processing overhead.
*
- * @param string $bookmark_name Identifies this particular bookmark.
+ * Bookmarks cannot be set on tokens that do no appear in the original
+ * HTML text. For example, the HTML `
` stops at tags `TABLE`,
+ * `TBODY`, `TR`, and `TD`. The `TBODY` and `TR` tags do not appear in
+ * the original HTML and cannot be used as bookmarks.
*
- * @return bool Whether the bookmark was successfully created.
* @since 6.4.0
*
+ * @param string $bookmark_name Identifies this particular bookmark.
+ * @return bool Whether the bookmark was successfully created.
*/
public function set_bookmark( $bookmark_name ): bool {
+ if ( $this->is_virtual() ) {
+ _doing_it_wrong(
+ __METHOD__,
+ __( 'Cannot set bookmarks on tokens that do no appear in the original HTML text.' ),
+ '6.8.0'
+ );
+ return false;
+ }
return parent::set_bookmark( "_{$bookmark_name}" );
}
/**
* Checks whether a bookmark with the given name exists.
*
- * @param string $bookmark_name Name to identify a bookmark that potentially exists.
- *
- * @return bool Whether that bookmark exists.
* @since 6.5.0
*
+ * @param string $bookmark_name Name to identify a bookmark that potentially exists.
+ * @return bool Whether that bookmark exists.
*/
public function has_bookmark( $bookmark_name ): bool {
return parent::has_bookmark( "_{$bookmark_name}" );
@@ -5636,10 +5719,10 @@ public function has_bookmark( $bookmark_name ): bool {
/**
* Closes a P element.
*
- * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
- *
* @since 6.4.0
*
+ * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
+ *
* @see https://html.spec.whatwg.org/#close-a-p-element
*/
private function close_a_p_element(): void {
@@ -5650,13 +5733,12 @@ private function close_a_p_element(): void {
/**
* Closes elements that have implied end tags.
*
- * @param string|null $except_for_this_element Perform as if this element doesn't exist in the stack of open elements.
- *
+ * @since 6.4.0
* @since 6.7.0 Full spec support.
*
* @see https://html.spec.whatwg.org/#generate-implied-end-tags
*
- * @since 6.4.0
+ * @param string|null $except_for_this_element Perform as if this element doesn't exist in the stack of open elements.
*/
private function generate_implied_end_tags( ?string $except_for_this_element = null ): void {
$elements_with_implied_end_tags = array(
@@ -5750,13 +5832,13 @@ private function get_adjusted_current_node(): ?WP_HTML_Token {
* > in the current body, cell, or caption (whichever is youngest) that haven't
* > been explicitly closed.
*
- * @return bool Whether any formatting elements needed to be reconstructed.
+ * @since 6.4.0
+ *
* @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
*
* @see https://html.spec.whatwg.org/#reconstruct-the-active-formatting-elements
*
- * @since 6.4.0
- *
+ * @return bool Whether any formatting elements needed to be reconstructed.
*/
private function reconstruct_active_formatting_elements(): bool {
/*
@@ -5861,13 +5943,11 @@ private function reset_insertion_mode_appropriately(): void {
*/
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;
/*
@@ -5878,18 +5958,16 @@ private function reset_insertion_mode_appropriately(): void {
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.
- */
+ /*
+ * > 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;
/*
@@ -5900,7 +5978,6 @@ private function reset_insertion_mode_appropriately(): void {
case 'THEAD':
case 'TFOOT':
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE_BODY;
-
return;
/*
@@ -5909,7 +5986,6 @@ private function reset_insertion_mode_appropriately(): void {
*/
case 'CAPTION':
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_CAPTION;
-
return;
/*
@@ -5918,7 +5994,6 @@ private function reset_insertion_mode_appropriately(): void {
*/
case 'COLGROUP':
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_COLUMN_GROUP;
-
return;
/*
@@ -5927,7 +6002,6 @@ private function reset_insertion_mode_appropriately(): void {
*/
case 'TABLE':
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_TABLE;
-
return;
/*
@@ -5936,7 +6010,6 @@ private function reset_insertion_mode_appropriately(): void {
*/
case 'TEMPLATE':
$this->state->insertion_mode = end( $this->state->stack_of_template_insertion_modes );
-
return;
/*
@@ -5946,7 +6019,6 @@ private function reset_insertion_mode_appropriately(): void {
case 'HEAD':
if ( ! $last ) {
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_HEAD;
-
return;
}
break;
@@ -5957,7 +6029,6 @@ private function reset_insertion_mode_appropriately(): void {
*/
case 'BODY':
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_BODY;
-
return;
/*
@@ -5966,7 +6037,6 @@ private function reset_insertion_mode_appropriately(): void {
*/
case 'FRAMESET':
$this->state->insertion_mode = WP_HTML_Processor_State::INSERTION_MODE_IN_FRAMESET;
-
return;
/*
@@ -5980,7 +6050,6 @@ private function reset_insertion_mode_appropriately(): void {
$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;
}
}
@@ -5997,10 +6066,10 @@ private function reset_insertion_mode_appropriately(): void {
/**
* Runs the adoption agency algorithm.
*
- * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
- *
* @since 6.4.0
*
+ * @throws WP_HTML_Unsupported_Exception When encountering unsupported HTML input.
+ *
* @see https://html.spec.whatwg.org/#adoption-agency-algorithm
*/
private function run_adoption_agency_algorithm(): void {
@@ -6015,13 +6084,12 @@ private function run_adoption_agency_algorithm(): void {
! $this->state->active_formatting_elements->contains_node( $current_node )
) {
$this->state->stack_of_open_elements->pop();
-
return;
}
$outer_loop_counter = 0;
- while ( $budget -- > 0 ) {
- if ( $outer_loop_counter ++ >= 8 ) {
+ while ( $budget-- > 0 ) {
+ if ( $outer_loop_counter++ >= 8 ) {
return;
}
@@ -6051,7 +6119,6 @@ private function run_adoption_agency_algorithm(): void {
// > If formatting element is not in the stack of open elements, then this is a parse error; remove the element from the list, and return.
if ( ! $this->state->stack_of_open_elements->contains_node( $formatting_element ) ) {
$this->state->active_formatting_elements->remove_node( $formatting_element );
-
return;
}
@@ -6093,7 +6160,6 @@ private function run_adoption_agency_algorithm(): void {
if ( $formatting_element->bookmark_name === $item->bookmark_name ) {
$this->state->active_formatting_elements->remove_node( $formatting_element );
-
return;
}
}
@@ -6135,12 +6201,11 @@ private function close_cell(): void {
/**
* Inserts an HTML element on the stack of open elements.
*
- * @param WP_HTML_Token $token Name of bookmark pointing to element in original input HTML.
+ * @since 6.4.0
*
* @see https://html.spec.whatwg.org/#insert-a-foreign-element
*
- * @since 6.4.0
- *
+ * @param WP_HTML_Token $token Name of bookmark pointing to element in original input HTML.
*/
private function insert_html_element( WP_HTML_Token $token ): void {
$this->state->stack_of_open_elements->push( $token );
@@ -6149,15 +6214,14 @@ private function insert_html_element( WP_HTML_Token $token ): void {
/**
* Inserts a foreign element on to the stack of open elements.
*
- * @param WP_HTML_Token $token Insert this token. The token's namespace and
- * insertion point will be updated correctly.
- * @param bool $only_add_to_element_stack Whether to skip the "insert an element at the adjusted
- * insertion location" algorithm when adding this element.
- *
* @since 6.7.0
*
* @see https://html.spec.whatwg.org/#insert-a-foreign-element
*
+ * @param WP_HTML_Token $token Insert this token. The token's namespace and
+ * insertion point will be updated correctly.
+ * @param bool $only_add_to_element_stack Whether to skip the "insert an element at the adjusted
+ * insertion location" algorithm when adding this element.
*/
private function insert_foreign_element( WP_HTML_Token $token, bool $only_add_to_element_stack ): void {
$adjusted_current_node = $this->get_adjusted_current_node();
@@ -6189,13 +6253,12 @@ private function insert_foreign_element( WP_HTML_Token $token, bool $only_add_to
/**
* Inserts a virtual element on the stack of open elements.
*
- * @param string $token_name Name of token to create and insert into the stack of open elements.
- * @param string|null $bookmark_name Optional. Name to give bookmark for created virtual node.
- * Defaults to auto-creating a bookmark name.
- *
- * @return WP_HTML_Token Newly-created virtual token.
* @since 6.7.0
*
+ * @param string $token_name Name of token to create and insert into the stack of open elements.
+ * @param string|null $bookmark_name Optional. Name to give bookmark for created virtual node.
+ * Defaults to auto-creating a bookmark name.
+ * @return WP_HTML_Token Newly-created virtual token.
*/
private function insert_virtual_node( $token_name, $bookmark_name = null ): WP_HTML_Token {
$here = $this->bookmarks[ $this->state->current_token->bookmark_name ];
@@ -6205,7 +6268,6 @@ private function insert_virtual_node( $token_name, $bookmark_name = null ): WP_H
$token = new WP_HTML_Token( $name, $token_name, false );
$this->insert_html_element( $token );
-
return $token;
}
@@ -6216,11 +6278,11 @@ private function insert_virtual_node( $token_name, $bookmark_name = null ): WP_H
/**
* Indicates if the current token is a MathML integration point.
*
- * @return bool Whether the current token is a MathML integration point.
- * @see https://html.spec.whatwg.org/#mathml-text-integration-point
- *
* @since 6.7.0
*
+ * @see https://html.spec.whatwg.org/#mathml-text-integration-point
+ *
+ * @return bool Whether the current token is a MathML integration point.
*/
private function is_mathml_integration_point(): bool {
$current_token = $this->state->current_token;
@@ -6252,11 +6314,11 @@ private function is_mathml_integration_point(): bool {
* Otherwise it would be required to scan the HTML and ensure that
* no other accounting is overlooked.
*
- * @return bool Whether the current token is an HTML integration point.
- * @see https://html.spec.whatwg.org/#html-integration-point
- *
* @since 6.7.0
*
+ * @see https://html.spec.whatwg.org/#html-integration-point
+ *
+ * @return bool Whether the current token is an HTML integration point.
*/
private function is_html_integration_point(): bool {
$current_token = $this->state->current_token;
@@ -6295,7 +6357,6 @@ private function is_html_integration_point(): bool {
}
$this->bail( 'Should not have reached end of HTML Integration Point detection: check HTML API code.' );
-
// This unnecessary return prevents tools from inaccurately reporting type errors.
return false;
}
@@ -6303,13 +6364,12 @@ private function is_html_integration_point(): bool {
/**
* Returns whether an element of a given name is in the HTML special category.
*
- * @param WP_HTML_Token|string $tag_name Node to check, or only its name if in the HTML namespace.
- *
- * @return bool Whether the element of the given name is in the special category.
* @since 6.4.0
*
* @see https://html.spec.whatwg.org/#special
*
+ * @param WP_HTML_Token|string $tag_name Node to check, or only its name if in the HTML namespace.
+ * @return bool Whether the element of the given name is in the special category.
*/
public static function is_special( $tag_name ): bool {
if ( is_string( $tag_name ) ) {
@@ -6425,13 +6485,12 @@ public static function is_special( $tag_name ): bool {
*
* > area, base, br, col, embed, hr, img, input, link, meta, source, track, wbr
*
- * @param string $tag_name Name of HTML tag to check.
- *
- * @return bool Whether the given tag is an HTML Void Element.
* @since 6.4.0
*
* @see https://html.spec.whatwg.org/#void-elements
*
+ * @param string $tag_name Name of HTML tag to check.
+ * @return bool Whether the given tag is an HTML Void Element.
*/
public static function is_void( $tag_name ): bool {
$tag_name = strtoupper( $tag_name );
@@ -6478,8 +6537,7 @@ public static function is_void( $tag_name ): bool {
*
* @since 6.7.0
*
- * @param string $label A string which may specify a known encoding.
- *
+ * @param string $label A string which may specify a known encoding.
* @return string|null Known encoding if matched, otherwise null.
*/
protected static function get_encoding( string $label ): ?string {
diff --git a/components/HTML/class-wp-html-span.php b/components/HTML/class-wp-html-span.php
index 44fefe82..c8ba9ecd 100644
--- a/components/HTML/class-wp-html-span.php
+++ b/components/HTML/class-wp-html-span.php
@@ -1,4 +1,6 @@
start = $start;
diff --git a/components/HTML/class-wp-html-stack-event.php b/components/HTML/class-wp-html-stack-event.php
index 5c8db013..8e329272 100644
--- a/components/HTML/class-wp-html-stack-event.php
+++ b/components/HTML/class-wp-html-stack-event.php
@@ -1,4 +1,6 @@
token = $token;
diff --git a/components/HTML/class-wp-html-tag-processor.php b/components/HTML/class-wp-html-tag-processor.php
index 309ed364..995feaa9 100644
--- a/components/HTML/class-wp-html-tag-processor.php
+++ b/components/HTML/class-wp-html-tag-processor.php
@@ -1,4 +1,11 @@
html = $html;
@@ -842,12 +848,11 @@ public function __construct( $html ) {
* Switches parsing mode into a new namespace, such as when
* encountering an SVG tag and entering foreign content.
*
- * @param string $new_namespace One of 'html', 'svg', or 'math' indicating into what
- * namespace the next tokens will be processed.
- *
- * @return bool Whether the namespace was valid and changed.
* @since 6.7.0
*
+ * @param string $new_namespace One of 'html', 'svg', or 'math' indicating into what
+ * namespace the next tokens will be processed.
+ * @return bool Whether the namespace was valid and changed.
*/
public function change_parsing_namespace( string $new_namespace ): bool {
if ( ! in_array( $new_namespace, array( 'html', 'math', 'svg' ), true ) ) {
@@ -855,27 +860,26 @@ public function change_parsing_namespace( string $new_namespace ): bool {
}
$this->parsing_namespace = $new_namespace;
-
return true;
}
/**
* Finds the next tag matching the $query.
*
- * @param array|string|null $query {
+ * @since 6.2.0
+ * @since 6.5.0 No longer processes incomplete tokens at end of document; pauses the processor at start of token.
+ *
+ * @param array|string|null $query {
* Optional. Which tag name to find, having which class, etc. Default is to find any tag.
*
- * @type string|null $tag_name Which tag to find, or `null` for "any tag."
- * @type int|null $match_offset Find the Nth tag matching all search criteria.
+ * @type string|null $tag_name Which tag to find, or `null` for "any tag."
+ * @type int|null $match_offset Find the Nth tag matching all search criteria.
* 1 for "first" tag, 3 for "third," etc.
* Defaults to first tag.
- * @type string|null $class_name Tag must contain this whole class name to match.
- * @type string|null $tag_closers "visit" or "skip": whether to stop on tag closers, e.g. .
+ * @type string|null $class_name Tag must contain this whole class name to match.
+ * @type string|null $tag_closers "visit" or "skip": whether to stop on tag closers, e.g. .
* }
* @return bool Whether a tag was matched.
- * @since 6.2.0
- * @since 6.5.0 No longer processes incomplete tokens at end of document; pauses the processor at start of token.
- *
*/
public function next_tag( $query = null ): bool {
$this->parse_query( $query );
@@ -891,7 +895,7 @@ public function next_tag( $query = null ): bool {
}
if ( $this->matches() ) {
- ++ $already_found;
+ ++$already_found;
}
} while ( $already_found < $this->sought_match_offset );
@@ -921,10 +925,10 @@ public function next_tag( $query = null ): bool {
*
* The Tag Processor currently only supports the tag token.
*
- * @return bool Whether a token was parsed.
+ * @since 6.5.0
* @since 6.7.0 Recognizes CDATA sections within foreign content.
*
- * @since 6.5.0
+ * @return bool Whether a token was parsed.
*/
public function next_token(): bool {
return $this->base_class_next_token();
@@ -939,11 +943,11 @@ public function next_token(): bool {
* without triggering subclass methods for things like `next_token()`, e.g. when
* applying patches before searching for the next token.
*
- * @return bool Whether a token was parsed.
* @since 6.5.0
*
* @access private
*
+ * @return bool Whether a token was parsed.
*/
private function base_class_next_token(): bool {
$was_at = $this->bytes_already_parsed;
@@ -965,7 +969,6 @@ private function base_class_next_token(): bool {
if ( $this->bytes_already_parsed >= strlen( $this->html ) ) {
$this->parser_state = self::STATE_COMPLETE;
-
return false;
}
@@ -1053,7 +1056,6 @@ private function base_class_next_token(): bool {
*/
if ( 'LISTING' === $tag_name || 'PRE' === $tag_name ) {
$this->skip_newline_at = $this->bytes_already_parsed;
-
return true;
}
@@ -1116,7 +1118,6 @@ private function base_class_next_token(): bool {
if ( ! $found_closer ) {
$this->parser_state = self::STATE_INCOMPLETE_INPUT;
$this->bytes_already_parsed = $was_at;
-
return false;
}
@@ -1149,9 +1150,9 @@ private function base_class_next_token(): bool {
* false === $processor->get_next_tag();
* true === $processor->paused_at_incomplete_token();
*
- * @return bool Whether the parse paused at the start of an incomplete token.
* @since 6.5.0
*
+ * @return bool Whether the parse paused at the start of an incomplete token.
*/
public function paused_at_incomplete_token(): bool {
return self::STATE_INCOMPLETE_INPUT === $this->parser_state;
@@ -1227,11 +1228,10 @@ public function class_list() {
/**
* Returns if a matched tag contains the given ASCII case-insensitive class name.
*
- * @param string $wanted_class Look for this CSS class name, ASCII case-insensitive.
- *
- * @return bool|null Whether the matched tag contains the given class name, or null if not matched.
* @since 6.4.0
*
+ * @param string $wanted_class Look for this CSS class name, ASCII case-insensitive.
+ * @return bool|null Whether the matched tag contains the given class name, or null if not matched.
*/
public function has_class( $wanted_class ): ?bool {
if ( self::STATE_MATCHED_TAG !== $this->parser_state ) {
@@ -1329,11 +1329,10 @@ public function has_class( $wanted_class ): ?bool {
* reaching for it, as inappropriate use could lead to broken
* HTML structure or unwanted processing overhead.
*
- * @param string $name Identifies this particular bookmark.
- *
- * @return bool Whether the bookmark was successfully created.
* @since 6.2.0
*
+ * @param string $name Identifies this particular bookmark.
+ * @return bool Whether the bookmark was successfully created.
*/
public function set_bookmark( $name ): bool {
// It only makes sense to set a bookmark if the parser has paused on a concrete token.
@@ -1350,7 +1349,6 @@ public function set_bookmark( $name ): bool {
__( 'Too many bookmarks: cannot create any more.' ),
'6.2.0'
);
-
return false;
}
@@ -1366,8 +1364,7 @@ public function set_bookmark( $name ): bool {
* Releasing a bookmark frees up the small
* performance overhead it requires.
*
- * @param string $name Name of the bookmark to remove.
- *
+ * @param string $name Name of the bookmark to remove.
* @return bool Whether the bookmark already existed before removal.
*/
public function release_bookmark( $name ): bool {
@@ -1383,13 +1380,12 @@ public function release_bookmark( $name ): bool {
/**
* Skips contents of generic rawtext elements.
*
- * @param string $tag_name The uppercase tag name which will close the RAWTEXT region.
- *
- * @return bool Whether an end to the RAWTEXT region was found before the end of the document.
* @since 6.3.2
*
* @see https://html.spec.whatwg.org/#generic-raw-text-element-parsing-algorithm
*
+ * @param string $tag_name The uppercase tag name which will close the RAWTEXT region.
+ * @return bool Whether an end to the RAWTEXT region was found before the end of the document.
*/
private function skip_rawtext( string $tag_name ): bool {
/*
@@ -1403,13 +1399,12 @@ private function skip_rawtext( string $tag_name ): bool {
/**
* Skips contents of RCDATA elements, namely title and textarea tags.
*
- * @param string $tag_name The uppercase tag name which will close the RCDATA region.
- *
- * @return bool Whether an end to the RCDATA region was found before the end of the document.
* @since 6.2.0
*
* @see https://html.spec.whatwg.org/multipage/parsing.html#rcdata-state
*
+ * @param string $tag_name The uppercase tag name which will close the RCDATA region.
+ * @return bool Whether an end to the RCDATA region was found before the end of the document.
*/
private function skip_rcdata( string $tag_name ): bool {
$html = $this->html;
@@ -1437,7 +1432,7 @@ private function skip_rcdata( string $tag_name ): bool {
* comparing; any character which could be impacted by such
* normalization could not be part of a tag name.
*/
- for ( $i = 0; $i < $tag_length; $i ++ ) {
+ for ( $i = 0; $i < $tag_length; $i++ ) {
$tag_char = $tag_name[ $i ];
$html_char = $html[ $at + $i ];
@@ -1447,7 +1442,7 @@ private function skip_rcdata( string $tag_name ): bool {
}
}
- $at += $tag_length;
+ $at += $tag_length;
$this->bytes_already_parsed = $at;
if ( $at >= strlen( $html ) ) {
@@ -1476,7 +1471,6 @@ private function skip_rcdata( string $tag_name ): bool {
if ( '>' === $html[ $at ] ) {
$this->bytes_already_parsed = $at + 1;
-
return true;
}
@@ -1486,7 +1480,6 @@ private function skip_rcdata( string $tag_name ): bool {
if ( '/' === $html[ $at ] && '>' === $html[ $at + 1 ] ) {
$this->bytes_already_parsed = $at + 2;
-
return true;
}
}
@@ -1497,9 +1490,9 @@ private function skip_rcdata( string $tag_name ): bool {
/**
* Skips contents of script tags.
*
- * @return bool Whether the script tag was closed before the end of the document.
* @since 6.2.0
*
+ * @return bool Whether the script tag was closed before the end of the document.
*/
private function skip_script_data(): bool {
$state = 'unescaped';
@@ -1521,7 +1514,7 @@ private function skip_script_data(): bool {
'-' === $html[ $at + 1 ] &&
'>' === $html[ $at + 2 ]
) {
- $at += 3;
+ $at += 3;
$state = 'unescaped';
continue;
}
@@ -1534,7 +1527,7 @@ private function skip_script_data(): bool {
* Everything of interest past here starts with "<".
* Check this character and advance position regardless.
*/
- if ( '<' !== $html[ $at ++ ] ) {
+ if ( '<' !== $html[ $at++ ] ) {
continue;
}
@@ -1556,7 +1549,7 @@ private function skip_script_data(): bool {
'-' === $html[ $at + 1 ] &&
'-' === $html[ $at + 2 ]
) {
- $at += 3;
+ $at += 3;
$state = 'unescaped' === $state ? 'escaped' : $state;
continue;
}
@@ -1564,7 +1557,7 @@ private function skip_script_data(): bool {
if ( '/' === $html[ $at ] ) {
$closer_potentially_starts_at = $at - 1;
$is_closing = true;
- ++ $at;
+ ++$at;
} else {
$is_closing = false;
}
@@ -1583,7 +1576,7 @@ private function skip_script_data(): bool {
( 'p' === $html[ $at + 4 ] || 'P' === $html[ $at + 4 ] ) &&
( 't' === $html[ $at + 5 ] || 'T' === $html[ $at + 5 ] )
) ) {
- ++ $at;
+ ++$at;
continue;
}
@@ -1597,9 +1590,9 @@ private function skip_script_data(): bool {
continue;
}
$at += 6;
- $c = $html[ $at ];
+ $c = $html[ $at ];
if ( ' ' !== $c && "\t" !== $c && "\r" !== $c && "\n" !== $c && '/' !== $c && '>' !== $c ) {
- ++ $at;
+ ++$at;
continue;
}
@@ -1631,13 +1624,12 @@ private function skip_script_data(): bool {
}
if ( '>' === $html[ $this->bytes_already_parsed ] ) {
- ++ $this->bytes_already_parsed;
-
+ ++$this->bytes_already_parsed;
return true;
}
}
- ++ $at;
+ ++$at;
}
return false;
@@ -1651,10 +1643,10 @@ private function skip_script_data(): bool {
* name. It does not parse the attributes or scan to the
* closing `>`; these are left for other methods.
*
- * @return bool Whether a tag was found before the end of the document.
+ * @since 6.2.0
* @since 6.2.1 Support abruptly-closed comments, invalid-tag-closer-comments, and empty elements.
*
- * @since 6.2.0
+ * @return bool Whether a tag was found before the end of the document.
*/
private function parse_next_tag(): bool {
$this->after_tag();
@@ -1683,8 +1675,8 @@ private function parse_next_tag(): bool {
*
* @see https://html.spec.whatwg.org/#tag-open-state
*/
- if ( 1 !== strspn( $html, '!/?abcdefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ', $at + 1, 1 ) ) {
- ++ $at;
+ if ( 1 !== strspn( $html, '!/?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', $at + 1, 1 ) ) {
+ ++$at;
continue;
}
@@ -1694,7 +1686,6 @@ private function parse_next_tag(): bool {
$this->text_starts_at = $was_at;
$this->text_length = $this->token_length;
$this->bytes_already_parsed = $at;
-
return true;
}
@@ -1702,7 +1693,7 @@ private function parse_next_tag(): bool {
if ( $at + 1 < $doc_length && '/' === $this->html[ $at + 1 ] ) {
$this->is_closing_tag = true;
- ++ $at;
+ ++$at;
} else {
$this->is_closing_tag = false;
}
@@ -1723,12 +1714,11 @@ private function parse_next_tag(): bool {
*/
$tag_name_prefix_length = strspn( $html, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', $at + 1 );
if ( $tag_name_prefix_length > 0 ) {
- ++ $at;
+ ++$at;
$this->parser_state = self::STATE_MATCHED_TAG;
$this->tag_name_starts_at = $at;
$this->tag_name_length = $tag_name_prefix_length + strcspn( $html, " \t\f\r\n/>", $at + $tag_name_prefix_length );
$this->bytes_already_parsed = $at + $this->tag_name_length;
-
return true;
}
@@ -1783,7 +1773,6 @@ private function parse_next_tag(): bool {
}
$this->bytes_already_parsed = $closer_at + $span_of_dashes + 1;
-
return true;
}
@@ -1793,8 +1782,8 @@ private function parse_next_tag(): bool {
*
* See https://html.spec.whatwg.org/#parse-error-incorrectly-closed-comment
*/
- -- $closer_at; // Pre-increment inside condition below reduces risk of accidental infinite looping.
- while ( ++ $closer_at < $doc_length ) {
+ --$closer_at; // Pre-increment inside condition below reduces risk of accidental infinite looping.
+ while ( ++$closer_at < $doc_length ) {
$closer_at = strpos( $html, '--', $closer_at );
if ( false === $closer_at ) {
$this->parser_state = self::STATE_INCOMPLETE_INPUT;
@@ -1809,7 +1798,6 @@ private function parse_next_tag(): bool {
$this->text_starts_at = $this->token_starts_at + 4;
$this->text_length = $closer_at - $this->text_starts_at;
$this->bytes_already_parsed = $closer_at + 3;
-
return true;
}
@@ -1824,7 +1812,6 @@ private function parse_next_tag(): bool {
$this->text_starts_at = $this->token_starts_at + 4;
$this->text_length = $closer_at - $this->text_starts_at;
$this->bytes_already_parsed = $closer_at + 4;
-
return true;
}
}
@@ -1857,7 +1844,6 @@ private function parse_next_tag(): bool {
$this->text_starts_at = $this->token_starts_at + 9;
$this->text_length = $closer_at - $this->text_starts_at;
$this->bytes_already_parsed = $closer_at + 1;
-
return true;
}
@@ -1884,7 +1870,6 @@ private function parse_next_tag(): bool {
$this->text_length = $closer_at - $this->text_starts_at;
$this->token_length = $closer_at + 3 - $this->token_starts_at;
$this->bytes_already_parsed = $closer_at + 3;
-
return true;
}
@@ -1934,8 +1919,8 @@ private function parse_next_tag(): bool {
']' === $html[ $closer_at - 1 ] &&
']' === $html[ $closer_at - 2 ]
) {
- $this->parser_state = self::STATE_COMMENT;
- $this->comment_type = self::COMMENT_AS_CDATA_LOOKALIKE;
+ $this->parser_state = self::STATE_COMMENT;
+ $this->comment_type = self::COMMENT_AS_CDATA_LOOKALIKE;
$this->text_starts_at += 7;
$this->text_length -= 9;
}
@@ -1955,14 +1940,13 @@ private function parse_next_tag(): bool {
if ( '>' === $html[ $at + 1 ] ) {
// `<>` is interpreted as plaintext.
if ( ! $this->is_closing_tag ) {
- ++ $at;
+ ++$at;
continue;
}
$this->parser_state = self::STATE_PRESUMPTUOUS_TAG;
$this->token_length = $at + 2 - $this->token_starts_at;
$this->bytes_already_parsed = $at + 2;
-
return true;
}
@@ -2017,14 +2001,13 @@ private function parse_next_tag(): bool {
$pi_target_length = strspn( $comment_text, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:_' );
if ( 0 < $pi_target_length ) {
- $pi_target_length += strspn( $comment_text, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:_-.',
- $pi_target_length );
+ $pi_target_length += strspn( $comment_text, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:_-.', $pi_target_length );
$this->comment_type = self::COMMENT_AS_PI_NODE_LOOKALIKE;
$this->tag_name_starts_at = $this->token_starts_at + 2;
$this->tag_name_length = $pi_target_length;
- $this->text_starts_at += $pi_target_length;
- $this->text_length -= $pi_target_length + 1;
+ $this->text_starts_at += $pi_target_length;
+ $this->text_length -= $pi_target_length + 1;
}
}
@@ -2060,11 +2043,10 @@ private function parse_next_tag(): bool {
$this->text_starts_at = $this->token_starts_at + 2;
$this->text_length = $closer_at - $this->text_starts_at;
$this->bytes_already_parsed = $closer_at + 1;
-
return true;
}
- ++ $at;
+ ++$at;
}
/*
@@ -2077,16 +2059,15 @@ private function parse_next_tag(): bool {
$this->text_starts_at = $was_at;
$this->text_length = $this->token_length;
$this->bytes_already_parsed = $doc_length;
-
return true;
}
/**
* Parses the next attribute.
*
- * @return bool Whether an attribute was found before the end of the document.
* @since 6.2.0
*
+ * @return bool Whether an attribute was found before the end of the document.
*/
private function parse_next_attribute(): bool {
$doc_length = strlen( $this->html );
@@ -2114,8 +2095,8 @@ private function parse_next_attribute(): bool {
return false;
}
- $attribute_start = $this->bytes_already_parsed;
- $attribute_name = substr( $this->html, $attribute_start, $name_length );
+ $attribute_start = $this->bytes_already_parsed;
+ $attribute_name = substr( $this->html, $attribute_start, $name_length );
$this->bytes_already_parsed += $name_length;
if ( $this->bytes_already_parsed >= $doc_length ) {
$this->parser_state = self::STATE_INCOMPLETE_INPUT;
@@ -2132,7 +2113,7 @@ private function parse_next_attribute(): bool {
$has_value = '=' === $this->html[ $this->bytes_already_parsed ];
if ( $has_value ) {
- ++ $this->bytes_already_parsed;
+ ++$this->bytes_already_parsed;
$this->skip_whitespace();
if ( $this->bytes_already_parsed >= $doc_length ) {
$this->parser_state = self::STATE_INCOMPLETE_INPUT;
@@ -2323,6 +2304,7 @@ private function class_name_updates_to_attributes_updates(): void {
* attribute, skipping removed classes on the way, and then appending
* added classes at the end. Only when finished processing will the
* value contain the final new value.
+
* @var string $class
*/
$class = '';
@@ -2377,7 +2359,7 @@ private function class_name_updates_to_attributes_updates(): void {
// Skip to the first non-whitespace character.
$ws_at = $at;
$ws_length = strspn( $existing_class, " \t\f\r\n", $ws_at );
- $at += $ws_length;
+ $at += $ws_length;
// Capture the class name β it's everything until the next whitespace.
$name_length = strcspn( $existing_class, " \t\f\r\n", $at );
@@ -2388,7 +2370,7 @@ private function class_name_updates_to_attributes_updates(): void {
$name = substr( $existing_class, $at, $name_length );
$comparable_class_name = $is_quirks ? strtolower( $name ) : $name;
- $at += $name_length;
+ $at += $name_length;
// If this class is marked for removal, remove it and move on to the next one.
if ( in_array( $comparable_class_name, $to_remove, true ) ) {
@@ -2447,13 +2429,12 @@ private function class_name_updates_to_attributes_updates(): void {
/**
* Applies attribute updates to HTML document.
*
- * @param int $shift_this_point Accumulate and return shift for this position.
- *
- * @return int How many bytes the given pointer moved in response to the updates.
- * @since 6.3.0 Invalidate any bookmarks whose targets are overwritten.
- *
* @since 6.2.0
* @since 6.2.1 Accumulates shift for internal cursor and passed pointer.
+ * @since 6.3.0 Invalidate any bookmarks whose targets are overwritten.
+ *
+ * @param int $shift_this_point Accumulate and return shift for this position.
+ * @return int How many bytes the given pointer moved in response to the updates.
*/
private function apply_attributes_updates( int $shift_this_point ): int {
if ( ! count( $this->lexical_updates ) ) {
@@ -2489,8 +2470,8 @@ private function apply_attributes_updates( int $shift_this_point ): int {
$accumulated_shift_for_given_point += $shift;
}
- $output_buffer .= substr( $this->html, $bytes_already_copied, $diff->start - $bytes_already_copied );
- $output_buffer .= $diff->text;
+ $output_buffer .= substr( $this->html, $bytes_already_copied, $diff->start - $bytes_already_copied );
+ $output_buffer .= $diff->text;
$bytes_already_copied = $diff->start + $diff->length;
}
@@ -2547,11 +2528,10 @@ private function apply_attributes_updates( int $shift_this_point ): int {
/**
* Checks whether a bookmark with the given name exists.
*
- * @param string $bookmark_name Name to identify a bookmark that potentially exists.
- *
- * @return bool Whether that bookmark exists.
* @since 6.3.0
*
+ * @param string $bookmark_name Name to identify a bookmark that potentially exists.
+ * @return bool Whether that bookmark exists.
*/
public function has_bookmark( $bookmark_name ): bool {
return array_key_exists( $bookmark_name, $this->bookmarks );
@@ -2563,11 +2543,10 @@ public function has_bookmark( $bookmark_name ): bool {
* In order to prevent accidental infinite loops, there's a
* maximum limit on the number of times seek() can be called.
*
- * @param string $bookmark_name Jump to the place in the document identified by this bookmark name.
- *
- * @return bool Whether the internal cursor was successfully moved to the bookmark's location.
* @since 6.2.0
*
+ * @param string $bookmark_name Jump to the place in the document identified by this bookmark name.
+ * @return bool Whether the internal cursor was successfully moved to the bookmark's location.
*/
public function seek( $bookmark_name ): bool {
if ( ! array_key_exists( $bookmark_name, $this->bookmarks ) ) {
@@ -2576,17 +2555,24 @@ public function seek( $bookmark_name ): bool {
__( 'Unknown bookmark name.' ),
'6.2.0'
);
-
return false;
}
- if ( ++ $this->seek_count > static::MAX_SEEK_OPS ) {
+ $existing_bookmark = $this->bookmarks[ $bookmark_name ];
+
+ if (
+ $this->token_starts_at === $existing_bookmark->start &&
+ $this->token_length === $existing_bookmark->length
+ ) {
+ return true;
+ }
+
+ if ( ++$this->seek_count > static::MAX_SEEK_OPS ) {
_doing_it_wrong(
__METHOD__,
__( 'Too many calls to seek() - this can lead to performance issues.' ),
'6.2.0'
);
-
return false;
}
@@ -2596,19 +2582,17 @@ public function seek( $bookmark_name ): bool {
// Point this tag processor before the sought tag opener and consume it.
$this->bytes_already_parsed = $this->bookmarks[ $bookmark_name ]->start;
$this->parser_state = self::STATE_READY;
-
return $this->next_token();
}
/**
* Compare two WP_HTML_Text_Replacement objects.
*
- * @param WP_HTML_Text_Replacement $a First attribute update.
- * @param WP_HTML_Text_Replacement $b Second attribute update.
- *
- * @return int Comparison value for string order.
* @since 6.2.0
*
+ * @param WP_HTML_Text_Replacement $a First attribute update.
+ * @param WP_HTML_Text_Replacement $b Second attribute update.
+ * @return int Comparison value for string order.
*/
private static function sort_start_ascending( WP_HTML_Text_Replacement $a, WP_HTML_Text_Replacement $b ): int {
$by_start = $a->start - $b->start;
@@ -2625,7 +2609,6 @@ private static function sort_start_ascending( WP_HTML_Text_Replacement $a, WP_HT
* This code should be unreachable, because it implies the two replacements
* start at the same location and contain the same text.
*/
-
return $a->length - $b->length;
}
@@ -2638,11 +2621,10 @@ private static function sort_start_ascending( WP_HTML_Text_Replacement $a, WP_HT
* - If an attribute is enqueued to be removed, the return will be `null` to indicate that.
* - If no updates are enqueued, the return will be `false` to differentiate from "removed."
*
- * @param string $comparable_name The attribute name in its comparable form.
- *
- * @return string|boolean|null Value of enqueued update if present, otherwise false.
* @since 6.2.0
*
+ * @param string $comparable_name The attribute name in its comparable form.
+ * @return string|boolean|null Value of enqueued update if present, otherwise false.
*/
private function get_enqueued_attribute_value( string $comparable_name ) {
if ( self::STATE_MATCHED_TAG !== $this->parser_state ) {
@@ -2692,8 +2674,7 @@ private function get_enqueued_attribute_value( string $comparable_name ) {
* 2. Double-quoting starts one after the equals sign.
* 3. Double-quoting ends at the last character in the update.
*/
- $enqueued_value = substr( $enqueued_text, $equals_at + 2, - 1 );
-
+ $enqueued_value = substr( $enqueued_text, $equals_at + 2, -1 );
return WP_HTML_Decoder::decode_attribute( $enqueued_value );
}
@@ -2711,11 +2692,10 @@ private function get_enqueued_attribute_value( string $comparable_name ) {
* $p->next_tag() === false;
* $p->get_attribute( 'class' ) === null;
*
- * @param string $name Name of attribute whose value is requested.
- *
- * @return string|true|null Value of attribute or `null` if not available. Boolean attributes return `true`.
* @since 6.2.0
*
+ * @param string $name Name of attribute whose value is requested.
+ * @return string|true|null Value of attribute or `null` if not available. Boolean attributes return `true`.
*/
public function get_attribute( $name ) {
if ( self::STATE_MATCHED_TAG !== $this->parser_state ) {
@@ -2790,13 +2770,12 @@ public function get_attribute( $name ) {
* $p->next_tag() === false;
* $p->get_attribute_names_with_prefix( 'data-' ) === null;
*
- * @param string $prefix Prefix of requested attribute names.
- *
- * @return array|null List of attribute names, or `null` when no tag opener is matched.
* @since 6.2.0
*
* @see https://html.spec.whatwg.org/multipage/syntax.html#attributes-2:ascii-case-insensitive
*
+ * @param string $prefix Prefix of requested attribute names.
+ * @return array|null List of attribute names, or `null` when no tag opener is matched.
*/
public function get_attribute_names_with_prefix( $prefix ): ?array {
if (
@@ -2810,20 +2789,19 @@ public function get_attribute_names_with_prefix( $prefix ): ?array {
$matches = array();
foreach ( array_keys( $this->attributes ) as $attr_name ) {
- if ( strncmp( $attr_name, $comparable, strlen( $comparable ) ) === 0 ) {
+ if ( str_starts_with( $attr_name, $comparable ) ) {
$matches[] = $attr_name;
}
}
-
return $matches;
}
/**
* Returns the namespace of the matched token.
*
- * @return string One of 'html', 'math', or 'svg'.
* @since 6.7.0
*
+ * @return string One of 'html', 'math', or 'svg'.
*/
public function get_namespace(): string {
return $this->parsing_namespace;
@@ -2841,9 +2819,9 @@ public function get_namespace(): string {
* $p->next_tag() === false;
* $p->get_tag() === null;
*
- * @return string|null Name of currently matched tag in input HTML, or `null` if none found.
* @since 6.2.0
*
+ * @return string|null Name of currently matched tag in input HTML, or `null` if none found.
*/
public function get_tag(): ?string {
if ( null === $this->tag_name_starts_at ) {
@@ -2870,9 +2848,9 @@ public function get_tag(): ?string {
* Returns the adjusted tag name for a given token, taking into
* account the current parsing context, whether HTML, SVG, or MathML.
*
- * @return string|null Name of current tag name.
* @since 6.7.0
*
+ * @return string|null Name of current tag name.
*/
public function get_qualified_tag_name(): ?string {
$tag_name = $this->get_tag();
@@ -3015,11 +2993,11 @@ public function get_qualified_tag_name(): ?string {
* Returns the adjusted attribute name for a given attribute, taking into
* account the current parsing context, whether HTML, SVG, or MathML.
*
- * @param string $attribute_name Which attribute to adjust.
- *
- * @return string|null
* @since 6.7.0
*
+ * @param string $attribute_name Which attribute to adjust.
+ *
+ * @return string|null
*/
public function get_qualified_attribute_name( $attribute_name ): ?string {
if ( self::STATE_MATCHED_TAG !== $this->parser_state ) {
@@ -3264,9 +3242,9 @@ public function get_qualified_attribute_name( $attribute_name ): ?string {
* This function does not determine if a tag is self-closing,
* but only if the self-closing flag is present in the syntax.
*
- * @return bool Whether the currently matched tag contains the self-closing flag.
* @since 6.3.0
*
+ * @return bool Whether the currently matched tag contains the self-closing flag.
*/
public function has_self_closing_flag(): bool {
if ( self::STATE_MATCHED_TAG !== $this->parser_state ) {
@@ -3281,7 +3259,6 @@ public function has_self_closing_flag(): bool {
*
* ^ this appears one character before the end of the closing ">".
*/
-
return '/' === $this->html[ $this->token_starts_at + $this->token_length - 2 ];
}
@@ -3297,10 +3274,10 @@ public function has_self_closing_flag(): bool {
* $p->next_tag( array( 'tag_name' => 'div', 'tag_closers' => 'visit' ) );
* $p->is_tag_closer() === true;
*
- * @return bool Whether the current tag is a tag closer.
+ * @since 6.2.0
* @since 6.7.0 Reports all BR tags as opening tags.
*
- * @since 6.2.0
+ * @return bool Whether the current tag is a tag closer.
*/
public function is_tag_closer(): bool {
return (
@@ -3336,9 +3313,9 @@ public function is_tag_closer(): bool {
* - `#presumptuous-tag` when matched on an empty tag closer.
* - `#funky-comment` when matched on a funky comment.
*
- * @return string|null What kind of token is matched, or null.
* @since 6.5.0
*
+ * @return string|null What kind of token is matched, or null.
*/
public function get_token_type(): ?string {
switch ( $this->parser_state ) {
@@ -3369,9 +3346,9 @@ public function get_token_type(): ?string {
* hasn't yet found a token or because it reached the end
* of the document without matching a token.
*
- * @return string|null Name of the matched token.
* @since 6.5.0
*
+ * @return string|null Name of the matched token.
*/
public function get_token_name(): ?string {
switch ( $this->parser_state ) {
@@ -3409,7 +3386,7 @@ public function get_token_name(): ?string {
* they are commonly known, but a number of unrelated syntax errors
* also produce comments.
*
- * @return string|null
+ * @see self::COMMENT_AS_ABRUPTLY_CLOSED_COMMENT
* @see self::COMMENT_AS_CDATA_LOOKALIKE
* @see self::COMMENT_AS_INVALID_HTML
* @see self::COMMENT_AS_HTML_COMMENT
@@ -3417,7 +3394,7 @@ public function get_token_name(): ?string {
*
* @since 6.5.0
*
- * @see self::COMMENT_AS_ABRUPTLY_CLOSED_COMMENT
+ * @return string|null
*/
public function get_comment_type(): ?string {
if ( self::STATE_COMMENT !== $this->parser_state ) {
@@ -3440,10 +3417,10 @@ public function get_comment_type(): ?string {
* that character were modified, it would be possible to change the node
* type.
*
- * @return string|null The comment text as it would appear in the browser or null
- * if not on a comment type node.
* @since 6.7.0
*
+ * @return string|null The comment text as it would appear in the browser or null
+ * if not on a comment type node.
*/
public function get_full_comment_text(): ?string {
if ( self::STATE_FUNKY_COMMENT === $this->parser_state ) {
@@ -3473,7 +3450,6 @@ public function get_full_comment_text(): ?string {
case self::COMMENT_AS_INVALID_HTML:
$preceding_character = $this->html[ $this->text_starts_at - 1 ];
$comment_start = '?' === $preceding_character ? '?' : '';
-
return "{$comment_start}{$this->get_modifiable_text()}";
}
@@ -3507,9 +3483,9 @@ public function get_full_comment_text(): ?string {
* true === $processor->next_token(); // Text is "More".
* false === $processor->subdivide_text_appropriately();
*
- * @return bool Whether the text node was subdivided.
* @since 6.7.0
*
+ * @return bool Whether the text node was subdivided.
*/
public function subdivide_text_appropriately(): bool {
if ( self::STATE_TEXT_NODE !== $this->parser_state ) {
@@ -3528,7 +3504,6 @@ public function subdivide_text_appropriately(): bool {
$this->text_length = $leading_nulls;
$this->bytes_already_parsed = $this->token_starts_at + $leading_nulls;
$this->text_node_classification = self::TEXT_IS_NULL_SEQUENCE;
-
return true;
}
@@ -3541,7 +3516,7 @@ public function subdivide_text_appropriately(): bool {
$end = $this->text_starts_at + $this->text_length;
while ( $at < $end ) {
$skipped = strspn( $this->html, " \t\f\r\n", $at, $end - $at );
- $at += $skipped;
+ $at += $skipped;
if ( $at < $end && '&' === $this->html[ $at ] ) {
$matched_byte_length = null;
@@ -3561,7 +3536,6 @@ public function subdivide_text_appropriately(): bool {
$this->token_length = $new_length;
$this->bytes_already_parsed = $at;
$this->text_node_classification = self::TEXT_IS_WHITESPACE;
-
return true;
}
@@ -3591,10 +3565,10 @@ public function subdivide_text_appropriately(): bool {
* newline is treated properly, seek to the LISTING or PRE opening
* tag instead of to the first text node inside the element.
*
- * @return string
+ * @since 6.5.0
* @since 6.7.0 Replaces NULL bytes (U+0000) and newlines appropriately.
*
- * @since 6.5.0
+ * @return string
*/
public function get_modifiable_text(): string {
$has_enqueued_update = isset( $this->lexical_updates['modifiable text'] );
@@ -3671,7 +3645,6 @@ public function get_modifiable_text(): string {
* text is processed according to the insertion mode, not according
* to the foreign content rules. This should strip the NULL bytes.
*/
-
return ( '#text' === $tag_name && 'html' === $this->get_namespace() )
? str_replace( "\x00", '', $decoded )
: str_replace( "\x00", "\u{FFFD}", $decoded );
@@ -3717,11 +3690,11 @@ public function get_modifiable_text(): string {
* $processor->set_modifiable_text( str_replace( ':)', 'π', $chunk ) );
* }
*
- * @param string $plaintext_content New text content to represent in the matched token.
- *
- * @return bool Whether the text was able to update.
* @since 6.7.0
*
+ * @param string $plaintext_content New text content to represent in the matched token.
+ *
+ * @return bool Whether the text was able to update.
*/
public function set_modifiable_text( string $plaintext_content ): bool {
if ( self::STATE_TEXT_NODE === $this->parser_state ) {
@@ -3837,13 +3810,12 @@ static function ( $tag_match ) {
*
* For string attributes, the value is escaped using the `esc_attr` function.
*
- * @param string $name The attribute name to target.
- * @param string|bool $value The new attribute value.
- *
- * @return bool Whether an attribute value was set.
+ * @since 6.2.0
* @since 6.2.1 Fix: Only create a single update for multiple calls with case-variant attribute names.
*
- * @since 6.2.0
+ * @param string $name The attribute name to target.
+ * @param string|bool $value The new attribute value.
+ * @return bool Whether an attribute value was set.
*/
public function set_attribute( $name, $value ): bool {
if (
@@ -3874,17 +3846,17 @@ public function set_attribute( $name, $value ): bool {
*/
if ( preg_match(
'~[' .
- // Syntax-like characters.
- '"\'>& =' .
- // Control characters.
- '\x{00}-\x{1F}' .
- // HTML noncharacters.
- '\x{FDD0}-\x{FDEF}' .
- '\x{FFFE}\x{FFFF}\x{1FFFE}\x{1FFFF}\x{2FFFE}\x{2FFFF}\x{3FFFE}\x{3FFFF}' .
- '\x{4FFFE}\x{4FFFF}\x{5FFFE}\x{5FFFF}\x{6FFFE}\x{6FFFF}\x{7FFFE}\x{7FFFF}' .
- '\x{8FFFE}\x{8FFFF}\x{9FFFE}\x{9FFFF}\x{AFFFE}\x{AFFFF}\x{BFFFE}\x{BFFFF}' .
- '\x{CFFFE}\x{CFFFF}\x{DFFFE}\x{DFFFF}\x{EFFFE}\x{EFFFF}\x{FFFFE}\x{FFFFF}' .
- '\x{10FFFE}\x{10FFFF}' .
+ // Syntax-like characters.
+ '"\'>& =' .
+ // Control characters.
+ '\x{00}-\x{1F}' .
+ // HTML noncharacters.
+ '\x{FDD0}-\x{FDEF}' .
+ '\x{FFFE}\x{FFFF}\x{1FFFE}\x{1FFFF}\x{2FFFE}\x{2FFFF}\x{3FFFE}\x{3FFFF}' .
+ '\x{4FFFE}\x{4FFFF}\x{5FFFE}\x{5FFFF}\x{6FFFE}\x{6FFFF}\x{7FFFE}\x{7FFFF}' .
+ '\x{8FFFE}\x{8FFFF}\x{9FFFE}\x{9FFFF}\x{AFFFE}\x{AFFFF}\x{BFFFE}\x{BFFFF}' .
+ '\x{CFFFE}\x{CFFFF}\x{DFFFE}\x{DFFFF}\x{EFFFE}\x{EFFFF}\x{FFFFE}\x{FFFFF}' .
+ '\x{10FFFE}\x{10FFFF}' .
']~Ssu',
$name
) ) {
@@ -3989,11 +3961,10 @@ public function set_attribute( $name, $value ): bool {
/**
* Remove an attribute from the currently-matched tag.
*
- * @param string $name The attribute name to remove.
- *
- * @return bool Whether an attribute was removed.
* @since 6.2.0
*
+ * @param string $name The attribute name to remove.
+ * @return bool Whether an attribute was removed.
*/
public function remove_attribute( $name ): bool {
if (
@@ -4033,7 +4004,6 @@ public function remove_attribute( $name ): bool {
if ( isset( $this->lexical_updates[ $name ] ) ) {
unset( $this->lexical_updates[ $name ] );
}
-
return false;
}
@@ -4069,11 +4039,10 @@ public function remove_attribute( $name ): bool {
/**
* Adds a new class name to the currently matched tag.
*
- * @param string $class_name The class name to add.
- *
- * @return bool Whether the class was set to be added.
* @since 6.2.0
*
+ * @param string $class_name The class name to add.
+ * @return bool Whether the class was set to be added.
*/
public function add_class( $class_name ): bool {
if (
@@ -4085,7 +4054,6 @@ public function add_class( $class_name ): bool {
if ( self::QUIRKS_MODE !== $this->compat_mode ) {
$this->classname_updates[ $class_name ] = self::ADD_CLASS;
-
return true;
}
@@ -4102,24 +4070,21 @@ public function add_class( $class_name ): bool {
0 === substr_compare( $updated_name, $class_name, 0, $class_name_length, true )
) {
$this->classname_updates[ $updated_name ] = self::ADD_CLASS;
-
return true;
}
}
$this->classname_updates[ $class_name ] = self::ADD_CLASS;
-
return true;
}
/**
* Removes a class name from the currently matched tag.
*
- * @param string $class_name The class name to remove.
- *
- * @return bool Whether the class was set to be removed.
* @since 6.2.0
*
+ * @param string $class_name The class name to remove.
+ * @return bool Whether the class was set to be removed.
*/
public function remove_class( $class_name ): bool {
if (
@@ -4131,7 +4096,6 @@ public function remove_class( $class_name ): bool {
if ( self::QUIRKS_MODE !== $this->compat_mode ) {
$this->classname_updates[ $class_name ] = self::REMOVE_CLASS;
-
return true;
}
@@ -4148,24 +4112,22 @@ public function remove_class( $class_name ): bool {
0 === substr_compare( $updated_name, $class_name, 0, $class_name_length, true )
) {
$this->classname_updates[ $updated_name ] = self::REMOVE_CLASS;
-
return true;
}
}
$this->classname_updates[ $class_name ] = self::REMOVE_CLASS;
-
return true;
}
/**
* Returns the string representation of the HTML Tag Processor.
*
- * @return string The processed HTML.
- * @see WP_HTML_Tag_Processor::get_updated_html()
- *
* @since 6.2.0
*
+ * @see WP_HTML_Tag_Processor::get_updated_html()
+ *
+ * @return string The processed HTML.
*/
public function __toString(): string {
return $this->get_updated_html();
@@ -4174,11 +4136,11 @@ public function __toString(): string {
/**
* Returns the string representation of the HTML Tag Processor.
*
- * @return string The processed HTML.
+ * @since 6.2.0
* @since 6.2.1 Shifts the internal cursor corresponding to the applied updates.
* @since 6.4.0 No longer calls subclass method `next_tag()` after updating HTML.
*
- * @since 6.2.0
+ * @return string The processed HTML.
*/
public function get_updated_html(): string {
$requires_no_updating = 0 === count( $this->classname_updates ) && 0 === count( $this->lexical_updates );
@@ -4232,18 +4194,18 @@ public function get_updated_html(): string {
/**
* Parses tag query input into internal search criteria.
*
- * @param array|string|null $query {
+ * @since 6.2.0
+ *
+ * @param array|string|null $query {
* Optional. Which tag name to find, having which class, etc. Default is to find any tag.
*
- * @type string|null $tag_name Which tag to find, or `null` for "any tag."
- * @type int|null $match_offset Find the Nth tag matching all search criteria.
+ * @type string|null $tag_name Which tag to find, or `null` for "any tag."
+ * @type int|null $match_offset Find the Nth tag matching all search criteria.
* 1 for "first" tag, 3 for "third," etc.
* Defaults to first tag.
- * @type string|null $class_name Tag must contain this class name to match.
- * @type string $tag_closers "visit" or "skip": whether to stop on tag closers, e.g. .
+ * @type string|null $class_name Tag must contain this class name to match.
+ * @type string $tag_closers "visit" or "skip": whether to stop on tag closers, e.g. .
* }
- * @since 6.2.0
- *
*/
private function parse_query( $query ) {
if ( null !== $query && $query === $this->last_query ) {
@@ -4259,7 +4221,6 @@ private function parse_query( $query ) {
// A single string value means "find the tag of this name".
if ( is_string( $query ) ) {
$this->sought_tag_name = $query;
-
return;
}
@@ -4275,7 +4236,6 @@ private function parse_query( $query ) {
__( 'The query argument must be an array or a tag name.' ),
'6.2.0'
);
-
return;
}
@@ -4300,9 +4260,9 @@ private function parse_query( $query ) {
/**
* Checks whether a given tag and its attributes match the search criteria.
*
- * @return bool Whether the given tag and its attribute match the search criteria.
* @since 6.2.0
*
+ * @return bool Whether the given tag and its attribute match the search criteria.
*/
private function matches(): bool {
if ( $this->is_closing_tag && ! $this->stop_on_tag_closers ) {
diff --git a/components/HTML/class-wp-html-text-replacement.php b/components/HTML/class-wp-html-text-replacement.php
index e94d271e..dd19ebc7 100644
--- a/components/HTML/class-wp-html-text-replacement.php
+++ b/components/HTML/class-wp-html-text-replacement.php
@@ -1,4 +1,6 @@
start = $start;
diff --git a/components/HTML/class-wp-html-token.php b/components/HTML/class-wp-html-token.php
index dc6bbe63..370dd0e4 100644
--- a/components/HTML/class-wp-html-token.php
+++ b/components/HTML/class-wp-html-token.php
@@ -1,4 +1,6 @@
bookmark_name = $bookmark_name;
@@ -122,6 +123,6 @@ public function __destruct() {
* @since 6.4.2
*/
public function __wakeup() {
- throw new LogicException( __CLASS__ . ' should never be unserialized' );
+ throw new \LogicException( __CLASS__ . ' should never be unserialized' );
}
}
diff --git a/components/HTML/class-wp-html-unsupported-exception.php b/components/HTML/class-wp-html-unsupported-exception.php
index f20e436d..43cb4dd2 100644
--- a/components/HTML/class-wp-html-unsupported-exception.php
+++ b/components/HTML/class-wp-html-unsupported-exception.php
@@ -1,4 +1,7 @@
token_name = $token_name;
$this->token_at = $token_at;
$this->token = $token;
- $this->stack_of_open_elements = $stack_of_open_elements;
+ $this->stack_of_open_elements = $stack_of_open_elements;
$this->active_formatting_elements = $active_formatting_elements;
}
}
diff --git a/components/HTML/class-wp-token-map.php b/components/HTML/class-wp-token-map.php
index 0687a34d..946b7a7f 100644
--- a/components/HTML/class-wp-token-map.php
+++ b/components/HTML/class-wp-token-map.php
@@ -1,5 +1,9 @@
'π',
* ) );
*
- * @param array $mappings The keys transform into the values, both are strings.
- * @param int $key_length Determines the group key length. Leave at the default value
+ * @since 6.6.0
+ *
+ * @param array $mappings The keys transform into the values, both are strings.
+ * @param int $key_length Determines the group key length. Leave at the default value
* of 2 unless there's an empirical reason to change it.
*
* @return WP_Token_Map|null Token map, unless unable to create it.
- * @since 6.6.0
- *
*/
public static function from_array( array $mappings, int $key_length = 2 ): ?WP_Token_Map {
$map = new WP_Token_Map();
@@ -296,13 +300,12 @@ public static function from_array( array $mappings, int $key_length = 2 ): ?WP_T
_doing_it_wrong(
__METHOD__,
sprintf(
- /* translators: 1: maximum byte length (a count) */
+ /* translators: 1: maximum byte length (a count) */
__( 'Token Map tokens and substitutions must all be shorter than %1$d bytes.' ),
self::MAX_LENGTH
),
'6.6.0'
);
-
return null;
}
@@ -338,7 +341,7 @@ static function ( array $a, array $b ): int {
// Finally construct the optimized lookups.
foreach ( $shorts as $word ) {
- $map->small_words .= str_pad( $word, $key_length + 1, "\x00", STR_PAD_RIGHT );
+ $map->small_words .= str_pad( $word, $key_length + 1, "\x00", STR_PAD_RIGHT );
$map->small_mappings[] = $mappings[ $word ];
}
@@ -355,7 +358,7 @@ static function ( array $a, array $b ): int {
$word_length = pack( 'C', strlen( $word ) );
$mapping_length = pack( 'C', strlen( $mapping ) );
- $group_string .= "{$word_length}{$word}{$mapping_length}{$mapping}";
+ $group_string .= "{$word_length}{$word}{$mapping_length}{$mapping}";
}
$map->large_words[] = $group_string;
@@ -371,20 +374,20 @@ static function ( array $a, array $b ): int {
* This function should only be used to load data created with
* WP_Token_Map::precomputed_php_source_tag().
*
- * @param array $state {
+ * @since 6.6.0
+ *
+ * @param array $state {
* Stores pre-computed state for directly loading into a Token Map.
*
- * @type string $storage_version Which version of the code produced this state.
- * @type int $key_length Group key length.
- * @type string $groups Group lookup index.
- * @type array $large_words Large word groups and packed strings.
- * @type string $small_words Small words packed string.
- * @type array $small_mappings Small word mappings.
+ * @type string $storage_version Which version of the code produced this state.
+ * @type int $key_length Group key length.
+ * @type string $groups Group lookup index.
+ * @type array $large_words Large word groups and packed strings.
+ * @type string $small_words Small words packed string.
+ * @type array $small_mappings Small word mappings.
* }
*
* @return WP_Token_Map Map with precomputed data loaded.
- * @since 6.6.0
- *
*/
public static function from_precomputed_table( $state ): ?WP_Token_Map {
$has_necessary_state = isset(
@@ -402,7 +405,6 @@ public static function from_precomputed_table( $state ): ?WP_Token_Map {
__( 'Missing required inputs to pre-computed WP_Token_Map.' ),
'6.6.0'
);
-
return null;
}
@@ -410,11 +412,9 @@ public static function from_precomputed_table( $state ): ?WP_Token_Map {
_doing_it_wrong(
__METHOD__,
/* translators: 1: version string, 2: version string. */
- sprintf( __( 'Loaded version \'%1$s\' incompatible with expected version \'%2$s\'.' ), $state['storage_version'],
- self::STORAGE_VERSION ),
+ sprintf( __( 'Loaded version \'%1$s\' incompatible with expected version \'%2$s\'.' ), $state['storage_version'], self::STORAGE_VERSION ),
'6.6.0'
);
-
return null;
}
@@ -437,12 +437,11 @@ public static function from_precomputed_table( $state ): ?WP_Token_Map {
* true === $smilies->contains( ':)' );
* false === $smilies->contains( 'simile' );
*
- * @param string $word Determine if this word is a lookup key in the map.
- * @param string $case_sensitivity Optional. Pass 'ascii-case-insensitive' to ignore ASCII case when matching. Default 'case-sensitive'.
- *
- * @return bool Whether there's an entry for the given word in the map.
* @since 6.6.0
*
+ * @param string $word Determine if this word is a lookup key in the map.
+ * @param string $case_sensitivity Optional. Pass 'ascii-case-insensitive' to ignore ASCII case when matching. Default 'case-sensitive'.
+ * @return bool Whether there's an entry for the given word in the map.
*/
public function contains( string $word, string $case_sensitivity = 'case-sensitive' ): bool {
$ignore_case = 'ascii-case-insensitive' === $case_sensitivity;
@@ -473,10 +472,10 @@ public function contains( string $word, string $case_sensitivity = 'case-sensiti
$at = 0;
while ( $at < $group_length ) {
- $token_length = unpack( 'C', $group[ $at ++ ] )[1];
+ $token_length = unpack( 'C', $group[ $at++ ] )[1];
$token_at = $at;
- $at += $token_length;
- $mapping_length = unpack( 'C', $group[ $at ++ ] )[1];
+ $at += $token_length;
+ $mapping_length = unpack( 'C', $group[ $at++ ] )[1];
$mapping_at = $at;
if ( $token_length === $length && 0 === substr_compare( $group, $slug, $token_at, $token_length, $ignore_case ) ) {
@@ -523,21 +522,16 @@ public function contains( string $word, string $case_sensitivity = 'case-sensiti
* $output .= "{$prefix}{$smily}";
* }
*
- * @param string $text String in which to search for a lookup key.
- * @param int $offset Optional. How many bytes into the string where the lookup key ought to start. Default 0.
- * @param int|null &$matched_token_byte_length Optional. Holds byte-length of found token matched, otherwise not set. Default null.
- * @param string $case_sensitivity Optional. Pass 'ascii-case-insensitive' to ignore ASCII case when matching. Default 'case-sensitive'.
- *
- * @return string|null Mapped value of lookup key if found, otherwise `null`.
* @since 6.6.0
*
+ * @param string $text String in which to search for a lookup key.
+ * @param int $offset Optional. How many bytes into the string where the lookup key ought to start. Default 0.
+ * @param int|null &$matched_token_byte_length Optional. Holds byte-length of found token matched, otherwise not set. Default null.
+ * @param string $case_sensitivity Optional. Pass 'ascii-case-insensitive' to ignore ASCII case when matching. Default 'case-sensitive'.
+ *
+ * @return string|null Mapped value of lookup key if found, otherwise `null`.
*/
- public function read_token(
- string $text,
- int $offset = 0,
- &$matched_token_byte_length = null,
- $case_sensitivity = 'case-sensitive'
- ): ?string {
+ public function read_token( string $text, int $offset = 0, &$matched_token_byte_length = null, $case_sensitivity = 'case-sensitive' ): ?string {
$ignore_case = 'ascii-case-insensitive' === $case_sensitivity;
$text_length = strlen( $text );
@@ -557,15 +551,14 @@ public function read_token(
$group_length = strlen( $group );
$at = 0;
while ( $at < $group_length ) {
- $token_length = unpack( 'C', $group[ $at ++ ] )[1];
+ $token_length = unpack( 'C', $group[ $at++ ] )[1];
$token = substr( $group, $at, $token_length );
- $at += $token_length;
- $mapping_length = unpack( 'C', $group[ $at ++ ] )[1];
+ $at += $token_length;
+ $mapping_length = unpack( 'C', $group[ $at++ ] )[1];
$mapping_at = $at;
if ( 0 === substr_compare( $text, $token, $offset + $this->key_length, $token_length, $ignore_case ) ) {
$matched_token_byte_length = $this->key_length + $token_length;
-
return substr( $group, $mapping_at, $mapping_length );
}
@@ -582,21 +575,16 @@ public function read_token(
/**
* Finds a match for a short word at the index.
*
- * @param string $text String in which to search for a lookup key.
- * @param int $offset Optional. How many bytes into the string where the lookup key ought to start. Default 0.
- * @param int|null &$matched_token_byte_length Optional. Holds byte-length of found lookup key if matched, otherwise not set. Default null.
- * @param string $case_sensitivity Optional. Pass 'ascii-case-insensitive' to ignore ASCII case when matching. Default 'case-sensitive'.
- *
- * @return string|null Mapped value of lookup key if found, otherwise `null`.
* @since 6.6.0
*
+ * @param string $text String in which to search for a lookup key.
+ * @param int $offset Optional. How many bytes into the string where the lookup key ought to start. Default 0.
+ * @param int|null &$matched_token_byte_length Optional. Holds byte-length of found lookup key if matched, otherwise not set. Default null.
+ * @param string $case_sensitivity Optional. Pass 'ascii-case-insensitive' to ignore ASCII case when matching. Default 'case-sensitive'.
+ *
+ * @return string|null Mapped value of lookup key if found, otherwise `null`.
*/
- private function read_small_token(
- string $text,
- int $offset = 0,
- &$matched_token_byte_length = null,
- $case_sensitivity = 'case-sensitive'
- ): ?string {
+ private function read_small_token( string $text, int $offset = 0, &$matched_token_byte_length = null, $case_sensitivity = 'case-sensitive' ): ?string {
$ignore_case = 'ascii-case-insensitive' === $case_sensitivity;
$small_length = strlen( $this->small_words );
$search_text = substr( $text, $offset, $this->key_length );
@@ -615,10 +603,9 @@ private function read_small_token(
continue;
}
- for ( $adjust = 1; $adjust < $this->key_length; $adjust ++ ) {
+ for ( $adjust = 1; $adjust < $this->key_length; $adjust++ ) {
if ( "\x00" === $this->small_words[ $at + $adjust ] ) {
$matched_token_byte_length = $adjust;
-
return $this->small_mappings[ $at / ( $this->key_length + 1 ) ];
}
@@ -632,7 +619,6 @@ private function read_small_token(
}
$matched_token_byte_length = $adjust;
-
return $this->small_mappings[ $at / ( $this->key_length + 1 ) ];
}
@@ -661,7 +647,7 @@ public function to_array(): array {
$small_length = strlen( $this->small_words );
while ( $at < $small_length ) {
$key = rtrim( substr( $this->small_words, $at, $this->key_length + 1 ), "\x00" );
- $value = $this->small_mappings[ $small_mapping ++ ];
+ $value = $this->small_mappings[ $small_mapping++ ];
$tokens[ $key ] = $value;
$at += $this->key_length + 1;
@@ -672,15 +658,15 @@ public function to_array(): array {
$group_length = strlen( $group );
$at = 0;
while ( $at < $group_length ) {
- $length = unpack( 'C', $group[ $at ++ ] )[1];
+ $length = unpack( 'C', $group[ $at++ ] )[1];
$key = $prefix . substr( $group, $at, $length );
- $at += $length;
- $length = unpack( 'C', $group[ $at ++ ] )[1];
+ $at += $length;
+ $length = unpack( 'C', $group[ $at++ ] )[1];
$value = substr( $group, $at, $length );
$tokens[ $key ] = $value;
- $at += $length;
+ $at += $length;
}
}
@@ -710,11 +696,10 @@ public function to_array(): array {
* )
* );
*
- * @param string $indent Optional. Use this string for indentation, or rely on the default horizontal tab character. Default "\t".
- *
- * @return string Value which can be pasted into a PHP source file for quick loading of table.
* @since 6.6.0
*
+ * @param string $indent Optional. Use this string for indentation, or rely on the default horizontal tab character. Default "\t".
+ * @return string Value which can be pasted into a PHP source file for quick loading of table.
*/
public function precomputed_php_source_table( string $indent = "\t" ): string {
$i1 = $indent;
@@ -723,13 +708,13 @@ public function precomputed_php_source_table( string $indent = "\t" ): string {
$class_version = self::STORAGE_VERSION;
- $output = self::class . "::from_precomputed_table(\n";
+ $output = self::class . "::from_precomputed_table(\n";
$output .= "{$i1}array(\n";
$output .= "{$i2}\"storage_version\" => \"{$class_version}\",\n";
$output .= "{$i2}\"key_length\" => {$this->key_length},\n";
$group_line = str_replace( "\x00", "\\x00", $this->groups );
- $output .= "{$i2}\"groups\" => \"{$group_line}\",\n";
+ $output .= "{$i2}\"groups\" => \"{$group_line}\",\n";
$output .= "{$i2}\"large_words\" => array(\n";
@@ -744,12 +729,12 @@ public function precomputed_php_source_table( string $indent = "\t" ): string {
$data_line = "{$i3}\"";
$at = 0;
while ( $at < $group_length ) {
- $token_length = unpack( 'C', $group[ $at ++ ] )[1];
+ $token_length = unpack( 'C', $group[ $at++ ] )[1];
$token = substr( $group, $at, $token_length );
- $at += $token_length;
- $mapping_length = unpack( 'C', $group[ $at ++ ] )[1];
+ $at += $token_length;
+ $mapping_length = unpack( 'C', $group[ $at++ ] )[1];
$mapping = substr( $group, $at, $mapping_length );
- $at += $mapping_length;
+ $at += $mapping_length;
$token_digits = str_pad( dechex( $token_length ), 2, '0', STR_PAD_LEFT );
$mapping_digits = str_pad( dechex( $mapping_length ), 2, '0', STR_PAD_LEFT );
@@ -766,7 +751,6 @@ static function ( $match_result ) {
default:
$hex = dechex( ord( $match_result[0] ) );
-
return "\\x{$hex}";
}
},
@@ -790,11 +774,11 @@ static function ( $match_result ) {
$at = 0;
while ( $at < $small_length ) {
$small_words[] = substr( $this->small_words, $at, $this->key_length + 1 );
- $at += $this->key_length + 1;
+ $at += $this->key_length + 1;
}
$small_text = str_replace( "\x00", '\x00', implode( '', $small_words ) );
- $output .= "{$i2}\"small_words\" => \"{$small_text}\",\n";
+ $output .= "{$i2}\"small_words\" => \"{$small_text}\",\n";
$output .= "{$i2}\"small_mappings\" => array(\n";
foreach ( $this->small_mappings as $mapping ) {
@@ -816,12 +800,11 @@ static function ( $match_result ) {
* match. For example, it should not detect `Cap` when matching
* against the string `CapitalDifferentialD`.
*
- * @param string $a First string to compare.
- * @param string $b Second string to compare.
- *
- * @return int -1 or lower if `$a` is less than `$b`; 1 or greater if `$a` is greater than `$b`, and 0 if they are equal.
* @since 6.6.0
*
+ * @param string $a First string to compare.
+ * @param string $b Second string to compare.
+ * @return int -1 or lower if `$a` is less than `$b`; 1 or greater if `$a` is greater than `$b`, and 0 if they are equal.
*/
private static function longest_first_then_alphabetical( string $a, string $b ): int {
if ( $a === $b ) {
diff --git a/components/HTML/composer.json b/components/HTML/composer.json
index d4fc89c0..4595f56b 100644
--- a/components/HTML/composer.json
+++ b/components/HTML/composer.json
@@ -1,29 +1,33 @@
{
- "name": "wordpress/html",
- "description": "HTML component for WordPress.",
- "type": "library",
- "authors": [
- {
- "name": "Adam Zielinski",
- "email": "adam@adamziel.com"
- },
- {
- "name": "WordPress Team",
- "email": "wordpress@wordpress.org"
- }
- ],
- "require": {
- "php": ">=7.2"
- },
- "autoload": {
- "classmap": [
- "./"
- ],
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "require-dev": {
- "phpunit/phpunit": "^9.5"
- }
-}
+ "name": "wordpress\/html",
+ "description": "HTML component for WordPress.",
+ "type": "library",
+ "authors": [
+ {
+ "name": "Adam Zielinski",
+ "email": "adam@adamziel.com"
+ },
+ {
+ "name": "WordPress Team",
+ "email": "wordpress@wordpress.org"
+ }
+ ],
+ "require": {
+ "php": ">=7.2"
+ },
+ "autoload": {
+ "psr-4": {
+ "WordPress\\HTML\\": "."
+ },
+ "classmap": [
+ ".\/"
+ ],
+ "exclude-from-classmap": [
+ "\/Tests\/"
+ ]
+ },
+ "require-dev": {
+ "phpunit\/phpunit": "^9.5"
+ },
+ "version": "6.8"
+}
\ No newline at end of file
diff --git a/components/HTML/html5-named-character-references.php b/components/HTML/html5-named-character-references.php
index 53b773d6..f57deb90 100644
--- a/components/HTML/html5-named-character-references.php
+++ b/components/HTML/html5-named-character-references.php
@@ -1,5 +1,7 @@
"6.6.0-trunk",
- "key_length" => 2,
- "groups" => "AE\x00AM\x00Aa\x00Ab\x00Ac\x00Af\x00Ag\x00Al\x00Am\x00An\x00Ao\x00Ap\x00Ar\x00As\x00At\x00Au\x00Ba\x00Bc\x00Be\x00Bf\x00Bo\x00Br\x00Bs\x00Bu\x00CH\x00CO\x00Ca\x00Cc\x00Cd\x00Ce\x00Cf\x00Ch\x00Ci\x00Cl\x00Co\x00Cr\x00Cs\x00Cu\x00DD\x00DJ\x00DS\x00DZ\x00Da\x00Dc\x00De\x00Df\x00Di\x00Do\x00Ds\x00EN\x00ET\x00Ea\x00Ec\x00Ed\x00Ef\x00Eg\x00El\x00Em\x00Eo\x00Ep\x00Eq\x00Es\x00Et\x00Eu\x00Ex\x00Fc\x00Ff\x00Fi\x00Fo\x00Fs\x00GJ\x00GT\x00Ga\x00Gb\x00Gc\x00Gd\x00Gf\x00Gg\x00Go\x00Gr\x00Gs\x00Gt\x00HA\x00Ha\x00Hc\x00Hf\x00Hi\x00Ho\x00Hs\x00Hu\x00IE\x00IJ\x00IO\x00Ia\x00Ic\x00Id\x00If\x00Ig\x00Im\x00In\x00Io\x00Is\x00It\x00Iu\x00Jc\x00Jf\x00Jo\x00Js\x00Ju\x00KH\x00KJ\x00Ka\x00Kc\x00Kf\x00Ko\x00Ks\x00LJ\x00LT\x00La\x00Lc\x00Le\x00Lf\x00Ll\x00Lm\x00Lo\x00Ls\x00Lt\x00Ma\x00Mc\x00Me\x00Mf\x00Mi\x00Mo\x00Ms\x00Mu\x00NJ\x00Na\x00Nc\x00Ne\x00Nf\x00No\x00Ns\x00Nt\x00Nu\x00OE\x00Oa\x00Oc\x00Od\x00Of\x00Og\x00Om\x00Oo\x00Op\x00Or\x00Os\x00Ot\x00Ou\x00Ov\x00Pa\x00Pc\x00Pf\x00Ph\x00Pi\x00Pl\x00Po\x00Pr\x00Ps\x00QU\x00Qf\x00Qo\x00Qs\x00RB\x00RE\x00Ra\x00Rc\x00Re\x00Rf\x00Rh\x00Ri\x00Ro\x00Rr\x00Rs\x00Ru\x00SH\x00SO\x00Sa\x00Sc\x00Sf\x00Sh\x00Si\x00Sm\x00So\x00Sq\x00Ss\x00St\x00Su\x00TH\x00TR\x00TS\x00Ta\x00Tc\x00Tf\x00Th\x00Ti\x00To\x00Tr\x00Ts\x00Ua\x00Ub\x00Uc\x00Ud\x00Uf\x00Ug\x00Um\x00Un\x00Uo\x00Up\x00Ur\x00Us\x00Ut\x00Uu\x00VD\x00Vb\x00Vc\x00Vd\x00Ve\x00Vf\x00Vo\x00Vs\x00Vv\x00Wc\x00We\x00Wf\x00Wo\x00Ws\x00Xf\x00Xi\x00Xo\x00Xs\x00YA\x00YI\x00YU\x00Ya\x00Yc\x00Yf\x00Yo\x00Ys\x00Yu\x00ZH\x00Za\x00Zc\x00Zd\x00Ze\x00Zf\x00Zo\x00Zs\x00aa\x00ab\x00ac\x00ae\x00af\x00ag\x00al\x00am\x00an\x00ao\x00ap\x00ar\x00as\x00at\x00au\x00aw\x00bN\x00ba\x00bb\x00bc\x00bd\x00be\x00bf\x00bi\x00bk\x00bl\x00bn\x00bo\x00bp\x00br\x00bs\x00bu\x00ca\x00cc\x00cd\x00ce\x00cf\x00ch\x00ci\x00cl\x00co\x00cr\x00cs\x00ct\x00cu\x00cw\x00cy\x00dA\x00dH\x00da\x00db\x00dc\x00dd\x00de\x00df\x00dh\x00di\x00dj\x00dl\x00do\x00dr\x00ds\x00dt\x00du\x00dw\x00dz\x00eD\x00ea\x00ec\x00ed\x00ee\x00ef\x00eg\x00el\x00em\x00en\x00eo\x00ep\x00eq\x00er\x00es\x00et\x00eu\x00ex\x00fa\x00fc\x00fe\x00ff\x00fi\x00fj\x00fl\x00fn\x00fo\x00fp\x00fr\x00fs\x00gE\x00ga\x00gb\x00gc\x00gd\x00ge\x00gf\x00gg\x00gi\x00gj\x00gl\x00gn\x00go\x00gr\x00gs\x00gt\x00gv\x00hA\x00ha\x00hb\x00hc\x00he\x00hf\x00hk\x00ho\x00hs\x00hy\x00ia\x00ic\x00ie\x00if\x00ig\x00ii\x00ij\x00im\x00in\x00io\x00ip\x00iq\x00is\x00it\x00iu\x00jc\x00jf\x00jm\x00jo\x00js\x00ju\x00ka\x00kc\x00kf\x00kg\x00kh\x00kj\x00ko\x00ks\x00lA\x00lB\x00lE\x00lH\x00la\x00lb\x00lc\x00ld\x00le\x00lf\x00lg\x00lh\x00lj\x00ll\x00lm\x00ln\x00lo\x00lp\x00lr\x00ls\x00lt\x00lu\x00lv\x00mD\x00ma\x00mc\x00md\x00me\x00mf\x00mh\x00mi\x00ml\x00mn\x00mo\x00mp\x00ms\x00mu\x00nG\x00nL\x00nR\x00nV\x00na\x00nb\x00nc\x00nd\x00ne\x00nf\x00ng\x00nh\x00ni\x00nj\x00nl\x00nm\x00no\x00np\x00nr\x00ns\x00nt\x00nu\x00nv\x00nw\x00oS\x00oa\x00oc\x00od\x00oe\x00of\x00og\x00oh\x00oi\x00ol\x00om\x00oo\x00op\x00or\x00os\x00ot\x00ou\x00ov\x00pa\x00pc\x00pe\x00pf\x00ph\x00pi\x00pl\x00pm\x00po\x00pr\x00ps\x00pu\x00qf\x00qi\x00qo\x00qp\x00qs\x00qu\x00rA\x00rB\x00rH\x00ra\x00rb\x00rc\x00rd\x00re\x00rf\x00rh\x00ri\x00rl\x00rm\x00rn\x00ro\x00rp\x00rr\x00rs\x00rt\x00ru\x00rx\x00sa\x00sb\x00sc\x00sd\x00se\x00sf\x00sh\x00si\x00sl\x00sm\x00so\x00sp\x00sq\x00sr\x00ss\x00st\x00su\x00sw\x00sz\x00ta\x00tb\x00tc\x00td\x00te\x00tf\x00th\x00ti\x00to\x00tp\x00tr\x00ts\x00tw\x00uA\x00uH\x00ua\x00ub\x00uc\x00ud\x00uf\x00ug\x00uh\x00ul\x00um\x00uo\x00up\x00ur\x00us\x00ut\x00uu\x00uw\x00vA\x00vB\x00vD\x00va\x00vc\x00vd\x00ve\x00vf\x00vl\x00vn\x00vo\x00vp\x00vr\x00vs\x00vz\x00wc\x00we\x00wf\x00wo\x00wp\x00wr\x00ws\x00xc\x00xd\x00xf\x00xh\x00xi\x00xl\x00xm\x00xn\x00xo\x00xr\x00xs\x00xu\x00xv\x00xw\x00ya\x00yc\x00ye\x00yf\x00yi\x00yo\x00ys\x00yu\x00za\x00zc\x00zd\x00ze\x00zf\x00zh\x00zi\x00zo\x00zs\x00zw\x00",
- "large_words" => array(
+ "key_length" => 2,
+ "groups" => "AE\x00AM\x00Aa\x00Ab\x00Ac\x00Af\x00Ag\x00Al\x00Am\x00An\x00Ao\x00Ap\x00Ar\x00As\x00At\x00Au\x00Ba\x00Bc\x00Be\x00Bf\x00Bo\x00Br\x00Bs\x00Bu\x00CH\x00CO\x00Ca\x00Cc\x00Cd\x00Ce\x00Cf\x00Ch\x00Ci\x00Cl\x00Co\x00Cr\x00Cs\x00Cu\x00DD\x00DJ\x00DS\x00DZ\x00Da\x00Dc\x00De\x00Df\x00Di\x00Do\x00Ds\x00EN\x00ET\x00Ea\x00Ec\x00Ed\x00Ef\x00Eg\x00El\x00Em\x00Eo\x00Ep\x00Eq\x00Es\x00Et\x00Eu\x00Ex\x00Fc\x00Ff\x00Fi\x00Fo\x00Fs\x00GJ\x00GT\x00Ga\x00Gb\x00Gc\x00Gd\x00Gf\x00Gg\x00Go\x00Gr\x00Gs\x00Gt\x00HA\x00Ha\x00Hc\x00Hf\x00Hi\x00Ho\x00Hs\x00Hu\x00IE\x00IJ\x00IO\x00Ia\x00Ic\x00Id\x00If\x00Ig\x00Im\x00In\x00Io\x00Is\x00It\x00Iu\x00Jc\x00Jf\x00Jo\x00Js\x00Ju\x00KH\x00KJ\x00Ka\x00Kc\x00Kf\x00Ko\x00Ks\x00LJ\x00LT\x00La\x00Lc\x00Le\x00Lf\x00Ll\x00Lm\x00Lo\x00Ls\x00Lt\x00Ma\x00Mc\x00Me\x00Mf\x00Mi\x00Mo\x00Ms\x00Mu\x00NJ\x00Na\x00Nc\x00Ne\x00Nf\x00No\x00Ns\x00Nt\x00Nu\x00OE\x00Oa\x00Oc\x00Od\x00Of\x00Og\x00Om\x00Oo\x00Op\x00Or\x00Os\x00Ot\x00Ou\x00Ov\x00Pa\x00Pc\x00Pf\x00Ph\x00Pi\x00Pl\x00Po\x00Pr\x00Ps\x00QU\x00Qf\x00Qo\x00Qs\x00RB\x00RE\x00Ra\x00Rc\x00Re\x00Rf\x00Rh\x00Ri\x00Ro\x00Rr\x00Rs\x00Ru\x00SH\x00SO\x00Sa\x00Sc\x00Sf\x00Sh\x00Si\x00Sm\x00So\x00Sq\x00Ss\x00St\x00Su\x00TH\x00TR\x00TS\x00Ta\x00Tc\x00Tf\x00Th\x00Ti\x00To\x00Tr\x00Ts\x00Ua\x00Ub\x00Uc\x00Ud\x00Uf\x00Ug\x00Um\x00Un\x00Uo\x00Up\x00Ur\x00Us\x00Ut\x00Uu\x00VD\x00Vb\x00Vc\x00Vd\x00Ve\x00Vf\x00Vo\x00Vs\x00Vv\x00Wc\x00We\x00Wf\x00Wo\x00Ws\x00Xf\x00Xi\x00Xo\x00Xs\x00YA\x00YI\x00YU\x00Ya\x00Yc\x00Yf\x00Yo\x00Ys\x00Yu\x00ZH\x00Za\x00Zc\x00Zd\x00Ze\x00Zf\x00Zo\x00Zs\x00aa\x00ab\x00ac\x00ae\x00af\x00ag\x00al\x00am\x00an\x00ao\x00ap\x00ar\x00as\x00at\x00au\x00aw\x00bN\x00ba\x00bb\x00bc\x00bd\x00be\x00bf\x00bi\x00bk\x00bl\x00bn\x00bo\x00bp\x00br\x00bs\x00bu\x00ca\x00cc\x00cd\x00ce\x00cf\x00ch\x00ci\x00cl\x00co\x00cr\x00cs\x00ct\x00cu\x00cw\x00cy\x00dA\x00dH\x00da\x00db\x00dc\x00dd\x00de\x00df\x00dh\x00di\x00dj\x00dl\x00do\x00dr\x00ds\x00dt\x00du\x00dw\x00dz\x00eD\x00ea\x00ec\x00ed\x00ee\x00ef\x00eg\x00el\x00em\x00en\x00eo\x00ep\x00eq\x00er\x00es\x00et\x00eu\x00ex\x00fa\x00fc\x00fe\x00ff\x00fi\x00fj\x00fl\x00fn\x00fo\x00fp\x00fr\x00fs\x00gE\x00ga\x00gb\x00gc\x00gd\x00ge\x00gf\x00gg\x00gi\x00gj\x00gl\x00gn\x00go\x00gr\x00gs\x00gt\x00gv\x00hA\x00ha\x00hb\x00hc\x00he\x00hf\x00hk\x00ho\x00hs\x00hy\x00ia\x00ic\x00ie\x00if\x00ig\x00ii\x00ij\x00im\x00in\x00io\x00ip\x00iq\x00is\x00it\x00iu\x00jc\x00jf\x00jm\x00jo\x00js\x00ju\x00ka\x00kc\x00kf\x00kg\x00kh\x00kj\x00ko\x00ks\x00lA\x00lB\x00lE\x00lH\x00la\x00lb\x00lc\x00ld\x00le\x00lf\x00lg\x00lh\x00lj\x00ll\x00lm\x00ln\x00lo\x00lp\x00lr\x00ls\x00lt\x00lu\x00lv\x00mD\x00ma\x00mc\x00md\x00me\x00mf\x00mh\x00mi\x00ml\x00mn\x00mo\x00mp\x00ms\x00mu\x00nG\x00nL\x00nR\x00nV\x00na\x00nb\x00nc\x00nd\x00ne\x00nf\x00ng\x00nh\x00ni\x00nj\x00nl\x00nm\x00no\x00np\x00nr\x00ns\x00nt\x00nu\x00nv\x00nw\x00oS\x00oa\x00oc\x00od\x00oe\x00of\x00og\x00oh\x00oi\x00ol\x00om\x00oo\x00op\x00or\x00os\x00ot\x00ou\x00ov\x00pa\x00pc\x00pe\x00pf\x00ph\x00pi\x00pl\x00pm\x00po\x00pr\x00ps\x00pu\x00qf\x00qi\x00qo\x00qp\x00qs\x00qu\x00rA\x00rB\x00rH\x00ra\x00rb\x00rc\x00rd\x00re\x00rf\x00rh\x00ri\x00rl\x00rm\x00rn\x00ro\x00rp\x00rr\x00rs\x00rt\x00ru\x00rx\x00sa\x00sb\x00sc\x00sd\x00se\x00sf\x00sh\x00si\x00sl\x00sm\x00so\x00sp\x00sq\x00sr\x00ss\x00st\x00su\x00sw\x00sz\x00ta\x00tb\x00tc\x00td\x00te\x00tf\x00th\x00ti\x00to\x00tp\x00tr\x00ts\x00tw\x00uA\x00uH\x00ua\x00ub\x00uc\x00ud\x00uf\x00ug\x00uh\x00ul\x00um\x00uo\x00up\x00ur\x00us\x00ut\x00uu\x00uw\x00vA\x00vB\x00vD\x00va\x00vc\x00vd\x00ve\x00vf\x00vl\x00vn\x00vo\x00vp\x00vr\x00vs\x00vz\x00wc\x00we\x00wf\x00wo\x00wp\x00wr\x00ws\x00xc\x00xd\x00xf\x00xh\x00xi\x00xl\x00xm\x00xn\x00xo\x00xr\x00xs\x00xu\x00xv\x00xw\x00ya\x00yc\x00ye\x00yf\x00yi\x00yo\x00ys\x00yu\x00za\x00zc\x00zd\x00ze\x00zf\x00zh\x00zi\x00zo\x00zs\x00zw\x00",
+ "large_words" => array(
// AElig;[Γ] AElig[Γ].
"\x04lig;\x02Γ\x03lig\x02Γ",
// AMP;[&] AMP[&].
@@ -1302,12 +1304,12 @@
// zwnj;[β] zwj;[β].
"\x03nj;\x03β\x02j;\x03β",
),
- "small_words" => "GT\x00LT\x00gt\x00lt\x00",
- "small_mappings" => array(
+ "small_words" => "GT\x00LT\x00gt\x00lt\x00",
+ "small_mappings" => array(
">",
"<",
">",
"<",
- ),
+ )
)
);
diff --git a/components/HttpClient/Middleware/HttpMiddleware.php b/components/HttpClient/Middleware/HttpMiddleware.php
index b86e13ee..a5835ece 100644
--- a/components/HttpClient/Middleware/HttpMiddleware.php
+++ b/components/HttpClient/Middleware/HttpMiddleware.php
@@ -4,13 +4,12 @@
use WordPress\HttpClient\Client;
use WordPress\HttpClient\ClientState;
-use WordPress\HttpClient\HttpClientException;
use WordPress\HttpClient\Request;
use WordPress\HttpClient\Connection;
-use WordPress\HttpClient\Transport\CurlTransport;
-use WordPress\HttpClient\Transport\SocketTransport;
use WordPress\HttpClient\Transport\TransportInterface;
+use function WordPress\Polyfill\apply_filters;
+
class HttpMiddleware implements MiddlewareInterface {
const EVENT_GOT_HEADERS = 'EVENT_GOT_HEADERS';
diff --git a/components/Markdown/MarkdownConsumer.php b/components/Markdown/MarkdownConsumer.php
index 7a8dcecb..128aced1 100644
--- a/components/Markdown/MarkdownConsumer.php
+++ b/components/Markdown/MarkdownConsumer.php
@@ -18,7 +18,7 @@
use WordPress\DataLiberation\DataFormatConsumer\BlocksWithMetadata;
use WordPress\DataLiberation\DataFormatConsumer\DataFormatConsumer;
use WordPress\DataLiberation\Importer\ImportUtils;
-use WP_HTML_Tag_Processor;
+use WordPress\HTML\WP_HTML_Tag_Processor;
/**
* Transforms markdown with frontmatter into a block markup and metadata pair.
diff --git a/components/Markdown/MarkdownImporter.php b/components/Markdown/MarkdownImporter.php
index 405adfea..a5d34b12 100644
--- a/components/Markdown/MarkdownImporter.php
+++ b/components/Markdown/MarkdownImporter.php
@@ -7,6 +7,8 @@
use WordPress\DataLiberation\Importer\StreamImporter;
use WordPress\Filesystem\LocalFilesystem;
+use function WordPress\Polyfill\_doing_it_wrong;
+
class MarkdownImporter extends StreamImporter {
public static function create_for_markdown_directory( $markdown_directory, $options = array(), $cursor = null ) {
diff --git a/components/Markdown/MarkdownProducer.php b/components/Markdown/MarkdownProducer.php
index a1b9c511..6b8f3d9b 100644
--- a/components/Markdown/MarkdownProducer.php
+++ b/components/Markdown/MarkdownProducer.php
@@ -5,6 +5,8 @@
use WordPress\DataLiberation\DataFormatConsumer\BlocksWithMetadata;
use WordPress\DataLiberation\DataFormatProducer\DataFormatProducer;
use WordPress\DataLiberation\DataLiberationHTMLProcessor;
+use function WordPress\Polyfill\parse_blocks;
+use function WordPress\Polyfill\serialize_block;
/**
* Converts WordPress blocks and metadata to Markdown with frontmatter.
@@ -283,7 +285,7 @@ function ( $cell, $width ) {
$markdown = array();
$markdown[] = '';
$markdown[] = '```block';
- $markdown[] = \serialize_block( $block );
+ $markdown[] = serialize_block( $block );
$markdown[] = '```';
$markdown[] = '';
return implode( "\n", $markdown );
diff --git a/components/Markdown/Tests/MarkdownConsumerTest.php b/components/Markdown/Tests/MarkdownConsumerTest.php
index 1283d72f..15bc9a33 100644
--- a/components/Markdown/Tests/MarkdownConsumerTest.php
+++ b/components/Markdown/Tests/MarkdownConsumerTest.php
@@ -67,7 +67,7 @@ public function test_markdown_to_blocks_conversion( $markdown, $expected ) {
}
private function normalize_markup( $markup ) {
- $processor = WP_HTML_Processor::create_fragment( $markup );
+ $processor = \WordPress\HTML\WP_HTML_Processor::create_fragment( $markup );
$serialized = $processor->serialize();
$serialized = trim(
str_replace(
diff --git a/components/Merge/Validate/BlockMarkupMergeValidator.php b/components/Merge/Validate/BlockMarkupMergeValidator.php
index ca17be17..9ff62238 100644
--- a/components/Merge/Validate/BlockMarkupMergeValidator.php
+++ b/components/Merge/Validate/BlockMarkupMergeValidator.php
@@ -4,7 +4,7 @@
use ReflectionClass;
use WordPress\DataLiberation\BlockMarkup\BlockMarkupProcessor;
-use WP_HTML_Processor;
+use WordPress\HTML\WP_HTML_Processor;
class BlockMarkupMergeValidator implements MergeValidator {
@@ -55,7 +55,7 @@ public function validate( $html ) {
private function assert_html_is_structurally_sound( $html ) {
$html .= '';
- $html_processor = WP_HTML_Processor::create_fragment( $html );
+ $html_processor = \WordPress\HTML\WP_HTML_Processor::create_fragment( $html );
/**
* Make the is_virtual() method public to enable deeper inspection.
diff --git a/components/Polyfill/wordpress.php b/components/Polyfill/wordpress.php
index 5bc8773c..7084c089 100644
--- a/components/Polyfill/wordpress.php
+++ b/components/Polyfill/wordpress.php
@@ -2,7 +2,10 @@
/**
* Polyfills WordPress core functions for running in non-WordPress environments
*/
+namespace WordPress\Polyfill;
+// This may be loaded twice if Polyfills are included before WordPress, but that's fine.
+// There are no function declarations in that file, only a global variable.
if (
! isset( $html5_named_character_references ) &&
file_exists( __DIR__ . '/../HTML/html5-named-character-references.php' )
@@ -10,213 +13,233 @@
require_once __DIR__ . '/../HTML/html5-named-character-references.php';
}
+// @TODO: Wrap in namespaces before merging:
if ( ! class_exists( 'WP_Block_Parser' ) ) {
require_once __DIR__ . '/../BlockParser/class-wp-block-parser-block.php';
require_once __DIR__ . '/../BlockParser/class-wp-block-parser-frame.php';
require_once __DIR__ . '/../BlockParser/class-wp-block-parser.php';
}
-if ( ! function_exists( '_doing_it_wrong' ) ) {
- $GLOBALS['_doing_it_wrong_messages'] = array();
- function _doing_it_wrong( $method, $message, $version ) {
- $GLOBALS['_doing_it_wrong_messages'][] = $message;
+$GLOBALS['_doing_it_wrong_messages'] = array();
+function _doing_it_wrong( $method, $message, $version ) {
+ if ( function_exists( '\\_doing_it_wrong' ) ) {
+ return call_user_func_array( '\\_doing_it_wrong', func_get_args() );
}
+ $GLOBALS['_doing_it_wrong_messages'][] = $message;
}
-if ( ! class_exists( 'WP_Exception' ) ) {
- class WP_Exception extends Exception {
+function wp_trigger_error( $function_name, $message, $error_level = E_USER_NOTICE ) {
+ if ( function_exists( '\\wp_trigger_error' ) ) {
+ return call_user_func_array( '\\wp_trigger_error', func_get_args() );
}
-}
-if ( ! function_exists( 'wp_trigger_error' ) ) {
- function wp_trigger_error( $function_name, $message, $error_level = E_USER_NOTICE ) {
- if ( ! empty( $function_name ) ) {
- $message = sprintf( '%s(): %s', $function_name, $message );
- }
+ if ( ! empty( $function_name ) ) {
+ $message = sprintf( '%s(): %s', $function_name, $message );
+ }
- if ( E_USER_ERROR === $error_level ) {
- throw new WP_Exception( $message );
+ if ( E_USER_ERROR === $error_level ) {
+ if ( ! class_exists( '\WP_Exception' ) ) {
+ class WP_Exception extends \Exception {
+ }
}
-
- trigger_error( $message, $error_level );
+ throw new WP_Exception( $message );
}
+
+ trigger_error( $message, $error_level );
}
-if ( ! function_exists( 'wp_kses_uri_attributes' ) ) {
- function wp_kses_uri_attributes() {
- return array();
+function wp_kses_uri_attributes() {
+ if ( function_exists( '\\wp_kses_uri_attributes' ) ) {
+ return call_user_func_array( '\\wp_kses_uri_attributes', func_get_args() );
}
+ return array();
}
-if ( ! function_exists( '__' ) ) {
- function __( $input ) {
- return $input;
+function __( $input ) {
+ if ( function_exists( '\\__' ) ) {
+ return call_user_func_array( '\\__', func_get_args() );
}
+ return $input;
}
-if ( ! function_exists( 'esc_attr' ) ) {
- function esc_attr( $input ) {
- return htmlspecialchars( $input );
+function esc_attr( $input ) {
+ if ( function_exists( '\\esc_attr' ) ) {
+ return call_user_func_array( '\\esc_attr', func_get_args() );
}
+ return htmlspecialchars( $input );
}
-if ( ! function_exists( 'esc_html' ) ) {
- function esc_html( $input ) {
- return htmlspecialchars( $input );
+function esc_html( $input ) {
+ if ( function_exists( '\\esc_html' ) ) {
+ return call_user_func_array( '\\esc_html', func_get_args() );
}
+ return htmlspecialchars( $input );
}
-if ( ! function_exists( 'esc_url' ) ) {
- function esc_url( $url ) {
- return htmlspecialchars( $url );
+function esc_url( $url ) {
+ if ( function_exists( '\\esc_url' ) ) {
+ return call_user_func_array( '\\esc_url', func_get_args() );
}
+ return htmlspecialchars( $url );
}
-if ( ! function_exists( 'add_filter' ) ) {
- function add_filter( $hook_name, $callback, $priority = 10, $accepted_args = 1 ) {
- global $wp_filter;
- if ( ! isset( $wp_filter ) ) {
- $wp_filter = array();
- }
- if ( ! isset( $wp_filter[ $hook_name ] ) ) {
- $wp_filter[ $hook_name ] = array();
- }
- if ( ! isset( $wp_filter[ $hook_name ][ $priority ] ) ) {
- $wp_filter[ $hook_name ][ $priority ] = array();
- }
- $wp_filter[ $hook_name ][ $priority ][] = array(
- 'function' => $callback,
- 'accepted_args' => $accepted_args,
- );
+function add_filter( $hook_name, $callback, $priority = 10, $accepted_args = 1 ) {
+ global $wp_filter;
+ if ( function_exists( '\\add_filter' ) ) {
+ return call_user_func_array( '\\add_filter', func_get_args() );
+ }
- return true;
+ if ( ! isset( $wp_filter ) ) {
+ $wp_filter = array();
+ }
+ if ( ! isset( $wp_filter[ $hook_name ] ) ) {
+ $wp_filter[ $hook_name ] = array();
+ }
+ if ( ! isset( $wp_filter[ $hook_name ][ $priority ] ) ) {
+ $wp_filter[ $hook_name ][ $priority ] = array();
}
+ $wp_filter[ $hook_name ][ $priority ][] = array(
+ 'function' => $callback,
+ 'accepted_args' => $accepted_args,
+ );
+
+ return true;
}
-if ( ! function_exists( 'add_action' ) ) {
- function add_action( $hook_name, $callback, $priority = 10, $accepted_args = 1 ) {
- return add_filter( $hook_name, $callback, $priority, $accepted_args );
+function add_action( $hook_name, $callback, $priority = 10, $accepted_args = 1 ) {
+ if ( function_exists( '\\add_action' ) ) {
+ return call_user_func_array( '\\add_action', func_get_args() );
}
+ return add_filter( $hook_name, $callback, $priority, $accepted_args );
}
-if ( ! function_exists( 'apply_filters' ) ) {
- function apply_filters( $hook_name, $value ) {
- global $wp_filter;
- if ( ! isset( $wp_filter[ $hook_name ] ) ) {
- return $value;
- }
- $args = func_get_args();
- array_shift( $args ); // Remove hook name
-
- ksort( $wp_filter[ $hook_name ] );
- foreach ( $wp_filter[ $hook_name ] as $priority => $functions ) {
- foreach ( $functions as $function ) {
- $args[0] = $value;
- $value = call_user_func_array( $function['function'], array_slice( $args, 0, $function['accepted_args'] ) );
- }
- }
+function apply_filters( $hook_name, $value ) {
+ global $wp_filter;
+ if ( function_exists( '\\apply_filters' ) ) {
+ return call_user_func_array( '\\apply_filters', func_get_args() );
+ }
+ if ( ! isset( $wp_filter[ $hook_name ] ) ) {
return $value;
}
-}
+ $args = func_get_args();
+ array_shift( $args ); // Remove hook name
-if ( ! function_exists( 'do_action' ) ) {
- function do_action( $hook_name ) {
- global $wp_filter;
- if ( ! isset( $wp_filter[ $hook_name ] ) ) {
- return;
- }
- $args = func_get_args();
- array_shift( $args ); // Remove hook name
-
- ksort( $wp_filter[ $hook_name ] );
- foreach ( $wp_filter[ $hook_name ] as $priority => $functions ) {
- foreach ( $functions as $function ) {
- call_user_func_array( $function['function'], array_slice( $args, 0, $function['accepted_args'] ) );
- }
+ ksort( $wp_filter[ $hook_name ] );
+ foreach ( $wp_filter[ $hook_name ] as $priority => $functions ) {
+ foreach ( $functions as $function ) {
+ $args[0] = $value;
+ $value = call_user_func_array( $function['function'], array_slice( $args, 0, $function['accepted_args'] ) );
}
}
+
+ return $value;
}
-if ( ! function_exists( 'parse_blocks' ) ) {
- function parse_blocks( $input ) {
- $parser = new WP_Block_Parser();
+function do_action( $hook_name ) {
+ global $wp_filter;
+ if ( function_exists( '\\do_action' ) ) {
+ return call_user_func_array( '\\do_action', func_get_args() );
+ }
- return $parser->parse( $input );
+ if ( ! isset( $wp_filter[ $hook_name ] ) ) {
+ return;
}
-}
+ $args = func_get_args();
+ array_shift( $args ); // Remove hook name
-if ( ! function_exists( 'serialize_blocks' ) ) {
- function serialize_blocks( $blocks ) {
- return implode( '', array_map( 'serialize_block', $blocks ) );
+ ksort( $wp_filter[ $hook_name ] );
+ foreach ( $wp_filter[ $hook_name ] as $priority => $functions ) {
+ foreach ( $functions as $function ) {
+ call_user_func_array( $function['function'], array_slice( $args, 0, $function['accepted_args'] ) );
+ }
}
}
-if ( ! function_exists( 'serialize_block' ) ) {
- function serialize_block( $block ) {
- $block_content = '';
-
- $index = 0;
- foreach ( $block['innerContent'] as $chunk ) {
- $block_content .= is_string( $chunk ) ? $chunk : serialize_block( $block['innerBlocks'][ $index ++ ] );
- }
+function parse_blocks( $input ) {
+ if ( function_exists( '\\parse_blocks' ) ) {
+ return call_user_func_array( '\\parse_blocks', func_get_args() );
+ }
+ $parser = new \WordPress\BlockParser\WP_Block_Parser();
- if ( ! is_array( $block['attrs'] ) ) {
- $block['attrs'] = array();
- }
+ return $parser->parse( $input );
+}
- return get_comment_delimited_block_content(
- $block['blockName'],
- $block['attrs'],
- $block_content
- );
+function serialize_blocks( $blocks ) {
+ if ( function_exists( '\\serialize_blocks' ) ) {
+ return call_user_func_array( '\\serialize_blocks', func_get_args() );
}
+ return implode( '', array_map( 'serialize_block', $blocks ) );
}
-if ( ! function_exists( 'get_comment_delimited_block_content' ) ) {
- function get_comment_delimited_block_content( $block_name, $block_attributes, $block_content ) {
- if ( is_null( $block_name ) ) {
- return $block_content;
- }
-
- $serialized_block_name = strip_core_block_namespace( $block_name );
- $serialized_attributes = empty( $block_attributes ) ? '' : serialize_block_attributes( $block_attributes ) . ' ';
+function serialize_block( $block ) {
+ if ( function_exists( '\\serialize_block' ) ) {
+ return call_user_func_array( '\\serialize_block', func_get_args() );
+ }
+ $block_content = '';
- if ( empty( $block_content ) ) {
- return sprintf( '', $serialized_block_name, $serialized_attributes );
- }
+ $index = 0;
+ foreach ( $block['innerContent'] as $chunk ) {
+ $block_content .= is_string( $chunk ) ? $chunk : serialize_block( $block['innerBlocks'][ $index ++ ] );
+ }
- return sprintf(
- '%s',
- $serialized_block_name,
- $serialized_attributes,
- $block_content,
- $serialized_block_name
- );
+ if ( ! is_array( $block['attrs'] ) ) {
+ $block['attrs'] = array();
}
+
+ return get_comment_delimited_block_content(
+ $block['blockName'],
+ $block['attrs'],
+ $block_content
+ );
}
-if ( ! function_exists( 'strip_core_block_namespace' ) ) {
- function strip_core_block_namespace( $block_name = null ) {
- if ( is_string( $block_name ) && strncmp( $block_name, 'core/', strlen( 'core/' ) ) === 0 ) {
- return substr( $block_name, 5 );
- }
+function get_comment_delimited_block_content( $block_name, $block_attributes, $block_content ) {
+ if ( function_exists( '\\get_comment_delimited_block_content' ) ) {
+ return call_user_func_array( '\\get_comment_delimited_block_content', func_get_args() );
+ }
+ if ( is_null( $block_name ) ) {
+ return $block_content;
+ }
+
+ $serialized_block_name = strip_core_block_namespace( $block_name );
+ $serialized_attributes = empty( $block_attributes ) ? '' : serialize_block_attributes( $block_attributes ) . ' ';
- return $block_name;
+ if ( empty( $block_content ) ) {
+ return sprintf( '', $serialized_block_name, $serialized_attributes );
}
+
+ return sprintf(
+ '%s',
+ $serialized_block_name,
+ $serialized_attributes,
+ $block_content,
+ $serialized_block_name
+ );
}
+function strip_core_block_namespace( $block_name = null ) {
+ if ( function_exists( '\\strip_core_block_namespace' ) ) {
+ return call_user_func_array( '\\strip_core_block_namespace', func_get_args() );
+ }
+ if ( is_string( $block_name ) && strncmp( $block_name, 'core/', strlen( 'core/' ) ) === 0 ) {
+ return substr( $block_name, 5 );
+ }
-if ( ! function_exists( 'serialize_block_attributes' ) ) {
- function serialize_block_attributes( $block_attributes ) {
- $encoded_attributes = json_encode( $block_attributes, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
- $encoded_attributes = preg_replace( '/--/', '\\u002d\\u002d', $encoded_attributes );
- $encoded_attributes = preg_replace( '/', '\\u003c', $encoded_attributes );
- $encoded_attributes = preg_replace( '/>/', '\\u003e', $encoded_attributes );
- $encoded_attributes = preg_replace( '/&/', '\\u0026', $encoded_attributes );
- // Regex: /\\"/
- $encoded_attributes = preg_replace( '/\\\\"/', '\\u0022', $encoded_attributes );
+ return $block_name;
+}
- return $encoded_attributes;
+function serialize_block_attributes( $block_attributes ) {
+ if ( function_exists( '\\serialize_block_attributes' ) ) {
+ return call_user_func_array( '\\serialize_block_attributes', func_get_args() );
}
+ $encoded_attributes = json_encode( $block_attributes, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
+ $encoded_attributes = preg_replace( '/--/', '\\u002d\\u002d', $encoded_attributes );
+ $encoded_attributes = preg_replace( '/', '\\u003c', $encoded_attributes );
+ $encoded_attributes = preg_replace( '/>/', '\\u003e', $encoded_attributes );
+ $encoded_attributes = preg_replace( '/&/', '\\u0026', $encoded_attributes );
+ // Regex: /\\"/
+ $encoded_attributes = preg_replace( '/\\\\"/', '\\u0022', $encoded_attributes );
+
+ return $encoded_attributes;
}
diff --git a/components/XML/Tests/XMLProcessorTest.php b/components/XML/Tests/XMLProcessorTest.php
index cf20183e..3b00ca2d 100644
--- a/components/XML/Tests/XMLProcessorTest.php
+++ b/components/XML/Tests/XMLProcessorTest.php
@@ -1486,7 +1486,7 @@ public function __construct( $xml ) {
*/
public function insert_after( $new_xml ) {
$this->set_bookmark( 'here' );
- $this->lexical_updates[] = new WP_HTML_Text_Replacement(
+ $this->lexical_updates[] = new \WordPress\HTML\WP_HTML_Text_Replacement(
$this->bookmarks['here']->start + $this->bookmarks['here']->length,
0,
$new_xml
diff --git a/components/XML/XMLDecoder.php b/components/XML/XMLDecoder.php
index a68f7bdf..524b28b8 100644
--- a/components/XML/XMLDecoder.php
+++ b/components/XML/XMLDecoder.php
@@ -2,7 +2,7 @@
namespace WordPress\XML;
-use WP_HTML_Decoder;
+use WordPress\HTML\WP_HTML_Decoder;
/**
* XML API: WP_XML_Decoder class
diff --git a/components/XML/XMLProcessor.php b/components/XML/XMLProcessor.php
index 3f70f707..639a8165 100644
--- a/components/XML/XMLProcessor.php
+++ b/components/XML/XMLProcessor.php
@@ -2,10 +2,12 @@
namespace WordPress\XML;
-use WP_HTML_Span;
-use WP_HTML_Text_Replacement;
+use WordPress\HTML\WP_HTML_Span;
+use WordPress\HTML\WP_HTML_Text_Replacement;
use function WordPress\Encoding\utf8_codepoint_at;
+use function WordPress\Polyfill\_doing_it_wrong;
+use function WordPress\Polyfill\__;
/**
* XML API: XMLProcessor class
@@ -624,7 +626,7 @@ class XMLProcessor {
* // sourced from the lazily-parsed XML recognizer.
* $start = $attributes['src']->start;
* $length = $attributes['src']->length;
- * $modifications[] = new WP_HTML_Text_Replacement( $start, $length, $new_value );
+ * $modifications[] = new \WordPress\HTML\WP_HTML_Text_Replacement( $start, $length, $new_value );
*
* // Correspondingly, something like this will appear in this array.
* $lexical_updates = array(
@@ -3491,7 +3493,7 @@ public function set_modifiable_text( $new_value ) {
switch ( $this->parser_state ) {
case self::STATE_TEXT_NODE:
case self::STATE_COMMENT:
- $this->lexical_updates[] = new WP_HTML_Text_Replacement(
+ $this->lexical_updates[] = new \WordPress\HTML\WP_HTML_Text_Replacement(
$this->text_starts_at,
$this->text_length,
// @TODO: Audit this in details. Is this too naive? Or is it actually safe?
@@ -3501,7 +3503,7 @@ public function set_modifiable_text( $new_value ) {
return true;
case self::STATE_CDATA_NODE:
- $this->lexical_updates[] = new WP_HTML_Text_Replacement(
+ $this->lexical_updates[] = new \WordPress\HTML\WP_HTML_Text_Replacement(
$this->text_starts_at,
$this->text_length,
// @TODO: Audit this in details. Is this too naive? Or is it actually safe?
@@ -3598,7 +3600,7 @@ public function set_attribute( $namespace, $local_name, $value ) {
* Result:
*/
$existing_attribute = $this->attributes[ $name ];
- $this->lexical_updates[ $name ] = new WP_HTML_Text_Replacement(
+ $this->lexical_updates[ $name ] = new \WordPress\HTML\WP_HTML_Text_Replacement(
$existing_attribute->start,
$existing_attribute->length,
$updated_attribute
@@ -3616,7 +3618,7 @@ public function set_attribute( $namespace, $local_name, $value ) {
*
* Result:
*/
- $this->lexical_updates[ $name ] = new WP_HTML_Text_Replacement(
+ $this->lexical_updates[ $name ] = new \WordPress\HTML\WP_HTML_Text_Replacement(
$this->tag_name_starts_at + $this->tag_name_length,
0,
' ' . $updated_attribute
@@ -3673,7 +3675,7 @@ public function remove_attribute( $namespace, $local_name ) {
*
* Result:
*/
- $this->lexical_updates[ $name ] = new WP_HTML_Text_Replacement(
+ $this->lexical_updates[ $name ] = new \WordPress\HTML\WP_HTML_Text_Replacement(
$this->attributes[ $name ]->start,
$this->attributes[ $name ]->length,
''
@@ -4474,5 +4476,5 @@ private function bail( string $message, $reason = self::ERROR_UNSUPPORTED ) {
*
* @access private
*/
- const CONSTRUCTOR_UNLOCK_CODE = 'Use WP_HTML_Processor::create_fragment() instead of calling the class constructor directly.';
+ const CONSTRUCTOR_UNLOCK_CODE = 'Use \WordPress\HTML\WP_HTML_Processor::create_fragment() instead of calling the class constructor directly.';
}
diff --git a/composer.json b/composer.json
index 51f88cf0..c87ad316 100644
--- a/composer.json
+++ b/composer.json
@@ -69,7 +69,9 @@
"WordPress\\Zip\\": "components/Zip/",
"WordPress\\HttpServer\\": "components/HttpServer/",
"WordPress\\CORSProxy\\": "components/CORSProxy/",
- "WordPress\\Git\\": "components/Git/"
+ "WordPress\\Git\\": "components/Git/",
+ "WordPress\\HTML\\": "components/HTML/",
+ "WordPress\\BlockParser\\": "components/BlockParser/"
}
},
"scripts": {
diff --git a/examples/create-wp-site/import-markdown-directory.php b/examples/create-wp-site/import-markdown-directory.php
index 348737a2..27c6f805 100644
--- a/examples/create-wp-site/import-markdown-directory.php
+++ b/examples/create-wp-site/import-markdown-directory.php
@@ -19,6 +19,8 @@
use function WordPress\DataLiberation\URL\is_child_url_of;
use function WordPress\Filesystem\wp_join_unix_paths;
+use function WordPress\Polyfill\add_action;
+use function WordPress\Polyfill\add_filter;
if ( file_exists( '/wordpress/wp-load.php' ) ) {
require_once '/wordpress/wp-load.php';
diff --git a/plugins/static-files-editor/plugin.php b/plugins/static-files-editor/plugin.php
index fc954dba..dfd713e5 100644
--- a/plugins/static-files-editor/plugin.php
+++ b/plugins/static-files-editor/plugin.php
@@ -1072,7 +1072,7 @@ private static function parse_local_file( $content, $format ) {
break;
case 'html':
$converter = new AnnotatedBlockMarkupConsumer(
- WP_HTML_Processor::create_fragment( $content )
+ \WordPress\HTML\WP_HTML_Processor::create_fragment( $content )
);
break;
case 'md':