Skip to content

Commit

Permalink
gutenberg_get_global_styles: resolve custom CSS format (#50366)
Browse files Browse the repository at this point in the history
Co-authored-by: André <583546+oandregal@users.noreply.github.com>

This PR addresses #49693 so the return value for `wp_get_global_styles` given the following theme.json dataset

```
"core/post-terms": {
    "typography": { "fontSize": "var(--wp--preset--font-size--small)" },
    "color":{ "background": "var:preset|color|secondary" }
}
```

is:

```
(
    [typography] => Array( [fontSize] => var(--wp--preset--font-size--small) )
    [color] => Array( [background] => var(--wp--preset--color--secondary) )
)
```
  • Loading branch information
samnajian committed May 10, 2023
1 parent 1db3d30 commit ccd529d
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 16 deletions.
63 changes: 48 additions & 15 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,7 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n
if ( empty( $result ) ) {
unset( $output[ $subtree ] );
} else {
$output[ $subtree ] = $result;
$output[ $subtree ] = static::resolve_custom_css_format( $result );
}
}

Expand Down Expand Up @@ -1989,20 +1989,6 @@ protected static function get_property_value( $styles, $path, $theme_json = null
return $value;
}

// Convert custom CSS properties.
$prefix = 'var:';
$prefix_len = strlen( $prefix );
$token_in = '|';
$token_out = '--';
if ( 0 === strncmp( $value, $prefix, $prefix_len ) ) {
$unwrapped_name = str_replace(
$token_in,
$token_out,
substr( $value, $prefix_len )
);
$value = "var(--wp--$unwrapped_name)";
}

return $value;
}

Expand Down Expand Up @@ -3578,4 +3564,51 @@ protected function get_feature_declarations_for_node( $metadata, &$node ) {

return $declarations;
}

/**
* This is used to convert the internal representation of variables to the CSS representation.
* For example, `var:preset|color|vivid-green-cyan` becomes `var(--wp--preset--color--vivid-green-cyan)`.
*
* @since 6.3.0
* @param string $value The variable such as var:preset|color|vivid-green-cyan to convert.
* @return string The converted variable.
*/
private static function convert_custom_properties( $value ) {
$prefix = 'var:';
$prefix_len = strlen( $prefix );
$token_in = '|';
$token_out = '--';
if ( 0 === strpos( $value, $prefix ) ) {
$unwrapped_name = str_replace(
$token_in,
$token_out,
substr( $value, $prefix_len )
);
$value = "var(--wp--$unwrapped_name)";
}

return $value;
}

/**
* Given a tree, converts the internal representation of variables to the CSS representation.
* It is recursive and modifies the input in-place.
*
* @since 6.3.0
* @param array $tree Input to process.
* @return array The modified $tree.
*/
private static function resolve_custom_css_format( $tree ) {
$prefix = 'var:';

foreach ( $tree as $key => $data ) {
if ( is_string( $data ) && 0 === strpos( $data, $prefix ) ) {
$tree[ $key ] = self::convert_custom_properties( $data );
} elseif ( is_array( $data ) ) {
$tree[ $key ] = self::resolve_custom_css_format( $data );
}
}

return $tree;
}
}
34 changes: 34 additions & 0 deletions lib/compat/wordpress-6.3/get-global-styles-and-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,37 @@ function wp_get_block_css_selector( $block_type, $target = 'root', $fallback = f
function gutenberg_get_remote_theme_patterns() {
return WP_Theme_JSON_Resolver_Gutenberg::get_theme_data( array(), array( 'with_supports' => false ) )->get_patterns();
}

/**
* Gets the styles resulting of merging core, theme, and user data.
*
* @since 5.9.0
* @since 6.3.0 the internal link format "var:preset|color|secondary" is resolved
* to "var(--wp--preset--font-size--small)" so consumers don't have to.
*
* @param array $path Path to the specific style to retrieve. Optional.
* If empty, will return all styles.
* @param array $context {
* Metadata to know where to retrieve the $path from. Optional.
*
* @type string $block_name Which block to retrieve the styles from.
* If empty, it'll return the styles for the global context.
* @type string $origin Which origin to take data from.
* Valid values are 'all' (core, theme, and user) or 'base' (core and theme).
* If empty or unknown, 'all' is used.
* }
* @return array The styles to retrieve.
*/
function gutenberg_get_global_styles( $path = array(), $context = array() ) {
if ( ! empty( $context['block_name'] ) ) {
$path = array_merge( array( 'blocks', $context['block_name'] ), $path );
}

$origin = 'custom';
if ( isset( $context['origin'] ) && 'base' === $context['origin'] ) {
$origin = 'theme';
}
$styles = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data( $origin )->get_raw_data()['styles'];

return _wp_array_get( $styles, $path, $styles );
}
2 changes: 1 addition & 1 deletion lib/experimental/block-editor-settings-mobile.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function gutenberg_get_block_editor_settings_mobile( $settings ) {
'mobile' === $_GET['context']
) {
if ( wp_theme_has_theme_json() ) {
$settings['__experimentalStyles'] = wp_get_global_styles();
$settings['__experimentalStyles'] = gutenberg_get_global_styles();
}

// To tell mobile that the site uses quote v2 (inner blocks).
Expand Down
65 changes: 65 additions & 0 deletions phpunit/class-wp-theme-json-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -2071,4 +2071,69 @@ public function data_process_blocks_custom_css() {
),
);
}

public function test_internal_syntax_is_converted_to_css_variables() {
$result = new WP_Theme_JSON_Gutenberg(
array(
'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA,
'styles' => array(
'color' => array(
'background' => 'var:preset|color|primary',
'text' => 'var(--wp--preset--color--secondary)',
),
'elements' => array(
'link' => array(
'color' => array(
'background' => 'var:preset|color|pri',
'text' => 'var(--wp--preset--color--sec)',
),
),
),
'blocks' => array(
'core/post-terms' => array(
'typography' => array( 'fontSize' => 'var(--wp--preset--font-size--small)' ),
'color' => array( 'background' => 'var:preset|color|secondary' ),
),
'core/navigation' => array(
'elements' => array(
'link' => array(
'color' => array(
'background' => 'var:preset|color|p',
'text' => 'var(--wp--preset--color--s)',
),
),
),
),
'core/quote' => array(
'typography' => array( 'fontSize' => 'var(--wp--preset--font-size--d)' ),
'color' => array( 'background' => 'var:preset|color|d' ),
'variations' => array(
'plain' => array(
'typography' => array( 'fontSize' => 'var(--wp--preset--font-size--s)' ),
'color' => array( 'background' => 'var:preset|color|s' ),
),
),
),
),
),
)
);
$styles = $result->get_raw_data()['styles'];

$this->assertEquals( 'var(--wp--preset--color--primary)', $styles['color']['background'], 'Top level: Assert the originally correct values are still correct.' );
$this->assertEquals( 'var(--wp--preset--color--secondary)', $styles['color']['text'], 'Top level: Assert the originally correct values are still correct.' );

$this->assertEquals( 'var(--wp--preset--color--pri)', $styles['elements']['link']['color']['background'], 'Element top level: Assert the originally correct values are still correct.' );
$this->assertEquals( 'var(--wp--preset--color--sec)', $styles['elements']['link']['color']['text'], 'Element top level: Assert the originally correct values are still correct.' );

$this->assertEquals( 'var(--wp--preset--font-size--small)', $styles['blocks']['core/post-terms']['typography']['fontSize'], 'Top block level: Assert the originally correct values are still correct.' );
$this->assertEquals( 'var(--wp--preset--color--secondary)', $styles['blocks']['core/post-terms']['color']['background'], 'Top block level: Assert the internal variables are convert to CSS custom variables.' );

$this->assertEquals( 'var(--wp--preset--color--p)', $styles['blocks']['core/navigation']['elements']['link']['color']['background'], 'Elements block level: Assert the originally correct values are still correct.' );
$this->assertEquals( 'var(--wp--preset--color--s)', $styles['blocks']['core/navigation']['elements']['link']['color']['text'], 'Elements block level: Assert the originally correct values are still correct.' );

$this->assertEquals( 'var(--wp--preset--font-size--s)', $styles['blocks']['core/quote']['variations']['plain']['typography']['fontSize'], 'Style variations: Assert the originally correct values are still correct.' );
$this->assertEquals( 'var(--wp--preset--color--s)', $styles['blocks']['core/quote']['variations']['plain']['color']['background'], 'Style variations: Assert the internal variables are convert to CSS custom variables.' );

}
}

1 comment on commit ccd529d

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected in ccd529d.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/4934153489
📝 Reported issues:

Please sign in to comment.