Skip to content

Commit

Permalink
Revert "Duotone: Limit SVG filter output to used filters" (#49102)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Lende authored Mar 15, 2023
1 parent 0f38d66 commit d9a96d9
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 358 deletions.
190 changes: 62 additions & 128 deletions lib/block-supports/duotone.php
Original file line number Diff line number Diff line change
Expand Up @@ -436,67 +436,54 @@ function gutenberg_render_duotone_support( $block_content, $block ) {
$duotone_support = _wp_array_get( $block_type->supports, array( 'color', '__experimentalDuotone' ), false );
}

// The block should have a duotone attribute or have duotone defined in its theme.json to be processed.
$has_duotone_attribute = isset( $block['attrs']['style']['color']['duotone'] );
$has_global_styles_duotone = array_key_exists( $block['blockName'], WP_Duotone::$global_styles_block_names );
$has_duotone_attribute = isset( $block['attrs']['style']['color']['duotone'] );

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

// Generate the pieces needed for rendering a duotone to the page.
if ( $has_duotone_attribute ) {

// Possible values for duotone attribute:
// 1. Array of colors - e.g. array('#000000', '#ffffff').
// 2. Variable for an existing Duotone preset - e.g. 'var:preset|duotone|green-blue' or 'var(--wp--preset--duotone--green-blue)''
// 3. A CSS string - e.g. 'unset' to remove globally applied duotone.

$duotone_attr = $block['attrs']['style']['color']['duotone'];
$is_preset = is_string( $duotone_attr ) && WP_Duotone::is_preset( $duotone_attr );
$is_css = is_string( $duotone_attr ) && ! $is_preset;
$is_custom = is_array( $duotone_attr );

if ( $is_preset ) {

// Extract the slug from the preset variable string.
$slug = WP_Duotone::gutenberg_get_slug_from_attr( $duotone_attr );

// Utilize existing preset CSS custom property.
$filter_property = "var(--wp--preset--duotone--$slug)";

WP_Duotone::$output[ $slug ] = WP_Duotone::$global_styles_presets[ $slug ];
// Possible values for duotone attribute:
// 1. Array of colors - e.g. array('#000000', '#ffffff').
// 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'];

} elseif ( $is_css ) {
// Build a unique slug for the filter based on the CSS value.
$slug = wp_unique_id( sanitize_key( $duotone_attr . '-' ) );
$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 );

// 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.
$slug = wp_unique_id( sanitize_key( implode( '-', $duotone_attr ) . '-' ) );

$filter_data = array(
'slug' => $slug,
'colors' => $duotone_attr,
);
// Build a customized CSS filter property for unique slug.
$filter_property = gutenberg_get_duotone_filter_property( $filter_data );

WP_Duotone::$output[ $slug ] = $filter_data;
}
} elseif ( $has_global_styles_duotone ) {
$slug = WP_Duotone::$global_styles_block_names[ $block['blockName'] ];
// 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 );

// Utilize existing preset CSS custom property.
$filter_property = "var(--wp--preset--duotone--$slug)";
} 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.
$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,
);

WP_Duotone::$output[ $slug ] = WP_Duotone::$global_styles_presets[ $slug ];
// 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.
Expand All @@ -506,11 +493,6 @@ function gutenberg_render_duotone_support( $block_content, $block ) {
// Build the CSS selectors to which the filter will be applied.
$selector = WP_Theme_JSON_Gutenberg::scope_selector( '.' . $filter_id, $duotone_support );

// We only want to add the selector if we have it in the output already, essentially skipping 'unset'.
if ( array_key_exists( $slug, WP_Duotone::$output ) ) {
WP_Duotone::$output[ $slug ]['selector'] = $selector;
}

// Calling gutenberg_style_engine_get_stylesheet_from_css_rules ensures that
// the styles are rendered in an inline for block supports because we're
// using the `context` option to instruct it so.
Expand All @@ -532,6 +514,33 @@ function gutenberg_render_duotone_support( $block_content, $block ) {
)
);

// 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 ) {
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 ) {
/*
* Simply accessing el.offsetHeight flushes layout and style
* changes in WebKit without having to wait for setTimeout.
*/
printf(
'<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="', '/' ) . '/',
Expand All @@ -541,81 +550,6 @@ function gutenberg_render_duotone_support( $block_content, $block ) {
);
}


add_action(
'wp_footer',
static function () {

foreach ( WP_Duotone::$output as $filter_data ) {

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

echo $filter_svg;

// This is for classic themes - in block themes, the CSS is added in the head via the value_func.
if ( ! wp_is_block_theme() ) {
$duotone_preset_css_var = WP_Theme_JSON_Gutenberg::get_preset_css_var( array( 'color', 'duotone' ), $filter_data['slug'] );
wp_add_inline_style( 'core-block-supports', 'body{' . $duotone_preset_css_var . ' :' . $filter_property . ';}' );
}

global $is_safari;
if ( $is_safari ) {
duotone_safari_rerender_hack( $filter_data['selector'] );
}
}
}
);

/**
* Appends the used duotone fitler CSS Vars to the inline global styles CSS
*/
add_action(
'wp_enqueue_scripts',
static function() {

if ( empty( WP_Duotone::$output ) ) {
return;
}

$duotone_css_vars = '';

foreach ( WP_Duotone::$output as $filter_data ) {
if ( ! array_key_exists( $filter_data['slug'], WP_Duotone::$global_styles_presets ) ) {
continue;
}

$filter_property = gutenberg_get_duotone_filter_property( $filter_data );

$duotone_preset_css_var = WP_Theme_JSON_Gutenberg::get_preset_css_var( array( 'color', 'duotone' ), $filter_data['slug'] );
$duotone_css_vars .= $duotone_preset_css_var . ': ' . $filter_property . ';';
}

if ( ! empty( $duotone_css_vars ) ) {
wp_add_inline_style( 'global-styles', 'body{' . $duotone_css_vars . '}' );
}
},
11
);

/**
* 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.
*
* @param string $selector The selector to apply the hack for.
*/
function duotone_safari_rerender_hack( $selector ) {
/*
* Simply accessing el.offsetHeight flushes layout and style
* changes in WebKit without having to wait for setTimeout.
*/
printf(
'<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 )
);
}

// Register the block support.
WP_Block_Supports::get_instance()->register(
'duotone',
Expand Down
150 changes: 0 additions & 150 deletions lib/class-wp-duotone.php

This file was deleted.

Loading

1 comment on commit d9a96d9

@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 d9a96d9.
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/4428532118
📝 Reported issues:

Please sign in to comment.