Make WordPress Core

Changeset 54260


Ignore:
Timestamp:
09/20/2022 03:41:44 PM (2 years ago)
Author:
hellofromTonya
Message:

Editor: Introduces fluid typography and uses Style Engine.

This commit introduces fluid typography block supports and switches to use the Style Engine for typography and colors.

The motivation for fluid typography block supports:

"Fluid typography" describes how a site's font sizes adapt to every change in screen size, for example, growing larger as the viewport width increases, or smaller as it decreases.

Font sizes can smoothly scale between minimum and maximum viewport widths.

Typography changes introduced from Gutenberg:

  • Uses the Style Engine to generate the CSS and classnames in wp_apply_typography_support().
  • Introduces wp_typography_get_preset_inline_style_value() for backwards-compatibility.
  • Introduces a private internal function called wp_get_typography_value_and_unit(), for checking and getting typography unit and value.
  • Introduces a private internal function called wp_get_computed_fluid_typography_value(), for an internal implementation of CSS clamp().
  • Deprecates wp_typography_get_css_variable_inline_style().

References:

Follow-up to [53076], [52302], [52069], [51089], [50761], [49226].

Props ramonopoly, youknowriad, aristath, oandregal, aaronrobertshaw, cbirdsong, jorgefilipecosta, ironprogrammer, hellofromTonya.
See #56467.

Location:
trunk
Files:
5 edited

