diff --git a/docs/designers-developers/developers/themes/theme-json.md b/docs/designers-developers/developers/themes/theme-json.md index 987acc0b866ae2..cb1a39c69a429d 100644 --- a/docs/designers-developers/developers/themes/theme-json.md +++ b/docs/designers-developers/developers/themes/theme-json.md @@ -6,9 +6,9 @@ This is documentation for the current direction and work in progress about how themes can hook into the various sub-systems that the Block Editor provides. -* Rationale -* Specification -* Current Status +- Rationale +- Specification +- Current Status ## Rationale @@ -153,8 +153,16 @@ Each block will declare which style properties it exposes. This has been coined The list of properties that are currently exposed via this method are: -- Paragraph and Heading: line-height, font-size, color. -- Group, Columns, and MediaText: color. +| Context | Text's Color | Background's Color | Background's Gradient | Font Size | Line Height | +| --- | --- | --- | --- | --- | --- | +| Global | - | Yes | - | - | - | +| Paragraph | Yes | Yes | - | Yes | Yes | +| Heading [1] | Yes | Yes | - | Yes | Yes | +| Group | Yes | Yes | Yes | - | - | +| Columns | Yes | Yes | Yes | - | - | +| Media & text | Yes | Yes | Yes | - | - | + +[1] The heading block represents 6 distinct HTML elements: H1-H6. It comes with selectors to target each individual element (ex: core/heading/h1 for H1, etc). ### Features @@ -164,74 +172,146 @@ This is being implemented, so it's not currently available. ``` { - global: { - presets: { - color: [ + "global": { + "presets": { + "color": [ { - slug: , - value: , + "slug": , + "value": }, - { ... }, + { } ], - font-size: [ + "font-size": [ { - slug: , - value: , + "slug": , + "value": }, - { ... }, + { } ], - gradient: [ + "gradient": [ { - slug: , - value: , + "slug": , + "value": }, - { ... }, + { } ] + }, + "styles: { + "color: { + "background": + } } }, - core/paragraph: { - styles: { - typography: { - lineHeight: , - fontSize: + "core/paragraph": { + "styles": { + "typography": { + "fontSize": , + "lineHeight": }, - color: { - text: + "color": { + "background": , + "text": } } }, - /* core/heading/h1, core/heading/h2, etc */ - core/heading/h*: { - styles: { - typography: { - lineHeight: , - fontSize: + "core/heading/h1": { + "styles": { + "typography": { + "fontSize": , + "lineHeight": }, - color: { - text: + "color": { + "background": , + "text": } } }, - core/columns: { - styles: { - color: { - text: + "core/heading/h2": { + "styles": { + "typography": { + "fontSize": , + "lineHeight": + }, + "color": { + "background": , + "text": } } }, - core/group: { - styles: { - color: { - text: + "core/heading/h3": { + "styles": { + "typography": { + "fontSize": , + "lineHeight": + }, + "color": { + "background": , + "text": + } + } + }, + "core/heading/h4": { + "styles": { + "typography": { + "fontSize": , + "lineHeight": + }, + "color": { + "background": , + "text": } } }, - core/media-text: { - styles: { - color: { - text: + "core/heading/h5": { + "styles": { + "typography": { + "fontSize": , + "lineHeight": + }, + "color": { + "background": , + "text": } } }, + "core/heading/h6": { + "styles": { + "typography": { + "fontSize": , + "lineHeight": + }, + "color": { + "background": , + "text": + } + } + }, + "core/columns": { + "styles": { + "color": { + "background": , + "gradient": , + "text": + } + } + }, + "core/group": { + "styles": { + "color": { + "background": , + "gradient": , + "text": + } + } + }, + "core/media-text": { + "styles": { + "color": { + "background": , + "gradient": , + "text": + } + } + } } ``` diff --git a/lib/global-styles.php b/lib/global-styles.php index c2f9eb250646fc..a46473c3a2d772 100644 --- a/lib/global-styles.php +++ b/lib/global-styles.php @@ -80,6 +80,13 @@ function gutenberg_experimental_global_styles_get_from_file( $file_path ) { file_get_contents( $file_path ), true ); + + $json_decoding_error = json_last_error(); + if ( JSON_ERROR_NONE !== $json_decoding_error ) { + error_log( 'Error when decoding file schema: ' . json_last_error_msg() ); + return $config; + } + if ( is_array( $decoded_file ) ) { $config = $decoded_file; } @@ -97,6 +104,13 @@ function gutenberg_experimental_global_styles_get_user() { $user_cpt = gutenberg_experimental_global_styles_get_user_cpt( array( 'publish' ) ); if ( array_key_exists( 'post_content', $user_cpt ) ) { $decoded_data = json_decode( $user_cpt['post_content'], true ); + + $json_decoding_error = json_last_error(); + if ( JSON_ERROR_NONE !== $json_decoding_error ) { + error_log( 'Error when decoding user schema: ' . json_last_error_msg() ); + return $config; + } + if ( is_array( $decoded_data ) ) { $config = $decoded_data; } @@ -253,64 +267,101 @@ function gutenberg_experimental_global_styles_get_theme() { return $theme_config; } +/** + * Returns the style features a particular block supports. + * + * @param array $supports The block supports array. + * + * @return array Style features supported by the block. + */ +function gutenberg_experimental_global_styles_get_supported_styles( $supports ) { + $style_features = array( + 'color' => array( '__experimentalColor' ), + 'background-color' => array( '__experimentalColor' ), + 'background' => array( '__experimentalColor', 'gradients' ), + 'line-height' => array( '__experimentalLineHeight' ), + 'font-size' => array( '__experimentalFontSize' ), + ); + + $supported_features = array(); + foreach ( $style_features as $style_feature => $path ) { + if ( gutenberg_experimental_get( $supports, $path ) ) { + $supported_features[] = $style_feature; + } + } + + return $supported_features; +} + /** * Retrieves the block data (selector/supports). * * @return array */ function gutenberg_experimental_global_styles_get_block_data() { - // TODO: this data should be taken from the block registry. - // - // At the moment this array replicates the current capabilities - // declared by blocks via __experimentalLineHeight, - // __experimentalColor, and __experimentalFontSize. $block_data = array( - 'global' => array( + 'global' => array( 'selector' => ':root', - 'supports' => array(), // By being blank, the 'global' section won't output any style yet. - ), - 'core/paragraph' => array( - 'selector' => 'p', - 'supports' => array( 'line-height', 'font-size', 'color' ), - ), - 'core/heading/h1' => array( - 'selector' => 'h1', - 'supports' => array( 'line-height', 'font-size', 'color' ), - ), - 'core/heading/h2' => array( - 'selector' => 'h2', - 'supports' => array( 'line-height', 'font-size', 'color' ), - ), - 'core/heading/h3' => array( - 'selector' => 'h3', - 'supports' => array( 'line-height', 'font-size', 'color' ), - ), - 'core/heading/h4' => array( - 'selector' => 'h4', - 'supports' => array( 'line-height', 'font-size', 'color' ), - ), - 'core/heading/h5' => array( - 'selector' => 'h5', - 'supports' => array( 'line-height', 'font-size', 'color' ), - ), - 'core/heading/h6' => array( - 'selector' => 'h6', - 'supports' => array( 'line-height', 'font-size', 'color' ), - ), - 'core/columns' => array( - 'selector' => '.wp-block-columns', - 'supports' => array( 'color' ), - ), - 'core/group' => array( - 'selector' => '.wp-block-group', - 'supports' => array( 'color' ), - ), - 'core/media-text' => array( - 'selector' => '.wp-block-media-text', - 'supports' => array( 'color' ), + 'supports' => array( 'background-color' ), ), ); + $registry = WP_Block_Type_Registry::get_instance(); + foreach ( $registry->get_all_registered() as $block_name => $block_type ) { + if ( ! is_array( $block_type->supports ) ) { + continue; + } + + $supports = gutenberg_experimental_global_styles_get_supported_styles( $block_type->supports ); + if ( empty( $supports ) ) { + continue; + } + + /* + * Assign the selector for the block. + * + * Some blocks can declare multiple selectors: + * + * - core/heading represents the H1-H6 HTML elements + * - core/list represents the UL and OL HTML elements + * - core/group is meant to represent DIV and other HTML elements + * + * Some other blocks don't provide a selector, + * so we generate a class for them based on their name: + * + * - 'core/group' => '.wp-block-group' + * - 'my-custom-library/block-name' => '.wp-block-my-custom-library-block-name' + * + * Note that, for core blocks, we don't add the `core/` prefix to its class name. + * This is for historical reasons, as they come with a class without that infix. + * + */ + if ( + isset( $block_type->supports['__experimentalSelector'] ) && + is_string( $block_type->supports['__experimentalSelector'] ) + ) { + $block_data[ $block_name ] = array( + 'selector' => $block_type->supports['__experimentalSelector'], + 'supports' => $supports, + ); + } elseif ( + isset( $block_type->supports['__experimentalSelector'] ) && + is_array( $block_type->supports['__experimentalSelector'] ) + ) { + foreach ( $block_type->supports['__experimentalSelector'] as $key => $selector ) { + $block_data[ $key ] = array( + 'selector' => $selector, + 'supports' => $supports, + ); + } + } else { + $block_data[ $block_name ] = array( + 'selector' => '.wp-block-' . str_replace( '/', '-', str_replace( 'core/', '', $block_name ) ), + 'supports' => $supports, + ); + } + } + return $block_data; } diff --git a/packages/block-library/src/heading/block.json b/packages/block-library/src/heading/block.json index eb367c9c4bf735..d47b35c26eebe1 100644 --- a/packages/block-library/src/heading/block.json +++ b/packages/block-library/src/heading/block.json @@ -20,12 +20,20 @@ } }, "supports": { - "className": false, "anchor": true, - "__unstablePasteTextInline": true, + "className": false, "lightBlockWrapper": true, "__experimentalColor": true, + "__experimentalFontSize": true, "__experimentalLineHeight": true, - "__experimentalFontSize": true + "__experimentalSelector": { + "core/heading/h1": "h1", + "core/heading/h2": "h2", + "core/heading/h3": "h3", + "core/heading/h4": "h4", + "core/heading/h5": "h5", + "core/heading/h6": "h6" + }, + "__unstablePasteTextInline": true } } diff --git a/packages/block-library/src/paragraph/block.json b/packages/block-library/src/paragraph/block.json index ae17bc373f2062..c7897c8f92ac08 100644 --- a/packages/block-library/src/paragraph/block.json +++ b/packages/block-library/src/paragraph/block.json @@ -28,15 +28,16 @@ }, "supports": { "className": false, - "__unstablePasteTextInline": true, "lightBlockWrapper": true, "__experimentalColor": true, - "__experimentalLineHeight": true, "__experimentalFontSize": true, + "__experimentalLineHeight": true, "__experimentalFeatures": { "typography": { "dropCap": true } - } + }, + "__experimentalSelector": "p", + "__unstablePasteTextInline": true } }