-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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: Limit SVG filter output to used filters #48995
Conversation
This doesn't do anything at the moment. On block render, it checks if the block has duotone filters set via theme.json/global styles/custom styles and returns early if not.
Co-authored-by: scruffian <[email protected]>
…utput. Name could still be better.
Flaky tests detected in f5499b4. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/4420262538
|
Refactored out duotone specific code from theme json gutenberg globla styles. Switched theme_json_register_declarations from action to filter.
Doesn't seem like a legitimately useful filter at the moment. Only for us to be able to use global styles in our duotone-specific output.
We were already getting the presets via the global settings, so the filter was unnecessary.
The filter isn't necesary for us to access what we need. I've removed the refactor as it would be a larger change that can be done in a different PR if needed.
@@ -144,7 +144,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' ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure the entire duotone section of PRESETS_METADATA
can be removed since generating the preset is done by duotone.php now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, it looks like the constructor still uses it for keying presets by origin which we need later. That being said, I still think we can remove the css_vars
key and have that solely defined in duotone.php as part of the cleanup.
Also, I noticed that the theme.json styles.blocks['core/block'].filter.duotone
filters are being applied on the frontend, but not the editor, so there are also likely changes that need to be done in the block-editor duotone.js hook and use-global-styles-output.js as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The properties
key is also probably redundant now since we're no longer generating properties here.
return array( | ||
'pipe-slug' => array( 'var:preset|duotone|blue-orange', 'blue-orange' ), | ||
'css-var' => array( 'var(--wp--preset--duotone--blue-orange)', 'blue-orange' ), | ||
'css-var-weird-chars' => array( 'var(--wp--preset--duotone--.)', '.' ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.
isn't a valid identifier token according to the CSS spec.
CSS custom properties always take the first --
branch of this railroad diagram and then allow for [a-zA-Z0-9_-]
and a set of non-ascii code points.
It looks like slugs in WordPress are handled by sanitize_title_with_dashes()
according to this Stack Exchange answer.
So I would be inclined to further restrict the non-ascii section to characters that get output from that function as well.
And I think somewhere in the global styles code, we also restrict slugs to not contain consecutive hyphens (--
) since those would get converted to pipes (|
) in the var:
syntax.
For some reason, the render_block filter runs even on blocks that are not included on the page. So, if you have a duotone filter defined in your theme.json, such as for the core/post-featured-image block, it will run the block filter even if no featured image is set. As a result, the duotonen defined in theme.json per block would get output even if that block wasn't in use. The only reliable check I could find to determine if the block was in use or not was to check the block content. By bailing early if no block content, we avoid adding unused SVG to the output.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is looking great, and in my testing its working well.
IMO we should merge this and deal with any more improvements in followups, as this PR is already very large.
* | ||
* @access public | ||
*/ | ||
class WP_Duotone { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did we figure out if files in the lib
folder get the _Gutenberg
suffix. If not, this should have that suffix because we want to be able to make changes in Gutenberg without affecting core by referencing the _Gutenberg
version.
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 ); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can get this working without adding this to the public API. The only place the css_vars
for frontend duotone is being used is within the block supports now, and we already have it hardcoded a couple times there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That'd be lovely. For the record, I saw that this PR was reverted at #49102
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This version of the PR did get reverted, and then was cleaned up and merged in this PR: #49103
We were able to get the PR merged without adding anything to lib/class-wp-theme-json-gutenberg.php
Rework of #48374
Fixes #38299.
What?
This PR only adds the needed duotone code to the frontend output if that duotone definition is being used.
Why?
There are currently eight globally defined duotone styles, and all of their CSS and SVG definitions are output on the frontend of a WordPress website, even if no images are using the duotone filters. The base raw HTML from TT3 on the Sherbert theme variation results in a 76.4kb request. Without any SVG or duotone-related code, the same page HTML is 67.4kb, which means there is up to 9kb of unnecessary duotone-related HTML on every request.
How?
There's quite a bit of changes required to make this happen. We've gone with a route that adds a new
WP_Duotone
class that handles what filters need to be added to the page based on what duotone filters, if any, are in use. Here's a general overview of the high-level changes being made, and why:1. Remove all duotone output from global styles
These are handled by removing the actions related to SVG filters:
2. Register all duotone filters from global styles and store in the WP_Duotone class
WP_Duotone::$global_styles_presets
is an array that scrapes all of the global styles duotone filters. These could be defined from theme.json globally, per theme, or in custom global styles. We need to do this to have quick access to the duotone filter definitions if we come across a block that needs to access these styles.3. Register all block-level duotone filters from global styles and store in the WP_Duotone class
WP_Duotone::$global_styles_block_names
is an array that scrapes all of the blocks that use a duotone filter from global styles, and stores the slug of the duotone filter it uses, such asdefault-filter
,blue-orange
, etc. We need to do this in order to decide if a block being rendered has a duotone filter we need to apply to it.4. Process all blocks to determine the correct duotone output needed
This is the same as before, but we're only outputting the duotone code if needed. On the 'render_block' filter, we process every block and determine:
WP_Duotone::$output
5. Output the CSS
On the
'wp_enqueue_scripts' action, output all the necessary CSS for duotone filters collected from
WP_Duotone::$output`.6. Output the SVG
On the
'wp_footer' action, output all necessary SVG for duotone filters from
WP_Duotone::$output`.Testing Instructions
These are the different types of Duotone that need testing:
For each of these it possible to set the duotone to a
preset
value, a custom value, orunset
.For presets, it is possible to set them using two different formats:
var:preset|duotone|blue-orange
orvar(--wp--preset--duotone--blue-orange)
.It is also important to test that only the SVG filters and CSS that is needed on the page is output - rather than outputting all the presets even if they aren't used.
To test an individual block:
To test Global Styles
Testing Instructions for Keyboard
Screenshots or screencast