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

Add duotone theme.json styles support #34667

Merged
merged 24 commits into from
Sep 29, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
bbdd7ab
Add duotone theme.json styles support
ajlende Sep 8, 2021
5ec2efe
Add support for generating duotone CSS variables
ajlende Sep 8, 2021
3c0a97e
Add value_func and value_args metadata to compute duotone
ajlende Sep 9, 2021
ec86c0b
Update phpunit tests
ajlende Sep 9, 2021
358c456
Fix duotone filter id on css variables
ajlende Sep 9, 2021
8c421cc
Exmplain why !important is needed
ajlende Sep 9, 2021
e9abc0b
Fix get_settings_values_by_slug example
ajlende Sep 9, 2021
cebab75
Add color.duotone to PATHS_WITH_MERGE
ajlende Sep 9, 2021
5956f18
Rename $meta to $preset_meta to be more descriptive
ajlende Sep 9, 2021
c15c1cf
Render duotone styles when settings are disabled
ajlende Sep 14, 2021
3c2c166
Improve mechanism to declare a selector for the property
oandregal Sep 21, 2021
220d86d
Revert "Improve mechanism to declare a selector for the property"
oandregal Sep 22, 2021
a0134b1
Merge branch 'trunk' into add/duotone-theme-json-styles
ajlende Sep 22, 2021
537d608
duotone-filter to just duotone css var infix
ajlende Sep 23, 2021
23cd929
Merge branch 'trunk' into add/duotone-theme-json-styles
ajlende Sep 27, 2021
775717e
Revert duotone SVG to be inside the footer
ajlende Sep 27, 2021
2a6a7e8
Simplify value_func args
ajlende Sep 27, 2021
c147b04
Additionally strip multiple spaces in SVG
ajlende Sep 27, 2021
e31fa8e
Improve code quality and inline docs
ajlende Sep 27, 2021
8aaa12f
Fix value_func after rename
ajlende Sep 27, 2021
c793a69
Improve inline docs
ajlende Sep 27, 2021
df50ef0
Update duotone-filter -> duotone for generated ids
ajlende Sep 28, 2021
53b154b
Rename preset_meta -> preset_metadata
ajlende Sep 28, 2021
008c5d5
Move duotone styles from color -> filter
ajlende Sep 28, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
136 changes: 69 additions & 67 deletions lib/block-supports/duotone.php
Original file line number Diff line number Diff line change
Expand Up @@ -251,31 +251,14 @@ function gutenberg_register_duotone_support( $block_type ) {
}

/**
* Render out the duotone stylesheet and SVG.
* Get the duotone filter property.
*
* @param string $block_content Rendered block content.
* @param array $block Block object.
* @return string Filtered block content.
* @param string $duotone_id Unique id for the duotone filter.
* @param array $duotone_colors Array of CSS color strings that can be parsed by tinycolor.
*
* @return string Duotone CSS filter property.
*/
function gutenberg_render_duotone_support( $block_content, $block ) {
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );

$duotone_support = false;
if ( $block_type && property_exists( $block_type, 'supports' ) ) {
$duotone_support = _wp_array_get( $block_type->supports, array( 'color', '__experimentalDuotone' ), false );
}

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

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

$duotone_colors = $block['attrs']['style']['color']['duotone'];

function gutenberg_get_duotone_filter_property( $duotone_id, $duotone_colors ) {
$duotone_values = array(
'r' => array(),
'g' => array(),
Expand All @@ -289,46 +272,21 @@ function gutenberg_render_duotone_support( $block_content, $block ) {
$duotone_values['b'][] = $color['b'] / 255;
}

$duotone_id = 'wp-duotone-filter-' . uniqid();

$selectors = explode( ',', $duotone_support );
$selectors_scoped = array_map(
function ( $selector ) use ( $duotone_id ) {
return '.' . $duotone_id . ' ' . trim( $selector );
},
$selectors
);
$selectors_group = implode( ', ', $selectors_scoped );

ob_start();

?>

<style>
<?php echo $selectors_group; ?> {
filter: url( <?php echo esc_url( '#' . $duotone_id ); ?> );
}
</style>

<svg
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 0 0"
width="0"
height="0"
focusable="false"
role="none"
style="visibility: hidden; position: absolute; left: -9999px; overflow: hidden;"
>
<svg xmlns="http://www.w3.org/2000/svg">
ajlende marked this conversation as resolved.
Show resolved Hide resolved
<defs>
<filter id="<?php echo esc_attr( $duotone_id ); ?>">
<feColorMatrix
type="matrix"
<?php // phpcs:disable Generic.WhiteSpace.DisallowSpaceIndent ?>
values=".299 .587 .114 0 0
.299 .587 .114 0 0
.299 .587 .114 0 0
0 0 0 1 0"
<?php // phpcs:enable Generic.WhiteSpace.DisallowSpaceIndent ?>
values="
.299 .587 .114 0 0
.299 .587 .114 0 0
.299 .587 .114 0 0
0 0 0 1 0
"
/>
<feComponentTransfer color-interpolation-filters="sRGB" >
<feFuncR type="table" tableValues="<?php echo esc_attr( implode( ' ', $duotone_values['r'] ) ); ?>" />
Expand All @@ -341,25 +299,69 @@ function ( $selector ) use ( $duotone_id ) {

<?php

$duotone = ob_get_clean();
$svg = ob_get_clean();

// Clean up the whitespace so it can be used in a data uri.
$svg = preg_replace( "/(\r|\n|\t)+/", ' ', $svg );
$svg = preg_replace( '/> </', '><', $svg );
$svg = trim( $svg );

$data_uri = 'data:image/svg+xml,' . $svg . '#' . $duotone_id;

// All the variables are already escaped above, so we're not calling esc_url() here.
return "url('" . $data_uri . "')";
ajlende marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Render out the duotone stylesheet and SVG.
*
* @param string $block_content Rendered block content.
* @param array $block Block object.
* @return string Filtered block content.
*/
function gutenberg_render_duotone_support( $block_content, $block ) {
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );

$duotone_support = false;
if ( $block_type && property_exists( $block_type, 'supports' ) ) {
$duotone_support = _wp_array_get( $block_type->supports, array( 'color', '__experimentalDuotone' ), false );
}

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

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

$duotone_id = 'wp-duotone-filter-' . uniqid();
$duotone_colors = $block['attrs']['style']['color']['duotone'];
$filter_property = gutenberg_get_duotone_filter_property( $duotone_id, $duotone_colors );

$selectors = explode( ',', $duotone_support );
$scoped = array();
foreach ( $selectors as $sel ) {
$scoped[] = '.' . $duotone_id . ' ' . trim( $sel );
}
$selector = implode( ', ', $scoped );

$filter_style = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG
? $selector . " {\n\tfilter: " . $filter_property . " !important;\n}\n"
: $selector . '{filter:' . $filter_property . ' !important;}';

wp_register_style( $duotone_id, false, array(), true, true );
wp_add_inline_style( $duotone_id, $filter_style );
wp_enqueue_style( $duotone_id );
ajlende marked this conversation as resolved.
Show resolved Hide resolved

// Like the layout hook, this assumes the hook only applies to blocks with a single wrapper.
$content = preg_replace(
return preg_replace(
'/' . preg_quote( 'class="', '/' ) . '/',
'class="' . $duotone_id . ' ',
$block_content,
1
);

add_action(
// Ideally we should use wp_head, but SVG defs can't be put in there.
'wp_footer',
function () use ( $duotone ) {
echo $duotone;
}
);

return $content;
}

// Register the block support.
Expand Down