Changeset 56101
- Timestamp:
- 06/29/2023 06:19:41 AM (17 months ago)
- Location:
- trunk
- Files:
-
- 2 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/block-supports/duotone.php
r55988 r56101 33 33 */ 34 34 35 /**36 * Takes input from [0, n] and returns it as [0, 1].37 *38 * Direct port of TinyColor's function, lightly simplified to maintain39 * consistency with TinyColor.40 *41 * @see https://github.com/bgrins/TinyColor42 *43 * @since 5.8.044 * @access private45 *46 * @param mixed $n Number of unknown type.47 * @param int $max Upper value of the range to bound to.48 * @return float Value in the range [0, 1].49 */50 function wp_tinycolor_bound01( $n, $max ) {51 if ( 'string' === gettype( $n ) && str_contains( $n, '.' ) && 1 === (float) $n ) {52 $n = '100%';53 }54 55 $n = min( $max, max( 0, (float) $n ) );56 57 // Automatically convert percentage into number.58 if ( 'string' === gettype( $n ) && str_contains( $n, '%' ) ) {59 $n = (int) ( $n * $max ) / 100;60 }61 62 // Handle floating point rounding errors.63 if ( ( abs( $n - $max ) < 0.000001 ) ) {64 return 1.0;65 }66 67 // Convert into [0, 1] range if it isn't already.68 return ( $n % $max ) / (float) $max;69 }70 71 /**72 * Direct port of tinycolor's boundAlpha function to maintain consistency with73 * how tinycolor works.74 *75 * @see https://github.com/bgrins/TinyColor76 *77 * @since 5.9.078 * @access private79 *80 * @param mixed $n Number of unknown type.81 * @return float Value in the range [0,1].82 */83 function _wp_tinycolor_bound_alpha( $n ) {84 if ( is_numeric( $n ) ) {85 $n = (float) $n;86 if ( $n >= 0 && $n <= 1 ) {87 return $n;88 }89 }90 return 1;91 }92 93 /**94 * Rounds and converts values of an RGB object.95 *96 * Direct port of TinyColor's function, lightly simplified to maintain97 * consistency with TinyColor.98 *99 * @see https://github.com/bgrins/TinyColor100 *101 * @since 5.8.0102 * @access private103 *104 * @param array $rgb_color RGB object.105 * @return array Rounded and converted RGB object.106 */107 function wp_tinycolor_rgb_to_rgb( $rgb_color ) {108 return array(109 'r' => wp_tinycolor_bound01( $rgb_color['r'], 255 ) * 255,110 'g' => wp_tinycolor_bound01( $rgb_color['g'], 255 ) * 255,111 'b' => wp_tinycolor_bound01( $rgb_color['b'], 255 ) * 255,112 );113 }114 115 /**116 * Helper function for hsl to rgb conversion.117 *118 * Direct port of TinyColor's function, lightly simplified to maintain119 * consistency with TinyColor.120 *121 * @see https://github.com/bgrins/TinyColor122 *123 * @since 5.8.0124 * @access private125 *126 * @param float $p first component.127 * @param float $q second component.128 * @param float $t third component.129 * @return float R, G, or B component.130 */131 function wp_tinycolor_hue_to_rgb( $p, $q, $t ) {132 if ( $t < 0 ) {133 ++$t;134 }135 if ( $t > 1 ) {136 --$t;137 }138 if ( $t < 1 / 6 ) {139 return $p + ( $q - $p ) * 6 * $t;140 }141 if ( $t < 1 / 2 ) {142 return $q;143 }144 if ( $t < 2 / 3 ) {145 return $p + ( $q - $p ) * ( 2 / 3 - $t ) * 6;146 }147 return $p;148 }149 150 /**151 * Converts an HSL object to an RGB object with converted and rounded values.152 *153 * Direct port of TinyColor's function, lightly simplified to maintain154 * consistency with TinyColor.155 *156 * @see https://github.com/bgrins/TinyColor157 *158 * @since 5.8.0159 * @access private160 *161 * @param array $hsl_color HSL object.162 * @return array Rounded and converted RGB object.163 */164 function wp_tinycolor_hsl_to_rgb( $hsl_color ) {165 $h = wp_tinycolor_bound01( $hsl_color['h'], 360 );166 $s = wp_tinycolor_bound01( $hsl_color['s'], 100 );167 $l = wp_tinycolor_bound01( $hsl_color['l'], 100 );168 169 if ( 0 === $s ) {170 // Achromatic.171 $r = $l;172 $g = $l;173 $b = $l;174 } else {175 $q = $l < 0.5 ? $l * ( 1 + $s ) : $l + $s - $l * $s;176 $p = 2 * $l - $q;177 $r = wp_tinycolor_hue_to_rgb( $p, $q, $h + 1 / 3 );178 $g = wp_tinycolor_hue_to_rgb( $p, $q, $h );179 $b = wp_tinycolor_hue_to_rgb( $p, $q, $h - 1 / 3 );180 }181 182 return array(183 'r' => $r * 255,184 'g' => $g * 255,185 'b' => $b * 255,186 );187 }188 189 /**190 * Parses hex, hsl, and rgb CSS strings using the same regex as TinyColor v1.4.2191 * used in the JavaScript. Only colors output from react-color are implemented.192 *193 * Direct port of TinyColor's function, lightly simplified to maintain194 * consistency with TinyColor.195 *196 * @see https://github.com/bgrins/TinyColor197 * @see https://github.com/casesandberg/react-color/198 *199 * @since 5.8.0200 * @since 5.9.0 Added alpha processing.201 * @access private202 *203 * @param string $color_str CSS color string.204 * @return array RGB object.205 */206 function wp_tinycolor_string_to_rgb( $color_str ) {207 $color_str = strtolower( trim( $color_str ) );208 209 $css_integer = '[-\\+]?\\d+%?';210 $css_number = '[-\\+]?\\d*\\.\\d+%?';211 212 $css_unit = '(?:' . $css_number . ')|(?:' . $css_integer . ')';213 214 $permissive_match3 = '[\\s|\\(]+(' . $css_unit . ')[,|\\s]+(' . $css_unit . ')[,|\\s]+(' . $css_unit . ')\\s*\\)?';215 $permissive_match4 = '[\\s|\\(]+(' . $css_unit . ')[,|\\s]+(' . $css_unit . ')[,|\\s]+(' . $css_unit . ')[,|\\s]+(' . $css_unit . ')\\s*\\)?';216 217 $rgb_regexp = '/^rgb' . $permissive_match3 . '$/';218 if ( preg_match( $rgb_regexp, $color_str, $match ) ) {219 $rgb = wp_tinycolor_rgb_to_rgb(220 array(221 'r' => $match[1],222 'g' => $match[2],223 'b' => $match[3],224 )225 );226 227 $rgb['a'] = 1;228 229 return $rgb;230 }231 232 $rgba_regexp = '/^rgba' . $permissive_match4 . '$/';233 if ( preg_match( $rgba_regexp, $color_str, $match ) ) {234 $rgb = wp_tinycolor_rgb_to_rgb(235 array(236 'r' => $match[1],237 'g' => $match[2],238 'b' => $match[3],239 )240 );241 242 $rgb['a'] = _wp_tinycolor_bound_alpha( $match[4] );243 244 return $rgb;245 }246 247 $hsl_regexp = '/^hsl' . $permissive_match3 . '$/';248 if ( preg_match( $hsl_regexp, $color_str, $match ) ) {249 $rgb = wp_tinycolor_hsl_to_rgb(250 array(251 'h' => $match[1],252 's' => $match[2],253 'l' => $match[3],254 )255 );256 257 $rgb['a'] = 1;258 259 return $rgb;260 }261 262 $hsla_regexp = '/^hsla' . $permissive_match4 . '$/';263 if ( preg_match( $hsla_regexp, $color_str, $match ) ) {264 $rgb = wp_tinycolor_hsl_to_rgb(265 array(266 'h' => $match[1],267 's' => $match[2],268 'l' => $match[3],269 )270 );271 272 $rgb['a'] = _wp_tinycolor_bound_alpha( $match[4] );273 274 return $rgb;275 }276 277 $hex8_regexp = '/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/';278 if ( preg_match( $hex8_regexp, $color_str, $match ) ) {279 $rgb = wp_tinycolor_rgb_to_rgb(280 array(281 'r' => base_convert( $match[1], 16, 10 ),282 'g' => base_convert( $match[2], 16, 10 ),283 'b' => base_convert( $match[3], 16, 10 ),284 )285 );286 287 $rgb['a'] = _wp_tinycolor_bound_alpha(288 base_convert( $match[4], 16, 10 ) / 255289 );290 291 return $rgb;292 }293 294 $hex6_regexp = '/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/';295 if ( preg_match( $hex6_regexp, $color_str, $match ) ) {296 $rgb = wp_tinycolor_rgb_to_rgb(297 array(298 'r' => base_convert( $match[1], 16, 10 ),299 'g' => base_convert( $match[2], 16, 10 ),300 'b' => base_convert( $match[3], 16, 10 ),301 )302 );303 304 $rgb['a'] = 1;305 306 return $rgb;307 }308 309 $hex4_regexp = '/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/';310 if ( preg_match( $hex4_regexp, $color_str, $match ) ) {311 $rgb = wp_tinycolor_rgb_to_rgb(312 array(313 'r' => base_convert( $match[1] . $match[1], 16, 10 ),314 'g' => base_convert( $match[2] . $match[2], 16, 10 ),315 'b' => base_convert( $match[3] . $match[3], 16, 10 ),316 )317 );318 319 $rgb['a'] = _wp_tinycolor_bound_alpha(320 base_convert( $match[4] . $match[4], 16, 10 ) / 255321 );322 323 return $rgb;324 }325 326 $hex3_regexp = '/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/';327 if ( preg_match( $hex3_regexp, $color_str, $match ) ) {328 $rgb = wp_tinycolor_rgb_to_rgb(329 array(330 'r' => base_convert( $match[1] . $match[1], 16, 10 ),331 'g' => base_convert( $match[2] . $match[2], 16, 10 ),332 'b' => base_convert( $match[3] . $match[3], 16, 10 ),333 )334 );335 336 $rgb['a'] = 1;337 338 return $rgb;339 }340 341 /*342 * The JS color picker considers the string "transparent" to be a hex value,343 * so we need to handle it here as a special case.344 */345 if ( 'transparent' === $color_str ) {346 return array(347 'r' => 0,348 'g' => 0,349 'b' => 0,350 'a' => 0,351 );352 }353 }354 355 /**356 * Returns the prefixed id for the duotone filter for use as a CSS id.357 *358 * @since 5.9.1359 * @access private360 *361 * @param array $preset Duotone preset value as seen in theme.json.362 * @return string Duotone filter CSS id.363 */364 function 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.374 *375 * @since 5.9.0376 * @since 6.1.0 Allow unset for preset colors.377 * @access private378 *379 * @param array $preset Duotone preset value as seen in theme.json.380 * @return string Duotone CSS filter property url value.381 */382 function wp_get_duotone_filter_property( $preset ) {383 if ( isset( $preset['colors'] ) && 'unset' === $preset['colors'] ) {384 return 'none';385 }386 $filter_id = wp_get_duotone_filter_id( $preset );387 return "url('#" . $filter_id . "')";388 }389 390 /**391 * Returns the duotone filter SVG string for the preset.392 *393 * @since 5.9.1394 * @access private395 *396 * @param array $preset Duotone preset value as seen in theme.json.397 * @return string Duotone SVG filter.398 */399 function wp_get_duotone_filter_svg( $preset ) {400 $filter_id = wp_get_duotone_filter_id( $preset );401 402 $duotone_values = array(403 'r' => array(),404 'g' => array(),405 'b' => array(),406 'a' => array(),407 );408 409 if ( ! isset( $preset['colors'] ) || ! is_array( $preset['colors'] ) ) {410 $preset['colors'] = array();411 }412 413 foreach ( $preset['colors'] as $color_str ) {414 $color = wp_tinycolor_string_to_rgb( $color_str );415 416 $duotone_values['r'][] = $color['r'] / 255;417 $duotone_values['g'][] = $color['g'] / 255;418 $duotone_values['b'][] = $color['b'] / 255;419 $duotone_values['a'][] = $color['a'];420 }421 422 ob_start();423 424 ?>425 426 <svg427 xmlns="http://www.w3.org/2000/svg"428 viewBox="0 0 0 0"429 width="0"430 height="0"431 focusable="false"432 role="none"433 style="visibility: hidden; position: absolute; left: -9999px; overflow: hidden;"434 >435 <defs>436 <filter id="<?php echo esc_attr( $filter_id ); ?>">437 <feColorMatrix438 color-interpolation-filters="sRGB"439 type="matrix"440 values="441 .299 .587 .114 0 0442 .299 .587 .114 0 0443 .299 .587 .114 0 0444 .299 .587 .114 0 0445 "446 />447 <feComponentTransfer color-interpolation-filters="sRGB" >448 <feFuncR type="table" tableValues="<?php echo esc_attr( implode( ' ', $duotone_values['r'] ) ); ?>" />449 <feFuncG type="table" tableValues="<?php echo esc_attr( implode( ' ', $duotone_values['g'] ) ); ?>" />450 <feFuncB type="table" tableValues="<?php echo esc_attr( implode( ' ', $duotone_values['b'] ) ); ?>" />451 <feFuncA type="table" tableValues="<?php echo esc_attr( implode( ' ', $duotone_values['a'] ) ); ?>" />452 </feComponentTransfer>453 <feComposite in2="SourceGraphic" operator="in" />454 </filter>455 </defs>456 </svg>457 458 <?php459 460 $svg = ob_get_clean();461 462 if ( ! SCRIPT_DEBUG ) {463 // Clean up the whitespace.464 $svg = preg_replace( "/[\r\n\t ]+/", ' ', $svg );465 $svg = str_replace( '> <', '><', $svg );466 $svg = trim( $svg );467 }468 469 return $svg;470 }471 472 /**473 * Registers the style and colors block attributes for block types that support it.474 *475 * @since 5.8.0476 * @access private477 *478 * @param WP_Block_Type $block_type Block Type.479 */480 function wp_register_duotone_support( $block_type ) {481 $has_duotone_support = false;482 if ( property_exists( $block_type, 'supports' ) ) {483 $has_duotone_support = _wp_array_get( $block_type->supports, array( 'color', '__experimentalDuotone' ), false );484 }485 486 if ( $has_duotone_support ) {487 if ( ! $block_type->attributes ) {488 $block_type->attributes = array();489 }490 491 if ( ! array_key_exists( 'style', $block_type->attributes ) ) {492 $block_type->attributes['style'] = array(493 'type' => 'object',494 );495 }496 }497 }498 499 /**500 * Renders out the duotone stylesheet and SVG.501 *502 * @since 5.8.0503 * @since 6.1.0 Allow unset for preset colors.504 * @access private505 *506 * @param string $block_content Rendered block content.507 * @param array $block Block object.508 * @return string Filtered block content.509 */510 function wp_render_duotone_support( $block_content, $block ) {511 $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );512 513 $duotone_support = false;514 if ( $block_type && property_exists( $block_type, 'supports' ) ) {515 $duotone_support = _wp_array_get( $block_type->supports, array( 'color', '__experimentalDuotone' ), false );516 }517 518 $has_duotone_attribute = isset( $block['attrs']['style']['color']['duotone'] );519 520 if (521 ! $duotone_support ||522 ! $has_duotone_attribute523 ) {524 return $block_content;525 }526 527 $colors = $block['attrs']['style']['color']['duotone'];528 $filter_key = is_array( $colors ) ? implode( '-', $colors ) : $colors;529 $filter_preset = array(530 'slug' => wp_unique_id( sanitize_key( $filter_key . '-' ) ),531 'colors' => $colors,532 );533 $filter_property = wp_get_duotone_filter_property( $filter_preset );534 $filter_id = wp_get_duotone_filter_id( $filter_preset );535 536 $scope = '.' . $filter_id;537 $selectors = explode( ',', $duotone_support );538 $scoped = array();539 foreach ( $selectors as $sel ) {540 $scoped[] = $scope . ' ' . trim( $sel );541 }542 $selector = implode( ', ', $scoped );543 544 // !important is needed because these styles render before global styles,545 // and they should be overriding the duotone filters set by global styles.546 $filter_style = SCRIPT_DEBUG547 ? $selector . " {\n\tfilter: " . $filter_property . " !important;\n}\n"548 : $selector . '{filter:' . $filter_property . ' !important;}';549 550 wp_register_style( $filter_id, false );551 wp_add_inline_style( $filter_id, $filter_style );552 wp_enqueue_style( $filter_id );553 554 if ( 'unset' !== $colors ) {555 $filter_svg = wp_get_duotone_filter_svg( $filter_preset );556 add_action(557 'wp_footer',558 static function () use ( $filter_svg, $selector ) {559 echo $filter_svg;560 561 /*562 * Safari renders elements incorrectly on first paint when the563 * SVG filter comes after the content that it is filtering, so564 * we force a repaint with a WebKit hack which solves the issue.565 */566 global $is_safari;567 if ( $is_safari ) {568 /*569 * Simply accessing el.offsetHeight flushes layout and style570 * changes in WebKit without having to wait for setTimeout.571 */572 printf(573 '<script>( function() { var el = document.querySelector( %s ); var display = el.style.display; el.style.display = "none"; el.offsetHeight; el.style.display = display; } )();</script>',574 wp_json_encode( $selector )575 );576 }577 }578 );579 }580 581 // Like the layout hook, this assumes the hook only applies to blocks with a single wrapper.582 return preg_replace(583 '/' . preg_quote( 'class="', '/' ) . '/',584 'class="' . $filter_id . ' ',585 $block_content,586 1587 );588 }589 590 35 // Register the block support. 591 36 WP_Block_Supports::get_instance()->register( 592 37 'duotone', 593 38 array( 594 'register_attribute' => 'wp_register_duotone_support',39 'register_attribute' => array( 'WP_Duotone', 'register_duotone_support' ), 595 40 ) 596 41 ); 597 add_filter( 'render_block', 'wp_render_duotone_support', 10, 2 ); 42 43 // Set up metadata prior to rendering any blocks. 44 add_action( 'wp_loaded', array( 'WP_Duotone', 'set_global_styles_presets' ), 10 ); 45 add_action( 'wp_loaded', array( 'WP_Duotone', 'set_global_style_block_names' ), 10 ); 46 47 // Add classnames to blocks using duotone support. 48 add_filter( 'render_block', array( 'WP_Duotone', 'render_duotone_support' ), 10, 2 ); 49 50 // Enqueue styles. 51 // Block styles (core-block-supports-inline-css) before the style engine (wp_enqueue_stored_styles). 52 // Global styles (global-styles-inline-css) after the other global styles (wp_enqueue_global_styles). 53 add_action( 'wp_enqueue_scripts', array( 'WP_Duotone', 'output_block_styles' ), 9 ); 54 add_action( 'wp_enqueue_scripts', array( 'WP_Duotone', 'output_global_styles' ), 11 ); 55 56 // Add SVG filters to the footer. Also, for classic themes, output block styles (core-block-supports-inline-css). 57 add_action( 'wp_footer', array( 'WP_Duotone', 'output_footer_assets' ), 10 ); 58 59 // Add styles and SVGs for use in the editor via the EditorStyles component. 60 add_filter( 'block_editor_settings_all', array( 'WP_Duotone', 'add_editor_settings' ), 10 ); 61 62 // Migrate the old experimental duotone support flag. 63 add_filter( 'block_type_metadata_settings', array( 'WP_Duotone', 'migrate_experimental_duotone_support_flag' ), 10, 2 ); -
trunk/src/wp-includes/class-wp-theme-json.php
r56083 r56101 115 115 * `prevent_override` value for `color.duotone` to use `color.defaultDuotone`. 116 116 * @since 6.2.0 Added 'shadow' presets. 117 * @since 6.3.0 Replaced value_func for duotone with `null`. Custom properties are handled by class-wp-duotone.php. 117 118 * @var array 118 119 */ … … 144 145 'prevent_override' => array( 'color', 'defaultDuotone' ), 145 146 'use_default_names' => false, 146 'value_func' => 'wp_get_duotone_filter_property',147 'css_vars' => '--wp--preset--duotone--$slug',147 'value_func' => null, // CSS Custom Properties for duotone are handled by block supports in class-wp-duotone.php. 148 'css_vars' => null, 148 149 'classes' => array(), 149 150 'properties' => array( 'filter' ), -
trunk/src/wp-includes/default-filters.php
r56030 r56101 607 607 add_action( 'wp_footer', 'wp_enqueue_stored_styles', 1 ); 608 608 609 // SVG filters like duotone have to be loaded at the beginning of the body in both admin and the front-end.610 add_action( 'wp_body_open', 'wp_global_styles_render_svg_filters' );611 add_action( 'in_admin_header', 'wp_global_styles_render_svg_filters' );612 613 609 add_action( 'wp_default_styles', 'wp_default_styles' ); 614 610 add_filter( 'style_loader_src', 'wp_style_loader_src', 10, 2 ); -
trunk/src/wp-includes/deprecated.php
r56037 r56101 4805 4805 return $image; 4806 4806 } 4807 4808 /** 4809 * Takes input from [0, n] and returns it as [0, 1]. 4810 * 4811 * Direct port of TinyColor's function, lightly simplified to maintain 4812 * consistency with TinyColor. 4813 * 4814 * @link https://github.com/bgrins/TinyColor 4815 * 4816 * @since 5.8.0 4817 * @deprecated 6.3.0 4818 * 4819 * @access private 4820 * 4821 * @param mixed $n Number of unknown type. 4822 * @param int $max Upper value of the range to bound to. 4823 * @return float Value in the range [0, 1]. 4824 */ 4825 function wp_tinycolor_bound01( $n, $max ) { 4826 _deprecated_function( __FUNCTION__, '6.3.0' ); 4827 if ( 'string' === gettype( $n ) && str_contains( $n, '.' ) && 1 === (float) $n ) { 4828 $n = '100%'; 4829 } 4830 4831 $n = min( $max, max( 0, (float) $n ) ); 4832 4833 // Automatically convert percentage into number. 4834 if ( 'string' === gettype( $n ) && str_contains( $n, '%' ) ) { 4835 $n = (int) ( $n * $max ) / 100; 4836 } 4837 4838 // Handle floating point rounding errors. 4839 if ( ( abs( $n - $max ) < 0.000001 ) ) { 4840 return 1.0; 4841 } 4842 4843 // Convert into [0, 1] range if it isn't already. 4844 return ( $n % $max ) / (float) $max; 4845 } 4846 4847 /** 4848 * Direct port of tinycolor's boundAlpha function to maintain consistency with 4849 * how tinycolor works. 4850 * 4851 * @link https://github.com/bgrins/TinyColor 4852 * 4853 * @since 5.9.0 4854 * @deprecated 6.3.0 4855 * 4856 * @access private 4857 * 4858 * @param mixed $n Number of unknown type. 4859 * @return float Value in the range [0,1]. 4860 */ 4861 function _wp_tinycolor_bound_alpha( $n ) { 4862 _deprecated_function( __FUNCTION__, '6.3.0' ); 4863 4864 if ( is_numeric( $n ) ) { 4865 $n = (float) $n; 4866 if ( $n >= 0 && $n <= 1 ) { 4867 return $n; 4868 } 4869 } 4870 return 1; 4871 } 4872 4873 /** 4874 * Rounds and converts values of an RGB object. 4875 * 4876 * Direct port of TinyColor's function, lightly simplified to maintain 4877 * consistency with TinyColor. 4878 * 4879 * @link https://github.com/bgrins/TinyColor 4880 * 4881 * @since 5.8.0 4882 * @deprecated 6.3.0 4883 * 4884 * @access private 4885 * 4886 * @param array $rgb_color RGB object. 4887 * @return array Rounded and converted RGB object. 4888 */ 4889 function wp_tinycolor_rgb_to_rgb( $rgb_color ) { 4890 _deprecated_function( __FUNCTION__, '6.3.0' ); 4891 4892 return array( 4893 'r' => wp_tinycolor_bound01( $rgb_color['r'], 255 ) * 255, 4894 'g' => wp_tinycolor_bound01( $rgb_color['g'], 255 ) * 255, 4895 'b' => wp_tinycolor_bound01( $rgb_color['b'], 255 ) * 255, 4896 ); 4897 } 4898 4899 /** 4900 * Helper function for hsl to rgb conversion. 4901 * 4902 * Direct port of TinyColor's function, lightly simplified to maintain 4903 * consistency with TinyColor. 4904 * 4905 * @link https://github.com/bgrins/TinyColor 4906 * 4907 * @since 5.8.0 4908 * @deprecated 6.3.0 4909 * 4910 * @access private 4911 * 4912 * @param float $p first component. 4913 * @param float $q second component. 4914 * @param float $t third component. 4915 * @return float R, G, or B component. 4916 */ 4917 function wp_tinycolor_hue_to_rgb( $p, $q, $t ) { 4918 _deprecated_function( __FUNCTION__, '6.3.0' ); 4919 4920 if ( $t < 0 ) { 4921 ++$t; 4922 } 4923 if ( $t > 1 ) { 4924 --$t; 4925 } 4926 if ( $t < 1 / 6 ) { 4927 return $p + ( $q - $p ) * 6 * $t; 4928 } 4929 if ( $t < 1 / 2 ) { 4930 return $q; 4931 } 4932 if ( $t < 2 / 3 ) { 4933 return $p + ( $q - $p ) * ( 2 / 3 - $t ) * 6; 4934 } 4935 return $p; 4936 } 4937 4938 /** 4939 * Converts an HSL object to an RGB object with converted and rounded values. 4940 * 4941 * Direct port of TinyColor's function, lightly simplified to maintain 4942 * consistency with TinyColor. 4943 * 4944 * @link https://github.com/bgrins/TinyColor 4945 * 4946 * @since 5.8.0 4947 * @deprecated 6.3.0 4948 * 4949 * @access private 4950 * 4951 * @param array $hsl_color HSL object. 4952 * @return array Rounded and converted RGB object. 4953 */ 4954 function wp_tinycolor_hsl_to_rgb( $hsl_color ) { 4955 _deprecated_function( __FUNCTION__, '6.3.0' ); 4956 4957 $h = wp_tinycolor_bound01( $hsl_color['h'], 360 ); 4958 $s = wp_tinycolor_bound01( $hsl_color['s'], 100 ); 4959 $l = wp_tinycolor_bound01( $hsl_color['l'], 100 ); 4960 4961 if ( 0 === $s ) { 4962 // Achromatic. 4963 $r = $l; 4964 $g = $l; 4965 $b = $l; 4966 } else { 4967 $q = $l < 0.5 ? $l * ( 1 + $s ) : $l + $s - $l * $s; 4968 $p = 2 * $l - $q; 4969 $r = wp_tinycolor_hue_to_rgb( $p, $q, $h + 1 / 3 ); 4970 $g = wp_tinycolor_hue_to_rgb( $p, $q, $h ); 4971 $b = wp_tinycolor_hue_to_rgb( $p, $q, $h - 1 / 3 ); 4972 } 4973 4974 return array( 4975 'r' => $r * 255, 4976 'g' => $g * 255, 4977 'b' => $b * 255, 4978 ); 4979 } 4980 4981 /** 4982 * Parses hex, hsl, and rgb CSS strings using the same regex as TinyColor v1.4.2 4983 * used in the JavaScript. Only colors output from react-color are implemented. 4984 * 4985 * Direct port of TinyColor's function, lightly simplified to maintain 4986 * consistency with TinyColor. 4987 * 4988 * @link https://github.com/bgrins/TinyColor 4989 * @link https://github.com/casesandberg/react-color/ 4990 * 4991 * @since 5.8.0 4992 * @since 5.9.0 Added alpha processing. 4993 * @deprecated 6.3.0 4994 * 4995 * @access private 4996 * 4997 * @param string $color_str CSS color string. 4998 * @return array RGB object. 4999 */ 5000 function wp_tinycolor_string_to_rgb( $color_str ) { 5001 _deprecated_function( __FUNCTION__, '6.3.0' ); 5002 5003 $color_str = strtolower( trim( $color_str ) ); 5004 5005 $css_integer = '[-\\+]?\\d+%?'; 5006 $css_number = '[-\\+]?\\d*\\.\\d+%?'; 5007 5008 $css_unit = '(?:' . $css_number . ')|(?:' . $css_integer . ')'; 5009 5010 $permissive_match3 = '[\\s|\\(]+(' . $css_unit . ')[,|\\s]+(' . $css_unit . ')[,|\\s]+(' . $css_unit . ')\\s*\\)?'; 5011 $permissive_match4 = '[\\s|\\(]+(' . $css_unit . ')[,|\\s]+(' . $css_unit . ')[,|\\s]+(' . $css_unit . ')[,|\\s]+(' . $css_unit . ')\\s*\\)?'; 5012 5013 $rgb_regexp = '/^rgb' . $permissive_match3 . '$/'; 5014 if ( preg_match( $rgb_regexp, $color_str, $match ) ) { 5015 $rgb = wp_tinycolor_rgb_to_rgb( 5016 array( 5017 'r' => $match[1], 5018 'g' => $match[2], 5019 'b' => $match[3], 5020 ) 5021 ); 5022 5023 $rgb['a'] = 1; 5024 5025 return $rgb; 5026 } 5027 5028 $rgba_regexp = '/^rgba' . $permissive_match4 . '$/'; 5029 if ( preg_match( $rgba_regexp, $color_str, $match ) ) { 5030 $rgb = wp_tinycolor_rgb_to_rgb( 5031 array( 5032 'r' => $match[1], 5033 'g' => $match[2], 5034 'b' => $match[3], 5035 ) 5036 ); 5037 5038 $rgb['a'] = _wp_tinycolor_bound_alpha( $match[4] ); 5039 5040 return $rgb; 5041 } 5042 5043 $hsl_regexp = '/^hsl' . $permissive_match3 . '$/'; 5044 if ( preg_match( $hsl_regexp, $color_str, $match ) ) { 5045 $rgb = wp_tinycolor_hsl_to_rgb( 5046 array( 5047 'h' => $match[1], 5048 's' => $match[2], 5049 'l' => $match[3], 5050 ) 5051 ); 5052 5053 $rgb['a'] = 1; 5054 5055 return $rgb; 5056 } 5057 5058 $hsla_regexp = '/^hsla' . $permissive_match4 . '$/'; 5059 if ( preg_match( $hsla_regexp, $color_str, $match ) ) { 5060 $rgb = wp_tinycolor_hsl_to_rgb( 5061 array( 5062 'h' => $match[1], 5063 's' => $match[2], 5064 'l' => $match[3], 5065 ) 5066 ); 5067 5068 $rgb['a'] = _wp_tinycolor_bound_alpha( $match[4] ); 5069 5070 return $rgb; 5071 } 5072 5073 $hex8_regexp = '/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/'; 5074 if ( preg_match( $hex8_regexp, $color_str, $match ) ) { 5075 $rgb = wp_tinycolor_rgb_to_rgb( 5076 array( 5077 'r' => base_convert( $match[1], 16, 10 ), 5078 'g' => base_convert( $match[2], 16, 10 ), 5079 'b' => base_convert( $match[3], 16, 10 ), 5080 ) 5081 ); 5082 5083 $rgb['a'] = _wp_tinycolor_bound_alpha( 5084 base_convert( $match[4], 16, 10 ) / 255 5085 ); 5086 5087 return $rgb; 5088 } 5089 5090 $hex6_regexp = '/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/'; 5091 if ( preg_match( $hex6_regexp, $color_str, $match ) ) { 5092 $rgb = wp_tinycolor_rgb_to_rgb( 5093 array( 5094 'r' => base_convert( $match[1], 16, 10 ), 5095 'g' => base_convert( $match[2], 16, 10 ), 5096 'b' => base_convert( $match[3], 16, 10 ), 5097 ) 5098 ); 5099 5100 $rgb['a'] = 1; 5101 5102 return $rgb; 5103 } 5104 5105 $hex4_regexp = '/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/'; 5106 if ( preg_match( $hex4_regexp, $color_str, $match ) ) { 5107 $rgb = wp_tinycolor_rgb_to_rgb( 5108 array( 5109 'r' => base_convert( $match[1] . $match[1], 16, 10 ), 5110 'g' => base_convert( $match[2] . $match[2], 16, 10 ), 5111 'b' => base_convert( $match[3] . $match[3], 16, 10 ), 5112 ) 5113 ); 5114 5115 $rgb['a'] = _wp_tinycolor_bound_alpha( 5116 base_convert( $match[4] . $match[4], 16, 10 ) / 255 5117 ); 5118 5119 return $rgb; 5120 } 5121 5122 $hex3_regexp = '/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/'; 5123 if ( preg_match( $hex3_regexp, $color_str, $match ) ) { 5124 $rgb = wp_tinycolor_rgb_to_rgb( 5125 array( 5126 'r' => base_convert( $match[1] . $match[1], 16, 10 ), 5127 'g' => base_convert( $match[2] . $match[2], 16, 10 ), 5128 'b' => base_convert( $match[3] . $match[3], 16, 10 ), 5129 ) 5130 ); 5131 5132 $rgb['a'] = 1; 5133 5134 return $rgb; 5135 } 5136 5137 /* 5138 * The JS color picker considers the string "transparent" to be a hex value, 5139 * so we need to handle it here as a special case. 5140 */ 5141 if ( 'transparent' === $color_str ) { 5142 return array( 5143 'r' => 0, 5144 'g' => 0, 5145 'b' => 0, 5146 'a' => 0, 5147 ); 5148 } 5149 } 5150 5151 /** 5152 * Returns the prefixed id for the duotone filter for use as a CSS id. 5153 * 5154 * @since 5.9.1 5155 * @deprecated 6.3.0 5156 * 5157 * @access private 5158 * 5159 * @param array $preset Duotone preset value as seen in theme.json. 5160 * @return string Duotone filter CSS id. 5161 */ 5162 function wp_get_duotone_filter_id( $preset ) { 5163 _deprecated_function( __FUNCTION__, '6.3.0' ); 5164 return WP_Duotone::get_filter_id_from_preset( $preset ); 5165 } 5166 5167 /** 5168 * Returns the CSS filter property url to reference the rendered SVG. 5169 * 5170 * @since 5.9.0 5171 * @since 6.1.0 Allow unset for preset colors. 5172 * @deprecated 6.3.0 5173 * 5174 * @access private 5175 * 5176 * @param array $preset Duotone preset value as seen in theme.json. 5177 * @return string Duotone CSS filter property url value. 5178 */ 5179 function wp_get_duotone_filter_property( $preset ) { 5180 _deprecated_function( __FUNCTION__, '6.3.0' ); 5181 return WP_Duotone::get_filter_css_property_value_from_preset( $preset ); 5182 } 5183 5184 /** 5185 * Returns the duotone filter SVG string for the preset. 5186 * 5187 * @since 5.9.1 5188 * @deprecated 6.3.0 5189 * 5190 * @access private 5191 * 5192 * @param array $preset Duotone preset value as seen in theme.json. 5193 * @return string Duotone SVG filter. 5194 */ 5195 function wp_get_duotone_filter_svg( $preset ) { 5196 _deprecated_function( __FUNCTION__, '6.3.0' ); 5197 return WP_Duotone::get_filter_svg_from_preset( $preset ); 5198 } 5199 5200 /** 5201 * Registers the style and colors block attributes for block types that support it. 5202 * 5203 * @since 5.8.0 5204 * @deprecated 6.3.0 Use WP_Duotone::register_duotone_support() instead. 5205 * 5206 * @access private 5207 * 5208 * @param WP_Block_Type $block_type Block Type. 5209 */ 5210 function wp_register_duotone_support( $block_type ) { 5211 _deprecated_function( __FUNCTION__, '6.3.0', 'WP_Duotone::register_duotone_support' ); 5212 return WP_Duotone::register_duotone_support( $block_type ); 5213 } 5214 5215 /** 5216 * Renders out the duotone stylesheet and SVG. 5217 * 5218 * @since 5.8.0 5219 * @since 6.1.0 Allow unset for preset colors. 5220 * @deprecated 6.3.0 Use WP_Duotone::render_duotone_support() instead. 5221 * 5222 * @access private 5223 * 5224 * @param string $block_content Rendered block content. 5225 * @param array $block Block object. 5226 * @return string Filtered block content. 5227 */ 5228 function wp_render_duotone_support( $block_content, $block ) { 5229 _deprecated_function( __FUNCTION__, '6.3.0', 'WP_Duotone::render_duotone_support' ); 5230 return WP_Duotone::render_duotone_support( $block_content, $block ); 5231 } 5232 5233 /** 5234 * Returns a string containing the SVGs to be referenced as filters (duotone). 5235 * 5236 * @since 5.9.1 5237 * @deprecated 6.3.0 SVG generation is handled on a per-block basis in block supports. 5238 * 5239 * @return string 5240 */ 5241 function wp_get_global_styles_svg_filters() { 5242 _deprecated_function( __FUNCTION__, '6.3.0' ); 5243 5244 /* 5245 * Ignore cache when the development mode is set to 'theme', so it doesn't interfere with the theme 5246 * developer's workflow. 5247 */ 5248 $can_use_cached = wp_get_development_mode() !== 'theme'; 5249 $cache_group = 'theme_json'; 5250 $cache_key = 'wp_get_global_styles_svg_filters'; 5251 if ( $can_use_cached ) { 5252 $cached = wp_cache_get( $cache_key, $cache_group ); 5253 if ( $cached ) { 5254 return $cached; 5255 } 5256 } 5257 5258 $supports_theme_json = wp_theme_has_theme_json(); 5259 5260 $origins = array( 'default', 'theme', 'custom' ); 5261 if ( ! $supports_theme_json ) { 5262 $origins = array( 'default' ); 5263 } 5264 5265 $tree = WP_Theme_JSON_Resolver::get_merged_data(); 5266 $svgs = $tree->get_svg_filters( $origins ); 5267 5268 if ( $can_use_cached ) { 5269 wp_cache_set( $cache_key, $svgs, $cache_group ); 5270 } 5271 5272 return $svgs; 5273 } 5274 5275 /** 5276 * Renders the SVG filters supplied by theme.json. 5277 * 5278 * Note that this doesn't render the per-block user-defined 5279 * filters which are handled by wp_render_duotone_support, 5280 * but it should be rendered before the filtered content 5281 * in the body to satisfy Safari's rendering quirks. 5282 * 5283 * @since 5.9.1 5284 * @deprecated 6.3.0 SVG generation is handled on a per-block basis in block supports. 5285 */ 5286 function wp_global_styles_render_svg_filters() { 5287 _deprecated_function( __FUNCTION__, '6.3.0' ); 5288 5289 /* 5290 * When calling via the in_admin_header action, we only want to render the 5291 * SVGs on block editor pages. 5292 */ 5293 if ( 5294 is_admin() && 5295 ! get_current_screen()->is_block_editor() 5296 ) { 5297 return; 5298 } 5299 5300 $filters = wp_get_global_styles_svg_filters(); 5301 if ( ! empty( $filters ) ) { 5302 echo $filters; 5303 } 5304 } -
trunk/src/wp-includes/global-styles-and-settings.php
r56094 r56101 287 287 288 288 return $stylesheet; 289 }290 291 /**292 * Returns a string containing the SVGs to be referenced as filters (duotone).293 *294 * @since 5.9.1295 *296 * @return string297 */298 function wp_get_global_styles_svg_filters() {299 /*300 * Ignore cache when the development mode is set to 'theme', so it doesn't interfere with the theme301 * developer's workflow.302 */303 $can_use_cached = wp_get_development_mode() !== 'theme';304 $cache_group = 'theme_json';305 $cache_key = 'wp_get_global_styles_svg_filters';306 if ( $can_use_cached ) {307 $cached = wp_cache_get( $cache_key, $cache_group );308 if ( $cached ) {309 return $cached;310 }311 }312 313 $supports_theme_json = wp_theme_has_theme_json();314 315 $origins = array( 'default', 'theme', 'custom' );316 if ( ! $supports_theme_json ) {317 $origins = array( 'default' );318 }319 320 $tree = WP_Theme_JSON_Resolver::get_merged_data();321 $svgs = $tree->get_svg_filters( $origins );322 323 if ( $can_use_cached ) {324 wp_cache_set( $cache_key, $svgs, $cache_group );325 }326 327 return $svgs;328 289 } 329 290 -
trunk/src/wp-includes/script-loader.php
r56064 r56101 2481 2481 2482 2482 /** 2483 * Renders the SVG filters supplied by theme.json.2484 *2485 * Note that this doesn't render the per-block user-defined2486 * filters which are handled by wp_render_duotone_support,2487 * but it should be rendered before the filtered content2488 * in the body to satisfy Safari's rendering quirks.2489 *2490 * @since 5.9.12491 */2492 function wp_global_styles_render_svg_filters() {2493 /*2494 * When calling via the in_admin_header action, we only want to render the2495 * SVGs on block editor pages.2496 */2497 if (2498 is_admin() &&2499 ! get_current_screen()->is_block_editor()2500 ) {2501 return;2502 }2503 2504 $filters = wp_get_global_styles_svg_filters();2505 if ( ! empty( $filters ) ) {2506 echo $filters;2507 }2508 }2509 2510 /**2511 2483 * Checks if the editor scripts and styles for all registered block types 2512 2484 * should be enqueued on the current screen. -
trunk/src/wp-settings.php
r56082 r56101 176 176 require ABSPATH . WPINC . '/class-wp-theme-json.php'; 177 177 require ABSPATH . WPINC . '/class-wp-theme-json-resolver.php'; 178 require ABSPATH . WPINC . '/class-wp-duotone.php'; 178 179 require ABSPATH . WPINC . '/global-styles-and-settings.php'; 179 180 require ABSPATH . WPINC . '/class-wp-block-template.php'; -
trunk/tests/phpunit/tests/theme/wpGetGlobalStylesSvgFilters.php
r56042 r56101 1 <?php2 /**3 * Tests wp_get_global_styles_svg_filters().4 *5 * @group themes6 */7 class Tests_Theme_wpGetGlobalStylesSvgFilters extends WP_UnitTestCase {8 public function set_up() {9 parent::set_up();10 // Clear caches.11 wp_clean_themes_cache();12 }13 14 public function tear_down() {15 wp_clean_themes_cache();16 17 parent::tear_down();18 }19 20 /**21 * Tests that switching themes recalculates the svgs.22 *23 * @covers ::wp_get_global_styles_svg_filters24 *25 * @ticket 5756826 */27 public function test_switching_themes_should_recalculate_svg() {28 $svg_for_default_theme = wp_get_global_styles_svg_filters();29 switch_theme( 'block-theme' );30 $svg_for_block_theme = wp_get_global_styles_svg_filters();31 switch_theme( WP_DEFAULT_THEME );32 33 $this->assertStringContainsString( '<svg', $svg_for_default_theme, 'Default theme should contain SVG' );34 $this->assertStringContainsString( '<svg', $svg_for_default_theme, 'Block theme should contain SVG' );35 $this->assertNotSame( $svg_for_default_theme, $svg_for_block_theme, 'Cache value should have changed' );36 }37 38 /**39 * Tests that the function relies on the development mode for whether to use caching.40 *41 * @ticket 5748742 *43 * @covers ::wp_get_global_styles_svg_filters44 */45 public function test_caching_is_used_when_developing_theme() {46 global $_wp_tests_development_mode;47 48 switch_theme( 'block-theme' );49 50 // Store SVG in cache.51 $svg = '<svg></svg>';52 wp_cache_set( 'wp_get_global_styles_svg_filters', $svg, 'theme_json' );53 54 // By default, caching should be used, so the above value will be returned.55 $_wp_tests_development_mode = '';56 $this->assertSame( $svg, wp_get_global_styles_svg_filters(), 'Caching was not used despite development mode disabled' );57 58 // When the development mode is set to 'theme', caching should not be used.59 $_wp_tests_development_mode = 'theme';60 $this->assertNotSame( $svg, wp_get_global_styles_svg_filters(), 'Caching was used despite theme development mode' );61 }62 } -
trunk/tests/phpunit/tests/theme/wpThemeJson.php
r56083 r56101 637 637 ); 638 638 639 $variables = "body{--wp--preset--color--grey: grey;--wp--preset--gradient--custom-gradient: linear-gradient(135deg,rgba(0,0,0) 0%,rgb(0,0,0) 100%);--wp--preset--duotone--custom-duotone: url('#wp-duotone-custom-duotone');--wp--preset--font-family--small: 14px;--wp--preset--font-family--big: 41px;}.wp-block-group{--wp--custom--base-font: 16;--wp--custom--line-height--small: 1.2;--wp--custom--line-height--medium: 1.4;--wp--custom--line-height--large: 1.8;}";639 $variables = 'body{--wp--preset--color--grey: grey;--wp--preset--gradient--custom-gradient: linear-gradient(135deg,rgba(0,0,0) 0%,rgb(0,0,0) 100%);--wp--preset--font-family--small: 14px;--wp--preset--font-family--big: 41px;}.wp-block-group{--wp--custom--base-font: 16;--wp--custom--line-height--small: 1.2;--wp--custom--line-height--medium: 1.4;--wp--custom--line-height--large: 1.8;}'; 640 640 $styles = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}body .is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}body .is-layout-flex > *{margin: 0;}body .is-layout-grid{display: grid;}body .is-layout-grid > *{margin: 0;}body{color: var(--wp--preset--color--grey);}a:where(:not(.wp-element-button)){background-color: #333;color: #111;}.wp-element-button, .wp-block-button__link{box-shadow: 10px 10px 5px 0px rgba(0,0,0,0.66);}.wp-block-group{background: var(--wp--preset--gradient--custom-gradient);border-radius: 10px;padding: 24px;}.wp-block-group a:where(:not(.wp-element-button)){color: #111;}.wp-block-heading{color: #123456;}.wp-block-heading a:where(:not(.wp-element-button)){background-color: #333;color: #111;font-size: 60px;}.wp-block-post-date{color: #123456;}.wp-block-post-date a:where(:not(.wp-element-button)){background-color: #777;color: #555;}.wp-block-post-excerpt{column-count: 2;}.wp-block-image{margin-bottom: 30px;}.wp-block-image img, .wp-block-image .wp-block-image__crop-area, .wp-block-image .components-placeholder{border-top-left-radius: 10px;border-bottom-right-radius: 1em;}.wp-block-image img, .wp-block-image .components-placeholder{filter: var(--wp--preset--duotone--custom-duotone);}'; 641 641 $presets = '.has-grey-color{color: var(--wp--preset--color--grey) !important;}.has-grey-background-color{background-color: var(--wp--preset--color--grey) !important;}.has-grey-border-color{border-color: var(--wp--preset--color--grey) !important;}.has-custom-gradient-gradient-background{background: var(--wp--preset--gradient--custom-gradient) !important;}.has-small-font-family{font-family: var(--wp--preset--font-family--small) !important;}.has-big-font-family{font-family: var(--wp--preset--font-family--big) !important;}';
Note: See TracChangeset
for help on using the changeset viewer.