Commit 5d455d8d3d for wordpress.org

commit 5d455d8d3da780155d8377052a92b3126ed2328e
Author: westonruter <westonruter@git.wordpress.org>
Date:   Fri Nov 6 19:46:58 2026 +0000

    Code Quality: Define array shapes for block selectors and viewports.

    The `WP_Block_Type::$selectors` property was documented only as an `array`, so PHPStan saw every selector read from it as `mixed`. Its shape now follows the `selectors` schema in `block.json`: an optional `root` selector string, plus the selectors for each block support feature, each either a string or an array of selectors keyed by subfeature. The shape stays open to other keys, since core blocks also use `states` and `filter`, and third-party blocks can add their own. It is applied wherever the selectors pass through `WP_Theme_JSON` and the block state styles.

    Similarly, `WP_Theme_JSON::get_viewport_media_queries()` only ever returns the `@mobile`, `@tablet`, and `@desktop` keys, each holding a media query string, so its return value is now documented with that shape. Callers such as the Navigation block, which passes each query to `wp_style_engine_get_stylesheet_from_css_rules()` as the `rules_group`, no longer see them as `mixed`.

    Developed in https://github.com/WordPress/wordpress-develop/pull/15644.
    Follow-up to r55673, r56058, r62453, r62671, r64727.

    See #65817.

    Built from https://develop.svn.wordpress.org/trunk@65318


    git-svn-id: http://core.svn.wordpress.org/trunk@64458 1a063a9b-81f0-0310-95a4-ce76da25c4cd

diff --git a/wp-includes/block-supports/states.php b/wp-includes/block-supports/states.php
index 2a80c26db4..809072fd56 100644
--- a/wp-includes/block-supports/states.php
+++ b/wp-includes/block-supports/states.php
@@ -314,9 +314,11 @@ function wp_add_state_style_group( &$groups, $selector, $style ) {
  *
  * @since 7.1.0
  *
- * @param array $state_style     State style object.
- * @param array $block_selectors Block selectors metadata.
+ * @param array<string, mixed>                        $state_style     State style object.
+ * @param array<string, string|array<string, string>> $block_selectors Block selectors metadata.
  * @return array[] Selector/style groups.
+ *
+ * @phpstan-param array{ root?: string, ...<string, string|array<string, string>> } $block_selectors
  */
 function wp_get_state_style_groups( $state_style, $block_selectors ) {
 	$groups = array();
diff --git a/wp-includes/class-wp-block-type.php b/wp-includes/class-wp-block-type.php
index 811e65c6ab..921b83c94d 100644
--- a/wp-includes/class-wp-block-type.php
+++ b/wp-includes/class-wp-block-type.php
@@ -137,8 +137,15 @@ class WP_Block_Type {
 	/**
 	 * Custom CSS selectors for theme.json style generation.
 	 *
+	 * The `root` key holds the selector for the block itself. Each other key is a block support
+	 * feature (such as `color` or `typography`) whose value is either a selector string, or an
+	 * array of selectors keyed by subfeature (such as `root` or `text`). The exception is the
+	 * `states` key, which holds the selectors for the block's custom states, keyed by state
+	 * name (such as `-current`).
+	 *
 	 * @since 6.3.0
-	 * @var array
+	 * @var array<string, string|array<string, string>>
+	 * @phpstan-var array{ root?: string, ...<string, string|array<string, string>> }
 	 */
 	public $selectors = array();

@@ -311,37 +318,37 @@ class WP_Block_Type {
 	 *     Optional. Array or string of arguments for registering a block type. Any arguments may be defined,
 	 *     however the ones described below are supported by default. Default empty array.
 	 *
-	 *     @type string        $api_version              Block API version.
-	 *     @type string        $title                    Human-readable block type label.
-	 *     @type string|null   $category                 Block type category classification, used in
-	 *                                                   search interfaces to arrange block types by category.
-	 *     @type string[]|null $parent                   Setting parent lets a block require that it is only
-	 *                                                   available when nested within the specified blocks.
-	 *     @type string[]|null $ancestor                 Setting ancestor makes a block available only inside the specified
-	 *                                                   block types at any position of the ancestor's block subtree.
-	 *     @type string[]|null $allowed_blocks           Limits which block types can be inserted as children of this block type.
-	 *     @type string|null   $icon                     Block type icon.
-	 *     @type string        $description              A detailed block type description.
-	 *     @type string[]      $keywords                 Additional keywords to produce block type as
-	 *                                                   result in search interfaces.
-	 *     @type string|null   $textdomain               The translation textdomain.
-	 *     @type array[]       $styles                   Alternative block styles.
-	 *     @type array[]       $variations               Block variations.
-	 *     @type array         $selectors                Custom CSS selectors for theme.json style generation.
-	 *     @type array|null    $supports                 Supported features.
-	 *     @type array|null    $example                  Structured data for the block preview.
-	 *     @type callable|null $render_callback          Block type render callback.
-	 *     @type callable|null $variation_callback       Block type variations callback.
-	 *     @type array|null    $attributes               Block type attributes property schemas.
-	 *     @type string[]      $uses_context             Context values inherited by blocks of this type.
-	 *     @type string[]|null $provides_context         Context provided by blocks of this type.
-	 *     @type string[]      $block_hooks              Block hooks.
-	 *     @type string[]      $editor_script_handles    Block type editor only script handles.
-	 *     @type string[]      $script_handles           Block type front end and editor script handles.
-	 *     @type string[]      $view_script_handles      Block type front end only script handles.
-	 *     @type string[]      $editor_style_handles     Block type editor only style handles.
-	 *     @type string[]      $style_handles            Block type front end and editor style handles.
-	 *     @type string[]      $view_style_handles       Block type front end only style handles.
+	 *     @type string                                      $api_version           Block API version.
+	 *     @type string                                      $title                 Human-readable block type label.
+	 *     @type string|null                                 $category              Block type category classification, used in
+	 *                                                                              search interfaces to arrange block types by category.
+	 *     @type string[]|null                               $parent                Setting parent lets a block require that it is only
+	 *                                                                              available when nested within the specified blocks.
+	 *     @type string[]|null                               $ancestor              Setting ancestor makes a block available only inside the specified
+	 *                                                                              block types at any position of the ancestor's block subtree.
+	 *     @type string[]|null                               $allowed_blocks        Limits which block types can be inserted as children of this block type.
+	 *     @type string|null                                 $icon                  Block type icon.
+	 *     @type string                                      $description           A detailed block type description.
+	 *     @type string[]                                    $keywords              Additional keywords to produce block type as
+	 *                                                                              result in search interfaces.
+	 *     @type string|null                                 $textdomain            The translation textdomain.
+	 *     @type array[]                                     $styles                Alternative block styles.
+	 *     @type array[]                                     $variations            Block variations.
+	 *     @type array<string, string|array<string, string>> $selectors             Custom CSS selectors for theme.json style generation.
+	 *     @type array|null                                  $supports              Supported features.
+	 *     @type array|null                                  $example               Structured data for the block preview.
+	 *     @type callable|null                               $render_callback       Block type render callback.
+	 *     @type callable|null                               $variation_callback    Block type variations callback.
+	 *     @type array|null                                  $attributes            Block type attributes property schemas.
+	 *     @type string[]                                    $uses_context          Context values inherited by blocks of this type.
+	 *     @type string[]|null                               $provides_context      Context provided by blocks of this type.
+	 *     @type string[]                                    $block_hooks           Block hooks.
+	 *     @type string[]                                    $editor_script_handles Block type editor only script handles.
+	 *     @type string[]                                    $script_handles        Block type front end and editor script handles.
+	 *     @type string[]                                    $view_script_handles   Block type front end only script handles.
+	 *     @type string[]                                    $editor_style_handles  Block type editor only style handles.
+	 *     @type string[]                                    $style_handles         Block type front end and editor style handles.
+	 *     @type string[]                                    $view_style_handles    Block type front end only style handles.
 	 * }
 	 */
 	public function __construct( $block_type, $args = array() ) {
diff --git a/wp-includes/class-wp-theme-json.php b/wp-includes/class-wp-theme-json.php
index a4bfbe86df..86842aee6f 100644
--- a/wp-includes/class-wp-theme-json.php
+++ b/wp-includes/class-wp-theme-json.php
@@ -742,7 +742,13 @@ class WP_Theme_JSON {
 	 *
 	 *     @type bool $include_desktop Whether to include the desktop media query. Default false.
 	 * }
-	 * @return array Responsive media queries.
+	 * @return array<string, string> Responsive media queries, keyed by style-state name.
+	 *
+	 * @phpstan-return array{
+	 *     '@mobile'?: non-falsy-string,
+	 *     '@tablet'?: non-falsy-string,
+	 *     '@desktop'?: non-falsy-string,
+	 * }
 	 */
 	public static function get_viewport_media_queries( $viewport_settings = null, $options = array() ) {
 		$breakpoints = self::sanitize_viewport_settings( $viewport_settings );
@@ -5991,24 +5997,26 @@ class WP_Theme_JSON {
 	 *
 	 * @since 6.3.0
 	 *
-	 * @param object $block_type    The block type.
-	 * @param string $root_selector The block's root selector.
-	 * @return array The custom selectors set by the block.
+	 * @param WP_Block_Type $block_type    The block type.
+	 * @param string        $root_selector The block's root selector.
+	 * @return array<string, string|array<string, string>> The custom selectors set by the block.
+	 *
+	 * @phpstan-return array{ root?: string, ...<string, string|array<string, string>> }
 	 */
 	protected static function get_block_selectors( $block_type, $root_selector ) {
 		if ( ! empty( $block_type->selectors ) ) {
 			return $block_type->selectors;
 		}

-		$selectors = array( 'root' => $root_selector );
+		$feature_selectors = array();
 		foreach ( static::BLOCK_SUPPORT_FEATURE_LEVEL_SELECTORS as $key => $feature ) {
 			$feature_selector = wp_get_block_css_selector( $block_type, $key );
 			if ( null !== $feature_selector ) {
-				$selectors[ $feature ] = array( 'root' => $feature_selector );
+				$feature_selectors[ $feature ] = array( 'root' => $feature_selector );
 			}
 		}

-		return $selectors;
+		return array( 'root' => $root_selector ) + $feature_selectors;
 	}

 	/**
@@ -6055,7 +6063,7 @@ class WP_Theme_JSON {
 	 * @return array<string, array[]> The style declarations for the node's features with custom
 	 *                                selectors, keyed by selector.
 	 *
-	 * @phpstan-param array{ selectors?: array<string, string|array<string, string>> } $metadata
+	 * @phpstan-param array{ selectors?: array{ root?: string, ...<string, string|array<string, string>> } } $metadata
 	 * @phpstan-return array<string, list<array{ name: non-falsy-string, value: scalar }>>
 	 */
 	protected function get_feature_declarations_for_node( $metadata, &$node ) {
diff --git a/wp-includes/version.php b/wp-includes/version.php
index c072086d61..5e0274f309 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
  *
  * @global string $wp_version
  */
-$wp_version = '7.2-beta4-65317';
+$wp_version = '7.2-beta4-65318';

 /**
  * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.