Make WordPress Core

Changeset 65220


Ignore:
Timestamp:
11/03/2026 05:58:23 AM (3 days ago)
Author:
westonruter
Message:

HTML API: Type tag queries and tag names for PHPStan.

The $query parameter of next_tag() is documented as array|string|null, but its hash notation only describes the array form, so stubs generated from it (as used by Gutenberg) turned it into an array shape and dropped the bare tag-name form, reporting calls like next_tag( 'FIGURE' ) as errors. A Query type alias now covers the array, bare tag-name, and null forms, with each key allowed to be null as documented. The HTML Processor defines its own alias adding the breadcrumbs key, since type aliases are not inherited by subclasses.

Tag names are returned as non-falsy-string, since a parsed name is never empty or '0', but accepted as non-empty-string, since that is all a '' !== $tag check proves and a '0' query simply matches nothing.

The changes are to PHPDoc only, so there is no runtime change.

Developed in ​https://github.com/WordPress/wordpress-develop/pull/15305.
Follow-up to r55203.

Props westonruter, dmsnell.
See #65817.

Location:
trunk/src/wp-includes/html-api
Files:
3 edited

Legend:

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

    r64673 r65220  
    144144 * @link https://html.spec.whatwg.org/
    145145 * @phpstan-consistent-constructor
     146 *
     147 * @phpstan-type Query array{
     148 *     tag_name?: non-empty-string|null,
     149 *     match_offset?: int<1, max>|null,
     150 *     class_name?: non-empty-string|null,
     151 *     tag_closers?: 'visit'|'skip'|null,
     152 *     breadcrumbs?: array<non-empty-string>,
     153 * }|non-empty-string|null
    146154 */
    147155class WP_HTML_Processor extends WP_HTML_Tag_Processor {
    … …  
    238246         *
    239247         * @var string[]
     248         * @phpstan-var list<non-falsy-string>
    240249         */
    241250        private $breadcrumbs = array();
    … …  
    688697         * }
    689698         * @return bool Whether a tag was matched.
     699         *
     700         * @phpstan-param Query $query
    690701         */
    691702        public function next_tag( $query = null ): bool {
    … …  
    931942         *                              May also contain the wildcard `*` which matches a single element, e.g. `array( 'SECTION', '*' )`.
    932943         * @return bool Whether the currently-matched tag is found at the given nested structure.
     944         *
     945         * @phpstan-param array<non-empty-string> $breadcrumbs
    933946         */
    934947        public function matches_breadcrumbs( $breadcrumbs ): bool {
    … …  
    12021215         *
    12031216         * @return string[] Array of tag names representing path to matched node.
     1217         *
     1218         * @phpstan-return list<non-falsy-string>
    12041219         */
    12051220        public function get_breadcrumbs(): array {
    … …  
    51555170         *
    51565171         * @return string|null Name of currently matched tag in input HTML, or `null` if none found.
     5172         *
     5173         * @phpstan-return non-falsy-string|null
    51575174         */
    51585175        public function get_tag(): ?string {
    … …  
    52205237         *
    52215238         * @return string|null Name of the matched token.
     5239         *
     5240         * @phpstan-return non-falsy-string|null
    52225241         */
    52235242        public function get_token_name(): ?string {
    … …  
    62776296         *                                   Defaults to auto-creating a bookmark name.
    62786297         * @return WP_HTML_Token Newly-created virtual token.
     6298         *
     6299         * @phpstan-param non-falsy-string $token_name
    62796300         */
    62806301        private function insert_virtual_node( $token_name, $bookmark_name = null ): WP_HTML_Token {
  • trunk/src/wp-includes/html-api/class-wp-html-tag-processor.php

    r64872 r65220  
    408408 *              Introduces "special" elements which act like void elements, e.g. TITLE, STYLE.
    409409 *              Allows scanning through all tokens and processing modifiable text, where applicable.
     410 *
     411 * @phpstan-type Query array{
     412 *     tag_name?: non-empty-string|null,
     413 *     match_offset?: int<1, max>|null,
     414 *     class_name?: non-empty-string|null,
     415 *     tag_closers?: 'visit'|'skip'|null,
     416 * }|non-empty-string|null
    410417 */
    411418class WP_HTML_Tag_Processor {
    … …  
    444451         *
    445452         * @since 6.2.0
    446          * @var array|null
     453         * @var array|string|null
     454         * @phpstan-var Query
    447455         */
    448456        private $last_query;
    … …  
    453461         * @since 6.2.0
    454462         * @var string|null
     463         * @phpstan-var non-empty-string|null
    455464         */
    456465        private $sought_tag_name;
    … …  
    461470         * @since 6.2.0
    462471         * @var string|null
     472         * @phpstan-var non-empty-string|null
    463473         */
    464474        private $sought_class_name;
    … …  
    469479         * @since 6.2.0
    470480         * @var int|null
     481         * @phpstan-var int<1, max>|null
    471482         */
    472483        private $sought_match_offset;
    … …  
    896907         * @return bool Whether a tag was matched.
    897908         *
     909         * @phpstan-param Query $query
    898910         * @phpstan-impure
    899911         */
    … …  
    30353047         *
    30363048         * @return string|null Name of currently matched tag in input HTML, or `null` if none found.
     3049         *
     3050         * @phpstan-return non-falsy-string|null
    30373051         */
    30383052        public function get_tag(): ?string {
    … …  
    30413055                }
    30423056
     3057                /**
     3058                 * The name is never empty and never "0": a tag name starts with an ASCII
     3059                 * letter, a processing instruction target with a letter or "_", and the
     3060                 * target of a comment which looks like a processing instruction with a
     3061                 * letter, ":", or "_".
     3062                 *
     3063                 * @var non-falsy-string $tag_name
     3064                 */
    30433065                $tag_name = str_replace( "\x00", "\u{FFFD}", substr( $this->html, $this->tag_name_starts_at, $this->tag_name_length ) );
    30443066
    … …  
    30723094         *
    30733095         * @return string|null Name of current tag name.
     3096         *
     3097         * @phpstan-return non-falsy-string|null
    30743098         */
    30753099        public function get_qualified_tag_name(): ?string {
    … …  
    35703594         *
    35713595         * @return string|null Name of the matched token.
     3596         *
     3597         * @phpstan-return non-falsy-string|null
    35723598         */
    35733599        public function get_token_name(): ?string {
    … …  
    49895015         *     @type string      $tag_closers  "visit" or "skip": whether to stop on tag closers, e.g. </div>.
    49905016         * }
     5017         * @phpstan-param Query $query
    49915018         */
    49925019        private function parse_query( $query ) {
  • trunk/src/wp-includes/html-api/class-wp-html-token.php

    r64636 r65220  
    4444         *
    4545         * @var string
     46         * @phpstan-var non-falsy-string
    4647         */
    4748        public $node_name = null;
    … …  
    9798         * @param bool          $has_self_closing_flag Whether the source token contains the self-closing flag, regardless of whether it's valid.
    9899         * @param callable|null $on_destroy            Optional. Function to call when destroying token, useful for releasing the bookmark.
     100         *
     101         * @phpstan-param non-falsy-string $node_name
    99102         */
    100103        public function __construct( ?string $bookmark_name, string $node_name, bool $has_self_closing_flag, ?callable $on_destroy = null ) {
Note: See TracChangeset for help on using the changeset viewer.