| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Typography block support flag. 4 * 5 * @package WordPress 6 * @since 5.6.0 7 */ 8 9 /** 10 * Registers the style and typography block attributes for block types that support it. 11 * 12 * @since 5.6.0 13 * @since 6.3.0 Added support for text-columns. 14 * @since 7.0.0 Added support for text-indent. 15 * @access private 16 * 17 * @param WP_Block_Type $block_type Block Type. 18 */ 19 function wp_register_typography_support( $block_type ) { 20 if ( ! ( $block_type instanceof WP_Block_Type ) ) { 21 return; 22 } 23 24 $typography_supports = $block_type->supports['typography'] ?? false; 25 if ( ! $typography_supports ) { 26 return; 27 } 28 29 $has_font_family_support = $typography_supports['__experimentalFontFamily'] ?? false; 30 $has_font_size_support = $typography_supports['fontSize'] ?? false; 31 $has_font_style_support = $typography_supports['__experimentalFontStyle'] ?? false; 32 $has_font_weight_support = $typography_supports['__experimentalFontWeight'] ?? false; 33 $has_letter_spacing_support = $typography_supports['__experimentalLetterSpacing'] ?? false; 34 $has_line_height_support = $typography_supports['lineHeight'] ?? false; 35 $has_text_align_support = $typography_supports['textAlign'] ?? false; 36 $has_text_columns_support = $typography_supports['textColumns'] ?? false; 37 $has_text_decoration_support = $typography_supports['__experimentalTextDecoration'] ?? false; 38 $has_text_transform_support = $typography_supports['__experimentalTextTransform'] ?? false; 39 $has_text_indent_support = $typography_supports['textIndent'] ?? false; 40 $has_writing_mode_support = $typography_supports['__experimentalWritingMode'] ?? false; 41 42 $has_typography_support = $has_font_family_support 43 || $has_font_size_support 44 || $has_font_style_support 45 || $has_font_weight_support 46 || $has_letter_spacing_support 47 || $has_line_height_support 48 || $has_text_align_support 49 || $has_text_columns_support 50 || $has_text_decoration_support 51 || $has_text_transform_support 52 || $has_text_indent_support 53 || $has_writing_mode_support; 54 55 if ( ! $block_type->attributes ) { 56 $block_type->attributes = array(); 57 } 58 59 if ( $has_typography_support && ! array_key_exists( 'style', $block_type->attributes ) ) { 60 $block_type->attributes['style'] = array( 61 'type' => 'object', 62 ); 63 } 64 65 if ( $has_font_size_support && ! array_key_exists( 'fontSize', $block_type->attributes ) ) { 66 $block_type->attributes['fontSize'] = array( 67 'type' => 'string', 68 ); 69 } 70 71 if ( $has_font_family_support && ! array_key_exists( 'fontFamily', $block_type->attributes ) ) { 72 $block_type->attributes['fontFamily'] = array( 73 'type' => 'string', 74 ); 75 } 76 } 77 78 /** 79 * Adds CSS classes and inline styles for typography features such as font sizes 80 * to the incoming attributes array. This will be applied to the block markup in 81 * the front-end. 82 * 83 * @since 5.6.0 84 * @since 6.1.0 Used the style engine to generate CSS and classnames. 85 * @since 6.3.0 Added support for text-columns. 86 * @since 7.0.0 Added support for text-indent. 87 * @access private 88 * 89 * @param WP_Block_Type $block_type Block type. 90 * @param array $block_attributes Block attributes. 91 * @return array Typography CSS classes and inline styles. 92 */ 93 function wp_apply_typography_support( $block_type, $block_attributes ) { 94 if ( ! ( $block_type instanceof WP_Block_Type ) ) { 95 return array(); 96 } 97 98 $typography_supports = $block_type->supports['typography'] ?? false; 99 if ( ! $typography_supports ) { 100 return array(); 101 } 102 103 if ( wp_should_skip_block_supports_serialization( $block_type, 'typography' ) ) { 104 return array(); 105 } 106 107 $has_font_family_support = $typography_supports['__experimentalFontFamily'] ?? false; 108 $has_font_size_support = $typography_supports['fontSize'] ?? false; 109 $has_font_style_support = $typography_supports['__experimentalFontStyle'] ?? false; 110 $has_font_weight_support = $typography_supports['__experimentalFontWeight'] ?? false; 111 $has_letter_spacing_support = $typography_supports['__experimentalLetterSpacing'] ?? false; 112 $has_line_height_support = $typography_supports['lineHeight'] ?? false; 113 $has_text_align_support = $typography_supports['textAlign'] ?? false; 114 $has_text_columns_support = $typography_supports['textColumns'] ?? false; 115 $has_text_decoration_support = $typography_supports['__experimentalTextDecoration'] ?? false; 116 $has_text_transform_support = $typography_supports['__experimentalTextTransform'] ?? false; 117 $has_text_indent_support = $typography_supports['textIndent'] ?? false; 118 $has_writing_mode_support = $typography_supports['__experimentalWritingMode'] ?? false; 119 120 // Whether to skip individual block support features. 121 $should_skip_font_size = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontSize' ); 122 $should_skip_font_family = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontFamily' ); 123 $should_skip_font_style = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontStyle' ); 124 $should_skip_font_weight = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontWeight' ); 125 $should_skip_line_height = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'lineHeight' ); 126 $should_skip_text_align = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textAlign' ); 127 $should_skip_text_columns = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textColumns' ); 128 $should_skip_text_decoration = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textDecoration' ); 129 $should_skip_text_transform = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textTransform' ); 130 $should_skip_letter_spacing = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'letterSpacing' ); 131 $should_skip_text_indent = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textIndent' ); 132 $should_skip_writing_mode = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'writingMode' ); 133 134 $typography_block_styles = array(); 135 if ( $has_font_size_support && ! $should_skip_font_size ) { 136 $preset_font_size = array_key_exists( 'fontSize', $block_attributes ) 137 ? "var:preset|font-size|{$block_attributes['fontSize']}" 138 : null; 139 $custom_font_size = $block_attributes['style']['typography']['fontSize'] ?? null; 140 $typography_block_styles['fontSize'] = $preset_font_size ? $preset_font_size : wp_get_typography_font_size_value( 141 array( 142 'size' => $custom_font_size, 143 ) 144 ); 145 } 146 147 if ( $has_font_family_support && ! $should_skip_font_family ) { 148 $preset_font_family = array_key_exists( 'fontFamily', $block_attributes ) 149 ? "var:preset|font-family|{$block_attributes['fontFamily']}" 150 : null; 151 $custom_font_family = isset( $block_attributes['style']['typography']['fontFamily'] ) 152 ? wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['fontFamily'], 'font-family' ) 153 : null; 154 $typography_block_styles['fontFamily'] = $preset_font_family ? $preset_font_family : $custom_font_family; 155 } 156 157 if ( 158 $has_font_style_support && 159 ! $should_skip_font_style && 160 isset( $block_attributes['style']['typography']['fontStyle'] ) 161 ) { 162 $typography_block_styles['fontStyle'] = wp_typography_get_preset_inline_style_value( 163 $block_attributes['style']['typography']['fontStyle'], 164 'font-style' 165 ); 166 } 167 168 if ( 169 $has_font_weight_support && 170 ! $should_skip_font_weight && 171 isset( $block_attributes['style']['typography']['fontWeight'] ) 172 ) { 173 $typography_block_styles['fontWeight'] = wp_typography_get_preset_inline_style_value( 174 $block_attributes['style']['typography']['fontWeight'], 175 'font-weight' 176 ); 177 } 178 179 if ( $has_line_height_support && ! $should_skip_line_height ) { 180 $typography_block_styles['lineHeight'] = $block_attributes['style']['typography']['lineHeight'] ?? null; 181 } 182 183 if ( $has_text_align_support && ! $should_skip_text_align ) { 184 $typography_block_styles['textAlign'] = $block_attributes['style']['typography']['textAlign'] ?? null; 185 } 186 187 if ( $has_text_columns_support && ! $should_skip_text_columns && isset( $block_attributes['style']['typography']['textColumns'] ) ) { 188 $typography_block_styles['textColumns'] = $block_attributes['style']['typography']['textColumns'] ?? null; 189 } 190 191 if ( 192 $has_text_decoration_support && 193 ! $should_skip_text_decoration && 194 isset( $block_attributes['style']['typography']['textDecoration'] ) 195 ) { 196 $typography_block_styles['textDecoration'] = wp_typography_get_preset_inline_style_value( 197 $block_attributes['style']['typography']['textDecoration'], 198 'text-decoration' 199 ); 200 } 201 202 if ( 203 $has_text_transform_support && 204 ! $should_skip_text_transform && 205 isset( $block_attributes['style']['typography']['textTransform'] ) 206 ) { 207 $typography_block_styles['textTransform'] = wp_typography_get_preset_inline_style_value( 208 $block_attributes['style']['typography']['textTransform'], 209 'text-transform' 210 ); 211 } 212 213 if ( 214 $has_letter_spacing_support && 215 ! $should_skip_letter_spacing && 216 isset( $block_attributes['style']['typography']['letterSpacing'] ) 217 ) { 218 $typography_block_styles['letterSpacing'] = wp_typography_get_preset_inline_style_value( 219 $block_attributes['style']['typography']['letterSpacing'], 220 'letter-spacing' 221 ); 222 } 223 224 if ( $has_writing_mode_support && 225 ! $should_skip_writing_mode && 226 isset( $block_attributes['style']['typography']['writingMode'] ) 227 ) { 228 $typography_block_styles['writingMode'] = $block_attributes['style']['typography']['writingMode'] ?? null; 229 } 230 231 if ( $has_text_indent_support && ! $should_skip_text_indent && isset( $block_attributes['style']['typography']['textIndent'] ) ) { 232 $typography_block_styles['textIndent'] = $block_attributes['style']['typography']['textIndent'] ?? null; 233 } 234 235 $attributes = array(); 236 $classnames = array(); 237 $styles = wp_style_engine_get_styles( 238 array( 'typography' => $typography_block_styles ), 239 array( 'convert_vars_to_classnames' => true ) 240 ); 241 242 if ( ! empty( $styles['classnames'] ) ) { 243 $classnames[] = $styles['classnames']; 244 } 245 246 if ( $has_text_align_support && ! $should_skip_text_align && isset( $block_attributes['style']['typography']['textAlign'] ) ) { 247 $classnames[] = 'has-text-align-' . $block_attributes['style']['typography']['textAlign']; 248 } 249 250 if ( ! empty( $classnames ) ) { 251 $attributes['class'] = implode( ' ', $classnames ); 252 } 253 254 if ( ! empty( $styles['css'] ) ) { 255 $attributes['style'] = $styles['css']; 256 } 257 258 return $attributes; 259 } 260 261 /** 262 * Generates an inline style value for a typography feature e.g. text decoration, 263 * text transform, and font style. 264 * 265 * Note: This function is for backwards compatibility. 266 * * It is necessary to parse older blocks whose typography styles contain presets. 267 * * It mostly replaces the deprecated `wp_typography_get_css_variable_inline_style()`, 268 * but skips compiling a CSS declaration as the style engine takes over this role. 269 * @link https://github.com/wordpress/gutenberg/pull/27555 270 * 271 * @since 6.1.0 272 * 273 * @param string $style_value A raw style value for a single typography feature from a block's style attribute. 274 * @param string $css_property Slug for the CSS property the inline style sets. 275 * @return string A CSS inline style value. 276 */ 277 function wp_typography_get_preset_inline_style_value( $style_value, $css_property ) { 278 // If the style value is not a preset CSS variable go no further. 279 if ( empty( $style_value ) || ! str_contains( $style_value, "var:preset|{$css_property}|" ) ) { 280 return $style_value; 281 } 282 283 /* 284 * For backwards compatibility. 285 * Presets were removed in WordPress/gutenberg#27555. 286 * A preset CSS variable is the style. 287 * Gets the style value from the string and return CSS style. 288 */ 289 $index_to_splice = strrpos( $style_value, '|' ) + 1; 290 $slug = _wp_to_kebab_case( substr( $style_value, $index_to_splice ) ); 291 292 // Return the actual CSS inline style value, 293 // e.g. `var(--wp--preset--text-decoration--underline);`. 294 return sprintf( 'var(--wp--preset--%s--%s);', $css_property, $slug ); 295 } 296 297 /** 298 * Renders typography styles/content to the block wrapper. 299 * 300 * @since 6.1.0 301 * 302 * @param string $block_content Rendered block content. 303 * @param array $block Block object. 304 * @return string Filtered block content. 305 */ 306 function wp_render_typography_support( $block_content, $block ) { 307 if ( ! empty( $block['attrs']['fitText'] ) && $block['attrs']['fitText'] && ! is_admin() ) { 308 wp_enqueue_script_module( '@wordpress/block-editor/utils/fit-text-frontend' ); 309 310 // Add Interactivity API directives for fit text to work with client-side navigation. 311 if ( ! empty( $block_content ) ) { 312 $processor = new WP_HTML_Tag_Processor( $block_content ); 313 if ( $processor->next_tag() ) { 314 if ( ! $processor->get_attribute( 'data-wp-interactive' ) ) { 315 $processor->set_attribute( 'data-wp-interactive', true ); 316 } 317 $processor->set_attribute( 'data-wp-context---core-fit-text', 'core/fit-text::{"fontSize":""}' ); 318 $processor->set_attribute( 'data-wp-init---core-fit-text', 'core/fit-text::callbacks.init' ); 319 $processor->set_attribute( 'data-wp-style--font-size', 'core/fit-text::context.fontSize' ); 320 $block_content = $processor->get_updated_html(); 321 } 322 } 323 // fitText supersedes any other typography features 324 return $block_content; 325 } 326 if ( ! isset( $block['attrs']['style']['typography']['fontSize'] ) ) { 327 return $block_content; 328 } 329 330 $custom_font_size = $block['attrs']['style']['typography']['fontSize']; 331 $fluid_font_size = wp_get_typography_font_size_value( array( 'size' => $custom_font_size ) ); 332 333 /* 334 * Checks that $fluid_font_size does not match $custom_font_size, 335 * which means it's been mutated by the fluid font size functions. 336 */ 337 if ( ! empty( $fluid_font_size ) && $fluid_font_size !== $custom_font_size ) { 338 // Replaces the first instance of `font-size:$custom_font_size` with `font-size:$fluid_font_size`. 339 return preg_replace( '/font-size\s*:\s*' . preg_quote( $custom_font_size, '/' ) . '\s*;?/', 'font-size:' . esc_attr( $fluid_font_size ) . ';', $block_content, 1 ); 340 } 341 342 return $block_content; 343 } 344 345 /** 346 * Checks a string for a unit and value and returns an array 347 * consisting of `'value'` and `'unit'`, e.g. array( '42', 'rem' ). 348 * 349 * @since 6.1.0 350 * 351 * @param string|int|float $raw_value Raw size value from theme.json. 352 * @param array $options { 353 * Optional. An associative array of options. Default is empty array. 354 * 355 * @type string $coerce_to Coerce the value to rem or px. Default `'rem'`. 356 * @type int $root_size_value Value of root font size for rem|em <-> px conversion. Default `16`. 357 * @type string[] $acceptable_units An array of font size units. Default `array( 'rem', 'px', 'em' )`; 358 * } 359 * @return array|null An array consisting of `'value'` and `'unit'` properties on success. 360 * `null` on failure. 361 */ 362 function wp_get_typography_value_and_unit( $raw_value, $options = array() ) { 363 if ( ! is_string( $raw_value ) && ! is_int( $raw_value ) && ! is_float( $raw_value ) ) { 364 _doing_it_wrong( 365 __FUNCTION__, 366 __( 'Raw size value must be a string, integer, or float.' ), 367 '6.1.0' 368 ); 369 return null; 370 } 371 372 if ( empty( $raw_value ) ) { 373 return null; 374 } 375 376 // Converts numbers to pixel values by default. 377 if ( is_numeric( $raw_value ) ) { 378 $raw_value = $raw_value . 'px'; 379 } 380 381 $defaults = array( 382 'coerce_to' => '', 383 'root_size_value' => 16, 384 'acceptable_units' => array( 'rem', 'px', 'em' ), 385 ); 386 387 $options = wp_parse_args( $options, $defaults ); 388 389 $acceptable_units_group = implode( '|', $options['acceptable_units'] ); 390 $pattern = '/^(\d*\.?\d+)(' . $acceptable_units_group . '){1,1}$/'; 391 392 preg_match( $pattern, $raw_value, $matches ); 393 394 // Bails out if not a number value and a px or rem unit. 395 if ( ! isset( $matches[1] ) || ! isset( $matches[2] ) ) { 396 return null; 397 } 398 399 $value = $matches[1]; 400 $unit = $matches[2]; 401 402 /* 403 * Default browser font size. Later, possibly could inject some JS to 404 * compute this `getComputedStyle( document.querySelector( "html" ) ).fontSize`. 405 */ 406 if ( 'px' === $options['coerce_to'] && ( 'em' === $unit || 'rem' === $unit ) ) { 407 $value = $value * $options['root_size_value']; 408 $unit = $options['coerce_to']; 409 } 410 411 if ( 'px' === $unit && ( 'em' === $options['coerce_to'] || 'rem' === $options['coerce_to'] ) ) { 412 $value = $value / $options['root_size_value']; 413 $unit = $options['coerce_to']; 414 } 415 416 /* 417 * No calculation is required if swapping between em and rem yet, 418 * since we assume a root size value. Later we might like to differentiate between 419 * :root font size (rem) and parent element font size (em) relativity. 420 */ 421 if ( ( 'em' === $options['coerce_to'] || 'rem' === $options['coerce_to'] ) && ( 'em' === $unit || 'rem' === $unit ) ) { 422 $unit = $options['coerce_to']; 423 } 424 425 return array( 426 'value' => round( $value, 3 ), 427 'unit' => $unit, 428 ); 429 } 430 431 /** 432 * Internal implementation of CSS clamp() based on available min/max viewport 433 * width and min/max font sizes. 434 * 435 * @since 6.1.0 436 * @since 6.3.0 Checks for unsupported min/max viewport values that cause invalid clamp values. 437 * @since 6.5.0 Returns early when min and max viewport subtraction is zero to avoid division by zero. 438 * @access private 439 * 440 * @param array $args { 441 * Optional. An associative array of values to calculate a fluid formula 442 * for font size. Default is empty array. 443 * 444 * @type string $maximum_viewport_width Maximum size up to which type will have fluidity. 445 * @type string $minimum_viewport_width Minimum viewport size from which type will have fluidity. 446 * @type string $maximum_font_size Maximum font size for any clamp() calculation. 447 * @type string $minimum_font_size Minimum font size for any clamp() calculation. 448 * @type int $scale_factor A scale factor to determine how fast a font scales within boundaries. 449 * } 450 * @return string|null A font-size value using clamp() on success, otherwise null. 451 */ 452 function wp_get_computed_fluid_typography_value( $args = array() ) { 453 $maximum_viewport_width_raw = $args['maximum_viewport_width'] ?? null; 454 $minimum_viewport_width_raw = $args['minimum_viewport_width'] ?? null; 455 $maximum_font_size_raw = $args['maximum_font_size'] ?? null; 456 $minimum_font_size_raw = $args['minimum_font_size'] ?? null; 457 $scale_factor = $args['scale_factor'] ?? null; 458 459 // Normalizes the minimum font size in order to use the value for calculations. 460 $minimum_font_size = wp_get_typography_value_and_unit( $minimum_font_size_raw ); 461 462 /* 463 * We get a 'preferred' unit to keep units consistent when calculating, 464 * otherwise the result will not be accurate. 465 */ 466 $font_size_unit = $minimum_font_size['unit'] ?? 'rem'; 467 468 // Normalizes the maximum font size in order to use the value for calculations. 469 $maximum_font_size = wp_get_typography_value_and_unit( 470 $maximum_font_size_raw, 471 array( 472 'coerce_to' => $font_size_unit, 473 ) 474 ); 475 476 // Checks for mandatory min and max sizes, and protects against unsupported units. 477 if ( ! $maximum_font_size || ! $minimum_font_size ) { 478 return null; 479 } 480 481 // Uses rem for accessible fluid target font scaling. 482 $minimum_font_size_rem = wp_get_typography_value_and_unit( 483 $minimum_font_size_raw, 484 array( 485 'coerce_to' => 'rem', 486 ) 487 ); 488 489 // Viewport widths defined for fluid typography. Normalize units. 490 $maximum_viewport_width = wp_get_typography_value_and_unit( 491 $maximum_viewport_width_raw, 492 array( 493 'coerce_to' => $font_size_unit, 494 ) 495 ); 496 $minimum_viewport_width = wp_get_typography_value_and_unit( 497 $minimum_viewport_width_raw, 498 array( 499 'coerce_to' => $font_size_unit, 500 ) 501 ); 502 503 // Protects against unsupported units in min and max viewport widths. 504 if ( ! $minimum_viewport_width || ! $maximum_viewport_width ) { 505 return null; 506 } 507 508 // Calculates the linear factor denominator. If it's 0, we cannot calculate a fluid value. 509 $linear_factor_denominator = $maximum_viewport_width['value'] - $minimum_viewport_width['value']; 510 if ( empty( $linear_factor_denominator ) ) { 511 return null; 512 } 513 514 /* 515 * Build CSS rule. 516 * Borrowed from https://websemantics.uk/tools/responsive-font-calculator/. 517 */ 518 $view_port_width_offset = round( $minimum_viewport_width['value'] / 100, 3 ) . $font_size_unit; 519 $linear_factor = 100 * ( ( $maximum_font_size['value'] - $minimum_font_size['value'] ) / ( $linear_factor_denominator ) ); 520 $linear_factor_scaled = round( $linear_factor * $scale_factor, 3 ); 521 $linear_factor_scaled = empty( $linear_factor_scaled ) ? 1 : $linear_factor_scaled; 522 $fluid_target_font_size = implode( '', $minimum_font_size_rem ) . " + ((1vw - $view_port_width_offset) * $linear_factor_scaled)"; 523 524 return "clamp($minimum_font_size_raw, $fluid_target_font_size, $maximum_font_size_raw)"; 525 } 526 527 /** 528 * Returns a font-size value based on a given font-size preset. 529 * Takes into account fluid typography parameters and attempts to return a CSS 530 * formula depending on available, valid values. 531 * 532 * @since 6.1.0 533 * @since 6.1.1 Adjusted rules for min and max font sizes. 534 * @since 6.2.0 Added 'settings.typography.fluid.minFontSize' support. 535 * @since 6.3.0 Using layout.wideSize as max viewport width, and logarithmic scale factor to calculate minimum font scale. 536 * @since 6.4.0 Added configurable min and max viewport width values to the typography.fluid theme.json schema. 537 * @since 6.6.0 Deprecated bool argument $should_use_fluid_typography. 538 * @since 6.7.0 Font size presets can enable fluid typography individually, even if it’s disabled globally. 539 * 540 * @param array $preset { 541 * Required. fontSizes preset value as seen in theme.json. 542 * 543 * @type string $name Name of the font size preset. 544 * @type string $slug Kebab-case, unique identifier for the font size preset. 545 * @type string|int|float $size CSS font-size value, including units if applicable. 546 * } 547 * @param bool|array $settings Optional Theme JSON settings array that overrides any global theme settings. 548 * Default is false. 549 * @return string|null Font-size value or null if a size is not passed in $preset. 550 */ 551 552 553 function wp_get_typography_font_size_value( $preset, $settings = array() ) { 554 if ( ! isset( $preset['size'] ) ) { 555 return null; 556 } 557 558 /* 559 * Catches falsy values and 0/'0'. Fluid calculations cannot be performed on `0`. 560 * Also returns early when a preset font size explicitly disables fluid typography with `false`. 561 */ 562 $fluid_font_size_settings = $preset['fluid'] ?? null; 563 if ( false === $fluid_font_size_settings || empty( $preset['size'] ) ) { 564 return $preset['size']; 565 } 566 567 /* 568 * As a boolean (deprecated since 6.6), $settings acts as an override to switch fluid typography "on" (`true`) or "off" (`false`). 569 */ 570 if ( is_bool( $settings ) ) { 571 _deprecated_argument( __FUNCTION__, '6.6.0', __( '`boolean` type for second argument `$settings` is deprecated. Use `array()` instead.' ) ); 572 $settings = array( 573 'typography' => array( 574 'fluid' => $settings, 575 ), 576 ); 577 } 578 579 // Fallback to global settings as default. 580 $global_settings = wp_get_global_settings(); 581 $settings = wp_parse_args( 582 $settings, 583 $global_settings 584 ); 585 586 $typography_settings = $settings['typography'] ?? array(); 587 588 /* 589 * Return early when fluid typography is disabled in the settings, and there 590 * are no local settings to enable it for the individual preset. 591 * 592 * If this condition isn't met, either the settings or individual preset settings 593 * have enabled fluid typography. 594 */ 595 if ( empty( $typography_settings['fluid'] ) && empty( $fluid_font_size_settings ) ) { 596 return $preset['size']; 597 } 598 599 $fluid_settings = $typography_settings['fluid'] ?? array(); 600 $layout_settings = $settings['layout'] ?? array(); 601 602 // Defaults. 603 $default_maximum_viewport_width = '1600px'; 604 $default_minimum_viewport_width = '320px'; 605 $default_minimum_font_size_factor_max = 0.75; 606 $default_minimum_font_size_factor_min = 0.25; 607 $default_scale_factor = 1; 608 $default_minimum_font_size_limit = '14px'; 609 610 // Defaults overrides. 611 $minimum_viewport_width = $fluid_settings['minViewportWidth'] ?? $default_minimum_viewport_width; 612 $maximum_viewport_width = isset( $layout_settings['wideSize'] ) && ! empty( wp_get_typography_value_and_unit( $layout_settings['wideSize'] ) ) ? $layout_settings['wideSize'] : $default_maximum_viewport_width; 613 if ( isset( $fluid_settings['maxViewportWidth'] ) ) { 614 $maximum_viewport_width = $fluid_settings['maxViewportWidth']; 615 } 616 $has_min_font_size = isset( $fluid_settings['minFontSize'] ) && ! empty( wp_get_typography_value_and_unit( $fluid_settings['minFontSize'] ) ); 617 $minimum_font_size_limit = $has_min_font_size ? $fluid_settings['minFontSize'] : $default_minimum_font_size_limit; 618 619 // Try to grab explicit min and max fluid font sizes. 620 $minimum_font_size_raw = $fluid_font_size_settings['min'] ?? null; 621 $maximum_font_size_raw = $fluid_font_size_settings['max'] ?? null; 622 623 // Font sizes. 624 $preferred_size = wp_get_typography_value_and_unit( $preset['size'] ); 625 626 // Protects against unsupported units. 627 if ( empty( $preferred_size['unit'] ) ) { 628 return $preset['size']; 629 } 630 631 /* 632 * Normalizes the minimum font size limit according to the incoming unit, 633 * in order to perform comparative checks. 634 */ 635 $minimum_font_size_limit = wp_get_typography_value_and_unit( 636 $minimum_font_size_limit, 637 array( 638 'coerce_to' => $preferred_size['unit'], 639 ) 640 ); 641 642 // Don't enforce minimum font size if a font size has explicitly set a min and max value. 643 if ( ! empty( $minimum_font_size_limit ) && ( ! $minimum_font_size_raw && ! $maximum_font_size_raw ) ) { 644 /* 645 * If a minimum size was not passed to this function 646 * and the user-defined font size is lower than $minimum_font_size_limit, 647 * do not calculate a fluid value. 648 */ 649 if ( $preferred_size['value'] <= $minimum_font_size_limit['value'] ) { 650 return $preset['size']; 651 } 652 } 653 654 // If no fluid max font size is available use the incoming value. 655 if ( ! $maximum_font_size_raw ) { 656 $maximum_font_size_raw = $preferred_size['value'] . $preferred_size['unit']; 657 } 658 659 /* 660 * If no minimumFontSize is provided, create one using 661 * the given font size multiplied by the min font size scale factor. 662 */ 663 if ( ! $minimum_font_size_raw ) { 664 $preferred_font_size_in_px = 'px' === $preferred_size['unit'] ? $preferred_size['value'] : $preferred_size['value'] * 16; 665 666 /* 667 * The scale factor is a multiplier that affects how quickly the curve will move towards the minimum, 668 * that is, how quickly the size factor reaches 0 given increasing font size values. 669 * For a - b * log2(), lower values of b will make the curve move towards the minimum faster. 670 * The scale factor is constrained between min and max values. 671 */ 672 $minimum_font_size_factor = min( max( 1 - 0.075 * log( $preferred_font_size_in_px, 2 ), $default_minimum_font_size_factor_min ), $default_minimum_font_size_factor_max ); 673 $calculated_minimum_font_size = round( $preferred_size['value'] * $minimum_font_size_factor, 3 ); 674 675 // Only use calculated min font size if it's > $minimum_font_size_limit value. 676 if ( ! empty( $minimum_font_size_limit ) && $calculated_minimum_font_size <= $minimum_font_size_limit['value'] ) { 677 $minimum_font_size_raw = $minimum_font_size_limit['value'] . $minimum_font_size_limit['unit']; 678 } else { 679 $minimum_font_size_raw = $calculated_minimum_font_size . $preferred_size['unit']; 680 } 681 } 682 683 $fluid_font_size_value = wp_get_computed_fluid_typography_value( 684 array( 685 'minimum_viewport_width' => $minimum_viewport_width, 686 'maximum_viewport_width' => $maximum_viewport_width, 687 'minimum_font_size' => $minimum_font_size_raw, 688 'maximum_font_size' => $maximum_font_size_raw, 689 'scale_factor' => $default_scale_factor, 690 ) 691 ); 692 693 if ( ! empty( $fluid_font_size_value ) ) { 694 return $fluid_font_size_value; 695 } 696 697 return $preset['size']; 698 } 699 700 // Register the block support. 701 WP_Block_Supports::get_instance()->register( 702 'typography', 703 array( 704 'register_attribute' => 'wp_register_typography_support', 705 'apply' => 'wp_apply_typography_support', 706 ) 707 );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Fri Jun 26 08:20:11 2026 | Cross-referenced by PHPXref |