Skip to content

Commit

Permalink
Update lib/block-supports/elements.php
Browse files Browse the repository at this point in the history
Co-authored-by: André <nosolosw@users.noreply.github.com> (+3 squashed commits)
Squashed commits:
[994e5e3] Add link color as an element mechanism.
[e4a72bc] Remove existing link color
[7fcd57c] Fix nav placeholder colors and height. (#31875)
  • Loading branch information
jasmussen authored and jorgefilipecosta committed May 18, 2021
1 parent 269f31a commit 4bc2ac2
Show file tree
Hide file tree
Showing 18 changed files with 376 additions and 277 deletions.
18 changes: 0 additions & 18 deletions lib/block-supports/colors.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,24 +99,6 @@ function gutenberg_apply_colors_support( $block_type, $block_attributes ) {
}
}

// Link Colors.
if ( $has_link_colors_support ) {
$has_link_color = isset( $block_attributes['style']['color']['link'] );
// Apply required class and style.
if ( $has_link_color ) {
$classes[] = 'has-link-color';
// If link is a named color.
if ( strpos( $block_attributes['style']['color']['link'], 'var:preset|color|' ) !== false ) {
// Get the name from the string and add proper styles.
$index_to_splice = strrpos( $block_attributes['style']['color']['link'], '|' ) + 1;
$link_color_name = substr( $block_attributes['style']['color']['link'], $index_to_splice );
$styles[] = sprintf( '--wp--style--color--link: var(--wp--preset--color--%s);', $link_color_name );
} else {
$styles[] = sprintf( '--wp--style--color--link: %s;', $block_attributes['style']['color']['link'] );
}
}
}

