Make WordPress Core


Ignore:
Timestamp:
02/17/2022 04:16:59 PM (3 years ago)
Author:
audrasjb
Message:

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/block-supports/duotone.php

    r52301 r52757  
    353353}
    354354
    355 
    356 /**
    357  * Registers the style and colors block attributes for block types that support it.
    358  *
    359  * @since 5.8.0
    360  * @access private
    361  *
    362  * @param WP_Block_Type $block_type Block Type.
    363  */
    364 function wp_register_duotone_support( $block_type ) {
    365     $has_duotone_support = false;
    366     if ( property_exists( $block_type, 'supports' ) ) {
    367         $has_duotone_support = _wp_array_get( $block_type->supports, array( 'color', '__experimentalDuotone' ), false );
    368     }
    369 
    370     if ( $has_duotone_support ) {
    371         if ( ! $block_type->attributes ) {
    372             $block_type->attributes = array();
    373         }
    374 
    375         if ( ! array_key_exists( 'style', $block_type->attributes ) ) {
    376             $block_type->attributes['style'] = array(
    377                 'type' => 'object',
    378             );
    379         }
    380     }
    381 }
    382 
    383 /**
    384  * Renders the duotone filter SVG and returns the CSS filter property to
    385  * reference the rendered SVG.
     355/**
     356 * Returns the prefixed id for the duotone filter for use as a CSS id.
     357 *
     358 * @since 5.9.1
     359 * @access private
     360 *
     361 * @param array $preset Duotone preset value as seen in theme.json.
     362 * @return string Duotone filter CSS id.
     363 */
     364function wp_get_duotone_filter_id( $preset ) {
     365    if ( ! isset( $preset['slug'] ) ) {
     366        return '';
     367    }
     368
     369    return 'wp-duotone-' . $preset['slug'];
     370}
     371
     372/**
     373 * Returns the CSS filter property url to reference the rendered SVG.
    386374 *
    387375 * @since 5.9.0
    388376 * @access private
    389 
     377 *
    390378 * @param array $preset Duotone preset value as seen in theme.json.
    391  * @return string Duotone CSS filter property.
    392  */
    393 function wp_render_duotone_filter_preset( $preset ) {
    394     $duotone_id     = $preset['slug'];
    395     $duotone_colors = $preset['colors'];
    396     $filter_id      = 'wp-duotone-' . $duotone_id;
     379 * @return string Duotone CSS filter property url value.
     380 */
     381function wp_get_duotone_filter_property( $preset ) {
     382    $filter_id = wp_get_duotone_filter_id( $preset );
     383    return "url('#" . $filter_id . "')";
     384}
     385
     386/**
     387 * Returns the duotone filter SVG string for the preset.
     388 *
     389 * @since 5.9.1
     390 * @access private
     391 *
     392 * @param array $preset Duotone preset value as seen in theme.json.
     393 * @return string Duotone SVG filter.
     394 */
     395function wp_get_duotone_filter_svg( $preset ) {
     396    $filter_id = wp_get_duotone_filter_id( $preset );
     397
    397398    $duotone_values = array(
    398399        'r' => array(),
     
    401402        'a' => array(),
    402403    );
    403     foreach ( $duotone_colors as $color_str ) {
     404
     405    if ( ! isset( $preset['colors'] ) || ! is_array( $preset['colors'] ) ) {
     406        $preset['colors'] = array();
     407    }
     408
     409    foreach ( $preset['colors'] as $color_str ) {
    404410        $color = wp_tinycolor_string_to_rgb( $color_str );
    405411
     
    457463    }
    458464
    459     add_action(
    460         // Safari doesn't render SVG filters defined in data URIs,
    461         // and SVG filters won't render in the head of a document,
    462         // so the next best place to put the SVG is in the footer.
    463         is_admin() ? 'admin_footer' : 'wp_footer',
    464         function () use ( $svg ) {
    465             echo $svg;
     465    return $svg;
     466}
     467
     468/**
     469 * Registers the style and colors block attributes for block types that support it.
     470 *
     471 * @since 5.8.0
     472 * @access private
     473 *
     474 * @param WP_Block_Type $block_type Block Type.
     475 */
     476function wp_register_duotone_support( $block_type ) {
     477    $has_duotone_support = false;
     478    if ( property_exists( $block_type, 'supports' ) ) {
     479        $has_duotone_support = _wp_array_get( $block_type->supports, array( 'color', '__experimentalDuotone' ), false );
     480    }
     481
     482    if ( $has_duotone_support ) {
     483        if ( ! $block_type->attributes ) {
     484            $block_type->attributes = array();
    466485        }
    467     );
    468 
    469     return "url('#" . $filter_id . "')";
     486
     487        if ( ! array_key_exists( 'style', $block_type->attributes ) ) {
     488            $block_type->attributes['style'] = array(
     489                'type' => 'object',
     490            );
     491        }
     492    }
    470493}
    471494
     
    501524        'colors' => $block['attrs']['style']['color']['duotone'],
    502525    );
    503     $filter_property = wp_render_duotone_filter_preset( $filter_preset );
    504     $filter_id       = 'wp-duotone-' . $filter_preset['slug'];
     526    $filter_property = wp_get_duotone_filter_property( $filter_preset );
     527    $filter_id       = wp_get_duotone_filter_id( $filter_preset );
     528    $filter_svg      = wp_get_duotone_filter_svg( $filter_preset );
    505529
    506530    $scope     = '.' . $filter_id;
     
    521545    wp_add_inline_style( $filter_id, $filter_style );
    522546    wp_enqueue_style( $filter_id );
     547
     548    add_action(
     549        'wp_footer',
     550        static function () use ( $filter_svg, $selector ) {
     551            echo $filter_svg;
     552
     553            /*
     554             * Safari renders elements incorrectly on first paint when the SVG
     555             * filter comes after the content that it is filtering, so we force
     556             * a repaint with a WebKit hack which solves the issue.
     557             */
     558            global $is_safari;
     559            if ( $is_safari ) {
     560                printf(
     561                    // Simply accessing el.offsetHeight flushes layout and style
     562                    // changes in WebKit without having to wait for setTimeout.
     563                    '<script>( function() { var el = document.querySelector( %s ); var display = el.style.display; el.style.display = "none"; el.offsetHeight; el.style.display = display; } )();</script>',
     564                    wp_json_encode( $selector )
     565                );
     566            }
     567        }
     568    );
    523569
    524570    // Like the layout hook, this assumes the hook only applies to blocks with a single wrapper.
     
    539585);
    540586add_filter( 'render_block', 'wp_render_duotone_support', 10, 2 );
     587
     588/**
     589 * Render the SVG filters supplied by theme.json.
     590 *
     591 * Note that this doesn't render the per-block user-defined
     592 * filters which are handled by wp_render_duotone_support,
     593 * but it should be rendered in the same location as those to satisfy
     594 * Safari's rendering quirks.
     595 *
     596 * @since 5.9.1
     597 */
     598function wp_global_styles_render_svg_filters() {
     599    $filters = wp_get_global_styles_svg_filters();
     600    if ( ! empty( $filters ) ) {
     601        echo $filters;
     602    }
     603}
     604add_action( 'wp_body_open', 'wp_global_styles_render_svg_filters' );
Note: See TracChangeset for help on using the changeset viewer.