wp-includes/html-api/class-wp-html-decoder.php:12HTML API: WP_HTML_Decoder class
class WP_HTML_Decoder { /** * Indicates if an attribute value starts with a given raw string value. * * Use this method to determine if an attribute value starts with a given string, regardless * of how it might be encoded in HTML. For instance, `http:` could be represented as `http:` * or as `http:` or as `http:` or as `http:`, or in many other ways. * * This is equivalent to a byte-prefix test against the decoded attribute value, without * the need to allocate and decode the full string. * * Example: * * $value = 'http://wordpress.org/'; * true === WP_HTML_Decoder::attribute_starts_with( $value, 'http:', 'ascii-case-insensitive' ); * false === WP_HTML_Decoder::attribute_starts_with( $value, 'https:', 'ascii-case-insensitive' ); * * @since 6.6.0 * * @param string $haystack String containing the raw non-decoded attribute value. * @param string $search_text Does the attribute value start with this plain string. * @param string $case_sensitivity Optional. Pass 'ascii-case-insensitive' to ignore ASCII case when matching. * Default 'case-sensitive'. * @return bool Whether the attribute value starts with the given string. */ public static function attribute_starts_with( $haystack, $search_text, $case_sensitivity = 'case-sensitive' ): bool { $search_length = strlen( $search_text ); $loose_case = 'ascii-case-insensitive' === $case_sensitivity; $haystack_end = strlen( $haystack ); $search_at = 0; $haystack_at = 0; while ( $search_at < $search_length && $haystack_at < $haystack_end ) { $chars_match = $loose_case ? strtolower( $haystack[ $haystack_at ] ) === strtolower( $search_text[ $search_at ] ) : $haystack[ $haystack_at ] === $search_text[ $search_at ]; $is_introducer = '&' === $haystack[ $haystack_at ]; $next_chunk = $is_introducer ? self::read_character_reference( 'attribute', $haystack, $haystack_at, $token_length ) : null; // If there's no character reference and the characters don't match, the match fails. if ( null === $next_chunk && ! $chars_match ) { return false; } // If there's no character reference but the characters do match, then it could still match. if ( null === $next_chunk && $chars_match ) { ++$haystack_at; ++$search_at; continue; } /** * The decoded character reference in `$next_chunk` must be compared with the * corresponding `$search_text` bytes checking for matching prefixes. The remaining * search text may be shorter than the decoded chunk, in which case a partial match * satisfies the prefix. Otherwise, if the decoded chunk is fully matched, the * comparison must continue after advancing the appropriate byte lengths: the character * reference token length in the haystack and the decoded chunk length in the * search text. * * For example, consider searches that have reached the character reference * `fj` (7 bytes), decoded into the 2-byte chunk `fj`: * * $haystack_at * │ * │ ┌─after matching `fj` continue here * │ │ (advance by $token_length, 7 bytes) * ↓ ↓ * Haystack: startfjord * ╰──┬──╯ * fj - the decoded chunk, tested against the search text. * * $search_at * │ * │ ┌─after matching `fj` continue here * │ │ (advance by $match_length, 2 bytes) * ↓ ↓Introduced in 6.6.0. Unchanged from 6.7.7 through 7.1.0.
Signature, return type and hooks compared across 5 parsed releases.
src/wp-includes/html-api/class-wp-html-decoder.php, and regenerated for each WordPress release so it tracks the code rather than a snapshot of it.