Make WordPress Core

Changeset 52757


Ignore:
Timestamp:
02/17/2022 04:16:59 PM (2 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.

Location:
trunk/src/wp-includes
Files:
4 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' );
  • trunk/src/wp-includes/class-wp-theme-json.php

    r52744 r52757  
    133133            'override'          => true,
    134134            'use_default_names' => false,
    135             'value_func'        => 'wp_render_duotone_filter_preset',
     135            'value_func'        => 'wp_get_duotone_filter_property',
    136136            'css_vars'          => '--wp--preset--duotone--$slug',
    137137            'classes'           => array(),
     
    15881588
    15891589    /**
     1590     * Converts all filter (duotone) presets into SVGs.
     1591     *
     1592     * @since 5.9.1
     1593     *
     1594     * @param array $origins List of origins to process.
     1595     * @return string SVG filters.
     1596     */
     1597    public function get_svg_filters( $origins ) {
     1598        $blocks_metadata = static::get_blocks_metadata();
     1599        $setting_nodes   = static::get_setting_nodes( $this->theme_json, $blocks_metadata );
     1600
     1601        foreach ( $setting_nodes as $metadata ) {
     1602            $node = _wp_array_get( $this->theme_json, $metadata['path'], array() );
     1603            if ( empty( $node['color']['duotone'] ) ) {
     1604                continue;
     1605            }
     1606
     1607            $duotone_presets = $node['color']['duotone'];
     1608
     1609            $filters = '';
     1610            foreach ( $origins as $origin ) {
     1611                if ( ! isset( $duotone_presets[ $origin ] ) ) {
     1612                    continue;
     1613                }
     1614                foreach ( $duotone_presets[ $origin ] as $duotone_preset ) {
     1615                    $filters .= wp_get_duotone_filter_svg( $duotone_preset );
     1616                }
     1617            }
     1618        }
     1619
     1620        return $filters;
     1621    }
     1622
     1623    /**
    15901624     * Returns whether a presets should be overridden or not.
    15911625     *
  • trunk/src/wp-includes/deprecated.php

    r52425 r52757  
    42094209    return _excerpt_render_inner_blocks( $columns, $allowed_blocks );
    42104210}
     4211
     4212/**
     4213 * Renders the duotone filter SVG and returns the CSS filter property to
     4214 * reference the rendered SVG.
     4215 *
     4216 * @since 5.9.0
     4217 * @deprecated 5.9.1 Use `wp_get_duotone_filter_property` introduced in 5.9.1.
     4218 *
     4219 * @see wp_get_duotone_filter_property()
     4220 *
     4221 * @param array $preset Duotone preset value as seen in theme.json.
     4222 * @return string Duotone CSS filter property.
     4223 */
     4224function wp_render_duotone_filter_preset( $preset ) {
     4225    _deprecated_function( __FUNCTION__, '5.9.1', 'wp_get_duotone_filter_property()' );
     4226    return wp_get_duotone_filter_property( $preset );
     4227}
  • trunk/src/wp-includes/global-styles-and-settings.php

    r52676 r52757  
    151151    return $stylesheet;
    152152}
     153
     154/**
     155 * Returns a string containing the SVGs to be referenced as filters (duotone).
     156 *
     157 * @since 5.9.1
     158 *
     159 * @return string
     160 */
     161function wp_get_global_styles_svg_filters() {
     162    // Return cached value if it can be used and exists.
     163    // It's cached by theme to make sure that theme switching clears the cache.
     164    $can_use_cached = (
     165        ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) &&
     166        ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ) &&
     167        ( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) &&
     168        ! is_admin()
     169    );
     170    $transient_name = 'global_styles_svg_filters_' . get_stylesheet();
     171    if ( $can_use_cached ) {
     172        $cached = get_transient( $transient_name );
     173        if ( $cached ) {
     174            return $cached;
     175        }
     176    }
     177
     178    $supports_theme_json = WP_Theme_JSON_Resolver::theme_has_support();
     179
     180    $origins = array( 'default', 'theme', 'custom' );
     181    if ( ! $supports_theme_json ) {
     182        $origins = array( 'default' );
     183    }
     184
     185    $tree = WP_Theme_JSON_Resolver::get_merged_data();
     186    $svgs = $tree->get_svg_filters( $origins );
     187
     188    if ( $can_use_cached ) {
     189        // Cache for a minute, same as wp_get_global_stylesheet.
     190        set_transient( $transient_name, $svgs, MINUTE_IN_SECONDS );
     191    }
     192
     193    return $svgs;
     194}
Note: See TracChangeset for help on using the changeset viewer.