diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php index cddc762c86..66d64485d6 100644 --- a/src/wp-includes/default-filters.php +++ b/src/wp-includes/default-filters.php @@ -507,6 +507,10 @@ add_action( 'wp_default_scripts', 'wp_default_packages' ); add_action( 'wp_enqueue_scripts', 'wp_localize_jquery_ui_datepicker', 1000 ); add_action( 'admin_enqueue_scripts', 'wp_localize_jquery_ui_datepicker', 1000 ); +add_action( 'wp_enqueue_scripts', 'wp_common_block_scripts_and_styles' ); +add_action( 'admin_enqueue_scripts', 'wp_common_block_scripts_and_styles' ); +add_action( 'enqueue_block_assets', 'wp_enqueue_registered_block_scripts_and_styles' ); +add_action( 'enqueue_block_editor_assets', 'wp_enqueue_registered_block_scripts_and_styles' ); add_action( 'admin_print_scripts-index.php', 'wp_localize_community_events' ); add_filter( 'wp_print_scripts', 'wp_just_in_time_script_localization' ); add_filter( 'print_scripts_array', 'wp_prototype_before_jquery' ); diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index 6a83863bfe..798da85a9b 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -2415,3 +2415,74 @@ function script_concat_settings() { } } } + +/** + * Handles the enqueueing of block scripts and styles that are common to both + * the editor and the front-end. + * + * @since 5.0.0 + * + * @global WP_Screen $current_screen + */ +function wp_common_block_scripts_and_styles() { + global $current_screen; + + if ( is_admin() && ! $current_screen->is_block_editor() ) { + return; + } + + wp_enqueue_style( 'wp-block-library' ); + + if ( current_theme_supports( 'wp-block-styles' ) ) { + wp_enqueue_style( 'wp-block-library-theme' ); + } + + /** + * Fires after enqueuing block assets for both editor and front-end. + * + * Call `add_action` on any hook before 'wp_enqueue_scripts'. + * + * In the function call you supply, simply use `wp_enqueue_script` and + * `wp_enqueue_style` to add your functionality to the Gutenberg editor. + * + * @since 5.0.0 + */ + do_action( 'enqueue_block_assets' ); +} + +/** + * Enqueues registered block scripts and styles, depending on current rendered + * context (only enqueuing editor scripts while in context of the editor). + * + * @since 5.0.0 + * + * @global WP_Screen $current_screen + */ +function wp_enqueue_registered_block_scripts_and_styles() { + global $current_screen; + + $is_editor = ( is_admin() && $current_screen->is_block_editor() ); + + $block_registry = WP_Block_Type_Registry::get_instance(); + foreach ( $block_registry->get_all_registered() as $block_name => $block_type ) { + // Front-end styles. + if ( ! empty( $block_type->style ) ) { + wp_enqueue_style( $block_type->style ); + } + + // Front-end script. + if ( ! empty( $block_type->script ) ) { + wp_enqueue_script( $block_type->script ); + } + + // Editor styles. + if ( $is_editor && ! empty( $block_type->editor_style ) ) { + wp_enqueue_style( $block_type->editor_style ); + } + + // Editor script. + if ( $is_editor && ! empty( $block_type->editor_script ) ) { + wp_enqueue_script( $block_type->editor_script ); + } + } +} diff --git a/tests/phpunit/tests/dependencies/styles.php b/tests/phpunit/tests/dependencies/styles.php index 31e88df702..30ed7799ce 100644 --- a/tests/phpunit/tests/dependencies/styles.php +++ b/tests/phpunit/tests/dependencies/styles.php @@ -4,24 +4,45 @@ * @group scripts */ class Tests_Dependencies_Styles extends WP_UnitTestCase { - var $old_wp_styles; + private $old_wp_styles; + private $old_wp_scripts; function setUp() { parent::setUp(); + if ( empty( $GLOBALS['wp_styles'] ) ) { $GLOBALS['wp_styles'] = null; } + $this->old_wp_styles = $GLOBALS['wp_styles']; + + if ( empty( $GLOBALS['wp_scripts'] ) ) { + $GLOBALS['wp_scripts'] = null; + } + + $this->old_wp_styles = $GLOBALS['wp_scripts']; + remove_action( 'wp_default_styles', 'wp_default_styles' ); remove_action( 'wp_print_styles', 'print_emoji_styles' ); + $GLOBALS['wp_styles'] = new WP_Styles(); $GLOBALS['wp_styles']->default_version = get_bloginfo( 'version' ); + + $GLOBALS['wp_scripts'] = new WP_Scripts(); + $GLOBALS['wp_scripts']->default_version = get_bloginfo( 'version' ); } function tearDown() { - $GLOBALS['wp_styles'] = $this->old_wp_styles; + $GLOBALS['wp_styles'] = $this->old_wp_styles; + $GLOBALS['wp_scripts'] = $this->old_wp_scripts; + add_action( 'wp_default_styles', 'wp_default_styles' ); add_action( 'wp_print_styles', 'print_emoji_styles' ); + + if ( current_theme_supports( 'wp-block-styles' ) ) { + remove_theme_support( 'wp-block-styles' ); + } + parent::tearDown(); } @@ -305,4 +326,67 @@ CSS; ), ); } + + /** + * Tests that visual block styles are enqueued in the editor even when there is not theme support for 'wp-block-styles'. + * + * Visual block styles should always be enqueued when editing to avoid the appearance of a broken editor. + */ + function test_block_styles_for_editing_without_theme_support() { + // Confirm we are without theme support by default. + $this->assertFalse( current_theme_supports( 'wp-block-styles' ) ); + + wp_default_styles( $GLOBALS['wp_styles'] ); + + $this->assertFalse( wp_style_is( 'wp-block-library-theme' ) ); + wp_enqueue_style( 'wp-edit-blocks' ); + $this->assertTrue( wp_style_is( 'wp-block-library-theme' ) ); + } + + /** + * Tests that visual block styles are enqueued when there is theme support for 'wp-block-styles'. + * + * Visual block styles should always be enqueued when editing to avoid the appearance of a broken editor. + */ + function test_block_styles_for_editing_with_theme_support() { + add_theme_support( 'wp-block-styles' ); + + wp_default_styles( $GLOBALS['wp_styles'] ); + + $this->assertFalse( wp_style_is( 'wp-block-library-theme' ) ); + wp_common_block_scripts_and_styles(); + $this->assertTrue( wp_style_is( 'wp-block-library-theme' ) ); + } + + /** + * Tests that visual block styles are not enqueued for viewing when there is no theme support for 'wp-block-styles'. + * + * Visual block styles should not be enqueued unless a theme opts in. + * This way we avoid style conflicts with existing themes. + */ + function test_no_block_styles_for_viewing_without_theme_support() { + // Confirm we are without theme support by default. + $this->assertFalse( current_theme_supports( 'wp-block-styles' ) ); + + wp_default_styles( $GLOBALS['wp_styles'] ); + + $this->assertFalse( wp_style_is( 'wp-block-library-theme' ) ); + wp_enqueue_style( 'wp-block-library' ); + $this->assertFalse( wp_style_is( 'wp-block-library-theme' ) ); + } + + /** + * Tests that visual block styles are enqueued for viewing when there is theme support for 'wp-block-styles'. + * + * Visual block styles should be enqueued when a theme opts in. + */ + function test_block_styles_for_viewing_with_theme_support() { + add_theme_support( 'wp-block-styles' ); + + wp_default_styles( $GLOBALS['wp_styles'] ); + + $this->assertFalse( wp_style_is( 'wp-block-library-theme' ) ); + wp_common_block_scripts_and_styles(); + $this->assertTrue( wp_style_is( 'wp-block-library-theme' ) ); + } }