diff --git a/src/wp-includes/admin-bar.php b/src/wp-includes/admin-bar.php index 9fc3c2b46b348..2186802d5feda 100644 --- a/src/wp-includes/admin-bar.php +++ b/src/wp-includes/admin-bar.php @@ -1399,3 +1399,49 @@ function _get_admin_bar_pref( $context = 'front', $user = 0 ) { return 'true' === $pref; } + +/** + * Adds CSS from the administration color scheme stylesheet on the front end. + * + * @since 7.0.0 + * + * @global array $_wp_admin_css_colors Registered administration color schemes. + */ +function wp_admin_bar_add_color_scheme_to_front_end() { + if ( is_admin() ) { + return; + } + + global $_wp_admin_css_colors; + + if ( empty( $_wp_admin_css_colors ) ) { + register_admin_color_schemes(); + } + + $color_scheme = get_user_option( 'admin_color' ); + + if ( empty( $color_scheme ) || ! isset( $_wp_admin_css_colors[ $color_scheme ] ) ) { + $color_scheme = 'modern'; + } + + $color = $_wp_admin_css_colors[ $color_scheme ] ?? null; + $url = $color->url ?? ''; + + if ( $url ) { + $response = wp_remote_get( $url ); + if ( ! is_wp_error( $response ) ) { + $css = $response['body']; + if ( is_string( $css ) && str_contains( $css, '#wpadminbar' ) ) { + $start_position = strpos( $css, '#wpadminbar' ); + $end_position = strpos( $css, '.wp-pointer' ); + if ( false !== $end_position && $end_position > $start_position ) { + $css = substr( $css, $start_position, $end_position - $start_position ); + if ( SCRIPT_DEBUG ) { + $css = str_replace( '/* Pointers */', '', $css ); + } + } + wp_add_inline_style( 'admin-bar', $css ); + } + } + } +} diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php index 0bcd2d6b15acb..021ee08118b27 100644 --- a/src/wp-includes/default-filters.php +++ b/src/wp-includes/default-filters.php @@ -705,6 +705,7 @@ add_action( 'wp_body_open', 'wp_admin_bar_render', 0 ); add_action( 'wp_footer', 'wp_admin_bar_render', 1000 ); // Back-compat for themes not using `wp_body_open`. add_action( 'in_admin_header', 'wp_admin_bar_render', 0 ); +add_action( 'admin_bar_init', 'wp_admin_bar_add_color_scheme_to_front_end', 0 ); // Former admin filters that can also be hooked on the front end. add_action( 'media_buttons', 'media_buttons' ); diff --git a/tests/phpunit/tests/dependencies/wpStyleLoaderSrc.php b/tests/phpunit/tests/dependencies/wpStyleLoaderSrc.php index 6155ab0d178c3..170129580a3e7 100644 --- a/tests/phpunit/tests/dependencies/wpStyleLoaderSrc.php +++ b/tests/phpunit/tests/dependencies/wpStyleLoaderSrc.php @@ -12,15 +12,20 @@ class Tests_Dependencies_wpStyleLoaderSrc extends WP_UnitTestCase { /** * Tests that PHP warnings are not thrown when wp_style_loader_src() is called - * before the `$_wp_admin_css_colors` global is set. + * before the `$_wp_admin_css_colors` global is set within the admin. * * The warnings that we should not see: * `Warning: Trying to access array offset on null`. * `Warning: Attempt to read property "url" on null`. * * @ticket 61302 + * @ticket 64762 */ public function test_without_wp_admin_css_colors_global() { - $this->assertFalse( wp_style_loader_src( '', 'colors' ) ); + if ( is_admin() ) { + $this->assertFalse( wp_style_loader_src( '', 'colors' ) ); + } else { + $this->assertStringContainsString( '/colors.css', wp_style_loader_src( '', 'colors' ) ); + } } }