Skip to content

Commit

Permalink
Enqueue core and theme colors by using separate structures per origin. (
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgefilipecosta authored and youknowriad committed Jun 14, 2021
1 parent 8629186 commit beaaf60
Show file tree
Hide file tree
Showing 12 changed files with 590 additions and 544 deletions.
146 changes: 73 additions & 73 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,34 @@ private static function append_to_selector( $selector, $to_append ) {
return implode( ',', $new_selectors );
}

/**
* Function that given an array of presets keyed by origin
* and the value key of the preset returns an array where each key is
* the a preset slug and each value is the preset value.
*
* @param array $preset_per_origin Array of presets keyed by origin.
* @param string $value_key The property of the preset that contains its value.
*
* @return array Array of presets where each key is a slug and each value is the preset value.
*/
private static function get_merged_preset_by_slug( $preset_per_origin, $value_key ) {
$origins = array( 'core', 'theme', 'user' );
$result = array();
foreach ( $origins as $origin ) {
if ( ! isset( $preset_per_origin[ $origin ] ) ) {
continue;
}
foreach ( $preset_per_origin[ $origin ] as $preset ) {
// We don't want to use kebabCase here,
// see https://github.com/WordPress/gutenberg/issues/32347
// However, we need to make sure the generated class or css variable
// doesn't contain spaces.
$result[ preg_replace( '/\s+/', '-', $preset['slug'] ) ] = $preset[ $value_key ];
}
}
return $result;
}

/**
* Given a settings array, it returns the generated rulesets
* for the preset classes.
Expand All @@ -659,19 +687,16 @@ private static function compute_preset_classes( $settings, $selector ) {

$stylesheet = '';
foreach ( self::PRESETS_METADATA as $preset ) {
$values = _wp_array_get( $settings, $preset['path'], array() );
foreach ( $values as $value ) {
foreach ( $preset['classes'] as $class ) {
$preset_per_origin = _wp_array_get( $settings, $preset['path'], array() );
$preset_by_slug = self::get_merged_preset_by_slug( $preset_per_origin, $preset['value_key'] );
foreach ( $preset['classes'] as $class ) {
foreach ( $preset_by_slug as $slug => $value ) {
$stylesheet .= self::to_ruleset(
// We don't want to use kebabCase here,
// see https://github.com/WordPress/gutenberg/issues/32347
// However, we need to make sure the generated class
// doesn't contain spaces.
self::append_to_selector( $selector, '.has-' . preg_replace( '/\s+/', '-', $value['slug'] ) . '-' . $class['class_suffix'] ),
self::append_to_selector( $selector, '.has-' . $slug . '-' . $class['class_suffix'] ),
array(
array(
'name' => $class['property_name'],
'value' => $value[ $preset['value_key'] ] . ' !important',
'value' => $value . ' !important',
),
)
);
Expand Down Expand Up @@ -701,11 +726,12 @@ private static function compute_preset_classes( $settings, $selector ) {
private static function compute_preset_vars( $settings ) {
$declarations = array();
foreach ( self::PRESETS_METADATA as $preset ) {
$values = _wp_array_get( $settings, $preset['path'], array() );
foreach ( $values as $value ) {
$preset_per_origin = _wp_array_get( $settings, $preset['path'], array() );
$preset_by_slug = self::get_merged_preset_by_slug( $preset_per_origin, $preset['value_key'] );
foreach ( $preset_by_slug as $slug => $value ) {
$declarations[] = array(
'name' => '--wp--preset--' . $preset['css_var_infix'] . '--' . $value['slug'],
'value' => $value[ $preset['value_key'] ],
'name' => '--wp--preset--' . $preset['css_var_infix'] . '--' . $slug,
'value' => $value,
);
}
}
Expand Down Expand Up @@ -1101,85 +1127,59 @@ public function get_stylesheet( $type = 'all' ) {
/**
* Merge new incoming data.
*
* @param WP_Theme_JSON_Gutenberg $incoming Data to merge.
* @param string $update_or_remove Whether update or remove existing colors
* for which the incoming data has a duplicated slug.
* @param WP_Theme_JSON $incoming Data to merge.
* @param string $origin origin of the incoming data (e.g: core, theme, or user).
*/
public function merge( $incoming, $update_or_remove = 'remove' ) {
$incoming_data = $incoming->get_raw_data();
$existing_data = $this->theme_json;
public function merge( $incoming, $origin ) {

$incoming_data = $incoming->get_raw_data();
$this->theme_json = array_replace_recursive( $this->theme_json, $incoming_data );

// The array_replace_recursive algorithm merges at the leaf level.
// For leaf values that are arrays it will use the numeric indexes for replacement.
$this->theme_json = array_replace_recursive( $this->theme_json, $incoming_data );
// In those cases, what we want is to use the incoming value, if it exists.
//
// These are the cases that have array values at the leaf levels.
$properties = array();
$properties[] = array( 'custom' );
$properties[] = array( 'spacing', 'units' );
$properties[] = array( 'color', 'duotone' );

// There are a few cases in which we want to merge things differently
// from what array_replace_recursive does.

// Some incoming properties should replace the existing.
$to_replace = array();
$to_replace[] = array( 'custom' );
$to_replace[] = array( 'spacing', 'units' );
$to_replace[] = array( 'typography', 'fontSizes' );
$to_replace[] = array( 'typography', 'fontFamilies' );

// Some others should be appended to the existing.
// If the slug is the same than an existing element,
// the $update_or_remove param is used to decide
// what to do with the existing element:
// either remove it and append the incoming,
// or update it with the incoming.
$to_append = array();
$to_append[] = array( 'color', 'duotone' );
$to_append[] = array( 'color', 'gradients' );
$to_append[] = array( 'color', 'palette' );
$to_append[] = array( 'color', 'gradients' );
$to_append[] = array( 'typography', 'fontSizes' );
$to_append[] = array( 'typography', 'fontFamilies' );

$nodes = self::get_setting_nodes( $this->theme_json );
foreach ( $nodes as $metadata ) {
foreach ( $to_replace as $path_to_replace ) {
$path = array_merge( $metadata['path'], $path_to_replace );
foreach ( $properties as $property_path ) {
$path = array_merge( $metadata['path'], $property_path );
$node = _wp_array_get( $incoming_data, $path, array() );
if ( ! empty( $node ) ) {
gutenberg_experimental_set( $this->theme_json, $path, $node );
}
}
foreach ( $to_append as $path_to_append ) {
$path = array_merge( $metadata['path'], $path_to_append );
$incoming_node = _wp_array_get( $incoming_data, $path, array() );
$existing_node = _wp_array_get( $existing_data, $path, array() );

if ( empty( $incoming_node ) && empty( $existing_node ) ) {
continue;
}

$index_table = array();
$existing_slugs = array();
$merged = array();
foreach ( $existing_node as $key => $value ) {
$index_table[ $value['slug'] ] = $key;
$existing_slugs[] = $value['slug'];
$merged[ $key ] = $value;
}

$to_remove = array();
foreach ( $incoming_node as $value ) {
if ( ! in_array( $value['slug'], $existing_slugs, true ) ) {
$merged[] = $value;
} elseif ( 'update' === $update_or_remove ) {
$merged[ $index_table[ $value['slug'] ] ] = $value;
foreach ( $to_append as $property_path ) {
$path = array_merge( $metadata['path'], $property_path );
$node = _wp_array_get( $incoming_data, $path, null );
if ( null !== $node ) {
$existing_node = _wp_array_get( $this->theme_json, $path, null );
$new_node = array_filter(
$existing_node,
function ( $key ) {
return in_array( $key, array( 'core', 'theme', 'user ' ), true );
},
ARRAY_FILTER_USE_KEY
);
if ( isset( $node[ $origin ] ) ) {
$new_node[ $origin ] = $node[ $origin ];
} else {
$merged[] = $value;
$to_remove[] = $index_table[ $value['slug'] ];
$new_node[ $origin ] = $node;
}
gutenberg_experimental_set( $this->theme_json, $path, $new_node );
}

// Remove the duplicated values and pack the sparsed array.
foreach ( $to_remove as $index ) {
unset( $merged[ $index ] );
}
$merged = array_values( $merged );

gutenberg_experimental_set( $this->theme_json, $path, $merged );
}
}

Expand Down
8 changes: 4 additions & 4 deletions lib/class-wp-theme-json-resolver-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ public static function get_theme_data( $theme_support_data = array() ) {
* to override the ones declared via add_theme_support.
*/
$with_theme_supports = new WP_Theme_JSON_Gutenberg( $theme_support_data );
$with_theme_supports->merge( self::$theme );
$with_theme_supports->merge( self::$theme, 'theme' );

return $with_theme_supports;
}
Expand Down Expand Up @@ -415,11 +415,11 @@ public static function get_merged_data( $settings = array(), $origin = 'user' )
$theme_support_data = WP_Theme_JSON_Gutenberg::get_from_editor_settings( $settings );

$result = new WP_Theme_JSON_Gutenberg();
$result->merge( self::get_core_data() );
$result->merge( self::get_theme_data( $theme_support_data ) );
$result->merge( self::get_core_data(), 'core' );
$result->merge( self::get_theme_data( $theme_support_data ), 'theme' );

if ( 'user' === $origin ) {
$result->merge( self::get_user_data(), 'update' );
$result->merge( self::get_user_data(), 'user' );
}

return $result;
Expand Down
72 changes: 24 additions & 48 deletions lib/experimental-default-theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,148 +6,124 @@
{
"name": "Black",
"slug": "black",
"color": "#000000",
"origin": "core"
"color": "#000000"
},
{
"name": "Cyan bluish gray",
"slug": "cyan-bluish-gray",
"color": "#abb8c3",
"origin": "core"
"color": "#abb8c3"
},
{
"name": "White",
"slug": "white",
"color": "#ffffff",
"origin": "core"
"color": "#ffffff"
},
{
"name": "Pale pink",
"slug": "pale-pink",
"color": "#f78da7",
"origin": "core"
"color": "#f78da7"
},
{
"name": "Vivid red",
"slug": "vivid-red",
"color": "#cf2e2e",
"origin": "core"
"color": "#cf2e2e"
},
{
"name": "Luminous vivid orange",
"slug": "luminous-vivid-orange",
"color": "#ff6900",
"origin": "core"
"color": "#ff6900"
},
{
"name": "Luminous vivid amber",
"slug": "luminous-vivid-amber",
"color": "#fcb900",
"origin": "core"
"color": "#fcb900"
},
{
"name": "Light green cyan",
"slug": "light-green-cyan",
"color": "#7bdcb5",
"origin": "core"
"color": "#7bdcb5"
},
{
"name": "Vivid green cyan",
"slug": "vivid-green-cyan",
"color": "#00d084",
"origin": "core"
"color": "#00d084"
},
{
"name": "Pale cyan blue",
"slug": "pale-cyan-blue",
"color": "#8ed1fc",
"origin": "core"
"color": "#8ed1fc"
},
{
"name": "Vivid cyan blue",
"slug": "vivid-cyan-blue",
"color": "#0693e3",
"origin": "core"
"color": "#0693e3"
},
{
"name": "Vivid purple",
"slug": "vivid-purple",
"color": "#9b51e0",
"origin": "core"
"color": "#9b51e0"
}
],
"gradients": [
{
"name": "Vivid cyan blue to vivid purple",
"gradient": "linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)",
"slug": "vivid-cyan-blue-to-vivid-purple",
"origin": "core"
"slug": "vivid-cyan-blue-to-vivid-purple"
},
{
"name": "Light green cyan to vivid green cyan",
"gradient": "linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%)",
"slug": "light-green-cyan-to-vivid-green-cyan",
"origin": "core"
"slug": "light-green-cyan-to-vivid-green-cyan"
},
{
"name": "Luminous vivid amber to luminous vivid orange",
"gradient": "linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%)",
"slug": "luminous-vivid-amber-to-luminous-vivid-orange",
"origin": "core"
"slug": "luminous-vivid-amber-to-luminous-vivid-orange"
},
{
"name": "Luminous vivid orange to vivid red",
"gradient": "linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%)",
"slug": "luminous-vivid-orange-to-vivid-red",
"origin": "core"
"slug": "luminous-vivid-orange-to-vivid-red"
},
{
"name": "Very light gray to cyan bluish gray",
"gradient": "linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%)",
"slug": "very-light-gray-to-cyan-bluish-gray",
"origin": "core"
"slug": "very-light-gray-to-cyan-bluish-gray"
},
{
"name": "Cool to warm spectrum",
"gradient": "linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%)",
"slug": "cool-to-warm-spectrum",
"origin": "core"
"slug": "cool-to-warm-spectrum"
},
{
"name": "Blush light purple",
"gradient": "linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%)",
"slug": "blush-light-purple",
"origin": "core"
"slug": "blush-light-purple"
},
{
"name": "Blush bordeaux",
"gradient": "linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%)",
"slug": "blush-bordeaux",
"origin": "core"
"slug": "blush-bordeaux"
},
{
"name": "Luminous dusk",
"gradient": "linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)",
"slug": "luminous-dusk",
"origin": "core"
"slug": "luminous-dusk"
},
{
"name": "Pale ocean",
"gradient": "linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%)",
"slug": "pale-ocean",
"origin": "core"
"slug": "pale-ocean"
},
{
"name": "Electric grass",
"gradient": "linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%)",
"slug": "electric-grass",
"origin": "core"
"slug": "electric-grass"
},
{
"name": "Midnight",
"gradient": "linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%)",
"slug": "midnight",
"origin": "core"
"slug": "midnight"
}
],
"duotone": [
Expand Down
Loading

0 comments on commit beaaf60

Please sign in to comment.