Skip to content

HTML5 script support is always true#10919

Draft
sirreal wants to merge 9 commits intoWordPress:trunkfrom
sirreal:html5-script-support-true
Draft

HTML5 script support is always true#10919
sirreal wants to merge 9 commits intoWordPress:trunkfrom
sirreal:html5-script-support-true

Conversation

@sirreal
Copy link
Member

@sirreal sirreal commented Feb 13, 2026

Since non-HTML5 script output was completely removed in r61415, all scripts are now output as HTML5. This change makes the theme support check reflect that reality by always returning true for script support, regardless of whether themes explicitly declare support.

The behavior of add_theme_support() and remove_theme_support() remains unchanged.
Only the check via current_theme_supports( 'html5', 'script' ) is affected.

Theme REST API calls to remain unchanged:

(await wp.apiFetch({path: '/wp/v2/themes?status=active' }))[0].theme_supports.html5
// ['comment-form', 'comment-list', 'search-form', 'gallery', 'caption', 'style', 'script']

get_theme_support() behavior is unchanged at this time so current_theme_supports() may be incoherent. Additionally if no html5 support is enabled for a theme, script support remains false. REST API theme response inherits this strange behavior because it relies on both get_theme_support() and current_theme_supports(). Details in #10919 (comment).

Trac ticket: https://core.trac.wordpress.org/ticket/64442

Use of AI Tools

The basic implementation was performed by Claude Code. I performed full review and adaptation of the changes.


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

…n true.

Since non-HTML5 script output was completely removed in r61415 (WordPress 7.0),
all scripts are now output as HTML5. This change makes the theme support check
reflect that reality by always returning true for script support, regardless of
whether themes explicitly declare support.

The behavior of add_theme_support() and remove_theme_support() remains unchanged.
Only the check via current_theme_supports( 'html5', 'script' ) is affected.

Props sirreal.
Fixes #64442.
*/
$type = $args[0];

// HTML5 script support is always enabled since non-HTML5 script output was removed in 7.0.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// HTML5 script support is always enabled since non-HTML5 script output was removed in 7.0.

@sirreal sirreal force-pushed the html5-script-support-true branch from b3e070a to 4d295dc Compare February 13, 2026 09:17
@github-actions
Copy link

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@sirreal
Copy link
Member Author

sirreal commented Feb 13, 2026

This turns out to be messier than expected, largely because get_theme_support() and current_theme_supports() are both theme support lookup functions, but they both rely directly on the global $_wp_theme_features.

I think the cleanest way to implement this is to have current_theme_supports() rely on get_theme_support() and remove its use of the global. get_theme_support() can then be responsible for always declaring that 'html', 'script' support is enabled.

function get_theme_support( $feature, ...$args ) {
global $_wp_theme_features;
if ( ! isset( $_wp_theme_features[ $feature ] ) ) {
return false;
}
if ( ! $args ) {
return $_wp_theme_features[ $feature ];
}
switch ( $feature ) {
case 'custom-logo':
case 'custom-header':
case 'custom-background':
return $_wp_theme_features[ $feature ][0][ $args[0] ] ?? false;
default:
return $_wp_theme_features[ $feature ];
}
}

function current_theme_supports( $feature, ...$args ) {
global $_wp_theme_features;
if ( 'custom-header-uploads' === $feature ) {
return current_theme_supports( 'custom-header', 'uploads' );
}
if ( ! isset( $_wp_theme_features[ $feature ] ) ) {
return false;
}
// If no args passed then no extra checks need to be performed.
if ( ! $args ) {
/** 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 ) {
case 'post-thumbnails':
/*
* post-thumbnails can be registered for only certain content/post types
* by passing an array of types to add_theme_support().
* If no array was passed, then any type is accepted.
*/
if ( true === $_wp_theme_features[ $feature ] ) { // Registered for all types.
return true;
}
$content_type = $args[0];
return in_array( $content_type, $_wp_theme_features[ $feature ][0], true );
case 'html5':
case 'post-formats':
/*
* Specific post formats can be registered by passing an array of types
* to add_theme_support().
*
* Specific areas of HTML5 support *must* be passed via an array to add_theme_support().
*/
$type = $args[0];
return in_array( $type, $_wp_theme_features[ $feature ][0], true );
case 'custom-logo':
case 'custom-header':
case 'custom-background':
// Specific capabilities can be registered by passing an array to add_theme_support().
return ( isset( $_wp_theme_features[ $feature ][0][ $args[0] ] ) && $_wp_theme_features[ $feature ][0][ $args[0] ] );
}

if ( rest_is_field_included( 'theme_supports', $fields ) && $this->is_same_theme( $theme, $current_theme ) ) {
foreach ( get_registered_theme_features() as $feature => $config ) {
if ( ! is_array( $config['show_in_rest'] ) ) {
continue;
}
$name = $config['show_in_rest']['name'];
if ( ! rest_is_field_included( "theme_supports.{$name}", $fields ) ) {
continue;
}
if ( ! current_theme_supports( $feature ) ) {
$data['theme_supports'][ $name ] = $config['show_in_rest']['schema']['default'];
continue;
}
$support = get_theme_support( $feature );
if ( isset( $config['show_in_rest']['prepare_callback'] ) ) {
$prepare = $config['show_in_rest']['prepare_callback'];
} else {
$prepare = array( $this, 'prepare_theme_support' );
}
$prepared = $prepare( $support, $config, $feature, $request );
if ( is_wp_error( $prepared ) ) {
continue;
}
$data['theme_supports'][ $name ] = $prepared;
}
}

The alternative is to leave this as is (close this PR without landing). These checks are infrequent in plugins. get_theme_support( 'html5' ) in particular is very minimal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant