Skip to content

Commit

Permalink
Update performance of global styles code (#27779)
Browse files Browse the repository at this point in the history
  • Loading branch information
nosolosw authored Dec 22, 2020
1 parent 5b17eec commit 69bf4e6
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 38 deletions.
7 changes: 1 addition & 6 deletions lib/class-wp-theme-json-resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ private static function get_user_origin() {
$config = $decoded_data;
}
}
self::$user = new WP_Theme_JSON( $config );
self::$user = new WP_Theme_JSON( $config, true );

return self::$user;
}
Expand Down Expand Up @@ -270,7 +270,6 @@ private static function get_user_origin() {
* @return WP_Theme_JSON
*/
public function get_origin( $theme_support_data = array(), $origin = 'user', $merged = true ) {

if ( ( 'user' === $origin ) && $merged ) {
$result = new WP_Theme_JSON();
$result->merge( self::get_core_origin() );
Expand Down Expand Up @@ -301,10 +300,6 @@ public function get_origin( $theme_support_data = array(), $origin = 'user', $me
* Registers a Custom Post Type to store the user's origin config.
*/
public static function register_user_custom_post_type() {
if ( ! gutenberg_experimental_global_styles_has_theme_json_support() ) {
return;
}

$args = array(
'label' => __( 'Global Styles', 'gutenberg' ),
'description' => 'CPT to store user design tokens',
Expand Down
39 changes: 29 additions & 10 deletions lib/class-wp-theme-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ class WP_Theme_JSON {
'dropCap' => null,
'fontFamilies' => null,
'fontSizes' => null,
'customFontStyle' => null,
'customFontWeight' => null,
'customFontStyle' => null,
'customFontWeight' => null,
'customTextDecorations' => null,
'customTextTransforms' => null,
),
Expand Down Expand Up @@ -301,9 +301,10 @@ class WP_Theme_JSON {
/**
* Constructor.
*
* @param array $contexts A structure that follows the theme.json schema.
* @param array $contexts A structure that follows the theme.json schema.
* @param boolean $should_escape_styles Whether the incoming styles should be escaped.
*/
public function __construct( $contexts = array() ) {
public function __construct( $contexts = array(), $should_escape_styles = false ) {
$this->contexts = array();

if ( ! is_array( $contexts ) ) {
Expand All @@ -324,8 +325,9 @@ public function __construct( $contexts = array() ) {
// Process styles subtree.
$this->process_key( 'styles', $context, self::SCHEMA );
if ( isset( $context['styles'] ) ) {
$this->process_key( 'color', $context['styles'], self::SCHEMA['styles'] );
$this->process_key( 'typography', $context['styles'], self::SCHEMA['styles'] );
$this->process_key( 'color', $context['styles'], self::SCHEMA['styles'], $should_escape_styles );
$this->process_key( 'spacing', $context['styles'], self::SCHEMA['styles'], $should_escape_styles );
$this->process_key( 'typography', $context['styles'], self::SCHEMA['styles'], $should_escape_styles );

if ( empty( $context['styles'] ) ) {
unset( $context['styles'] );
Expand All @@ -337,6 +339,7 @@ public function __construct( $contexts = array() ) {
// Process settings subtree.
$this->process_key( 'settings', $context, self::SCHEMA );
if ( isset( $context['settings'] ) ) {
$this->process_key( 'border', $context['settings'], self::SCHEMA['settings'] );
$this->process_key( 'color', $context['settings'], self::SCHEMA['settings'] );
$this->process_key( 'spacing', $context['settings'], self::SCHEMA['settings'] );
$this->process_key( 'typography', $context['settings'], self::SCHEMA['settings'] );
Expand Down Expand Up @@ -469,11 +472,12 @@ private static function get_blocks_metadata() {
* This function modifies the given input by removing
* the nodes that aren't valid per the schema.
*
* @param string $key Key of the subtree to normalize.
* @param array $input Whole tree to normalize.
* @param array $schema Schema to use for normalization.
* @param string $key Key of the subtree to normalize.
* @param array $input Whole tree to normalize.
* @param array $schema Schema to use for normalization.
* @param boolean $should_escape Whether the subproperties should be escaped.
*/
private static function process_key( $key, &$input, $schema ) {
private static function process_key( $key, &$input, $schema, $should_escape = false ) {
if ( ! isset( $input[ $key ] ) ) {
return;
}
Expand All @@ -493,6 +497,21 @@ private static function process_key( $key, &$input, $schema ) {
$schema[ $key ]
);

if ( $should_escape ) {
$subtree = $input[ $key ];
foreach ( $subtree as $property => $value ) {
$name = 'background-color';
if ( 'gradient' === $property ) {
$name = 'background';
}
$result = safecss_filter_attr( "$name: $value" );

if ( '' === $result ) {
unset( $input[ $key ][ $property ] );
}
}
}

if ( 0 === count( $input[ $key ] ) ) {
unset( $input[ $key ] );
}
Expand Down
69 changes: 51 additions & 18 deletions lib/global-styles.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ function gutenberg_experimental_global_styles_get_stylesheet( $tree, $type = 'al
* and enqueues the resulting stylesheet.
*/
function gutenberg_experimental_global_styles_enqueue_assets() {
if ( ! gutenberg_experimental_global_styles_has_theme_json_support() ) {
return;
}

$settings = gutenberg_get_common_block_editor_settings();
$theme_support_data = gutenberg_experimental_global_styles_get_theme_support_settings( $settings );

Expand Down Expand Up @@ -196,45 +200,74 @@ function gutenberg_experimental_global_styles_settings( $settings ) {
unset( $settings['gradients'] );

$resolver = new WP_Theme_JSON_Resolver();
$all = $resolver->get_origin( $theme_support_data );
$base = $resolver->get_origin( $theme_support_data, 'theme' );
$origin = 'theme';
if (
gutenberg_experimental_global_styles_has_theme_json_support() &&
gutenberg_is_fse_theme()
) {
// Only lookup for the user data if we need it.
$origin = 'user';
}
$tree = $resolver->get_origin( $theme_support_data, $origin );

// STEP 1: ADD FEATURES
// These need to be added to settings always.
$settings['__experimentalFeatures'] = $all->get_settings();
//
// These need to be always added to the editor settings,
// even for themes that don't support theme.json.
// An example of this is that the presets are configured
// from the theme support data.
$settings['__experimentalFeatures'] = $tree->get_settings();

// STEP 2 - IF EDIT-SITE, ADD DATA REQUIRED FOR GLOBAL STYLES SIDEBAR
// The client needs some information to be able to access/update the user styles.
// We only do this if the theme has support for theme.json, though,
// as an indicator that the theme will know how to combine this with its stylesheet.
//
// In the site editor, the user can change styles, so the client
// needs the ability to create them. Hence, we pass it some data
// for this: base styles (core+theme) and the ID of the user CPT.
$screen = get_current_screen();
if (
! empty( $screen ) &&
function_exists( 'gutenberg_is_edit_site_page' ) &&
gutenberg_is_edit_site_page( $screen->id ) &&
gutenberg_experimental_global_styles_has_theme_json_support()
gutenberg_experimental_global_styles_has_theme_json_support() &&
gutenberg_is_fse_theme()
) {
$settings['__experimentalGlobalStylesUserEntityId'] = WP_Theme_JSON_Resolver::get_user_custom_post_type_id();
$settings['__experimentalGlobalStylesBaseStyles'] = $base->get_raw_data();
} else {
// STEP 3 - OTHERWISE, ADD STYLES
$user_cpt_id = WP_Theme_JSON_Resolver::get_user_custom_post_type_id();
$base_styles = $resolver->get_origin( $theme_support_data, 'theme' )->get_raw_data();

$settings['__experimentalGlobalStylesUserEntityId'] = $user_cpt_id;
$settings['__experimentalGlobalStylesBaseStyles'] = $base_styles;
} elseif ( gutenberg_experimental_global_styles_has_theme_json_support() ) {
// STEP 3 - ADD STYLES IF THEME HAS SUPPORT
//
// If we are in a block editor context, but not in edit-site,
// we need to add the styles via the settings. This is because
// we want them processed as if they were added via add_editor_styles,
// which adds the editor wrapper class.
// we add the styles via the settings, so the editor knows that
// some of these should be added the wrapper class,
// as if they were added via add_editor_styles.
$settings['styles'][] = array(
'css' => gutenberg_experimental_global_styles_get_stylesheet( $all, 'css_variables' ),
'css' => gutenberg_experimental_global_styles_get_stylesheet( $tree, 'css_variables' ),
'__experimentalNoWrapper' => true,
);
$settings['styles'][] = array(
'css' => gutenberg_experimental_global_styles_get_stylesheet( $all, 'block_styles' ),
'css' => gutenberg_experimental_global_styles_get_stylesheet( $tree, 'block_styles' ),
);
}

return $settings;
}

add_action( 'init', array( 'WP_Theme_JSON_Resolver', 'register_user_custom_post_type' ) );
/**
* Register CPT to store/access user data.
*
* @return array|undefined
*/
function gutenberg_experimental_global_styles_register_user_cpt() {
if ( ! gutenberg_experimental_global_styles_has_theme_json_support() ) {
return;
}

WP_Theme_JSON_Resolver::register_user_custom_post_type();
}

add_action( 'init', 'gutenberg_experimental_global_styles_register_user_cpt' );
add_filter( 'block_editor_settings', 'gutenberg_experimental_global_styles_settings', PHP_INT_MAX );
add_action( 'wp_enqueue_scripts', 'gutenberg_experimental_global_styles_enqueue_assets' );
41 changes: 37 additions & 4 deletions phpunit/class-wp-theme-json-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,39 @@

class WP_Theme_JSON_Test extends WP_UnitTestCase {

function test_user_data_is_escaped() {
$theme_json = new WP_Theme_JSON(
array(
'global' => array(
'styles' => array(
'color' => array(
'background' => 'green',
'gradient' => 'linear-gradient(10deg,rgba(6,147,227,1) 0%,rgb(61,132,163) 37%,rgb(155,81,224) 100%)',
'link' => 'linear-gradient(10deg,rgba(6,147,227,1) 0%,rgb(61,132,163) 37%,rgb(155,81,224) 100%)',
'text' => 'var:preset|color|dark-gray',
),
),
),
),
true
);
$result = $theme_json->get_raw_data();

$expected = array(
'global' => array(
'styles' => array(
'color' => array(
'background' => 'green',
'gradient' => 'linear-gradient(10deg,rgba(6,147,227,1) 0%,rgb(61,132,163) 37%,rgb(155,81,224) 100%)',
'text' => 'var:preset|color|dark-gray',
),
),
),
);

$this->assertEqualSetsWithIndex( $expected, $result );
}

function test_contexts_not_valid_are_skipped() {
$theme_json = new WP_Theme_JSON(
array(
Expand Down Expand Up @@ -298,13 +331,13 @@ public function test_merge_incoming_data() {
),
),
'typography' => array(
'fontSizes' => array(
'fontSizes' => array(
array(
'slug' => 'fontSize',
'size' => 'fontSize',
),
),
'fontFamilies' => array(
'fontFamilies' => array(
array(
'slug' => 'fontFamily',
'fontFamily' => 'fontFamily',
Expand Down Expand Up @@ -335,13 +368,13 @@ public function test_merge_incoming_data() {
),
),
'typography' => array(
'fontSizes' => array(
'fontSizes' => array(
array(
'slug' => 'fontSize',
'size' => 'fontSize',
),
),
'fontFamilies' => array(
'fontFamilies' => array(
array(
'slug' => 'fontFamily',
'fontFamily' => 'fontFamily',
Expand Down

0 comments on commit 69bf4e6

Please sign in to comment.