Geen omschrijving

border.php 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <?php
  2. /**
  3. * Border block support flag.
  4. *
  5. * @package WordPress
  6. * @since 5.8.0
  7. */
  8. /**
  9. * Registers the style attribute used by the border feature if needed for block
  10. * types that support borders.
  11. *
  12. * @since 5.8.0
  13. * @access private
  14. *
  15. * @param WP_Block_Type $block_type Block Type.
  16. */
  17. function wp_register_border_support( $block_type ) {
  18. // Determine if any border related features are supported.
  19. $has_border_support = block_has_support( $block_type, array( '__experimentalBorder' ) );
  20. $has_border_color_support = wp_has_border_feature_support( $block_type, 'color' );
  21. // Setup attributes and styles within that if needed.
  22. if ( ! $block_type->attributes ) {
  23. $block_type->attributes = array();
  24. }
  25. if ( $has_border_support && ! array_key_exists( 'style', $block_type->attributes ) ) {
  26. $block_type->attributes['style'] = array(
  27. 'type' => 'object',
  28. );
  29. }
  30. if ( $has_border_color_support && ! array_key_exists( 'borderColor', $block_type->attributes ) ) {
  31. $block_type->attributes['borderColor'] = array(
  32. 'type' => 'string',
  33. );
  34. }
  35. }
  36. /**
  37. * Adds CSS classes and inline styles for border styles to the incoming
  38. * attributes array. This will be applied to the block markup in the front-end.
  39. *
  40. * @since 5.8.0
  41. * @access private
  42. *
  43. * @param WP_Block_Type $block_type Block type.
  44. * @param array $block_attributes Block attributes.
  45. * @return array Border CSS classes and inline styles.
  46. */
  47. function wp_apply_border_support( $block_type, $block_attributes ) {
  48. if ( wp_should_skip_block_supports_serialization( $block_type, 'border' ) ) {
  49. return array();
  50. }
  51. $classes = array();
  52. $styles = array();
  53. // Border radius.
  54. if (
  55. wp_has_border_feature_support( $block_type, 'radius' ) &&
  56. isset( $block_attributes['style']['border']['radius'] ) &&
  57. ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'radius' )
  58. ) {
  59. $border_radius = $block_attributes['style']['border']['radius'];
  60. if ( is_array( $border_radius ) ) {
  61. // We have individual border radius corner values.
  62. foreach ( $border_radius as $key => $radius ) {
  63. // Convert CamelCase corner name to kebab-case.
  64. $corner = strtolower( preg_replace( '/(?<!^)[A-Z]/', '-$0', $key ) );
  65. $styles[] = sprintf( 'border-%s-radius: %s;', $corner, $radius );
  66. }
  67. } else {
  68. // This check handles original unitless implementation.
  69. if ( is_numeric( $border_radius ) ) {
  70. $border_radius .= 'px';
  71. }
  72. $styles[] = sprintf( 'border-radius: %s;', $border_radius );
  73. }
  74. }
  75. // Border style.
  76. if (
  77. wp_has_border_feature_support( $block_type, 'style' ) &&
  78. isset( $block_attributes['style']['border']['style'] ) &&
  79. ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'style' )
  80. ) {
  81. $border_style = $block_attributes['style']['border']['style'];
  82. $styles[] = sprintf( 'border-style: %s;', $border_style );
  83. }
  84. // Border width.
  85. if (
  86. wp_has_border_feature_support( $block_type, 'width' ) &&
  87. isset( $block_attributes['style']['border']['width'] ) &&
  88. ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'width' )
  89. ) {
  90. $border_width = $block_attributes['style']['border']['width'];
  91. // This check handles original unitless implementation.
  92. if ( is_numeric( $border_width ) ) {
  93. $border_width .= 'px';
  94. }
  95. $styles[] = sprintf( 'border-width: %s;', $border_width );
  96. }
  97. // Border color.
  98. if (
  99. wp_has_border_feature_support( $block_type, 'color' ) &&
  100. ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'color' )
  101. ) {
  102. $has_named_border_color = array_key_exists( 'borderColor', $block_attributes );
  103. $has_custom_border_color = isset( $block_attributes['style']['border']['color'] );
  104. if ( $has_named_border_color || $has_custom_border_color ) {
  105. $classes[] = 'has-border-color';
  106. }
  107. if ( $has_named_border_color ) {
  108. $classes[] = sprintf( 'has-%s-border-color', $block_attributes['borderColor'] );
  109. } elseif ( $has_custom_border_color ) {
  110. $border_color = $block_attributes['style']['border']['color'];
  111. $styles[] = sprintf( 'border-color: %s;', $border_color );
  112. }
  113. }
  114. // Collect classes and styles.
  115. $attributes = array();
  116. if ( ! empty( $classes ) ) {
  117. $attributes['class'] = implode( ' ', $classes );
  118. }
  119. if ( ! empty( $styles ) ) {
  120. $attributes['style'] = implode( ' ', $styles );
  121. }
  122. return $attributes;
  123. }
  124. /**
  125. * Checks whether the current block type supports the border feature requested.
  126. *
  127. * If the `__experimentalBorder` support flag is a boolean `true` all border
  128. * support features are available. Otherwise, the specific feature's support
  129. * flag nested under `experimentalBorder` must be enabled for the feature
  130. * to be opted into.
  131. *
  132. * @since 5.8.0
  133. * @access private
  134. *
  135. * @param WP_Block_Type $block_type Block type to check for support.
  136. * @param string $feature Name of the feature to check support for.
  137. * @param mixed $default_value Fallback value for feature support, defaults to false.
  138. * @return bool Whether the feature is supported.
  139. */
  140. function wp_has_border_feature_support( $block_type, $feature, $default_value = false ) {
  141. // Check if all border support features have been opted into via `"__experimentalBorder": true`.
  142. if (
  143. property_exists( $block_type, 'supports' ) &&
  144. ( true === _wp_array_get( $block_type->supports, array( '__experimentalBorder' ), $default_value ) )
  145. ) {
  146. return true;
  147. }
  148. // Check if the specific feature has been opted into individually
  149. // via nested flag under `__experimentalBorder`.
  150. return block_has_support( $block_type, array( '__experimentalBorder', $feature ), $default_value );
  151. }
  152. // Register the block support.
  153. WP_Block_Supports::get_instance()->register(
  154. 'border',
  155. array(
  156. 'register_attribute' => 'wp_register_border_support',
  157. 'apply' => 'wp_apply_border_support',
  158. )
  159. );