Skip to content

Commit

Permalink
Do not render global styles coming from the server in the site editor (
Browse files Browse the repository at this point in the history
  • Loading branch information
oandregal authored Apr 13, 2022
1 parent 39172d1 commit 49e4a4f
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 39 deletions.
85 changes: 56 additions & 29 deletions lib/compat/wordpress-6.0/block-editor-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,49 @@
* @package gutenberg
*/

/**
* Returns true if the style is coming from global styles.
*
* @param array $style Array containing a '__unstableType' key.
* @return boolean
*/
function gutenberg_is_global_styles_in_5_8( $style ) {
if ( isset( $style['__unstableType'] ) && ( 'globalStyles' === $style['__unstableType'] ) ) {
return true;
}

return false;
}

/**
* Returns true if the style is coming from global styles.
*
* @param array $style Array containing a '__unstableType' key and a 'css' key with the actual CSS.
* @return boolean
*/
function gutenberg_is_global_styles_in_5_9( $style ) {
/*
* In WordPress 5.9 we don't have a mechanism to distinguish block styles generated via theme.json
* from styles that come from the stylesheet of a theme.
*
* We do know that the block styles generated via theme.json have some rules for alignment.
* Hence, by detecting the presence of these rules, we can tell with high certainty
* whether or not the incoming $style has been generated from theme.json.
*/
$root_styles = '.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }';
$root_styles .= '.wp-site-blocks > .alignright { float: right; margin-left: 2em; }';
$root_styles .= '.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }';

if (
( isset( $style['__unstableType'] ) && ( 'presets' === $style['__unstableType'] ) ) ||
( isset( $style['__unstableType'] ) && ( 'theme' === $style['__unstableType'] ) && str_contains( $style['css'], $root_styles ) )
) {
return true;
}

return false;
}

/**
* Adds styles and __experimentalFeatures to the block editor settings.
*
Expand All @@ -15,15 +58,6 @@
function gutenberg_get_block_editor_settings( $settings ) {
// Set what is the context for this data request.
$context = 'other';
if (
is_callable( 'get_current_screen' ) &&
function_exists( 'gutenberg_is_edit_site_page' ) &&
is_object( get_current_screen() ) &&
gutenberg_is_edit_site_page( get_current_screen()->id )
) {
$context = 'site-editor';
}

if (
defined( 'REST_REQUEST' ) &&
REST_REQUEST &&
Expand All @@ -34,49 +68,41 @@ function_exists( 'gutenberg_is_edit_site_page' ) &&
}

if ( 'other' === $context ) {
global $wp_version;
$is_wp_5_8 = version_compare( $wp_version, '5.8', '>=' ) && version_compare( $wp_version, '5.9', '<' );
$is_wp_5_9 = version_compare( $wp_version, '5.9', '>=' ) && version_compare( $wp_version, '6.0-beta1', '<' );
$is_wp_6_0 = version_compare( $wp_version, '6.0-beta1', '>=' );

// Make sure the styles array exists.
// In some contexts, like the navigation editor, it doesn't.
if ( ! isset( $settings['styles'] ) ) {
$settings['styles'] = array();
}

// Remove existing global styles provided by core.
$styles_without_existing_global_styles = array();
foreach ( $settings['styles'] as $style ) {
if (
! isset( $style['__unstableType'] ) ||
// '__unstableType' is 'globalStyles' for WordPress 5.8 and 'presets' for WordPress 5.9.
//
// Note that styles classified as'theme', can be from the theme stylesheet
// or from the theme.json (the styles section).
// We are unable to identify which is which, so we can't remove and recreate those.
// Instead, we reload the theme.json styles from the plugin.
// Because they'll use the same selectors and load later,
// they'll have higher priority than core's.
//
// Theoretically, this approach with 'theme' styles could be problematic:
// if we remove style properties in the plugin, if selectors change, etc.
// We need to address this issue directly in core by alowing to identify
// styles coming from theme.json.
//
// A final note about 'theme' styles: this flag is used to identify theme
// styles that may need to be removed if the user toggles
// "Preferences > Use theme styles" in the preferences modal.
//
! in_array( $style['__unstableType'], array( 'globalStyles', 'presets' ), true )
( $is_wp_5_8 && ! gutenberg_is_global_styles_in_5_8( $style ) ) || // Can be removed when plugin minimum version is 5.9.
( $is_wp_5_9 && ! gutenberg_is_global_styles_in_5_9( $style ) ) || // Can be removed when plugin minimum version is 6.0.
( $is_wp_6_0 && ( ! isset( $style['isGlobalStyles'] ) || ! $style['isGlobalStyles'] ) )
) {
$styles_without_existing_global_styles[] = $style;
}
}

// Recreate global styles.
$new_global_styles = array();
$presets = array(
array(
'css' => 'variables',
'__unstableType' => 'presets',
'isGlobalStyles' => true,
),
array(
'css' => 'presets',
'__unstableType' => 'presets',
'isGlobalStyles' => true,
),
);
foreach ( $presets as $preset_style ) {
Expand All @@ -91,6 +117,7 @@ function_exists( 'gutenberg_is_edit_site_page' ) &&
$block_classes = array(
'css' => 'styles',
'__unstableType' => 'theme',
'isGlobalStyles' => true,
);
$actual_css = gutenberg_get_global_stylesheet( array( $block_classes['css'] ) );
if ( '' !== $actual_css ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,10 @@ describe( 'global styles renderer', () => {
};

expect( toStyles( tree, blockSelectors ) ).toEqual(
'.wp-site-blocks > * { margin-top: 0; margin-bottom: 0; }.wp-site-blocks > * + * { margin-top: var( --wp--style--block-gap ); }body{background-color: red;margin: 10px;padding: 10px;}h1{font-size: 42px;}.wp-block-group{margin-top: 10px;margin-right: 20px;margin-bottom: 30px;margin-left: 40px;padding-top: 11px;padding-right: 22px;padding-bottom: 33px;padding-left: 44px;}h1,h2,h3,h4,h5,h6{color: orange;}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{color: hotpink;}.has-white-color{color: var(--wp--preset--color--white) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}h1.has-blue-color,h2.has-blue-color,h3.has-blue-color,h4.has-blue-color,h5.has-blue-color,h6.has-blue-color{color: var(--wp--preset--color--blue) !important;}h1.has-blue-background-color,h2.has-blue-background-color,h3.has-blue-background-color,h4.has-blue-background-color,h5.has-blue-background-color,h6.has-blue-background-color{background-color: var(--wp--preset--color--blue) !important;}h1.has-blue-border-color,h2.has-blue-border-color,h3.has-blue-border-color,h4.has-blue-border-color,h5.has-blue-border-color,h6.has-blue-border-color{border-color: var(--wp--preset--color--blue) !important;}'
'body {margin: 0;}' +
'body{background-color: red;margin: 10px;padding: 10px;}h1{font-size: 42px;}.wp-block-group{margin-top: 10px;margin-right: 20px;margin-bottom: 30px;margin-left: 40px;padding-top: 11px;padding-right: 22px;padding-bottom: 33px;padding-left: 44px;}h1,h2,h3,h4,h5,h6{color: orange;}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{color: hotpink;}' +
'.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }' +
'.has-white-color{color: var(--wp--preset--color--white) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}h1.has-blue-color,h2.has-blue-color,h3.has-blue-color,h4.has-blue-color,h5.has-blue-color,h6.has-blue-color{color: var(--wp--preset--color--blue) !important;}h1.has-blue-background-color,h2.has-blue-background-color,h3.has-blue-background-color,h4.has-blue-background-color,h5.has-blue-background-color,h6.has-blue-background-color{background-color: var(--wp--preset--color--blue) !important;}h1.has-blue-border-color,h2.has-blue-border-color,h3.has-blue-border-color,h4.has-blue-border-color,h5.has-blue-border-color,h6.has-blue-border-color{border-color: var(--wp--preset--color--blue) !important;}'
);
} );
} );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,12 @@ import {
import { useEffect, useState, useContext } from '@wordpress/element';
import { getCSSRules } from '@wordpress/style-engine';

/**
* Internal dependencies
*/

/**
* Internal dependencies
*/
import { PRESET_METADATA, ROOT_BLOCK_SELECTOR } from './utils';
import { GlobalStylesContext } from './context';
import { useSetting } from './hooks';

function compileStyleValue( uncompiledValue ) {
const VARIABLE_REFERENCE_PREFIX = 'var:';
Expand Down Expand Up @@ -329,12 +326,19 @@ export const toCustomProperties = ( tree, blockSelectors ) => {
return ruleset;
};

export const toStyles = ( tree, blockSelectors ) => {
export const toStyles = ( tree, blockSelectors, hasBlockGapSupport ) => {
const nodesWithStyles = getNodesWithStyles( tree, blockSelectors );
const nodesWithSettings = getNodesWithSettings( tree, blockSelectors );

let ruleset =
'.wp-site-blocks > * { margin-top: 0; margin-bottom: 0; }.wp-site-blocks > * + * { margin-top: var( --wp--style--block-gap ); }';
/*
* Reset default browser margin on the root body element.
* This is set on the root selector **before** generating the ruleset
* from the `theme.json`. This is to ensure that if the `theme.json` declares
* `margin` in its `spacing` declaration for the `body` element then these
* user-generated values take precedence in the CSS cascade.
* @link https://github.com/WordPress/gutenberg/issues/36147.
*/
let ruleset = 'body {margin: 0;}';
nodesWithStyles.forEach( ( { selector, styles } ) => {
const declarations = getStylesDeclarations( styles );
if ( declarations.length === 0 ) {
Expand All @@ -343,6 +347,26 @@ export const toStyles = ( tree, blockSelectors ) => {
ruleset = ruleset + `${ selector }{${ declarations.join( ';' ) };}`;
} );

/* Add alignment / layout styles */
ruleset =
ruleset +
'.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }';
ruleset =
ruleset +
'.wp-site-blocks > .alignright { float: right; margin-left: 2em; }';
ruleset =
ruleset +
'.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }';

if ( hasBlockGapSupport ) {
ruleset =
ruleset +
'.wp-site-blocks > * { margin-block-start: 0; margin-block-end: 0; }';
ruleset =
ruleset +
'.wp-site-blocks > * + * { margin-block-start: var( --wp--style--block-gap ); }';
}

nodesWithSettings.forEach( ( { selector, presets } ) => {
if ( ROOT_BLOCK_SELECTOR === selector ) {
// Do not add extra specificity for top-level classes.
Expand Down Expand Up @@ -378,6 +402,8 @@ export function useGlobalStylesOutput() {
const [ stylesheets, setStylesheets ] = useState( [] );
const [ settings, setSettings ] = useState( {} );
const { merged: mergedConfig } = useContext( GlobalStylesContext );
const [ blockGap ] = useSetting( 'spacing.blockGap' );
const hasBlockGapSupport = blockGap !== null;

useEffect( () => {
if ( ! mergedConfig?.styles || ! mergedConfig?.settings ) {
Expand All @@ -389,7 +415,11 @@ export function useGlobalStylesOutput() {
mergedConfig,
blockSelectors
);
const globalStyles = toStyles( mergedConfig, blockSelectors );
const globalStyles = toStyles(
mergedConfig,
blockSelectors,
hasBlockGapSupport
);
setStylesheets( [
{
css: customProperties,
Expand All @@ -403,5 +433,5 @@ export function useGlobalStylesOutput() {
setSettings( mergedConfig.settings );
}, [ mergedConfig ] );

return [ stylesheets, settings ];
return [ stylesheets, settings, hasBlockGapSupport ];
}

0 comments on commit 49e4a4f

Please sign in to comment.