Skip to content
Draft
2 changes: 1 addition & 1 deletion src/wp-includes/class-wp-editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -1541,7 +1541,7 @@ public static function force_uncompressed_tinymce() {
$wp_scripts = wp_scripts();

$wp_scripts->remove( 'wp-tinymce' );
wp_register_tinymce_scripts( $wp_scripts, true );
wp_register_tinymce_scripts( $wp_scripts );
}

/**
Expand Down
53 changes: 30 additions & 23 deletions src/wp-includes/script-loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*
* Several constants are used to manage the loading, concatenating and compression of scripts and CSS:
* define('SCRIPT_DEBUG', true); loads the development (non-minified) versions of all scripts and CSS, and disables compression and concatenation,
* define('CONCATENATE_SCRIPTS', false); disables compression and concatenation of scripts and CSS,
* define('CONCATENATE_SCRIPTS', true); enables concatenation of scripts and CSS in the admin and on the login screen (disabled by default),
* define('COMPRESS_SCRIPTS', false); disables compression of scripts,
* define('COMPRESS_CSS', false); disables compression of CSS,
* define('ENFORCE_GZIP', true); forces gzip for compression (default is deflate).
Expand Down Expand Up @@ -37,35 +37,42 @@
/**
* Registers TinyMCE scripts.
*
* TinyMCE core and the compat3x plugin are registered as separate files. TinyMCE loads its theme
* and any other plugins itself when an editor is initialized. The `wp-tinymce.js` bundle of all of
* them is no longer registered, but it can still be registered in their place under the
* `wp-tinymce` handle.
*
* @since 5.0.0
* @since 7.2.0 The `wp-tinymce.js` bundle is no longer registered, regardless of whether scripts
* are concatenated or compressed.
* @since 7.2.0 The `$force_uncompressed` parameter was deprecated and renamed to `$deprecated`.
*
* @global string $tinymce_version
* @global bool $concatenate_scripts
* @global bool $compress_scripts
*
* @param WP_Scripts $scripts WP_Scripts object.
* @param bool $force_uncompressed Whether to forcibly prevent gzip compression. Default false.
* @param WP_Scripts $scripts WP_Scripts object.
* @param bool $deprecated Not used.
*
* @phpstan-param false $deprecated
*/
function wp_register_tinymce_scripts( $scripts, $force_uncompressed = false ) {
global $tinymce_version, $concatenate_scripts, $compress_scripts;
function wp_register_tinymce_scripts( $scripts, $deprecated = false ): void {
global $tinymce_version;

if ( false !== $deprecated ) {
_deprecated_argument( __FUNCTION__, '7.2.0' );
}

$suffix = wp_scripts_get_suffix();
$dev_suffix = wp_scripts_get_suffix( 'dev' );

script_concat_settings();

$compressed = $compress_scripts && $concatenate_scripts && ! $force_uncompressed;

/*
* Load tinymce.js when running from /src, otherwise load wp-tinymce.js (in production)
* or tinymce.min.js (when SCRIPT_DEBUG is true).
* This no longer depends on the concatenation settings, but it is where an admin screen has
* settled them until now, which the 'wp_should_concatenate_admin_scripts' filter documents.
*/
if ( $compressed ) {
$scripts->add( 'wp-tinymce', includes_url( 'js/tinymce/' ) . 'wp-tinymce.js', array(), $tinymce_version );
} else {
$scripts->add( 'wp-tinymce-root', includes_url( 'js/tinymce/' ) . "tinymce$dev_suffix.js", array(), $tinymce_version );
$scripts->add( 'wp-tinymce', includes_url( 'js/tinymce/' ) . "plugins/compat3x/plugin$dev_suffix.js", array( 'wp-tinymce-root' ), $tinymce_version );
}
script_concat_settings();

// Load tinymce.js when running from /src, otherwise tinymce.min.js.
$scripts->add( 'wp-tinymce-root', includes_url( 'js/tinymce/' ) . "tinymce$dev_suffix.js", array(), $tinymce_version );
$scripts->add( 'wp-tinymce', includes_url( 'js/tinymce/' ) . "plugins/compat3x/plugin$dev_suffix.js", array( 'wp-tinymce-root' ), $tinymce_version );

$scripts->add( 'wp-tinymce-lists', includes_url( "js/tinymce/plugins/lists/plugin$suffix.js" ), array( 'wp-tinymce' ), $tinymce_version );
}
Expand Down Expand Up @@ -2498,7 +2505,7 @@ function script_concat_settings() {
/**
* Determines whether scripts and styles are concatenated on admin screens and the login screen.
*
* Concatenation is on unless the `CONCATENATE_SCRIPTS` constant turns it off, and `SCRIPT_DEBUG`
* Concatenation is off unless the `CONCATENATE_SCRIPTS` constant turns it on, and `SCRIPT_DEBUG`
* turns it off regardless. Scripts and styles are never concatenated elsewhere.
*
* This is the default that script_concat_settings() gives the `$concatenate_scripts` global when
Expand All @@ -2515,7 +2522,7 @@ function script_concat_settings() {
* @return bool Whether scripts and styles are concatenated on admin screens and the login screen.
*/
function wp_should_concatenate_admin_scripts(): bool {
$concatenate = ( defined( 'CONCATENATE_SCRIPTS' ) ? (bool) CONCATENATE_SCRIPTS : true )
$concatenate = ( defined( 'CONCATENATE_SCRIPTS' ) ? (bool) CONCATENATE_SCRIPTS : false )
&& ! ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG );

/**
Expand All @@ -2532,8 +2539,8 @@ function wp_should_concatenate_admin_scripts(): bool {
*
* @since 7.2.0
*
* @param bool $concatenate Whether scripts and styles are concatenated. Default true, unless the
* `CONCATENATE_SCRIPTS` constant is false or `SCRIPT_DEBUG` is true.
* @param bool $concatenate Whether scripts and styles are concatenated. Default false, unless the
* `CONCATENATE_SCRIPTS` constant is true and `SCRIPT_DEBUG` is not.
*/
return (bool) apply_filters( 'wp_should_concatenate_admin_scripts', $concatenate );
}
Expand Down
70 changes: 67 additions & 3 deletions tests/phpunit/tests/dependencies/scripts.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ class Tests_Dependencies_Scripts extends WP_UnitTestCase {
*/
protected $old_concatenate_scripts;

/**
* @var mixed
*/
protected $old_compress_scripts;

/**
* @var WP_Styles
*/
Expand All @@ -54,6 +59,7 @@ public function set_up() {
$this->old_wp_scripts = $GLOBALS['wp_scripts'] ?? null;
$this->old_wp_styles = $GLOBALS['wp_styles'] ?? null;
$this->old_concatenate_scripts = $GLOBALS['concatenate_scripts'] ?? null;
$this->old_compress_scripts = $GLOBALS['compress_scripts'] ?? null;
remove_action( 'wp_default_scripts', 'wp_default_scripts' );
remove_action( 'wp_default_scripts', 'wp_default_packages' );
$GLOBALS['wp_scripts'] = new WP_Scripts();
Expand All @@ -77,6 +83,7 @@ public function tear_down() {
$GLOBALS['wp_scripts'] = $this->old_wp_scripts;
$GLOBALS['wp_styles'] = $this->old_wp_styles;
$GLOBALS['concatenate_scripts'] = $this->old_concatenate_scripts;
$GLOBALS['compress_scripts'] = $this->old_compress_scripts;
add_action( 'wp_default_scripts', 'wp_default_scripts' );
parent::tear_down();
}
Expand Down Expand Up @@ -3830,16 +3837,73 @@ static function () {
* @ticket 58648
*/
public function test_printing_tinymce_scripts() {
global $wp_scripts;

wp_register_tinymce_scripts( $wp_scripts, true );
wp_register_tinymce_scripts( wp_scripts() );

$actual = get_echo( 'wp_print_scripts', array( array( 'wp-tinymce' ) ) );

$this->assertStringNotContainsString( 'async', $actual, 'TinyMCE should not have an async attribute.' );
$this->assertStringNotContainsString( 'defer', $actual, 'TinyMCE should not have a defer attribute.' );
}

/**
* Tests that TinyMCE is registered as separate files, never as the `wp-tinymce.js` bundle.
*
* @ticket 57548
*
* @covers ::wp_register_tinymce_scripts
*
* @dataProvider data_register_tinymce_scripts_unbundled
*
* @param bool $concatenate Value of the `$concatenate_scripts` global.
* @param bool $compress Value of the `$compress_scripts` global.
*/
public function test_register_tinymce_scripts_unbundled( bool $concatenate, bool $compress ): void {
global $concatenate_scripts, $compress_scripts;

$concatenate_scripts = $concatenate;
$compress_scripts = $compress;

$wp_scripts = wp_scripts();
wp_register_tinymce_scripts( $wp_scripts );

$root = $wp_scripts->query( 'wp-tinymce-root' );
$this->assertInstanceOf( _WP_Dependency::class, $root, 'Expected TinyMCE core to be registered.' );
$this->assertIsString( $root->src );
$this->assertMatchesRegularExpression( '#/js/tinymce/tinymce(\.min)?\.js$#', $root->src );

$tinymce = $wp_scripts->query( 'wp-tinymce' );
$this->assertInstanceOf( _WP_Dependency::class, $tinymce, 'Expected the wp-tinymce handle to be registered.' );
$this->assertIsString( $tinymce->src );
$this->assertMatchesRegularExpression( '#/js/tinymce/plugins/compat3x/plugin(\.min)?\.js$#', $tinymce->src );
$this->assertSame( array( 'wp-tinymce-root' ), $tinymce->deps );
}

/**
* Data provider for test_register_tinymce_scripts_unbundled().
*
* @return array<non-falsy-string, array{ concatenate: bool, compress: bool }>
*/
public function data_register_tinymce_scripts_unbundled(): array {
return array(
'concatenated and compressed' => array(
'concatenate' => true,
'compress' => true,
),
'concatenated only' => array(
'concatenate' => true,
'compress' => false,
),
'compressed only' => array(
'concatenate' => false,
'compress' => true,
),
'neither' => array(
'concatenate' => false,
'compress' => false,
),
);
}

/**
* Make sure scripts with a loading strategy that are printed
* without being enqueued are handled properly.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ public function test_constant_off(): void {
}

/**
* Tests the default when `CONCATENATE_SCRIPTS` is not defined, which is to concatenate unless
* `SCRIPT_DEBUG` is on.
* Tests the default when `CONCATENATE_SCRIPTS` is not defined, which is not to concatenate.
*
* @ticket 57548
*/
Expand All @@ -84,7 +83,7 @@ public function test_default(): void {
$this->markTestSkipped( 'CONCATENATE_SCRIPTS is defined.' );
}

$this->assertSame( ! SCRIPT_DEBUG, wp_should_concatenate_admin_scripts() );
$this->assertFalse( wp_should_concatenate_admin_scripts() );
}

/**
Expand All @@ -96,7 +95,7 @@ public function test_filter(): void {
$filter = new MockAction();
add_filter( 'wp_should_concatenate_admin_scripts', array( $filter, 'filter' ) );

$this->assertSame( ! SCRIPT_DEBUG && ( ! defined( 'CONCATENATE_SCRIPTS' ) || CONCATENATE_SCRIPTS ), wp_should_concatenate_admin_scripts() );
$this->assertSame( ! SCRIPT_DEBUG && defined( 'CONCATENATE_SCRIPTS' ) && CONCATENATE_SCRIPTS, wp_should_concatenate_admin_scripts() );
$this->assertSame( 1, $filter->get_call_count() );

add_filter( 'wp_should_concatenate_admin_scripts', '__return_true', 20 );
Expand Down
Loading