wp/wp-includes/theme.php
changeset 19 3d72ae0968f4
parent 18 be944660c56a
child 21 48c4eec2b7e6
--- a/wp/wp-includes/theme.php	Wed Sep 21 18:19:35 2022 +0200
+++ b/wp/wp-includes/theme.php	Tue Sep 27 16:37:53 2022 +0200
@@ -45,7 +45,7 @@
 	$theme_directories = search_theme_directories();
 
 	if ( is_array( $wp_theme_directories ) && count( $wp_theme_directories ) > 1 ) {
-		// Make sure the current theme wins out, in case search_theme_directories() picks the wrong
+		// Make sure the active theme wins out, in case search_theme_directories() picks the wrong
 		// one in the case of a conflict. (Normally, last registered theme root wins.)
 		$current_theme = get_stylesheet();
 		if ( isset( $theme_directories[ $current_theme ] ) ) {
@@ -105,10 +105,10 @@
  *
  * @global array $wp_theme_directories
  *
- * @param string $stylesheet Optional. Directory name for the theme. Defaults to current theme.
+ * @param string $stylesheet Optional. Directory name for the theme. Defaults to active theme.
  * @param string $theme_root Optional. Absolute path of the theme root to look in.
  *                           If not specified, get_raw_theme_root() is used to calculate
- *                           the theme root for the $stylesheet provided (or current theme).
+ *                           the theme root for the $stylesheet provided (or active theme).
  * @return WP_Theme Theme object. Be sure to check the object's exists() method
  *                  if you need to confirm the theme's existence.
  */
@@ -182,11 +182,11 @@
 }
 
 /**
- * Retrieves stylesheet directory path for current theme.
+ * Retrieves stylesheet directory path for the active theme.
  *
  * @since 1.5.0
  *
- * @return string Path to current theme's stylesheet directory.
+ * @return string Path to active theme's stylesheet directory.
  */
 function get_stylesheet_directory() {
 	$stylesheet     = get_stylesheet();
@@ -194,23 +194,23 @@
 	$stylesheet_dir = "$theme_root/$stylesheet";
 
 	/**
-	 * Filters the stylesheet directory path for current theme.
+	 * Filters the stylesheet directory path for the active theme.
 	 *
 	 * @since 1.5.0
 	 *
-	 * @param string $stylesheet_dir Absolute path to the current theme.
-	 * @param string $stylesheet     Directory name of the current theme.
+	 * @param string $stylesheet_dir Absolute path to the active theme.
+	 * @param string $stylesheet     Directory name of the active theme.
 	 * @param string $theme_root     Absolute path to themes directory.
 	 */
 	return apply_filters( 'stylesheet_directory', $stylesheet_dir, $stylesheet, $theme_root );
 }
 
 /**
- * Retrieves stylesheet directory URI for current theme.
+ * Retrieves stylesheet directory URI for the active theme.
  *
  * @since 1.5.0
  *
- * @return string URI to current theme's stylesheet directory.
+ * @return string URI to active theme's stylesheet directory.
  */
 function get_stylesheet_directory_uri() {
 	$stylesheet         = str_replace( '%2F', '/', rawurlencode( get_stylesheet() ) );
@@ -230,25 +230,25 @@
 }
 
 /**
- * Retrieves stylesheet URI for current theme.
+ * Retrieves stylesheet URI for the active theme.
  *
  * The stylesheet file name is 'style.css' which is appended to the stylesheet directory URI path.
  * See get_stylesheet_directory_uri().
  *
  * @since 1.5.0
  *
- * @return string URI to current theme's stylesheet.
+ * @return string URI to active theme's stylesheet.
  */
 function get_stylesheet_uri() {
 	$stylesheet_dir_uri = get_stylesheet_directory_uri();
 	$stylesheet_uri     = $stylesheet_dir_uri . '/style.css';
 	/**
-	 * Filters the URI of the current theme stylesheet.
+	 * Filters the URI of the active theme stylesheet.
 	 *
 	 * @since 1.5.0
 	 *
-	 * @param string $stylesheet_uri     Stylesheet URI for the current theme/child theme.
-	 * @param string $stylesheet_dir_uri Stylesheet directory URI for the current theme/child theme.
+	 * @param string $stylesheet_uri     Stylesheet URI for the active theme/child theme.
+	 * @param string $stylesheet_dir_uri Stylesheet directory URI for the active theme/child theme.
 	 */
 	return apply_filters( 'stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri );
 }
@@ -272,7 +272,7 @@
  *
  * @global WP_Locale $wp_locale WordPress date and time locale object.
  *
- * @return string URI to current theme's localized stylesheet.
+ * @return string URI to active theme's localized stylesheet.
  */
 function get_locale_stylesheet_uri() {
 	global $wp_locale;
@@ -298,7 +298,7 @@
 }
 
 /**
- * Retrieves name of the current theme.
+ * Retrieves name of the active theme.
  *
  * @since 1.5.0
  *
@@ -306,21 +306,21 @@
  */
 function get_template() {
 	/**
-	 * Filters the name of the current theme.
+	 * Filters the name of the active theme.
 	 *
 	 * @since 1.5.0
 	 *
-	 * @param string $template Current theme's directory name.
+	 * @param string $template active theme's directory name.
 	 */
 	return apply_filters( 'template', get_option( 'template' ) );
 }
 
 /**
- * Retrieves template directory path for current theme.
+ * Retrieves template directory path for the active theme.
  *
  * @since 1.5.0
  *
- * @return string Path to current theme's template directory.
+ * @return string Path to active theme's template directory.
  */
 function get_template_directory() {
 	$template     = get_template();
@@ -328,23 +328,23 @@
 	$template_dir = "$theme_root/$template";
 
 	/**
-	 * Filters the current theme directory path.
+	 * Filters the active theme directory path.
 	 *
 	 * @since 1.5.0
 	 *
-	 * @param string $template_dir The path of the current theme directory.
-	 * @param string $template     Directory name of the current theme.
+	 * @param string $template_dir The path of the active theme directory.
+	 * @param string $template     Directory name of the active theme.
 	 * @param string $theme_root   Absolute path to the themes directory.
 	 */
 	return apply_filters( 'template_directory', $template_dir, $template, $theme_root );
 }
 
 /**
- * Retrieves template directory URI for current theme.
+ * Retrieves template directory URI for the active theme.
  *
  * @since 1.5.0
  *
- * @return string URI to current theme's template directory.
+ * @return string URI to active theme's template directory.
  */
 function get_template_directory_uri() {
 	$template         = str_replace( '%2F', '/', rawurlencode( get_template() ) );
@@ -352,12 +352,12 @@
 	$template_dir_uri = "$theme_root_uri/$template";
 
 	/**
-	 * Filters the current theme directory URI.
+	 * Filters the active theme directory URI.
 	 *
 	 * @since 1.5.0
 	 *
-	 * @param string $template_dir_uri The URI of the current theme directory.
-	 * @param string $template         Directory name of the current theme.
+	 * @param string $template_dir_uri The URI of the active theme directory.
+	 * @param string $template         Directory name of the active theme.
 	 * @param string $theme_root_uri   The themes root URI.
 	 */
 	return apply_filters( 'template_directory_uri', $template_dir_uri, $template, $theme_root_uri );
@@ -499,7 +499,7 @@
 	/* Loop the registered theme directories and extract all themes */
 	foreach ( $wp_theme_directories as $theme_root ) {
 
-		// Start with directories in the root of the current theme directory.
+		// Start with directories in the root of the active theme directory.
 		$dirs = @ scandir( $theme_root );
 		if ( ! $dirs ) {
 			trigger_error( "$theme_root is not readable", E_USER_NOTICE );
@@ -683,7 +683,7 @@
 
 	$theme_root = false;
 
-	// If requesting the root for the current theme, consult options to avoid calling get_theme_roots().
+	// If requesting the root for the active theme, consult options to avoid calling get_theme_roots().
 	if ( ! $skip_cache ) {
 		if ( get_option( 'stylesheet' ) == $stylesheet_or_template ) {
 			$theme_root = get_option( 'stylesheet_root' );
@@ -830,16 +830,20 @@
 }
 
 /**
- * Checks that the current theme has 'index.php' and 'style.css' files.
+ * Checks that the active theme has the required files.
+ *
+ * Standalone themes need to have a `templates/index.html` or `index.php` template file.
+ * Child themes need to have a `Template` header in the `style.css` stylesheet.
  *
  * Does not initially check the default theme, which is the fallback and should always exist.
  * But if it doesn't exist, it'll fall back to the latest core default theme that does exist.
- * Will switch theme to the fallback theme if current theme does not validate.
+ * Will switch theme to the fallback theme if active theme does not validate.
  *
  * You can use the {@see 'validate_current_theme'} filter to return false to disable
  * this functionality.
  *
  * @since 1.5.0
+ * @since 6.0.0 Removed the requirement for block themes to have an `index.php` template.
  *
  * @see WP_DEFAULT_THEME
  *
@@ -847,17 +851,21 @@
  */
 function validate_current_theme() {
 	/**
-	 * Filters whether to validate the current theme.
+	 * Filters whether to validate the active theme.
 	 *
 	 * @since 2.7.0
 	 *
-	 * @param bool $validate Whether to validate the current theme. Default true.
+	 * @param bool $validate Whether to validate the active theme. Default true.
 	 */
 	if ( wp_installing() || ! apply_filters( 'validate_current_theme', true ) ) {
 		return true;
 	}
 
-	if ( ! file_exists( get_template_directory() . '/index.php' ) ) {
+	if (
+		! file_exists( get_template_directory() . '/templates/index.html' )
+		&& ! file_exists( get_template_directory() . '/block-templates/index.html' ) // Deprecated path support since 5.9.0.
+		&& ! file_exists( get_template_directory() . '/index.php' )
+	) {
 		// Invalid.
 	} elseif ( ! file_exists( get_template_directory() . '/style.css' ) ) {
 		// Invalid.
@@ -908,20 +916,6 @@
 function validate_theme_requirements( $stylesheet ) {
 	$theme = wp_get_theme( $stylesheet );
 
-	// If the theme is a Full Site Editing theme, check for the presence of the Gutenberg plugin.
-	$theme_tags = $theme->get( 'Tags' );
-
-	if ( ! empty( $theme_tags ) && in_array( 'full-site-editing', $theme_tags, true ) && ! function_exists( 'gutenberg_is_fse_theme' ) ) {
-		return new WP_Error(
-			'theme_requires_gutenberg_plugin',
-			sprintf(
-					/* translators: %s: Theme name. */
-				_x( '<strong>Error:</strong> This theme (%s) uses Full Site Editing, which requires the Gutenberg plugin to be activated.', 'theme' ),
-				$theme->display( 'Name' )
-			)
-		);
-	}
-
 	$requirements = array(
 		'requires'     => ! empty( $theme->get( 'RequiresWP' ) ) ? $theme->get( 'RequiresWP' ) : '',
 		'requires_php' => ! empty( $theme->get( 'RequiresPHP' ) ) ? $theme->get( 'RequiresPHP' ) : '',
@@ -966,38 +960,46 @@
  * Retrieves all theme modifications.
  *
  * @since 3.1.0
- *
- * @return array|void Theme modifications.
+ * @since 5.9.0 The return value is always an array.
+ *
+ * @return array Theme modifications.
  */
 function get_theme_mods() {
 	$theme_slug = get_option( 'stylesheet' );
 	$mods       = get_option( "theme_mods_$theme_slug" );
+
 	if ( false === $mods ) {
 		$theme_name = get_option( 'current_theme' );
 		if ( false === $theme_name ) {
 			$theme_name = wp_get_theme()->get( 'Name' );
 		}
+
 		$mods = get_option( "mods_$theme_name" ); // Deprecated location.
 		if ( is_admin() && false !== $mods ) {
 			update_option( "theme_mods_$theme_slug", $mods );
 			delete_option( "mods_$theme_name" );
 		}
 	}
+
+	if ( ! is_array( $mods ) ) {
+		$mods = array();
+	}
+
 	return $mods;
 }
 
 /**
- * Retrieves theme modification value for the current theme.
- *
- * If the modification name does not exist, then the $default will be passed
- * through {@link https://www.php.net/sprintf sprintf()} PHP function with
- * the template directory URI as the first string and the stylesheet directory URI
- * as the second string.
+ * Retrieves theme modification value for the active theme.
+ *
+ * If the modification name does not exist and `$default` is a string, then the
+ * default will be passed through the {@link https://www.php.net/sprintf sprintf()}
+ * PHP function with the template directory URI as the first value and the
+ * stylesheet directory URI as the second value.
  *
  * @since 2.1.0
  *
- * @param string       $name    Theme modification name.
- * @param string|false $default Optional. Theme modification default value. Default false.
+ * @param string $name    Theme modification name.
+ * @param mixed  $default Optional. Theme modification default value. Default false.
  * @return mixed Theme modification value.
  */
 function get_theme_mod( $name, $default = false ) {
@@ -1013,7 +1015,7 @@
 		 *
 		 * @since 2.2.0
 		 *
-		 * @param string $current_mod The value of the current theme modification.
+		 * @param mixed $current_mod The value of the active theme modification.
 		 */
 		return apply_filters( "theme_mod_{$name}", $mods[ $name ] );
 	}
@@ -1032,7 +1034,7 @@
 }
 
 /**
- * Updates theme modification value for the current theme.
+ * Updates theme modification value for the active theme.
  *
  * @since 2.1.0
  * @since 5.6.0 A return value was added.
@@ -1054,8 +1056,8 @@
 	 *
 	 * @since 3.9.0
 	 *
-	 * @param string $value     The new value of the theme modification.
-	 * @param string $old_value The current value of the theme modification.
+	 * @param mixed $value     The new value of the theme modification.
+	 * @param mixed $old_value The current value of the theme modification.
 	 */
 	$mods[ $name ] = apply_filters( "pre_set_theme_mod_{$name}", $value, $old_value );
 
@@ -1065,7 +1067,7 @@
 }
 
 /**
- * Removes theme modification name from current theme list.
+ * Removes theme modification name from active theme list.
  *
  * If removing the name also removes all elements, then the entire option
  * will be removed.
@@ -1094,7 +1096,7 @@
 }
 
 /**
- * Removes theme modifications option for current theme.
+ * Removes theme modifications option for the active theme.
  *
  * @since 2.1.0
  */
@@ -1199,6 +1201,16 @@
 
 	$width  = absint( $header->width );
 	$height = absint( $header->height );
+	$alt    = '';
+
+	// Use alternative text assigned to the image, if available. Otherwise, leave it empty.
+	if ( ! empty( $header->attachment_id ) ) {
+		$image_alt = get_post_meta( $header->attachment_id, '_wp_attachment_image_alt', true );
+
+		if ( is_string( $image_alt ) ) {
+			$alt = $image_alt;
+		}
+	}
 
 	$attr = wp_parse_args(
 		$attr,
@@ -1206,7 +1218,7 @@
 			'src'    => $header->url,
 			'width'  => $width,
 			'height' => $height,
-			'alt'    => get_bloginfo( 'name' ),
+			'alt'    => $alt,
 		)
 	);
 
@@ -1217,7 +1229,12 @@
 
 		if ( is_array( $image_meta ) ) {
 			$srcset = wp_calculate_image_srcset( $size_array, $header->url, $image_meta, $header->attachment_id );
-			$sizes  = ! empty( $attr['sizes'] ) ? $attr['sizes'] : wp_calculate_image_sizes( $size_array, $header->url, $image_meta, $header->attachment_id );
+
+			if ( ! empty( $attr['sizes'] ) ) {
+				$sizes = $attr['sizes'];
+			} else {
+				$sizes = wp_calculate_image_sizes( $size_array, $header->url, $image_meta, $header->attachment_id );
+			}
 
 			if ( $srcset && $sizes ) {
 				$attr['srcset'] = $srcset;
@@ -1226,6 +1243,16 @@
 		}
 	}
 
+	/**
+	 * Filters the list of header image attributes.
+	 *
+	 * @since 5.9.0
+	 *
+	 * @param array  $attr   Array of the attributes for the image tag.
+	 * @param object $header The custom header object returned by 'get_custom_header()'.
+	 */
+	$attr = apply_filters( 'get_header_image_tag_attributes', $attr, $header );
+
 	$attr = array_map( 'esc_attr', $attr );
 	$html = '<img';
 
@@ -1270,10 +1297,10 @@
  * @return object
  */
 function _get_random_header_data() {
+	global $_wp_default_headers;
 	static $_wp_random_header = null;
 
 	if ( empty( $_wp_random_header ) ) {
-		global $_wp_default_headers;
 		$header_image_mod = get_theme_mod( 'header_image', '' );
 		$headers          = array();
 
@@ -1295,8 +1322,17 @@
 
 		$_wp_random_header = (object) $headers[ array_rand( $headers ) ];
 
-		$_wp_random_header->url           = sprintf( $_wp_random_header->url, get_template_directory_uri(), get_stylesheet_directory_uri() );
-		$_wp_random_header->thumbnail_url = sprintf( $_wp_random_header->thumbnail_url, get_template_directory_uri(), get_stylesheet_directory_uri() );
+		$_wp_random_header->url = sprintf(
+			$_wp_random_header->url,
+			get_template_directory_uri(),
+			get_stylesheet_directory_uri()
+		);
+
+		$_wp_random_header->thumbnail_url = sprintf(
+			$_wp_random_header->thumbnail_url,
+			get_template_directory_uri(),
+			get_stylesheet_directory_uri()
+		);
 	}
 
 	return $_wp_random_header;
@@ -1367,7 +1403,7 @@
 }
 
 /**
- * Gets the header images uploaded for the current theme.
+ * Gets the header images uploaded for the active theme.
  *
  * @since 3.2.0
  *
@@ -1396,12 +1432,17 @@
 		$header_data  = wp_get_attachment_metadata( $header->ID );
 		$header_index = $header->ID;
 
-		$header_images[ $header_index ]                      = array();
-		$header_images[ $header_index ]['attachment_id']     = $header->ID;
-		$header_images[ $header_index ]['url']               = $url;
-		$header_images[ $header_index ]['thumbnail_url']     = $url;
-		$header_images[ $header_index ]['alt_text']          = get_post_meta( $header->ID, '_wp_attachment_image_alt', true );
-		$header_images[ $header_index ]['attachment_parent'] = isset( $header_data['attachment_parent'] ) ? $header_data['attachment_parent'] : '';
+		$header_images[ $header_index ]                  = array();
+		$header_images[ $header_index ]['attachment_id'] = $header->ID;
+		$header_images[ $header_index ]['url']           = $url;
+		$header_images[ $header_index ]['thumbnail_url'] = $url;
+		$header_images[ $header_index ]['alt_text']      = get_post_meta( $header->ID, '_wp_attachment_image_alt', true );
+
+		if ( isset( $header_data['attachment_parent'] ) ) {
+			$header_images[ $header_index ]['attachment_parent'] = $header_data['attachment_parent'];
+		} else {
+			$header_images[ $header_index ]['attachment_parent'] = '';
+		}
 
 		if ( isset( $header_data['width'] ) ) {
 			$header_images[ $header_index ]['width'] = $header_data['width'];
@@ -1492,6 +1533,7 @@
  */
 function unregister_default_headers( $header ) {
 	global $_wp_default_headers;
+
 	if ( is_array( $header ) ) {
 		array_map( 'unregister_default_headers', $header );
 	} elseif ( isset( $_wp_default_headers[ $header ] ) ) {
@@ -1827,7 +1869,10 @@
 		$type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"';
 		?>
 		<style<?php echo $type_attr; ?> id="wp-custom-css">
-			<?php echo strip_tags( $styles ); // Note that esc_html() cannot be used because `div &gt; span` is not interpreted properly. ?>
+			<?php
+			// Note that esc_html() cannot be used because `div &gt; span` is not interpreted properly.
+			echo strip_tags( $styles );
+			?>
 		</style>
 		<?php
 	endif;
@@ -1838,7 +1883,7 @@
  *
  * @since 4.7.0
  *
- * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the current theme.
+ * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the active theme.
  * @return WP_Post|null The custom_css post or null if none exists.
  */
 function wp_get_custom_css_post( $stylesheet = '' ) {
@@ -1889,7 +1934,7 @@
  *
  * @since 4.7.0
  *
- * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the current theme.
+ * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the active theme.
  * @return string The Custom CSS Post content.
  */
 function wp_get_custom_css( $stylesheet = '' ) {
@@ -1905,11 +1950,11 @@
 	}
 
 	/**
-	 * Filters the Custom CSS Output into the <head>.
+	 * Filters the custom CSS output into the head element.
 	 *
 	 * @since 4.7.0
 	 *
-	 * @param string $css        CSS pulled in from the Custom CSS CPT.
+	 * @param string $css        CSS pulled in from the Custom CSS post type.
 	 * @param string $stylesheet The theme stylesheet name.
 	 */
 	$css = apply_filters( 'wp_get_custom_css', $css, $stylesheet );
@@ -1928,8 +1973,10 @@
  * @param array  $args {
  *     Args.
  *
- *     @type string $preprocessed Pre-processed CSS, stored in `post_content_filtered`. Normally empty string. Optional.
- *     @type string $stylesheet   Stylesheet (child theme) to update. Optional, defaults to current theme/stylesheet.
+ *     @type string $preprocessed Optional. Pre-processed CSS, stored in `post_content_filtered`.
+ *                                Normally empty string.
+ *     @type string $stylesheet   Optional. Stylesheet (child theme) to update.
+ *                                Defaults to active theme/stylesheet.
  * }
  * @return WP_Post|WP_Error Post on success, error on failure.
  */
@@ -1948,7 +1995,8 @@
 	);
 
 	/**
-	 * Filters the `css` (`post_content`) and `preprocessed` (`post_content_filtered`) args for a `custom_css` post being updated.
+	 * Filters the `css` (`post_content`) and `preprocessed` (`post_content_filtered`) args
+	 * for a `custom_css` post being updated.
 	 *
 	 * This filter can be used by plugin that offer CSS pre-processors, to store the original
 	 * pre-processed CSS in `post_content_filtered` and then store processed CSS in `post_content`.
@@ -1970,7 +2018,8 @@
 	 *     Custom CSS data.
 	 *
 	 *     @type string $css          CSS stored in `post_content`.
-	 *     @type string $preprocessed Pre-processed CSS stored in `post_content_filtered`. Normally empty string.
+	 *     @type string $preprocessed Pre-processed CSS stored in `post_content_filtered`.
+	 *                                Normally empty string.
 	 * }
 	 * @param array $args {
 	 *     The args passed into `wp_update_custom_css_post()` merged with defaults.
@@ -2086,7 +2135,7 @@
  */
 function get_editor_stylesheets() {
 	$stylesheets = array();
-	// Load editor_style.css if the current theme supports it.
+	// Load editor_style.css if the active theme supports it.
 	if ( ! empty( $GLOBALS['editor_styles'] ) && is_array( $GLOBALS['editor_styles'] ) ) {
 		$editor_styles = $GLOBALS['editor_styles'];
 
@@ -2156,9 +2205,11 @@
 						'',
 						array(
 							'<strong>' . _x( 'Address', 'Theme starter content' ) . "</strong>\n",
-							_x( '123 Main Street', 'Theme starter content' ) . "\n" . _x( 'New York, NY 10001', 'Theme starter content' ) . "\n\n",
+							_x( '123 Main Street', 'Theme starter content' ) . "\n",
+							_x( 'New York, NY 10001', 'Theme starter content' ) . "\n\n",
 							'<strong>' . _x( 'Hours', 'Theme starter content' ) . "</strong>\n",
-							_x( 'Monday&ndash;Friday: 9:00AM&ndash;5:00PM', 'Theme starter content' ) . "\n" . _x( 'Saturday &amp; Sunday: 11:00AM&ndash;3:00PM', 'Theme starter content' ),
+							_x( 'Monday&ndash;Friday: 9:00AM&ndash;5:00PM', 'Theme starter content' ) . "\n",
+							_x( 'Saturday &amp; Sunday: 11:00AM&ndash;3:00PM', 'Theme starter content' ),
 						)
 					),
 					'filter' => true,
@@ -2360,7 +2411,10 @@
 							}
 
 							$content[ $type ][ $sidebar_id ][] = $widget;
-						} elseif ( is_string( $widget ) && ! empty( $core_content[ $type ] ) && ! empty( $core_content[ $type ][ $widget ] ) ) {
+						} elseif ( is_string( $widget )
+							&& ! empty( $core_content[ $type ] )
+							&& ! empty( $core_content[ $type ][ $widget ] )
+						) {
 							$content[ $type ][ $sidebar_id ][] = $core_content[ $type ][ $widget ];
 						}
 					}
@@ -2387,7 +2441,10 @@
 							}
 
 							$content[ $type ][ $nav_menu_location ]['items'][] = $nav_menu_item;
-						} elseif ( is_string( $nav_menu_item ) && ! empty( $core_content[ $type ] ) && ! empty( $core_content[ $type ][ $nav_menu_item ] ) ) {
+						} elseif ( is_string( $nav_menu_item )
+							&& ! empty( $core_content[ $type ] )
+							&& ! empty( $core_content[ $type ][ $nav_menu_item ] )
+						) {
 							$content[ $type ][ $nav_menu_location ]['items'][] = $core_content[ $type ][ $nav_menu_item ];
 						}
 					}
@@ -2547,19 +2604,30 @@
 
 				$args[0] = array_intersect( $args[0], array_keys( $post_formats ) );
 			} else {
-				_doing_it_wrong( "add_theme_support( 'post-formats' )", __( 'You need to pass an array of post formats.' ), '5.6.0' );
+				_doing_it_wrong(
+					"add_theme_support( 'post-formats' )",
+					__( 'You need to pass an array of post formats.' ),
+					'5.6.0'
+				);
 				return false;
 			}
 			break;
 
 		case 'html5':
 			// You can't just pass 'html5', you need to pass an array of types.
-			if ( empty( $args[0] ) ) {
+			if ( empty( $args[0] ) || ! is_array( $args[0] ) ) {
+				_doing_it_wrong(
+					"add_theme_support( 'html5' )",
+					__( 'You need to pass an array of types.' ),
+					'3.6.1'
+				);
+
+				if ( ! empty( $args[0] ) && ! is_array( $args[0] ) ) {
+					return false;
+				}
+
 				// Build an array of types for back-compat.
 				$args = array( 0 => array( 'comment-list', 'comment-form', 'search-form' ) );
-			} elseif ( ! isset( $args[0] ) || ! is_array( $args[0] ) ) {
-				_doing_it_wrong( "add_theme_support( 'html5' )", __( 'You need to pass an array of types.' ), '3.6.1' );
-				return false;
 			}
 
 			// Calling 'html5' again merges, rather than overwrites.
@@ -2799,7 +2867,10 @@
  * @access private
  */
 function _custom_logo_header_styles() {
-	if ( ! current_theme_supports( 'custom-header', 'header-text' ) && get_theme_support( 'custom-logo', 'header-text' ) && ! get_theme_mod( 'header_text', true ) ) {
+	if ( ! current_theme_supports( 'custom-header', 'header-text' )
+		&& get_theme_support( 'custom-logo', 'header-text' )
+		&& ! get_theme_mod( 'header_text', true )
+	) {
 		$classes = (array) get_theme_support( 'custom-logo', 'header-text' );
 		$classes = array_map( 'sanitize_html_class', $classes );
 		$classes = '.' . implode( ', .', $classes );
@@ -2838,6 +2909,7 @@
  */
 function get_theme_support( $feature, ...$args ) {
 	global $_wp_theme_features;
+
 	if ( ! isset( $_wp_theme_features[ $feature ] ) ) {
 		return false;
 	}
@@ -2963,7 +3035,7 @@
  * @param string $feature The feature being checked. See add_theme_support() for the list
  *                        of possible values.
  * @param mixed  ...$args Optional extra arguments to be checked against certain features.
- * @return bool True if the current theme supports the feature, false otherwise.
+ * @return bool True if the active theme supports the feature, false otherwise.
  */
 function current_theme_supports( $feature, ...$args ) {
 	global $_wp_theme_features;
@@ -2976,9 +3048,10 @@
 		return false;
 	}
 
-	// If no args passed then no extra checks need be performed.
+	// If no args passed then no extra checks need to be performed.
 	if ( ! $args ) {
-		return true;
+		/** This filter is documented in wp-includes/theme.php */
+		return apply_filters( "current_theme_supports-{$feature}", true, $args, $_wp_theme_features[ $feature ] ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
 	}
 
 	switch ( $feature ) {
@@ -3013,14 +3086,14 @@
 	}
 
 	/**
-	 * Filters whether the current theme supports a specific feature.
+	 * Filters whether the active theme supports a specific feature.
 	 *
 	 * The dynamic portion of the hook name, `$feature`, refers to the specific
 	 * theme feature. See add_theme_support() for the list of possible values.
 	 *
 	 * @since 3.4.0
 	 *
-	 * @param bool   $supports Whether the current theme supports the given feature. Default true.
+	 * @param bool   $supports Whether the active theme supports the given feature. Default true.
 	 * @param array  $args     Array of arguments for the feature.
 	 * @param string $feature  The theme feature.
 	 */
@@ -3035,7 +3108,7 @@
  * @param string $feature The feature being checked. See add_theme_support() for the list
  *                        of possible values.
  * @param string $include Path to the file.
- * @return bool True if the current theme supports the supplied feature, false otherwise.
+ * @return bool True if the active theme supports the supplied feature, false otherwise.
  */
 function require_if_theme_supports( $feature, $include ) {
 	if ( current_theme_supports( $feature ) ) {
@@ -3048,7 +3121,7 @@
 /**
  * Registers a theme feature for use in add_theme_support().
  *
- * This does not indicate that the current theme supports the feature, it only describes
+ * This does not indicate that the active theme supports the feature, it only describes
  * the feature's supported options.
  *
  * @since 5.5.0
@@ -3065,7 +3138,7 @@
  *     @type string     $type         The type of data associated with this feature.
  *                                    Valid values are 'string', 'boolean', 'integer',
  *                                    'number', 'array', and 'object'. Defaults to 'boolean'.
- *     @type boolean    $variadic     Does this feature utilize the variadic support
+ *     @type bool       $variadic     Does this feature utilize the variadic support
  *                                    of add_theme_support(), or are all arguments specified
  *                                    as the second parameter. Must be used with the "array" type.
  *     @type string     $description  A short description of the feature. Included in
@@ -3155,7 +3228,9 @@
 	}
 
 	if ( is_array( $args['show_in_rest'] ) ) {
-		if ( isset( $args['show_in_rest']['prepare_callback'] ) && ! is_callable( $args['show_in_rest']['prepare_callback'] ) ) {
+		if ( isset( $args['show_in_rest']['prepare_callback'] )
+			&& ! is_callable( $args['show_in_rest']['prepare_callback'] )
+		) {
 			return new WP_Error(
 				'invalid_rest_prepare_callback',
 				sprintf(
@@ -3274,6 +3349,7 @@
  */
 function check_theme_switched() {
 	$stylesheet = get_option( 'theme_switched' );
+
 	if ( $stylesheet ) {
 		$old_theme = wp_get_theme( $stylesheet );
 
@@ -3303,6 +3379,7 @@
 			/** This action is documented in wp-includes/theme.php */
 			do_action( 'after_switch_theme', $stylesheet, $old_theme );
 		}
+
 		flush_rewrite_rules();
 
 		update_option( 'theme_switched', false );
@@ -3342,7 +3419,14 @@
 	 * called before wp_magic_quotes() gets called. Besides this fact, none of
 	 * the values should contain any characters needing slashes anyway.
 	 */
-	$keys       = array( 'changeset_uuid', 'customize_changeset_uuid', 'customize_theme', 'theme', 'customize_messenger_channel', 'customize_autosaved' );
+	$keys       = array(
+		'changeset_uuid',
+		'customize_changeset_uuid',
+		'customize_theme',
+		'theme',
+		'customize_messenger_channel',
+		'customize_autosaved',
+	);
 	$input_vars = array_merge(
 		wp_array_slice_assoc( $_GET, $keys ),
 		wp_array_slice_assoc( $_POST, $keys )
@@ -3398,7 +3482,16 @@
 	$settings_previewed       = ! $is_customize_save_action;
 
 	require_once ABSPATH . WPINC . '/class-wp-customize-manager.php';
-	$GLOBALS['wp_customize'] = new WP_Customize_Manager( compact( 'changeset_uuid', 'theme', 'messenger_channel', 'settings_previewed', 'autosaved', 'branching' ) );
+	$GLOBALS['wp_customize'] = new WP_Customize_Manager(
+		compact(
+			'changeset_uuid',
+			'theme',
+			'messenger_channel',
+			'settings_previewed',
+			'autosaved',
+			'branching'
+		)
+	);
 }
 
 /**
@@ -3541,7 +3634,7 @@
  *
  * @since 3.4.0
  *
- * @param string $stylesheet Optional. Theme to customize. Defaults to current theme.
+ * @param string $stylesheet Optional. Theme to customize. Defaults to active theme.
  *                           The theme's stylesheet will be urlencoded if necessary.
  * @return string
  */
@@ -3610,7 +3703,8 @@
 }
 
 /**
- * Makes sure that auto-draft posts get their post_date bumped or status changed to draft to prevent premature garbage-collection.
+ * Makes sure that auto-draft posts get their post_date bumped or status changed
+ * to draft to prevent premature garbage-collection.
  *
  * When a changeset is updated but remains an auto-draft, ensure the post_date
  * for the auto-draft posts remains the same so that it will be
@@ -3707,6 +3801,7 @@
  * See {@see 'setup_theme'}.
  *
  * @since 5.5.0
+ * @since 6.0.1 The `block-templates` feature was added.
  */
 function create_initial_theme_features() {
 	register_theme_feature(
@@ -3724,6 +3819,13 @@
 		)
 	);
 	register_theme_feature(
+		'block-templates',
+		array(
+			'description'  => __( 'Whether a theme uses block-based templates.' ),
+			'show_in_rest' => true,
+		)
+	);
+	register_theme_feature(
 		'custom-background',
 		array(
 			'description'  => __( 'Custom background if defined by the theme.' ),
@@ -4071,3 +4173,41 @@
 		)
 	);
 }
+
+/**
+ * Returns whether the active theme is a block-based theme or not.
+ *
+ * @since 5.9.0
+ *
+ * @return boolean Whether the active theme is a block-based theme or not.
+ */
+function wp_is_block_theme() {
+	return wp_get_theme()->is_block_theme();
+}
+
+/**
+ * Adds default theme supports for block themes when the 'setup_theme' action fires.
+ *
+ * See {@see 'setup_theme'}.
+ *
+ * @since 5.9.0
+ * @access private
+ */
+function _add_default_theme_supports() {
+	if ( ! wp_is_block_theme() ) {
+		return;
+	}
+
+	add_theme_support( 'post-thumbnails' );
+	add_theme_support( 'responsive-embeds' );
+	add_theme_support( 'editor-styles' );
+	/*
+	 * Makes block themes support HTML5 by default for the comment block and search form
+	 * (which use default template functions) and `[caption]` and `[gallery]` shortcodes.
+	 * Other blocks contain their own HTML5 markup.
+	 */
+	add_theme_support( 'html5', array( 'comment-form', 'comment-list', 'search-form', 'gallery', 'caption', 'style', 'script' ) );
+	add_theme_support( 'automatic-feed-links' );
+
+	add_filter( 'should_load_separate_core_block_assets', '__return_true' );
+}