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

Duotone: Only output Duotone filters that are used #48291

Closed
wants to merge 12 commits into from
44 changes: 44 additions & 0 deletions lib/block-supports/duotone.php
Original file line number Diff line number Diff line change
Expand Up @@ -519,3 +519,47 @@ static function () use ( $filter_svg, $selector ) {
// Remove WordPress core filter to avoid rendering duplicate support elements.
remove_filter( 'render_block', 'wp_render_duotone_support', 10, 2 );
add_filter( 'render_block', 'gutenberg_render_duotone_support', 10, 2 );

class WP_Duotone {
/**
* An array of Duotone presets.
*
* @since 6.3.0
* @var array
*/
static $duotone_presets = array();

/**
* Registers the duotone preset.
*
* @param array $settings The block editor settings.
*
* @return array The block editor settings.
*/
public static function duotone_declarations( $declarations, $selector ) {
foreach ( $declarations as $index => $declaration ) {
if ( 'filter' === $declaration['name'] ) {
static::$duotone_presets[] = $declarations[ $index ]['value'];
}
}
}

public static function get_filter_svg( $duotone_preset ) {
$filters = '';
// Get the CSS variable for the preset.
$duotone_preset_css_var = WP_Theme_JSON_Gutenberg::get_preset_css_var( array( 'color', 'duotone' ), $duotone_preset['slug'] );
$duotone_preset_css_var_with_wrapper = 'var(' . $duotone_preset_css_var . ')';
// Only output the preset if it's used by a block.
if ( in_array( $duotone_preset_css_var_with_wrapper, WP_Duotone::$duotone_presets, true ) ) {
// Output the CSS for the preset.
// I think we should do this differently, but I'm not sure how.
$filters .= '<style>body{' . $duotone_preset_css_var . ':'. gutenberg_get_duotone_filter_property( $duotone_preset ) . ';}</style>';
Comment on lines +555 to +556
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be nice if it could still be handled by value_func in WP_Theme_JSON_Gutenberg instead of moving it here.

Maybe we have to think a little more about where the filters/actions belong in that code? Could it be more useful in gutenberg_add_global_styles_for_blocks—modifying the $metadata passed into get_styles_for_block?

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 @ajlende has a point. Somehow appending that preset CSS code doesn't feel it belongs in get_filter_svg and since it's a preset and WP Theme json gives us a way to add callback for presets then we should use that.

$filters .= wp_get_duotone_filter_svg( $duotone_preset );
}

return $filters;
}
}
add_action( 'theme_json_register_declarations', array( 'WP_Duotone', 'duotone_declarations' ), 10, 2 );

add_filter( 'theme_json_get_filter_svg', array( 'WP_Duotone', 'get_filter_svg' ), 10, 2 );
43 changes: 40 additions & 3 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class WP_Theme_JSON_Gutenberg {
'path' => array( 'color', 'duotone' ),
'prevent_override' => array( 'color', 'defaultDuotone' ),
'use_default_names' => false,
'value_func' => 'gutenberg_get_duotone_filter_property',
'value_func' => null, // Don't output CSS Custom Properties for duotone.
'css_vars' => '--wp--preset--duotone--$slug',
'classes' => array(),
'properties' => array( 'filter' ),
Expand Down Expand Up @@ -1463,7 +1463,6 @@ protected function get_css_variables( $nodes, $origins ) {
foreach ( $theme_vars_declarations as $theme_vars_declaration ) {
$declarations[] = $theme_vars_declaration;
}

$stylesheet .= static::to_ruleset( $selector, $declarations );
}

Expand Down Expand Up @@ -2418,6 +2417,9 @@ function( $pseudo_selector ) use ( $selector ) {

$block_rules = '';

// TODO
do_action( 'theme_json_register_declarations', $declarations, $selector );

/*
* 1. Separate the declarations that use the general selector
* from the ones using the duotone selector.
Expand Down Expand Up @@ -2700,14 +2702,49 @@ public function get_svg_filters( $origins ) {
continue;
}
foreach ( $duotone_presets[ $origin ] as $duotone_preset ) {
$filters .= wp_get_duotone_filter_svg( $duotone_preset );
$filters .= apply_filters( 'theme_json_get_filter_svg', $duotone_preset );
}
}
}

return $filters;
}

/**
* Returns the CSS variable for a preset.
*
* @since 6.3.0
*
* @param array $path Path to the preset.
* @param string $slug Slug of the preset.
* @return string CSS variable.
*/
public static function get_preset_css_var( $path, $slug ) {
$duotone_preset_metadata = static::get_preset_metadata_from_path( $path );
return static::replace_slug_in_string( $duotone_preset_metadata['css_vars'], $slug );
}

/**
* Returns the metadata for a preset.
*
* @since 6.3.0
*
* @param array $path Path to the preset.
* @return array Preset metadata.
*/
static function get_preset_metadata_from_path( $path ) {
$preset_metadata = array_filter(
static::PRESETS_METADATA,
function( $preset ) use ( &$path ) {
if ( $preset['path'] === $path ) {
return $preset;
}
}
);

return reset( $preset_metadata );
}

/**
* Determines whether a presets should be overridden or not.
*
Expand Down
42 changes: 42 additions & 0 deletions lib/compat/wordpress-6.2/get-global-styles-and-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,45 @@ function _gutenberg_add_non_persistent_theme_json_cache_group() {
wp_cache_add_non_persistent_groups( 'theme_json' );
}
add_action( 'plugins_loaded', '_gutenberg_add_non_persistent_theme_json_cache_group' );


/**
* Returns a string containing the SVGs to be referenced as filters (duotone).
*
* @since 5.9.1
*
* @return string
*/
function gutenberg_get_global_styles_svg_filters() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is just a copy of gutenberg_get_global_styles_svg_filters with the reference to the WP_Theme_JSON_Resolver class updated to WP_Theme_JSON_Resolver_Gutenberg.

/*
* Ignore cache when `WP_DEBUG` is enabled, so it doesn't interfere with the theme
* developer's workflow.
*
* @todo Replace `WP_DEBUG` once an "in development mode" check is available in Core.
*/
$can_use_cached = ! WP_DEBUG;
$cache_group = 'theme_json';
$cache_key = 'wp_get_global_styles_svg_filters';
if ( $can_use_cached ) {
$cached = wp_cache_get( $cache_key, $cache_group );
if ( $cached ) {
return $cached;
}
}

$supports_theme_json = wp_theme_has_theme_json();

$origins = array( 'default', 'theme', 'custom' );
if ( ! $supports_theme_json ) {
$origins = array( 'default' );
}

$tree = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data();
$svgs = $tree->get_svg_filters( $origins );

if ( $can_use_cached ) {
wp_cache_set( $cache_key, $svgs, $cache_group );
}

return $svgs;
}
35 changes: 35 additions & 0 deletions lib/compat/wordpress-6.2/script-loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,38 @@ function gutenberg_enqueue_global_styles_custom_css() {
}
}
add_action( 'wp_enqueue_scripts', 'gutenberg_enqueue_global_styles_custom_css' );



/**
* Renders the SVG filters supplied by theme.json.
*
* Note that this doesn't render the per-block user-defined
* filters which are handled by wp_render_duotone_support,
* but it should be rendered before the filtered content
* in the body to satisfy Safari's rendering quirks.
*
* @since 5.9.1
*/
function gutenberg_global_styles_render_svg_filters() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is just a copy of wp_global_styles_render_svg_filters

/*
* When calling via the in_admin_header action, we only want to render the
* SVGs on block editor pages.
*/
if (
is_admin() &&
! get_current_screen()->is_block_editor()
) {
return;
}

$filters = gutenberg_get_global_styles_svg_filters();
if ( ! empty( $filters ) ) {
echo $filters;
}
}

remove_action( 'wp_body_open', 'wp_global_styles_render_svg_filters' );
remove_action( 'in_admin_header', 'wp_global_styles_render_svg_filters' );
add_action( 'wp_body_open', 'gutenberg_global_styles_render_svg_filters' );
add_action( 'in_admin_header', 'gutenberg_global_styles_render_svg_filters' );