Legend:

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

    r53076 r54260  
    6666 *
    6767 * @since 5.6.0
     68 * @since 6.1.0 Used the style engine to generate CSS and classnames.
    6869 * @access private
    6970 *
     
    8586        return array();
    8687    }
    87 
    88     $attributes = array();
    89     $classes    = array();
    90     $styles     = array();
    9188
    9289    $has_font_family_support     = _wp_array_get( $typography_supports, array( '__experimentalFontFamily' ), false );
     
    9996    $has_text_transform_support  = _wp_array_get( $typography_supports, array( '__experimentalTextTransform' ), false );
    10097
    101     if ( $has_font_size_support && ! wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontSize' ) ) {
    102         $has_named_font_size  = array_key_exists( 'fontSize', $block_attributes );
    103         $has_custom_font_size = isset( $block_attributes['style']['typography']['fontSize'] );
    104 
    105         if ( $has_named_font_size ) {
    106             $classes[] = sprintf( 'has-%s-font-size', _wp_to_kebab_case( $block_attributes['fontSize'] ) );
    107         } elseif ( $has_custom_font_size ) {
    108             $styles[] = sprintf( 'font-size: %s;', $block_attributes['style']['typography']['fontSize'] );
    109         }
    110     }
    111 
    112     if ( $has_font_family_support && ! wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontFamily' ) ) {
    113         $has_named_font_family  = array_key_exists( 'fontFamily', $block_attributes );
    114         $has_custom_font_family = isset( $block_attributes['style']['typography']['fontFamily'] );
    115 
    116         if ( $has_named_font_family ) {
    117             $classes[] = sprintf( 'has-%s-font-family', _wp_to_kebab_case( $block_attributes['fontFamily'] ) );
    118         } elseif ( $has_custom_font_family ) {
    119             // Before using classes, the value was serialized as a CSS Custom Property.
    120             // We don't need this code path when it lands in core.
    121             $font_family_custom = $block_attributes['style']['typography']['fontFamily'];
    122             if ( strpos( $font_family_custom, 'var:preset|font-family' ) !== false ) {
    123                 $index_to_splice    = strrpos( $font_family_custom, '|' ) + 1;
    124                 $font_family_slug   = _wp_to_kebab_case( substr( $font_family_custom, $index_to_splice ) );
    125                 $font_family_custom = sprintf( 'var(--wp--preset--font-family--%s)', $font_family_slug );
    126             }
    127             $styles[] = sprintf( 'font-family: %s;', $font_family_custom );
    128         }
    129     }
    130 
    131     if ( $has_font_style_support && ! wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontStyle' ) ) {
    132         $font_style = wp_typography_get_css_variable_inline_style( $block_attributes, 'fontStyle', 'font-style' );
    133         if ( $font_style ) {
    134             $styles[] = $font_style;
    135         }
    136     }
    137 
    138     if ( $has_font_weight_support && ! wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontWeight' ) ) {
    139         $font_weight = wp_typography_get_css_variable_inline_style( $block_attributes, 'fontWeight', 'font-weight' );
    140         if ( $font_weight ) {
    141             $styles[] = $font_weight;
    142         }
    143     }
    144 
    145     if ( $has_line_height_support && ! wp_should_skip_block_supports_serialization( $block_type, 'typography', 'lineHeight' ) ) {
    146         $has_line_height = isset( $block_attributes['style']['typography']['lineHeight'] );
    147         if ( $has_line_height ) {
    148             $styles[] = sprintf( 'line-height: %s;', $block_attributes['style']['typography']['lineHeight'] );
    149         }
    150     }
    151 
    152     if ( $has_text_decoration_support && ! wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textDecoration' ) ) {
    153         $text_decoration_style = wp_typography_get_css_variable_inline_style( $block_attributes, 'textDecoration', 'text-decoration' );
    154         if ( $text_decoration_style ) {
    155             $styles[] = $text_decoration_style;
    156         }
    157     }
    158 
    159     if ( $has_text_transform_support && ! wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textTransform' ) ) {
    160         $text_transform_style = wp_typography_get_css_variable_inline_style( $block_attributes, 'textTransform', 'text-transform' );
    161         if ( $text_transform_style ) {
    162             $styles[] = $text_transform_style;
    163         }
    164     }
    165 
    166     if ( $has_letter_spacing_support && ! wp_should_skip_block_supports_serialization( $block_type, 'typography', 'letterSpacing' ) ) {
    167         $letter_spacing_style = wp_typography_get_css_variable_inline_style( $block_attributes, 'letterSpacing', 'letter-spacing' );
    168         if ( $letter_spacing_style ) {
    169             $styles[] = $letter_spacing_style;
    170         }
    171     }
    172 
    173     if ( ! empty( $classes ) ) {
    174         $attributes['class'] = implode( ' ', $classes );
    175     }
    176     if ( ! empty( $styles ) ) {
    177         $attributes['style'] = implode( ' ', $styles );
     98    // Whether to skip individual block support features.
     99    $should_skip_font_size       = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontSize' );
     100    $should_skip_font_family     = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontFamily' );
     101    $should_skip_font_style      = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontStyle' );
     102    $should_skip_font_weight     = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontWeight' );
     103    $should_skip_line_height     = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'lineHeight' );
     104    $should_skip_text_decoration = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textDecoration' );
     105    $should_skip_text_transform  = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textTransform' );
     106    $should_skip_letter_spacing  = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'letterSpacing' );
     107
     108    $typography_block_styles = array();
     109    if ( $has_font_size_support && ! $should_skip_font_size ) {
     110        $preset_font_size                    = array_key_exists( 'fontSize', $block_attributes )
     111            ? "var:preset|font-size|{$block_attributes['fontSize']}"
     112            : null;
     113        $custom_font_size                    = isset( $block_attributes['style']['typography']['fontSize'] )
     114            ? $block_attributes['style']['typography']['fontSize']
     115            : null;
     116        $typography_block_styles['fontSize'] = $preset_font_size ? $preset_font_size : $custom_font_size;
     117    }
     118
     119    if ( $has_font_family_support && ! $should_skip_font_family ) {
     120        $preset_font_family                    = array_key_exists( 'fontFamily', $block_attributes )
     121            ? "var:preset|font-family|{$block_attributes['fontFamily']}"
     122            : null;
     123        $custom_font_family                    = isset( $block_attributes['style']['typography']['fontFamily'] )
     124            ? wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['fontFamily'], 'font-family' )
     125            : null;
     126        $typography_block_styles['fontFamily'] = $preset_font_family ? $preset_font_family : $custom_font_family;
     127    }
     128
     129    if (
     130        $has_font_style_support &&
     131        ! $should_skip_font_style &&
     132        isset( $block_attributes['style']['typography']['fontStyle'] )
     133    ) {
     134        $typography_block_styles['fontStyle'] = wp_typography_get_preset_inline_style_value(
     135            $block_attributes['style']['typography']['fontStyle'],
     136            'font-style'
     137        );
     138    }
     139
     140    if (
     141        $has_font_weight_support &&
     142        ! $should_skip_font_weight &&
     143        isset( $block_attributes['style']['typography']['fontWeight'] )
     144    ) {
     145        $typography_block_styles['fontWeight'] = wp_typography_get_preset_inline_style_value(
     146            $block_attributes['style']['typography']['fontWeight'],
     147            'font-weight'
     148        );
     149    }
     150
     151    if ( $has_line_height_support && ! $should_skip_line_height ) {
     152        $typography_block_styles['lineHeight'] = _wp_array_get( $block_attributes, array( 'style', 'typography', 'lineHeight' ) );
     153    }
     154
     155    if (
     156        $has_text_decoration_support &&
     157        ! $should_skip_text_decoration &&
     158        isset( $block_attributes['style']['typography']['textDecoration'] )
     159    ) {
     160        $typography_block_styles['textDecoration'] = wp_typography_get_preset_inline_style_value(
     161            $block_attributes['style']['typography']['textDecoration'],
     162            'text-decoration'
     163        );
     164    }
     165
     166    if (
     167        $has_text_transform_support &&
     168        ! $should_skip_text_transform &&
     169        isset( $block_attributes['style']['typography']['textTransform'] )
     170    ) {
     171        $typography_block_styles['textTransform'] = wp_typography_get_preset_inline_style_value(
     172            $block_attributes['style']['typography']['textTransform'],
     173            'text-transform'
     174        );
     175    }
     176
     177    if (
     178        $has_letter_spacing_support &&
     179        ! $should_skip_letter_spacing &&
     180        isset( $block_attributes['style']['typography']['letterSpacing'] )
     181    ) {
     182        $typography_block_styles['letterSpacing'] = wp_typography_get_preset_inline_style_value(
     183            $block_attributes['style']['typography']['letterSpacing'],
     184            'letter-spacing'
     185        );
     186    }
     187
     188    $attributes = array();
     189    $styles     = wp_style_engine_get_styles(
     190        array( 'typography' => $typography_block_styles ),
     191        array( 'convert_vars_to_classnames' => true )
     192    );
     193
     194    if ( ! empty( $styles['classnames'] ) ) {
     195        $attributes['class'] = $styles['classnames'];
     196    }
     197
     198    if ( ! empty( $styles['css'] ) ) {
     199        $attributes['style'] = $styles['css'];
    178200    }
    179201
     
    182204
    183205/**
    184  * Generates an inline style for a typography feature e.g. text decoration,
     206 * Generates an inline style value for a typography feature e.g. text decoration,
    185207 * text transform, and font style.
    186208 *
    187  * @since 5.8.0
     209 * Note: This function is for backwards compatibility.
     210 * * It is necessary to parse older blocks whose typography styles contain presets.
     211 * * It mostly replaces the deprecated `wp_typography_get_css_variable_inline_style()`,
     212 *   but skips compiling a CSS declaration as the style engine takes over this role.
     213 * @link https://github.com/wordpress/gutenberg/pull/27555
     214 *
     215 * @since 6.1.0
     216 *
     217 * @param string $style_value  A raw style value for a single typography feature from a block's style attribute.
     218 * @param string $css_property Slug for the CSS property the inline style sets.
     219 * @return string A CSS inline style value.
     220 */
     221function wp_typography_get_preset_inline_style_value( $style_value, $css_property ) {
     222    // If the style value is not a preset CSS variable go no further.
     223    if ( empty( $style_value ) || ! str_contains( $style_value, "var:preset|{$css_property}|" ) ) {
     224        return $style_value;
     225    }
     226
     227    /*
     228     * For backwards compatibility.
     229     * Presets were removed in WordPress/gutenberg#27555.
     230     * A preset CSS variable is the style.
     231     * Gets the style value from the string and return CSS style.
     232     */
     233    $index_to_splice = strrpos( $style_value, '|' ) + 1;
     234    $slug            = _wp_to_kebab_case( substr( $style_value, $index_to_splice ) );
     235
     236    // Return the actual CSS inline style value,
     237    // e.g. `var(--wp--preset--text-decoration--underline);`.
     238    return sprintf( 'var(--wp--preset--%s--%s);', $css_property, $slug );
     239}
     240
     241/**
     242 * Checks a string for a unit and value and returns an array
     243 * consisting of `'value'` and `'unit'`, e.g., [ '42', 'rem' ].
     244 *
     245 * @since 6.1.0
    188246 * @access private
    189247 *
    190  * @param array  $attributes   Block's attributes.
    191  * @param string $feature      Key for the feature within the typography styles.
    192  * @param string $css_property Slug for the CSS property the inline style sets.
    193  * @return string CSS inline style.
    194  */
    195 function wp_typography_get_css_variable_inline_style( $attributes, $feature, $css_property ) {
    196     // Retrieve current attribute value or skip if not found.
    197     $style_value = _wp_array_get( $attributes, array( 'style', 'typography', $feature ), false );
    198     if ( ! $style_value ) {
    199         return;
    200     }
    201 
    202     // If we don't have a preset CSS variable, we'll assume it's a regular CSS value.
    203     if ( strpos( $style_value, "var:preset|{$css_property}|" ) === false ) {
    204         return sprintf( '%s:%s;', $css_property, $style_value );
    205     }
    206 
    207     // We have a preset CSS variable as the style.
    208     // Get the style value from the string and return CSS style.
    209     $index_to_splice = strrpos( $style_value, '|' ) + 1;
    210     $slug            = substr( $style_value, $index_to_splice );
    211 
    212     // Return the actual CSS inline style e.g. `text-decoration:var(--wp--preset--text-decoration--underline);`.
    213     return sprintf( '%s:var(--wp--preset--%s--%s);', $css_property, $css_property, $slug );
     248 * @param string $raw_value Raw size value from theme.json.
     249 * @param array  $options   {
     250 *     Optional. An associative array of options. Default is empty array.
     251 *
     252 *     @type string   $coerce_to        Coerce the value to rem or px. Default `'rem'`.
     253 *     @type int      $root_size_value  Value of root font size for rem|em <-> px conversion. Default `16`.
     254 *     @type string[] $acceptable_units An array of font size units. Default `[ 'rem', 'px', 'em' ]`;
     255 * }
     256 * @return array|null An array consisting of `'value'` and `'unit'` properties on success.
     257 *                    `null` on failure.
     258 */
     259function wp_get_typography_value_and_unit( $raw_value, $options = array() ) {
     260    if ( empty( $raw_value ) ) {
     261        return null;
     262    }
     263
     264    $defaults = array(
     265        'coerce_to'        => '',
     266        'root_size_value'  => 16,
     267        'acceptable_units' => array( 'rem', 'px', 'em' ),
     268    );
     269
     270    $options = wp_parse_args( $options, $defaults );
     271
     272    $acceptable_units_group = implode( '|', $options['acceptable_units'] );
     273    $pattern                = '/^(\d*\.?\d+)(' . $acceptable_units_group . '){1,1}$/';
     274
     275    preg_match( $pattern, $raw_value, $matches );
     276
     277    // Bails out if not a number value and a px or rem unit.
     278    if ( ! isset( $matches[1] ) || ! isset( $matches[2] ) ) {
     279        return null;
     280    }
     281
     282    $value = $matches[1];
     283    $unit  = $matches[2];
     284
     285    // Default browser font size. Later, possibly could inject some JS to
     286    // compute this `getComputedStyle( document.querySelector( "html" ) ).fontSize`.
     287    if ( 'px' === $options['coerce_to'] && ( 'em' === $unit || 'rem' === $unit ) ) {
     288        $value = $value * $options['root_size_value'];
     289        $unit  = $options['coerce_to'];
     290    }
     291
     292    if ( 'px' === $unit && ( 'em' === $options['coerce_to'] || 'rem' === $options['coerce_to'] ) ) {
     293        $value = $value / $options['root_size_value'];
     294        $unit  = $options['coerce_to'];
     295    }
     296
     297    return array(
     298        'value' => $value,
     299        'unit'  => $unit,
     300    );
     301}
     302
     303/**
     304 * Internal implementation of CSS clamp() based on available min/max viewport
     305 * width and min/max font sizes.
     306 *
     307 * @since 6.1.0
     308 * @access private
     309 *
     310 * @param array $args {
     311 *     Optional. An associative array of values to calculate a fluid formula
     312 *     for font size. Default is empty array.
     313 *
     314 *     @type string $maximum_viewport_width Maximum size up to which type will have fluidity.
     315 *     @type string $minimum_viewport_width Minimum viewport size from which type will have fluidity.
     316 *     @type string $maximum_font_size      Maximum font size for any clamp() calculation.
     317 *     @type string $minimum_font_size      Minimum font size for any clamp() calculation.
     318 *     @type int    $scale_factor           A scale factor to determine how fast a font scales within boundaries.
     319 * }
     320 * @return string|null A font-size value using clamp() on success. Else, null.
     321 */
     322function wp_get_computed_fluid_typography_value( $args = array() ) {
     323    $maximum_viewport_width_raw = isset( $args['maximum_viewport_width'] ) ? $args['maximum_viewport_width'] : null;
     324    $minimum_viewport_width_raw = isset( $args['minimum_viewport_width'] ) ? $args['minimum_viewport_width'] : null;
     325    $maximum_font_size_raw      = isset( $args['maximum_font_size'] ) ? $args['maximum_font_size'] : null;
     326    $minimum_font_size_raw      = isset( $args['minimum_font_size'] ) ? $args['minimum_font_size'] : null;
     327    $scale_factor               = isset( $args['scale_factor'] ) ? $args['scale_factor'] : null;
     328
     329    // Grab the minimum font size and normalize it in order to use the value for calculations.
     330    $minimum_font_size = wp_get_typography_value_and_unit( $minimum_font_size_raw );
     331
     332    // We get a 'preferred' unit to keep units consistent when calculating, otherwise the result will not be accurate.
     333    $font_size_unit = isset( $minimum_font_size['unit'] ) ? $minimum_font_size['unit'] : 'rem';
     334
     335    // Grab the maximum font size and normalize it in order to use the value for calculations.
     336    $maximum_font_size = wp_get_typography_value_and_unit(
     337        $maximum_font_size_raw,
     338        array(
     339            'coerce_to' => $font_size_unit,
     340        )
     341    );
     342
     343    // Protect against unsupported units.
     344    if ( ! $maximum_font_size || ! $minimum_font_size ) {
     345        return null;
     346    }
     347
     348    // Use rem for accessible fluid target font scaling.
     349    $minimum_font_size_rem = wp_get_typography_value_and_unit(
     350        $minimum_font_size_raw,
     351        array(
     352            'coerce_to' => 'rem',
     353        )
     354    );
     355
     356    // Viewport widths defined for fluid typography. Normalize units.
     357    $maximum_viewport_width = wp_get_typography_value_and_unit(
     358        $maximum_viewport_width_raw,
     359        array(
     360            'coerce_to' => $font_size_unit,
     361        )
     362    );
     363    $minimum_viewport_width = wp_get_typography_value_and_unit(
     364        $minimum_viewport_width_raw,
     365        array(
     366            'coerce_to' => $font_size_unit,
     367        )
     368    );
     369
     370    /*
     371     * Build CSS rule.
     372     * Borrowed from https://websemantics.uk/tools/responsive-font-calculator/.
     373     */
     374    $view_port_width_offset = round( $minimum_viewport_width['value'] / 100, 3 ) . $font_size_unit;
     375    $linear_factor          = 100 * ( ( $maximum_font_size['value'] - $minimum_font_size['value'] ) / ( $maximum_viewport_width['value'] - $minimum_viewport_width['value'] ) );
     376    $linear_factor          = round( $linear_factor, 3 ) * $scale_factor;
     377    $fluid_target_font_size = implode( '', $minimum_font_size_rem ) . " + ((1vw - $view_port_width_offset) * $linear_factor)";
     378
     379    return "clamp($minimum_font_size_raw, $fluid_target_font_size, $maximum_font_size_raw)";
     380}
     381
     382/**
     383 * Returns a font-size value based on a given font-size preset.
     384 * Takes into account fluid typography parameters and attempts to return a CSS
     385 * formula depending on available, valid values.
     386 *
     387 * @since 6.1.0
     388 *
     389 * @param array $preset                     {
     390 *     Required. fontSizes preset value as seen in theme.json.
     391 *
     392 *     @type string $name Name of the font size preset.
     393 *     @type string $slug Kebab-case unique identifier for the font size preset.
     394 *     @type string $size CSS font-size value, including units where applicable.
     395 * }
     396 * @param bool  $should_use_fluid_typography An override to switch fluid typography "on". Can be used for unit testing.
     397 *                                           Default is `false`.
     398 * @return string Font-size value.
     399 */
     400function wp_get_typography_font_size_value( $preset, $should_use_fluid_typography = false ) {
     401    // Checks if fluid font sizes are activated.
     402    $typography_settings         = wp_get_global_settings( array( 'typography' ) );
     403    $should_use_fluid_typography = isset( $typography_settings['fluid'] ) && true === $typography_settings['fluid'] ? true : $should_use_fluid_typography;
     404
     405    if ( ! $should_use_fluid_typography ) {
     406        return $preset['size'];
     407    }
     408
     409    // Defaults.
     410    $default_maximum_viewport_width   = '1600px';
     411    $default_minimum_viewport_width   = '768px';
     412    $default_minimum_font_size_factor = 0.75;
     413    $default_maximum_font_size_factor = 1.5;
     414    $default_scale_factor             = 1;
     415
     416    // Font sizes.
     417    $fluid_font_size_settings = isset( $preset['fluid'] ) ? $preset['fluid'] : null;
     418
     419    // A font size has explicitly bypassed fluid calculations.
     420    if ( false === $fluid_font_size_settings ) {
     421        return $preset['size'];
     422    }
     423
     424    // Try to grab explicit min and max fluid font sizes.
     425    $minimum_font_size_raw = isset( $fluid_font_size_settings['min'] ) ? $fluid_font_size_settings['min'] : null;
     426    $maximum_font_size_raw = isset( $fluid_font_size_settings['max'] ) ? $fluid_font_size_settings['max'] : null;
     427
     428    // Font sizes.
     429    $preferred_size = wp_get_typography_value_and_unit( $preset['size'] );
     430
     431    // Protect against unsupported units.
     432    if ( empty( $preferred_size['unit'] ) ) {
     433        return $preset['size'];
     434    }
     435
     436    // If no fluid min or max font sizes are available, create some using min/max font size factors.
     437    if ( ! $minimum_font_size_raw ) {
     438        $minimum_font_size_raw = ( $preferred_size['value'] * $default_minimum_font_size_factor ) . $preferred_size['unit'];
     439    }
     440
     441    if ( ! $maximum_font_size_raw ) {
     442        $maximum_font_size_raw = ( $preferred_size['value'] * $default_maximum_font_size_factor ) . $preferred_size['unit'];
     443    }
     444
     445    $fluid_font_size_value = wp_get_computed_fluid_typography_value(
     446        array(
     447            'minimum_viewport_width' => $default_minimum_viewport_width,
     448            'maximum_viewport_width' => $default_maximum_viewport_width,
     449            'minimum_font_size'      => $minimum_font_size_raw,
     450            'maximum_font_size'      => $maximum_font_size_raw,
     451            'scale_factor'           => $default_scale_factor,
     452        )
     453    );
     454
     455    if ( ! empty( $fluid_font_size_value ) ) {
     456        return $fluid_font_size_value;
     457    }
     458
     459    return $preset['size'];
    214460}
    215461
  • trunk/src/wp-includes/class-wp-theme-json.php

    r54253 r54260  
    151151            'prevent_override'  => false,
    152152            'use_default_names' => true,
    153             'value_key'         => 'size',
     153            'value_func'        => 'wp_get_typography_font_size_value',
    154154            'css_vars'          => '--wp--preset--font-size--$slug',
    155155            'classes'           => array( '.has-$slug-font-size' => 'font-size' ),
  • trunk/src/wp-includes/deprecated.php

    r54157 r54260  
    44574457    return $metadata;
    44584458}
     4459
     4460/**
     4461 * Generates an inline style for a typography feature e.g. text decoration,
     4462 * text transform, and font style.
     4463 *
     4464 * @since 5.8.0
     4465 * @access private
     4466 * @deprecated 6.1.0 Use wp_style_engine_get_styles() introduced in 6.1.0.
     4467 *
     4468 * @see wp_style_engine_get_styles()
     4469 *
     4470 * @param array  $attributes   Block's attributes.
     4471 * @param string $feature      Key for the feature within the typography styles.
     4472 * @param string $css_property Slug for the CSS property the inline style sets.
     4473 * @return string CSS inline style.
     4474 */
     4475function wp_typography_get_css_variable_inline_style( $attributes, $feature, $css_property ) {
     4476    _deprecated_function( __FUNCTION__, '6.1.0', 'wp_style_engine_get_styles()' );
     4477
     4478    // Retrieve current attribute value or skip if not found.
     4479    $style_value = _wp_array_get( $attributes, array( 'style', 'typography', $feature ), false );
     4480    if ( ! $style_value ) {
     4481        return;
     4482    }
     4483
     4484    // If we don't have a preset CSS variable, we'll assume it's a regular CSS value.
     4485    if ( strpos( $style_value, "var:preset|{$css_property}|" ) === false ) {
     4486        return sprintf( '%s:%s;', $css_property, $style_value );
     4487    }
     4488
     4489    /*
     4490     * We have a preset CSS variable as the style.
     4491     * Get the style value from the string and return CSS style.
     4492     */
     4493    $index_to_splice = strrpos( $style_value, '|' ) + 1;
     4494    $slug            = substr( $style_value, $index_to_splice );
     4495
     4496    // Return the actual CSS inline style e.g. `text-decoration:var(--wp--preset--text-decoration--underline);`.
     4497    return sprintf( '%s:var(--wp--preset--%s--%s);', $css_property, $css_property, $slug );
     4498}
  • trunk/tests/phpunit/tests/block-supports/typography.php

    r53680 r54260  
    22/**
    33 * @group block-supports
    4  *
    5  * @covers ::wp_apply_typography_support
    64 */
    75class Tests_Block_Supports_Typography extends WP_UnitTestCase {
     
    1614    }
    1715
     16    /**
     17     * Unregisters block type after each test.
     18     */
    1819    function tear_down() {
    1920        unregister_block_type( $this->test_block_name );
    2021        $this->test_block_name = null;
    21         parent::set_up();
    22     }
    23 
    24     /**
     22        parent::tear_down();
     23    }
     24
     25    /**
     26     * Tests whether slugs with numbers are kebab cased.
     27     *
    2528     * @ticket 54337
    26      */
    27     function test_font_size_slug_with_numbers_is_kebab_cased_properly() {
     29     *
     30     * @covers ::wp_apply_typography_support
     31     */
     32    function test_should_kebab_case_font_size_slug_with_numbers() {
    2833        $this->test_block_name = 'test/font-size-slug-with-numbers';
    2934        register_block_type(
     
    5358        $this->assertSame( $expected, $actual );
    5459    }
    55     /**
     60
     61    /**
     62     * Tests legacy inline styles for font family.
     63     *
    5664     * @ticket 54337
    57      */
    58     function test_font_family_with_legacy_inline_styles_using_a_value() {
     65     *
     66     * @covers ::wp_apply_typography_support
     67     */
     68    function test_should_generate_font_family_with_legacy_inline_styles_using_a_value() {
    5969        $this->test_block_name = 'test/font-family-with-inline-styles-using-value';
    6070        register_block_type(
     
    7989
    8090        $actual   = wp_apply_typography_support( $block_type, $block_atts );
    81         $expected = array( 'style' => 'font-family: serif;' );
    82 
    83         $this->assertSame( $expected, $actual );
    84     }
    85 
    86     /**
     91        $expected = array( 'style' => 'font-family:serif;' );
     92
     93        $this->assertSame( $expected, $actual );
     94    }
     95
     96    /**
     97     * Tests skipping serialization.
     98     *
    8799     * @ticket 55505
    88      */
    89     function test_typography_with_skipped_serialization_block_supports() {
     100     *
     101     * @covers ::wp_apply_typography_support
     102     */
     103    function test_should_skip_serialization_for_typography_block_supports() {
    90104        $this->test_block_name = 'test/typography-with-skipped-serialization-block-supports';
    91105        register_block_type(
     
    129143
    130144    /**
     145     * Tests skipping serialization of individual block supports properties.
     146     *
    131147     * @ticket 55505
    132      */
    133     function test_letter_spacing_with_individual_skipped_serialization_block_supports() {
    134         $this->test_block_name = 'test/letter-spacing-with-individua-skipped-serialization-block-supports';
     148     *
     149     * @covers ::wp_apply_typography_support
     150     */
     151    function test_should_skip_serialization_for_letter_spacing_block_supports() {
     152        $this->test_block_name = 'test/letter-spacing-with-individual-skipped-serialization-block-supports';
    135153        register_block_type(
    136154            $this->test_block_name,
     
    161179        $this->assertSame( $expected, $actual );
    162180    }
    163     /**
     181
     182    /**
     183     * Tests legacy css var inline styles for font family.
     184     *
    164185     * @ticket 54337
    165      */
    166     function test_font_family_with_legacy_inline_styles_using_a_css_var() {
     186     *
     187     * @covers ::wp_apply_typography_support
     188     */
     189    function test_should_generate_css_var_for_font_family_with_legacy_inline_styles() {
    167190        $this->test_block_name = 'test/font-family-with-inline-styles-using-css-var';
    168191        register_block_type(
     
    187210
    188211        $actual   = wp_apply_typography_support( $block_type, $block_atts );
    189         $expected = array( 'style' => 'font-family: var(--wp--preset--font-family--h-1);' );
    190 
    191         $this->assertSame( $expected, $actual );
    192     }
    193     /**
     212        $expected = array( 'style' => 'font-family:var(--wp--preset--font-family--h-1);' );
     213
     214        $this->assertSame( $expected, $actual );
     215    }
     216
     217    /**
     218     * Tests that a classname is generated for font family.
     219     *
    194220     * @ticket 54337
    195      */
    196     function test_font_family_with_class() {
     221     *
     222     * @covers ::wp_apply_typography_support
     223     */
     224    function test_should_generate_classname_for_font_family() {
    197225        $this->test_block_name = 'test/font-family-with-class';
    198226        register_block_type(
     
    222250    }
    223251
     252    /**
     253     * Tests generating font size values, including fluid formulae, from fontSizes preset.
     254     *
     255     * @ticket 56467
     256     *
     257     * @covers ::wp_get_typography_font_size_value
     258     *
     259     * @dataProvider data_generate_font_size_preset_fixtures
     260     *
     261     * @param array  $font_size_preset            {
     262     *      Required. fontSizes preset value as seen in theme.json.
     263     *
     264     *     @type string $name Name of the font size preset.
     265     *     @type string $slug Kebab-case unique identifier for the font size preset.
     266     *     @type string $size CSS font-size value, including units where applicable.
     267     * }
     268     * @param bool   $should_use_fluid_typography An override to switch fluid typography "on". Can be used for unit testing.
     269     * @param string $expected_output             Expected output.
     270     */
     271    function test_wp_get_typography_font_size_value( $font_size_preset, $should_use_fluid_typography, $expected_output ) {
     272        $actual = wp_get_typography_font_size_value( $font_size_preset, $should_use_fluid_typography );
     273
     274        $this->assertSame( $expected_output, $actual );
     275    }
     276
     277    /**
     278     * Data provider.
     279     *
     280     * @return array
     281     */
     282    public function data_generate_font_size_preset_fixtures() {
     283        return array(
     284            'default_return_value'                        => array(
     285                'font_size_preset'            => array(
     286                    'size' => '28px',
     287                ),
     288                'should_use_fluid_typography' => false,
     289                'expected_output'             => '28px',
     290            ),
     291
     292            'default_return_value_when_fluid_is_false'    => array(
     293                'font_size_preset'            => array(
     294                    'size'  => '28px',
     295                    'fluid' => false,
     296                ),
     297                'should_use_fluid_typography' => true,
     298                'expected_output'             => '28px',
     299            ),
     300
     301            'return_fluid_value'                          => array(
     302                'font_size_preset'            => array(
     303                    'size' => '1.75rem',
     304                ),
     305                'should_use_fluid_typography' => true,
     306                'expected_output'             => 'clamp(1.3125rem, 1.3125rem + ((1vw - 0.48rem) * 2.524), 2.625rem)',
     307            ),
     308
     309            'return_default_fluid_values_with_empty_fluid_array' => array(
     310                'font_size_preset'            => array(
     311                    'size'  => '28px',
     312                    'fluid' => array(),
     313                ),
     314                'should_use_fluid_typography' => true,
     315                'expected_output'             => 'clamp(21px, 1.3125rem + ((1vw - 7.68px) * 2.524), 42px)',
     316            ),
     317
     318            'return_default_fluid_values_with_null_value' => array(
     319                'font_size_preset'            => array(
     320                    'size'  => '28px',
     321                    'fluid' => null,
     322                ),
     323                'should_use_fluid_typography' => true,
     324                'expected_output'             => 'clamp(21px, 1.3125rem + ((1vw - 7.68px) * 2.524), 42px)',
     325            ),
     326
     327            'return_size_with_invalid_fluid_units'        => array(
     328                'font_size_preset'            => array(
     329                    'size'  => '10em',
     330                    'fluid' => array(
     331                        'min' => '20vw',
     332                        'max' => '50%',
     333                    ),
     334                ),
     335                'should_use_fluid_typography' => true,
     336                'expected_output'             => '10em',
     337            ),
     338
     339            'return_fluid_clamp_value'                    => array(
     340                'font_size_preset'            => array(
     341                    'size'  => '28px',
     342                    'fluid' => array(
     343                        'min' => '20px',
     344                        'max' => '50rem',
     345                    ),
     346                ),
     347                'should_use_fluid_typography' => true,
     348                'expected_output'             => 'clamp(20px, 1.25rem + ((1vw - 7.68px) * 93.75), 50rem)',
     349            ),
     350
     351            'return_clamp_value_with_default_fluid_max_value' => array(
     352                'font_size_preset'            => array(
     353                    'size'  => '28px',
     354                    'fluid' => array(
     355                        'min' => '2.6rem',
     356                    ),
     357                ),
     358                'should_use_fluid_typography' => true,
     359                'expected_output'             => 'clamp(2.6rem, 2.6rem + ((1vw - 0.48rem) * 0.048), 42px)',
     360            ),
     361
     362            'default_return_clamp_value_with_default_fluid_min_value' => array(
     363                'font_size_preset'            => array(
     364                    'size'  => '28px',
     365                    'fluid' => array(
     366                        'max' => '80px',
     367                    ),
     368                ),
     369                'should_use_fluid_typography' => true,
     370                'expected_output'             => 'clamp(21px, 1.3125rem + ((1vw - 7.68px) * 7.091), 80px)',
     371            ),
     372        );
     373    }
    224374}
  • trunk/tests/phpunit/tests/blocks/supportedStyles.php

    r54211 r54260  
    380380
    381381        $expected_classes = 'foo-bar-class wp-block-example';
    382         $expected_styles  = 'test: style; font-size: 10px;';
     382        $expected_styles  = 'test: style; font-size:10px;';
    383383
    384384        $this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
     
    437437
    438438        $expected_classes = 'foo-bar-class wp-block-example';
    439         $expected_styles  = 'test: style; line-height: 10;';
     439        $expected_styles  = 'test: style; line-height:10;';
    440440
    441441        $this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
     
    564564
    565565        $expected_classes = 'foo-bar-class wp-block-example has-text-color has-background alignwide';
    566         $expected_styles  = 'test: style; color:#000; background-color:#fff; font-size: 10px; line-height: 20;';
     566        $expected_styles  = 'test: style; color:#000; background-color:#fff; font-size:10px; line-height:20;';
    567567
    568568        $this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
     
    607607
    608608        $expected_classes = 'foo-bar-class wp-block-example';
    609         $expected_styles  = 'test: style; font-size: 10px;';
     609        $expected_styles  = 'test: style; font-size:10px;';
    610610
    611611        $this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
Note: See TracChangeset for help on using the changeset viewer.