// Background colors.
if ( $has_background_colors_support ) {
$has_named_background_color = array_key_exists( 'backgroundColor', $block_attributes );
Expand Down
65 changes: 65 additions & 0 deletions lib/block-supports/elements.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php
/**
* Elements styles block support.
*
* @package gutenberg
*/

/**
* Render the elements stylesheet.
*
* @param string $block_content Rendered block content.
* @param array $block Block object.
* @return string Filtered block content.
*/
function gutenberg_render_elements_support( $block_content, $block ) {
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
$link_color = _wp_array_get( $block['attrs'], array( 'style', 'elements', 'link', 'color', 'text' ), null );

/*
* For now we only care about link color.
* This code in the future when we have a public API
* should take advantage of WP_Theme_JSON::compute_style_properties
* and work for any element and style.
*/
if ( null === $link_color ) {
return $block_content;
}

$class_name = 'wp-elements-' . uniqid();

if ( strpos( $link_color, 'var:preset|color|' ) !== false ) {
// Get the name from the string and add proper styles.
$index_to_splice = strrpos( $link_color, '|' ) + 1;
$link_color_name = substr( $link_color, $index_to_splice );
$link_color = "var(--wp--preset--color--$link_color_name)";
}
$link_color_declaration = esc_html( safecss_filter_attr( "color: $link_color" ) );

$style = "<style>.$class_name a{" . $link_color_declaration . " !important;}</style>\n";

// Like the layout hook this assumes the hook only applies to blocks with a single wrapper.
// Retrieve the opening tag of the first HTML element.
$html_element_matches;
preg_match( '/<[^>]+>/', $block_content, $html_element_matches, PREG_OFFSET_CAPTURE );
$first_element = $html_element_matches[0][0];
// If the first HTML element has a class attribute just add the new class
// as we do on layout and duotone.
if ( strpos( $first_element, 'class="' ) !== false ) {
$content = preg_replace(
'/' . preg_quote( 'class="', '/' ) . '/',
'class="' . $class_name . ' ',
$block_content,
1
);
} else {
// If the first HTML element has no class attribute we should inject the attribute before the attribute at the end.
$first_element_offset = $html_element_matches[0][1];
$content = substr_replace( $block_content, ' class="' . $class_name . '"', $first_element_offset + strlen( $first_element ) - 1, 0 );
}
return $content . $style;

}


add_filter( 'render_block', 'gutenberg_render_elements_support', 10, 2 );
101 changes: 2 additions & 99 deletions lib/class-wp-theme-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,6 @@ class WP_Theme_JSON {
* - 'value': path to the value in theme.json and block attributes.
*/
const PROPERTIES_METADATA = array(
'--wp--style--color--link' => array(
'value' => array( 'color', 'link' ),
),
'background' => array(
'value' => array( 'color', 'gradient' ),
),
Expand Down Expand Up @@ -836,7 +833,7 @@ private function get_css_variables( $nodes ) {
* @return string The new stylesheet.
*/
private function get_block_styles( $style_nodes, $setting_nodes ) {
$block_rules = self::ELEMENTS['link'] . '{color: var(--wp--style--color--link, #00e);}';
$block_rules = '';
foreach ( $style_nodes as $metadata ) {
if ( null === $metadata['selector'] ) {
continue;
Expand All @@ -845,53 +842,7 @@ private function get_block_styles( $style_nodes, $setting_nodes ) {
$node = _wp_array_get( $this->theme_json, $metadata['path'], array() );
$selector = $metadata['selector'];
$declarations = self::compute_style_properties( $node );

$is_link_element = self::is_link_element( $metadata['selector'] );
if ( ! $is_link_element ) {
$block_rules .= self::to_ruleset( $selector, $declarations );
} else {
/*
* To be removed when the user provided styles for link color
* no longer use the --wp--style--link-color variable.
*
* We need to:
*
* 1. For the color property, output:
*
* $selector_without_the_link_element_selector {
* --wp--style--color--link: value
* }
*
* 2. For the rest of the properties:
*
* $selector {
* other-prop: value;
* other-prop: value;
* }
*
* The reason for 1 is that user styles are attached to the block wrapper.
* If 1 targets the a element is going to have higher specificity
* and will overwrite the user preferences.
*
* Once the user styles are updated to output an `a` element instead
* this can be removed.
*/
$declarations_color = array();
$declarations_other = array();
foreach ( $declarations as $declaration ) {
if ( 'color' === $declaration['name'] ) {
$declarations_color[] = array(
'name' => '--wp--style--color--link',
'value' => $declaration['value'],
);
} else {
$declarations_other[] = $declaration;
}
}

$block_rules .= self::to_ruleset( $selector, $declarations_other );
$block_rules .= self::to_ruleset( self::without_link_selector( $selector ), $declarations_color );
}
$block_rules .= self::to_ruleset( $selector, $declarations );
}

$preset_rules = '';
Expand Down Expand Up @@ -1219,15 +1170,6 @@ private static function remove_insecure_settings( $input ) {
private static function remove_insecure_styles( $input, $selector ) {
$output = array();
$declarations = self::compute_style_properties( $input );
// To be removed once the user styles
// no longer use the --wp--style--color--link.
if ( self::is_link_element( $selector ) ) {
foreach ( $declarations as $index => $declaration ) {
if ( 'color' === $declaration['name'] ) {
$declarations[ $index ]['name'] = '--wp--style--color--link';
}
}
}

foreach ( $declarations as $declaration ) {
if ( self::is_safe_css_declaration( $declaration['name'], $declaration['value'] ) ) {
Expand Down Expand Up @@ -1256,45 +1198,6 @@ private static function is_safe_css_declaration( $property_name, $property_value
return ! empty( trim( $filtered ) );
}

/**
* Whether the selector contains a link element.
*
* @param string $selector The selector to check.
*
* @return boolean
*/
private static function is_link_element( $selector ) {
if ( self::ELEMENTS['link'] === $selector ) {
return true;
}

$result = true;
if ( false === stripos( $selector, ' ' . self::ELEMENTS['link'] ) ) {
$result = false;
}

return $result;
}

/**
* Remove the link selector from the input.
*
* @param string $selector CSS selector to process.
*
* @return string
*/
private static function without_link_selector( $selector ) {
if ( self::ELEMENTS['link'] === $selector ) {
return $selector;
}

// The selector consist of "<something> <element_selector>".
// It can be compounded as well: "<one> <element_selector>, <two> <element_selector>, etc".
//
// We want to return "<something>" or "<one>, <two>, etc".
return str_ireplace( ' ' . self::ELEMENTS['link'], '', $selector );
}

/**
* Removes insecure data from theme.json.
*/
Expand Down
1 change: 1 addition & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/query-utils.php';

require __DIR__ . '/block-supports/generated-classname.php';
require __DIR__ . '/block-supports/elements.php';
require __DIR__ . '/block-supports/colors.php';
require __DIR__ . '/block-supports/align.php';
require __DIR__ . '/block-supports/typography.php';
Expand Down
34 changes: 18 additions & 16 deletions packages/block-editor/src/hooks/color.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* External dependencies
*/
import classnames from 'classnames';
import { isObject } from 'lodash';
import { isObject, setWith, clone } from 'lodash';

/**
* WordPress dependencies
Expand Down Expand Up @@ -162,7 +162,7 @@ export function addSaveProps( props, blockType, attributes ) {
backgroundColor ||
style?.color?.background ||
( hasGradient && ( gradient || style?.color?.gradient ) ),
'has-link-color': style?.color?.link,
'has-link-color': style?.elements?.link?.color,
}
);
props.className = newClassName ? newClassName : undefined;
Expand Down Expand Up @@ -205,6 +205,10 @@ const getLinkColorFromAttributeValue = ( colors, value ) => {
return value;
};

function immutableSet( object, path, value ) {
return setWith( object ? clone( object ) : {}, path, value, clone );
}

/**
* Inspector control panel containing the color related configuration
*
Expand Down Expand Up @@ -303,17 +307,15 @@ export function ColorEdit( props ) {

const onChangeLinkColor = ( value ) => {
const colorObject = getColorObjectByColorValue( colors, value );
props.setAttributes( {
style: {
...props.attributes.style,
color: {
...props.attributes.style?.color,
link: colorObject?.slug
? `var:preset|color|${ colorObject.slug }`
: value,
},
},
} );
const newLinkColorValue = colorObject?.slug
? `var:preset|color|${ colorObject.slug }`
: value;
const newStyle = immutableSet(
style,
[ 'elements', 'link', 'color', 'text' ],
newLinkColorValue
);
props.setAttributes( { style: newStyle } );
};

return (
Expand Down Expand Up @@ -363,10 +365,10 @@ export function ColorEdit( props ) {
onColorChange: onChangeLinkColor,
colorValue: getLinkColorFromAttributeValue(
colors,
style?.color?.link
style?.elements?.link?.color?.text
),
clearable: !! props.attributes.style?.color
?.link,
clearable: !! style?.elements?.link?.color
?.text,
},
]
: [] ),
Expand Down

0 comments on commit 4bc2ac2

Please sign in to comment.