Skip to content

Commit

Permalink
duotone.php code cleanup (#48607)
Browse files Browse the repository at this point in the history
* Update comment for possible duotone attribute contents

* Rename filter_preset to filter_data

* Use WP_Theme_JSON for scoping the selector

* Treat strings as CSS in gutenberg_get_duotone_filter_property

* Base is_duotone_preset based on is_string instead of !is_array

* Update comments

* Rename is_duotone_custom_colors

* 🇺🇸😉

* Shorten some var names

* Make each attribute case explicit

* Only use $filter_data for custom filters

* Add comment about rendering the SVG

* Fix php lint

* Update comments

* Fix php elseifs

* Fix CSS code path

* Add PHP unit tests

* Fix php lint

* Remove tear_down because I don't think it's used

---------

Co-authored-by: scruffian <ben@scruffian.com>
  • Loading branch information
Alex Lende and scruffian authored Mar 1, 2023
1 parent 116d032 commit 9189c3a
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 36 deletions.
70 changes: 34 additions & 36 deletions lib/block-supports/duotone.php
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,8 @@ 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';
if ( isset( $preset['colors'] ) && is_string( $preset['colors'] ) ) {
return $preset['colors'];
}
$filter_id = gutenberg_get_duotone_filter_id( $preset );
return "url('#" . $filter_id . "')";
Expand Down Expand Up @@ -447,50 +447,51 @@ function gutenberg_render_duotone_support( $block_content, $block ) {

// 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"..
// 2. Variable for an existing Duotone preset - e.g. 'var:preset|duotone|green-blue'.
// 3. A CSS string - e.g. 'unset' to remove globally applied duotone.
$duotone_attr = $block['attrs']['style']['color']['duotone'];

$is_duotone_colors_array = is_array( $duotone_attr );
$is_duotone_preset = ! $is_duotone_colors_array && strpos( $duotone_attr, 'var:preset|duotone|' ) === 0;
$is_preset = is_string( $duotone_attr ) && strpos( $duotone_attr, 'var:preset|duotone|' ) === 0;
$is_css = is_string( $duotone_attr ) && strpos( $duotone_attr, 'var:preset|duotone|' ) === false;
$is_custom = is_array( $duotone_attr );

if ( $is_duotone_preset ) {
$slug = str_replace( 'var:preset|duotone|', '', $duotone_attr );
$filter_preset = array(
'slug' => $slug,
);
// Generate the pieces needed for rendering a duotone to the page.
if ( $is_preset ) {
// Extract the slug from the preset variable string.
$slug = str_replace( 'var:preset|duotone|', '', $duotone_attr );

// Utilise existing CSS custom property.
// Utilize existing preset CSS custom property.
$filter_property = "var(--wp--preset--duotone--$slug)";
} else {
// Handle when Duotone is either:
// - "unset"
// - an array of colors.
} elseif ( $is_css ) {
// Build a unique slug for the filter based on the CSS value.
$slug = wp_unique_id( sanitize_key( $duotone_attr . '-' ) );

// Pass through the CSS value.
$filter_property = $duotone_attr;
} elseif ( $is_custom ) {
// 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(
'slug' => wp_unique_id( sanitize_key( $filter_key . '-' ) ),
'colors' => $duotone_attr, // required for building the SVG with gutenberg_get_duotone_filter_svg.
$slug = wp_unique_id( sanitize_key( implode( '-', $duotone_attr ) . '-' ) );

// This has the same shape as a preset, so it can be used in place of a
// preset when getting the filter property and SVG filter.
$filter_data = array(
'slug' => $slug,
'colors' => $duotone_attr,
);

// Build a customised CSS filter property for unique slug.
$filter_property = 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 );

// SVG will be output on the page later.
$filter_svg = gutenberg_get_duotone_filter_svg( $filter_data );
}

// - 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( array( 'slug' => $slug ) );

// 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 );

// 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 @@ -513,11 +514,8 @@ 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 );

// If we needed to generate an SVG, output it on the page.
if ( isset( $filter_svg ) ) {
add_action(
'wp_footer',
static function () use ( $filter_svg, $selector ) {
Expand Down
40 changes: 40 additions & 0 deletions phpunit/block-supports/duotone-test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

/**
* Test the block duotone support.
*
* @package Gutenberg
*/

class WP_Block_Supports_Duotone_Test extends WP_UnitTestCase {
public function test_gutenberg_render_duotone_support_preset() {
$block = array(
'blockName' => 'core/image',
'attrs' => array( 'style' => array( 'color' => array( 'duotone' => 'var:preset|duotone|slug' ) ) ),
);
$block_content = '<figure class="wp-block-image size-full"><img src="/my-image.jpg" /></figure>';
$expected = '<figure class="wp-duotone-slug wp-block-image size-full"><img src="/my-image.jpg" /></figure>';
$this->assertSame( $expected, gutenberg_render_duotone_support( $block_content, $block ) );
}

public function test_gutenberg_render_duotone_support_css() {
$block = array(
'blockName' => 'core/image',
'attrs' => array( 'style' => array( 'color' => array( 'duotone' => 'unset' ) ) ),
);
$block_content = '<figure class="wp-block-image size-full"><img src="/my-image.jpg" /></figure>';
$expected = '/<figure class="wp-duotone-unset-\d+ wp-block-image size-full"><img src="\\/my-image.jpg" \\/><\\/figure>/';
$this->assertMatchesRegularExpression( $expected, gutenberg_render_duotone_support( $block_content, $block ) );
}

public function test_gutenberg_render_duotone_support_custom() {
$block = array(
'blockName' => 'core/image',
'attrs' => array( 'style' => array( 'color' => array( 'duotone' => array( '#FFFFFF', '#000000' ) ) ) ),
);
$block_content = '<figure class="wp-block-image size-full"><img src="/my-image.jpg" /></figure>';
$expected = '/<figure class="wp-duotone-ffffff-000000-\d+ wp-block-image size-full"><img src="\\/my-image.jpg" \\/><\\/figure>/';
$this->assertMatchesRegularExpression( $expected, gutenberg_render_duotone_support( $block_content, $block ) );
}

}

1 comment on commit 9189c3a

@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 9189c3a.
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/4308926860
📝 Reported issues:

Please sign in to comment.