From 819e9c318d29a37b3d688e9938fba34e230d8a5f Mon Sep 17 00:00:00 2001
From: Andrew Serong <14988353+andrewserong@users.noreply.github.com>
Date: Wed, 20 Jul 2022 12:42:52 +1000
Subject: [PATCH] Layout: Add a disable-layout-styles theme supports flag to
opt-out of all layout styles
---
lib/block-supports/layout.php | 21 +++++++-----
.../wordpress-6.1/block-editor-settings.php | 1 +
.../wordpress-6.1/class-wp-theme-json-6-1.php | 5 +++
...-rest-block-editor-settings-controller.php | 6 ++++
packages/block-editor/src/hooks/layout.js | 22 ++++++++++--
.../src/components/visual-editor/index.js | 34 +++++++++++--------
.../global-styles/use-global-styles-output.js | 30 ++++++++++++++--
.../provider/use-block-editor-settings.js | 1 +
phpunit/class-wp-theme-json-test.php | 31 +++++++++++++++++
9 files changed, 123 insertions(+), 28 deletions(-)
diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php
index b26ed9df659c28..838327c626f209 100644
--- a/lib/block-supports/layout.php
+++ b/lib/block-supports/layout.php
@@ -241,15 +241,18 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
$fallback_gap_value = _wp_array_get( $block_type->supports, array( 'spacing', 'blockGap', '__experimentalDefault' ), '0.5em' );
$block_spacing = _wp_array_get( $block, array( 'attrs', 'style', 'spacing' ), null );
- // If a block's block.json skips serialization for spacing or spacing.blockGap,
- // don't apply the user-defined value to the styles.
- $should_skip_gap_serialization = gutenberg_should_skip_block_supports_serialization( $block_type, 'spacing', 'blockGap' );
- $style = gutenberg_get_layout_style( ".$block_classname.$container_class", $used_layout, $has_block_gap_support, $gap_value, $should_skip_gap_serialization, $fallback_gap_value, $block_spacing );
-
- // Only add container class and enqueue block support styles if unique styles were generated.
- if ( ! empty( $style ) ) {
- $class_names[] = $container_class;
- wp_enqueue_block_support_styles( $style );
+ // Only generate Layout styles if the theme has not opted-out.
+ if ( ! current_theme_supports( 'disable-layout-styles' ) ) {
+ // If a block's block.json skips serialization for spacing or spacing.blockGap,
+ // don't apply the user-defined value to the styles.
+ $should_skip_gap_serialization = gutenberg_should_skip_block_supports_serialization( $block_type, 'spacing', 'blockGap' );
+ $style = gutenberg_get_layout_style( ".$block_classname.$container_class", $used_layout, $has_block_gap_support, $gap_value, $should_skip_gap_serialization, $fallback_gap_value, $block_spacing );
+
+ // Only add container class and enqueue block support styles if unique styles were generated.
+ if ( ! empty( $style ) ) {
+ $class_names[] = $container_class;
+ wp_enqueue_block_support_styles( $style );
+ }
}
// This assumes the hook only applies to blocks with a single wrapper.
diff --git a/lib/compat/wordpress-6.1/block-editor-settings.php b/lib/compat/wordpress-6.1/block-editor-settings.php
index de61109ed3ac73..5512390db5910d 100644
--- a/lib/compat/wordpress-6.1/block-editor-settings.php
+++ b/lib/compat/wordpress-6.1/block-editor-settings.php
@@ -171,6 +171,7 @@ function gutenberg_get_block_editor_settings( $settings ) {
}
$settings['localAutosaveInterval'] = 15;
+ $settings['disableLayoutStyles'] = current_theme_supports( 'disable-layout-styles' );
return $settings;
}
diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php
index 1679e87c5a8a92..0261adb267035e 100644
--- a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php
+++ b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php
@@ -1252,6 +1252,11 @@ protected function get_layout_styles( $block_metadata ) {
$block_rules = '';
$block_type = null;
+ // Skip outputting layout styles if explicitly disabled.
+ if ( current_theme_supports( 'disable-layout-styles' ) ) {
+ return $block_rules;
+ }
+
if ( isset( $block_metadata['name'] ) ) {
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block_metadata['name'] );
if ( ! block_has_support( $block_type, array( '__experimentalLayout' ), false ) ) {
diff --git a/lib/experimental/class-wp-rest-block-editor-settings-controller.php b/lib/experimental/class-wp-rest-block-editor-settings-controller.php
index d9b726f1158da2..777e193ffe70a3 100644
--- a/lib/experimental/class-wp-rest-block-editor-settings-controller.php
+++ b/lib/experimental/class-wp-rest-block-editor-settings-controller.php
@@ -204,6 +204,12 @@ public function get_item_schema() {
'context' => array( 'post-editor', 'site-editor', 'widgets-editor' ),
),
+ 'disableLayoutStyles' => array(
+ 'description' => __( 'Disables output of layout styles.', 'gutenberg' ),
+ 'type' => 'boolean',
+ 'context' => array( 'post-editor', 'site-editor', 'widgets-editor' ),
+ ),
+
'enableCustomLineHeight' => array(
'description' => __( 'Enables custom line height.', 'gutenberg' ),
'type' => 'boolean',
diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js
index 4db7ac3b6ef05f..d7df54ea3c614c 100644
--- a/packages/block-editor/src/hooks/layout.js
+++ b/packages/block-editor/src/hooks/layout.js
@@ -84,6 +84,22 @@ function useLayoutClasses( layout, layoutDefinitions ) {
return layoutClassnames;
}
+/**
+ * Determines whether or not the theme has disabled all layout styles output.
+ *
+ * This feature only disables the output of layout styles,
+ * the controls for adjusting layout will still be available in the editor.
+ * Themes that use this feature commit to providing their own styling for layout features.
+ *
+ * @return {boolean} Whether or not the theme opts-in to disable all layout styles.
+ */
+function useThemeHasDisabledLayoutStyles() {
+ return useSelect( ( select ) => {
+ const { getSettings } = select( blockEditorStore );
+ return !! getSettings().disableLayoutStyles;
+ } );
+}
+
function LayoutPanel( { setAttributes, attributes, name: blockName } ) {
const { layout } = attributes;
const defaultThemeLayout = useSetting( 'layout' );
@@ -264,10 +280,12 @@ export const withInspectorControls = createHigherOrderComponent(
export const withLayoutStyles = createHigherOrderComponent(
( BlockListBlock ) => ( props ) => {
const { name, attributes } = props;
- const shouldRenderLayoutStyles = hasBlockSupport(
+ const hasLayoutBlockSupport = hasBlockSupport(
name,
layoutBlockSupportKey
);
+ const shouldRenderLayoutStyles =
+ hasLayoutBlockSupport && ! useThemeHasDisabledLayoutStyles();
const id = useInstanceId( BlockListBlock );
const defaultThemeLayout = useSetting( 'layout' ) || {};
const element = useContext( BlockList.__unstableElementContext );
@@ -277,7 +295,7 @@ export const withLayoutStyles = createHigherOrderComponent(
const usedLayout = layout?.inherit
? defaultThemeLayout
: layout || defaultBlockLayout || {};
- const layoutClasses = shouldRenderLayoutStyles
+ const layoutClasses = hasLayoutBlockSupport
? useLayoutClasses( usedLayout, defaultThemeLayout?.definitions )
: null;
const selector = `.${ getBlockDefaultClassName(
diff --git a/packages/edit-post/src/components/visual-editor/index.js b/packages/edit-post/src/components/visual-editor/index.js
index 77054884472a67..0f351f0148c0e8 100644
--- a/packages/edit-post/src/components/visual-editor/index.js
+++ b/packages/edit-post/src/components/visual-editor/index.js
@@ -118,13 +118,15 @@ export default function VisualEditor( { styles } ) {
( select ) => select( editPostStore ).hasMetaBoxes(),
[]
);
- const { themeSupportsLayout, assets } = useSelect( ( select ) => {
- const _settings = select( blockEditorStore ).getSettings();
- return {
- themeSupportsLayout: _settings.supportsLayout,
- assets: _settings.__unstableResolvedAssets,
- };
- }, [] );
+ const { themeHasDisabledLayoutStyles, themeSupportsLayout, assets } =
+ useSelect( ( select ) => {
+ const _settings = select( blockEditorStore ).getSettings();
+ return {
+ themeHasDisabledLayoutStyles: _settings.disableLayoutStyles,
+ themeSupportsLayout: _settings.supportsLayout,
+ assets: _settings.__unstableResolvedAssets,
+ };
+ }, [] );
const { clearSelectedBlock } = useDispatch( blockEditorStore );
const { setIsEditingTemplate } = useDispatch( editPostStore );
const desktopCanvasStyles = {
@@ -241,13 +243,17 @@ export default function VisualEditor( { styles } ) {
assets={ assets }
style={ { paddingBottom } }
>
- { themeSupportsLayout && ! isTemplateMode && (
-