Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow duotone presets to be stored in the "duotone" block attribute #48381

Closed
wants to merge 12 commits into from
70 changes: 31 additions & 39 deletions lib/block-supports/duotone.php
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,9 @@ function gutenberg_get_duotone_filter_id( $preset ) {
* @return string Duotone CSS filter property url value.
*/
function gutenberg_get_duotone_filter_property( $preset ) {
if ( isset( $preset['colors'] ) && 'unset' === $preset['colors'] ) {
return 'none';
}
Comment on lines +314 to +316
Copy link
Contributor Author

Choose a reason for hiding this comment

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

gutenberg_get_duotone_filter_property is used externally by WP_Theme_JSON, so we want to keep the original behavior.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh man. Its so horrible having to remember that everything is public in PHP. Thank you for catching this.

$filter_id = gutenberg_get_duotone_filter_id( $preset );
return "url('#" . $filter_id . "')";
}
Expand Down Expand Up @@ -433,61 +436,51 @@ function gutenberg_render_duotone_support( $block_content, $block ) {
$duotone_support = _wp_array_get( $block_type->supports, array( 'color', '__experimentalDuotone' ), false );
}

$has_duotone_attribute = isset( $block['attrs']['style']['color']['duotone'] );
$has_custom_duotone = isset( $block['attrs']['style']['color']['duotone'] );
$has_preset_duotone = isset( $block['attrs']['duotone'] );

if (
! $duotone_support ||
! $has_duotone_attribute
( ! $has_custom_duotone && ! $has_preset_duotone )
) {
return $block_content;
}

// Possible values for duotone attribute:
// 1. Array of colors - e.g. array('#000000', '#ffffff').
// 2. Slug of an existing Duotone preset - e.g. 'green-blue'.
// 3. The string 'unset' - indicates explicitly "no Duotone"..
$duotone_attr = $block['attrs']['style']['color']['duotone'];

$is_duotone_colors_array = is_array( $duotone_attr );
$is_duotone_unset = 'unset' === $duotone_attr;
$is_duotone_preset = ! $is_duotone_colors_array && ! $is_duotone_unset;
if ( $has_custom_duotone ) {
// Handle custom values for duotone attribute.

if ( $is_duotone_preset ) {
$filter_preset = array(
'slug' => $duotone_attr,
);

// Utilise existing CSS custom property.
$filter_property = "var(--wp--preset--duotone--$duotone_attr)";
} else {
// Handle when Duotone is either:
// - "unset"
// - an array of colors.
// 1. Array of colors - e.g. array('#000000', '#ffffff').
// 2. The string 'unset' - indicates explicitly "override the theme duotone with `filter: none !important`".
$duotone_attr = $block['attrs']['style']['color']['duotone'];

// Build a unique slug for the filter based on the array of colors.
$filter_key = $is_duotone_colors_array ? implode( '-', $duotone_attr ) : $duotone_attr;
$filter_preset = array(
$filter_key = is_array( $duotone_attr ) ? implode( '-', $duotone_attr ) : $duotone_attr;
$filter_data = array(
Copy link
Contributor

Choose a reason for hiding this comment

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

filter_data is much better name now - thank you.

'slug' => wp_unique_id( sanitize_key( $filter_key . '-' ) ),
'colors' => $duotone_attr, // required for building the SVG with gutenberg_get_duotone_filter_svg.
);

// Build a customised CSS filter property for unique slug.
$filter_property = $is_duotone_unset ? 'none' : gutenberg_get_duotone_filter_property( $filter_preset );
// Build a customized CSS filter property for unique slug.
$filter_property = gutenberg_get_duotone_filter_property( $filter_data );
} elseif ( $has_preset_duotone ) {
// Handle preset values for duotone iff the preset is set and there is no custom duotone.
getdave marked this conversation as resolved.
Show resolved Hide resolved

// 1. Slug of an existing Duotone preset - e.g. 'green-blue'.
$duotone_attr = $block['attrs']['duotone'];
$filter_data = array(
'slug' => $duotone_attr,
);

// Utilize existing CSS custom property.
$filter_property = "var(--wp--preset--duotone--$duotone_attr)";
}

// - Applied as a class attribute to the block wrapper.
// - Used as a selector to apply the filter to the block.
$filter_id = gutenberg_get_duotone_filter_id( $filter_preset );
$filter_id = gutenberg_get_duotone_filter_id( $filter_data );

// Build the CSS selectors to which the filter will be applied.
// Todo - encapsulate this in a function.
$scope = '.' . $filter_id;
$selectors = explode( ',', $duotone_support );
$scoped = array();
foreach ( $selectors as $sel ) {
$scoped[] = $scope . ' ' . trim( $sel );
}
$selector = implode( ', ', $scoped );
$selector = WP_Theme_JSON_Gutenberg::scope_selector( '.' . $filter_id, $duotone_support );
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I forget—when doing backports, renaming things like WP_Theme_JSON_Gutenberg to WP_Theme_JSON is part of the normal process, right? Or will this need special attention?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is fine, we just need to to rename it when we do the backport.

Copy link
Contributor

Choose a reason for hiding this comment

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

Nice! That bit of code was on my refactor this. Glad you found it.


// Calling gutenberg_style_engine_get_stylesheet_from_css_rules ensures that
// the styles are rendered in an inline for block supports because we're
Expand All @@ -510,10 +503,9 @@ function gutenberg_render_duotone_support( $block_content, $block ) {
)
);

// For *non*-presets then generate an SVG for the filter.
// Note: duotone presets are already pre-generated so no need to do this again.
if ( $is_duotone_colors_array ) {
$filter_svg = gutenberg_get_duotone_filter_svg( $filter_preset );
// Only custom duotone filters with values need to be rendered here.
if ( is_array( $duotone_attr ) ) {
$filter_svg = gutenberg_get_duotone_filter_svg( $filter_data );

add_action(
'wp_footer',
Expand Down
7 changes: 7 additions & 0 deletions packages/block-editor/src/hooks/duotone.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,13 @@ function addDuotoneAttributes( settings ) {
},
} );
}
if ( ! settings.attributes.duotone ) {
Object.assign( settings.attributes, {
duotone: {
type: 'string',
},
} );
}

return settings;
}
Expand Down