mirror of
https://github.com/WordPress/WordPress.git
synced 2024-12-31 13:37:51 +01:00
Editor: Backport Duotone fixes for 5.9.1.
This changeset is a backport for the following Gutenberg PRs: - Fix duotone theme cache gutenberg#36236 - Fix duotone render in non-fse themes gutenberg#37954 - Duotone: Allow users to specify custom filters gutenberg#38442 Props oandregal, scruffian, Mamaduka. See #55179. Built from https://develop.svn.wordpress.org/trunk@52757 git-svn-id: http://core.svn.wordpress.org/trunk@52346 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
9ac43b6ade
commit
26667ab0e1
@ -352,55 +352,61 @@ function wp_tinycolor_string_to_rgb( $color_str ) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Registers the style and colors block attributes for block types that support it.
|
||||
* Returns the prefixed id for the duotone filter for use as a CSS id.
|
||||
*
|
||||
* @since 5.8.0
|
||||
* @since 5.9.1
|
||||
* @access private
|
||||
*
|
||||
* @param WP_Block_Type $block_type Block Type.
|
||||
* @param array $preset Duotone preset value as seen in theme.json.
|
||||
* @return string Duotone filter CSS id.
|
||||
*/
|
||||
function wp_register_duotone_support( $block_type ) {
|
||||
$has_duotone_support = false;
|
||||
if ( property_exists( $block_type, 'supports' ) ) {
|
||||
$has_duotone_support = _wp_array_get( $block_type->supports, array( 'color', '__experimentalDuotone' ), false );
|
||||
function wp_get_duotone_filter_id( $preset ) {
|
||||
if ( ! isset( $preset['slug'] ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( $has_duotone_support ) {
|
||||
if ( ! $block_type->attributes ) {
|
||||
$block_type->attributes = array();
|
||||
}
|
||||
|
||||
if ( ! array_key_exists( 'style', $block_type->attributes ) ) {
|
||||
$block_type->attributes['style'] = array(
|
||||
'type' => 'object',
|
||||
);
|
||||
}
|
||||
}
|
||||
return 'wp-duotone-' . $preset['slug'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the duotone filter SVG and returns the CSS filter property to
|
||||
* reference the rendered SVG.
|
||||
* Returns the CSS filter property url to reference the rendered SVG.
|
||||
*
|
||||
* @since 5.9.0
|
||||
* @access private
|
||||
|
||||
*
|
||||
* @param array $preset Duotone preset value as seen in theme.json.
|
||||
* @return string Duotone CSS filter property.
|
||||
* @return string Duotone CSS filter property url value.
|
||||
*/
|
||||
function wp_render_duotone_filter_preset( $preset ) {
|
||||
$duotone_id = $preset['slug'];
|
||||
$duotone_colors = $preset['colors'];
|
||||
$filter_id = 'wp-duotone-' . $duotone_id;
|
||||
function wp_get_duotone_filter_property( $preset ) {
|
||||
$filter_id = wp_get_duotone_filter_id( $preset );
|
||||
return "url('#" . $filter_id . "')";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the duotone filter SVG string for the preset.
|
||||
*
|
||||
* @since 5.9.1
|
||||
* @access private
|
||||
*
|
||||
* @param array $preset Duotone preset value as seen in theme.json.
|
||||
* @return string Duotone SVG filter.
|
||||
*/
|
||||
function wp_get_duotone_filter_svg( $preset ) {
|
||||
$filter_id = wp_get_duotone_filter_id( $preset );
|
||||
|
||||
$duotone_values = array(
|
||||
'r' => array(),
|
||||
'g' => array(),
|
||||
'b' => array(),
|
||||
'a' => array(),
|
||||
);
|
||||
foreach ( $duotone_colors as $color_str ) {
|
||||
|
||||
if ( ! isset( $preset['colors'] ) || ! is_array( $preset['colors'] ) ) {
|
||||
$preset['colors'] = array();
|
||||
}
|
||||
|
||||
foreach ( $preset['colors'] as $color_str ) {
|
||||
$color = wp_tinycolor_string_to_rgb( $color_str );
|
||||
|
||||
$duotone_values['r'][] = $color['r'] / 255;
|
||||
@ -456,17 +462,34 @@ function wp_render_duotone_filter_preset( $preset ) {
|
||||
$svg = trim( $svg );
|
||||
}
|
||||
|
||||
add_action(
|
||||
// Safari doesn't render SVG filters defined in data URIs,
|
||||
// and SVG filters won't render in the head of a document,
|
||||
// so the next best place to put the SVG is in the footer.
|
||||
is_admin() ? 'admin_footer' : 'wp_footer',
|
||||
function () use ( $svg ) {
|
||||
echo $svg;
|
||||
}
|
||||
);
|
||||
return $svg;
|
||||
}
|
||||
|
||||
return "url('#" . $filter_id . "')";
|
||||
/**
|
||||
* Registers the style and colors block attributes for block types that support it.
|
||||
*
|
||||
* @since 5.8.0
|
||||
* @access private
|
||||
*
|
||||
* @param WP_Block_Type $block_type Block Type.
|
||||
*/
|
||||
function wp_register_duotone_support( $block_type ) {
|
||||
$has_duotone_support = false;
|
||||
if ( property_exists( $block_type, 'supports' ) ) {
|
||||
$has_duotone_support = _wp_array_get( $block_type->supports, array( 'color', '__experimentalDuotone' ), false );
|
||||
}
|
||||
|
||||
if ( $has_duotone_support ) {
|
||||
if ( ! $block_type->attributes ) {
|
||||
$block_type->attributes = array();
|
||||
}
|
||||
|
||||
if ( ! array_key_exists( 'style', $block_type->attributes ) ) {
|
||||
$block_type->attributes['style'] = array(
|
||||
'type' => 'object',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -500,8 +523,9 @@ function wp_render_duotone_support( $block_content, $block ) {
|
||||
'slug' => uniqid(),
|
||||
'colors' => $block['attrs']['style']['color']['duotone'],
|
||||
);
|
||||
$filter_property = wp_render_duotone_filter_preset( $filter_preset );
|
||||
$filter_id = 'wp-duotone-' . $filter_preset['slug'];
|
||||
$filter_property = wp_get_duotone_filter_property( $filter_preset );
|
||||
$filter_id = wp_get_duotone_filter_id( $filter_preset );
|
||||
$filter_svg = wp_get_duotone_filter_svg( $filter_preset );
|
||||
|
||||
$scope = '.' . $filter_id;
|
||||
$selectors = explode( ',', $duotone_support );
|
||||
@ -521,6 +545,28 @@ function wp_render_duotone_support( $block_content, $block ) {
|
||||
wp_add_inline_style( $filter_id, $filter_style );
|
||||
wp_enqueue_style( $filter_id );
|
||||
|
||||
add_action(
|
||||
'wp_footer',
|
||||
static function () use ( $filter_svg, $selector ) {
|
||||
echo $filter_svg;
|
||||
|
||||
/*
|
||||
* Safari renders elements incorrectly on first paint when the SVG
|
||||
* filter comes after the content that it is filtering, so we force
|
||||
* a repaint with a WebKit hack which solves the issue.
|
||||
*/
|
||||
global $is_safari;
|
||||
if ( $is_safari ) {
|
||||
printf(
|
||||
// Simply accessing el.offsetHeight flushes layout and style
|
||||
// changes in WebKit without having to wait for setTimeout.
|
||||
'<script>( function() { var el = document.querySelector( %s ); var display = el.style.display; el.style.display = "none"; el.offsetHeight; el.style.display = display; } )();</script>',
|
||||
wp_json_encode( $selector )
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Like the layout hook, this assumes the hook only applies to blocks with a single wrapper.
|
||||
return preg_replace(
|
||||
'/' . preg_quote( 'class="', '/' ) . '/',
|
||||
@ -538,3 +584,21 @@ WP_Block_Supports::get_instance()->register(
|
||||
)
|
||||
);
|
||||
add_filter( 'render_block', 'wp_render_duotone_support', 10, 2 );
|
||||
|
||||
/**
|
||||
* Render 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 in the same location as those to satisfy
|
||||
* Safari's rendering quirks.
|
||||
*
|
||||
* @since 5.9.1
|
||||
*/
|
||||
function wp_global_styles_render_svg_filters() {
|
||||
$filters = wp_get_global_styles_svg_filters();
|
||||
if ( ! empty( $filters ) ) {
|
||||
echo $filters;
|
||||
}
|
||||
}
|
||||
add_action( 'wp_body_open', 'wp_global_styles_render_svg_filters' );
|
||||
|
@ -132,7 +132,7 @@ class WP_Theme_JSON {
|
||||
'path' => array( 'color', 'duotone' ),
|
||||
'override' => true,
|
||||
'use_default_names' => false,
|
||||
'value_func' => 'wp_render_duotone_filter_preset',
|
||||
'value_func' => 'wp_get_duotone_filter_property',
|
||||
'css_vars' => '--wp--preset--duotone--$slug',
|
||||
'classes' => array(),
|
||||
'properties' => array( 'filter' ),
|
||||
@ -1586,6 +1586,40 @@ class WP_Theme_JSON {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts all filter (duotone) presets into SVGs.
|
||||
*
|
||||
* @since 5.9.1
|
||||
*
|
||||
* @param array $origins List of origins to process.
|
||||
* @return string SVG filters.
|
||||
*/
|
||||
public function get_svg_filters( $origins ) {
|
||||
$blocks_metadata = static::get_blocks_metadata();
|
||||
$setting_nodes = static::get_setting_nodes( $this->theme_json, $blocks_metadata );
|
||||
|
||||
foreach ( $setting_nodes as $metadata ) {
|
||||
$node = _wp_array_get( $this->theme_json, $metadata['path'], array() );
|
||||
if ( empty( $node['color']['duotone'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$duotone_presets = $node['color']['duotone'];
|
||||
|
||||
$filters = '';
|
||||
foreach ( $origins as $origin ) {
|
||||
if ( ! isset( $duotone_presets[ $origin ] ) ) {
|
||||
continue;
|
||||
}
|
||||
foreach ( $duotone_presets[ $origin ] as $duotone_preset ) {
|
||||
$filters .= wp_get_duotone_filter_svg( $duotone_preset );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a presets should be overridden or not.
|
||||
*
|
||||
|
@ -4208,3 +4208,20 @@ function _excerpt_render_inner_columns_blocks( $columns, $allowed_blocks ) {
|
||||
_deprecated_function( __FUNCTION__, '5.8.0', '_excerpt_render_inner_blocks()' );
|
||||
return _excerpt_render_inner_blocks( $columns, $allowed_blocks );
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the duotone filter SVG and returns the CSS filter property to
|
||||
* reference the rendered SVG.
|
||||
*
|
||||
* @since 5.9.0
|
||||
* @deprecated 5.9.1 Use `wp_get_duotone_filter_property` introduced in 5.9.1.
|
||||
*
|
||||
* @see wp_get_duotone_filter_property()
|
||||
*
|
||||
* @param array $preset Duotone preset value as seen in theme.json.
|
||||
* @return string Duotone CSS filter property.
|
||||
*/
|
||||
function wp_render_duotone_filter_preset( $preset ) {
|
||||
_deprecated_function( __FUNCTION__, '5.9.1', 'wp_get_duotone_filter_property()' );
|
||||
return wp_get_duotone_filter_property( $preset );
|
||||
}
|
||||
|
@ -150,3 +150,45 @@ function wp_get_global_stylesheet( $types = array() ) {
|
||||
|
||||
return $stylesheet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string containing the SVGs to be referenced as filters (duotone).
|
||||
*
|
||||
* @since 5.9.1
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function wp_get_global_styles_svg_filters() {
|
||||
// Return cached value if it can be used and exists.
|
||||
// It's cached by theme to make sure that theme switching clears the cache.
|
||||
$can_use_cached = (
|
||||
( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) &&
|
||||
( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ) &&
|
||||
( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) &&
|
||||
! is_admin()
|
||||
);
|
||||
$transient_name = 'global_styles_svg_filters_' . get_stylesheet();
|
||||
if ( $can_use_cached ) {
|
||||
$cached = get_transient( $transient_name );
|
||||
if ( $cached ) {
|
||||
return $cached;
|
||||
}
|
||||
}
|
||||
|
||||
$supports_theme_json = WP_Theme_JSON_Resolver::theme_has_support();
|
||||
|
||||
$origins = array( 'default', 'theme', 'custom' );
|
||||
if ( ! $supports_theme_json ) {
|
||||
$origins = array( 'default' );
|
||||
}
|
||||
|
||||
$tree = WP_Theme_JSON_Resolver::get_merged_data();
|
||||
$svgs = $tree->get_svg_filters( $origins );
|
||||
|
||||
if ( $can_use_cached ) {
|
||||
// Cache for a minute, same as wp_get_global_stylesheet.
|
||||
set_transient( $transient_name, $svgs, MINUTE_IN_SECONDS );
|
||||
}
|
||||
|
||||
return $svgs;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
* @global string $wp_version
|
||||
*/
|
||||
$wp_version = '6.0-alpha-52755';
|
||||
$wp_version = '6.0-alpha-52757';
|
||||
|
||||
/**
|
||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||
|
Loading…
Reference in New Issue
Block a user