Skip to content

Commit

Permalink
Revert "Duotone: Limit SVG filter output to used filters (#48995)"
Browse files Browse the repository at this point in the history
This reverts commit 0bb7a9c.
  • Loading branch information
ajlende authored Mar 15, 2023
1 parent 0f38d66 commit 10e18d5
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

0 comments on commit 10e18d5

Please sign in to comment.