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