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