9 /** |
9 /** |
10 * Registers the style attribute used by the border feature if needed for block |
10 * Registers the style attribute used by the border feature if needed for block |
11 * types that support borders. |
11 * types that support borders. |
12 * |
12 * |
13 * @since 5.8.0 |
13 * @since 5.8.0 |
|
14 * @since 6.1.0 Improved conditional blocks optimization. |
14 * @access private |
15 * @access private |
15 * |
16 * |
16 * @param WP_Block_Type $block_type Block Type. |
17 * @param WP_Block_Type $block_type Block Type. |
17 */ |
18 */ |
18 function wp_register_border_support( $block_type ) { |
19 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. |
20 // Setup attributes and styles within that if needed. |
24 if ( ! $block_type->attributes ) { |
21 if ( ! $block_type->attributes ) { |
25 $block_type->attributes = array(); |
22 $block_type->attributes = array(); |
26 } |
23 } |
27 |
24 |
28 if ( $has_border_support && ! array_key_exists( 'style', $block_type->attributes ) ) { |
25 if ( block_has_support( $block_type, '__experimentalBorder' ) && ! array_key_exists( 'style', $block_type->attributes ) ) { |
29 $block_type->attributes['style'] = array( |
26 $block_type->attributes['style'] = array( |
30 'type' => 'object', |
27 'type' => 'object', |
31 ); |
28 ); |
32 } |
29 } |
33 |
30 |
34 if ( $has_border_color_support && ! array_key_exists( 'borderColor', $block_type->attributes ) ) { |
31 if ( wp_has_border_feature_support( $block_type, 'color' ) && ! array_key_exists( 'borderColor', $block_type->attributes ) ) { |
35 $block_type->attributes['borderColor'] = array( |
32 $block_type->attributes['borderColor'] = array( |
36 'type' => 'string', |
33 'type' => 'string', |
37 ); |
34 ); |
38 } |
35 } |
39 } |
36 } |
52 function wp_apply_border_support( $block_type, $block_attributes ) { |
50 function wp_apply_border_support( $block_type, $block_attributes ) { |
53 if ( wp_should_skip_block_supports_serialization( $block_type, 'border' ) ) { |
51 if ( wp_should_skip_block_supports_serialization( $block_type, 'border' ) ) { |
54 return array(); |
52 return array(); |
55 } |
53 } |
56 |
54 |
57 $classes = array(); |
55 $border_block_styles = array(); |
58 $styles = array(); |
56 $has_border_color_support = wp_has_border_feature_support( $block_type, 'color' ); |
|
57 $has_border_width_support = wp_has_border_feature_support( $block_type, 'width' ); |
59 |
58 |
60 // Border radius. |
59 // Border radius. |
61 if ( |
60 if ( |
62 wp_has_border_feature_support( $block_type, 'radius' ) && |
61 wp_has_border_feature_support( $block_type, 'radius' ) && |
63 isset( $block_attributes['style']['border']['radius'] ) && |
62 isset( $block_attributes['style']['border']['radius'] ) && |
64 ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'radius' ) |
63 ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'radius' ) |
65 ) { |
64 ) { |
66 $border_radius = $block_attributes['style']['border']['radius']; |
65 $border_radius = $block_attributes['style']['border']['radius']; |
67 |
66 |
68 if ( is_array( $border_radius ) ) { |
67 if ( is_numeric( $border_radius ) ) { |
69 // We have individual border radius corner values. |
68 $border_radius .= 'px'; |
70 foreach ( $border_radius as $key => $radius ) { |
69 } |
71 // Convert CamelCase corner name to kebab-case. |
|
72 $corner = strtolower( preg_replace( '/(?<!^)[A-Z]/', '-$0', $key ) ); |
|
73 $styles[] = sprintf( 'border-%s-radius: %s;', $corner, $radius ); |
|
74 } |
|
75 } else { |
|
76 // This check handles original unitless implementation. |
|
77 if ( is_numeric( $border_radius ) ) { |
|
78 $border_radius .= 'px'; |
|
79 } |
|
80 |
70 |
81 $styles[] = sprintf( 'border-radius: %s;', $border_radius ); |
71 $border_block_styles['radius'] = $border_radius; |
82 } |
|
83 } |
72 } |
84 |
73 |
85 // Border style. |
74 // Border style. |
86 if ( |
75 if ( |
87 wp_has_border_feature_support( $block_type, 'style' ) && |
76 wp_has_border_feature_support( $block_type, 'style' ) && |
88 isset( $block_attributes['style']['border']['style'] ) && |
77 isset( $block_attributes['style']['border']['style'] ) && |
89 ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'style' ) |
78 ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'style' ) |
90 ) { |
79 ) { |
91 $border_style = $block_attributes['style']['border']['style']; |
80 $border_block_styles['style'] = $block_attributes['style']['border']['style']; |
92 $styles[] = sprintf( 'border-style: %s;', $border_style ); |
|
93 } |
81 } |
94 |
82 |
95 // Border width. |
83 // Border width. |
96 if ( |
84 if ( |
97 wp_has_border_feature_support( $block_type, 'width' ) && |
85 $has_border_width_support && |
98 isset( $block_attributes['style']['border']['width'] ) && |
86 isset( $block_attributes['style']['border']['width'] ) && |
99 ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'width' ) |
87 ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'width' ) |
100 ) { |
88 ) { |
101 $border_width = $block_attributes['style']['border']['width']; |
89 $border_width = $block_attributes['style']['border']['width']; |
102 |
90 |
103 // This check handles original unitless implementation. |
91 // This check handles original unitless implementation. |
104 if ( is_numeric( $border_width ) ) { |
92 if ( is_numeric( $border_width ) ) { |
105 $border_width .= 'px'; |
93 $border_width .= 'px'; |
106 } |
94 } |
107 |
95 |
108 $styles[] = sprintf( 'border-width: %s;', $border_width ); |
96 $border_block_styles['width'] = $border_width; |
109 } |
97 } |
110 |
98 |
111 // Border color. |
99 // Border color. |
112 if ( |
100 if ( |
113 wp_has_border_feature_support( $block_type, 'color' ) && |
101 $has_border_color_support && |
114 ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'color' ) |
102 ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'color' ) |
115 ) { |
103 ) { |
116 $has_named_border_color = array_key_exists( 'borderColor', $block_attributes ); |
104 $preset_border_color = array_key_exists( 'borderColor', $block_attributes ) ? "var:preset|color|{$block_attributes['borderColor']}" : null; |
117 $has_custom_border_color = isset( $block_attributes['style']['border']['color'] ); |
105 $custom_border_color = isset( $block_attributes['style']['border']['color'] ) ? $block_attributes['style']['border']['color'] : null; |
|
106 $border_block_styles['color'] = $preset_border_color ? $preset_border_color : $custom_border_color; |
|
107 } |
118 |
108 |
119 if ( $has_named_border_color || $has_custom_border_color ) { |
109 // Generates styles for individual border sides. |
120 $classes[] = 'has-border-color'; |
110 if ( $has_border_color_support || $has_border_width_support ) { |
121 } |
111 foreach ( array( 'top', 'right', 'bottom', 'left' ) as $side ) { |
122 |
112 $border = isset( $block_attributes['style']['border'][ $side ] ) ? $block_attributes['style']['border'][ $side ] : null; |
123 if ( $has_named_border_color ) { |
113 $border_side_values = array( |
124 $classes[] = sprintf( 'has-%s-border-color', $block_attributes['borderColor'] ); |
114 'width' => isset( $border['width'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'width' ) ? $border['width'] : null, |
125 } elseif ( $has_custom_border_color ) { |
115 'color' => isset( $border['color'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'color' ) ? $border['color'] : null, |
126 $border_color = $block_attributes['style']['border']['color']; |
116 'style' => isset( $border['style'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'style' ) ? $border['style'] : null, |
127 $styles[] = sprintf( 'border-color: %s;', $border_color ); |
117 ); |
|
118 $border_block_styles[ $side ] = $border_side_values; |
128 } |
119 } |
129 } |
120 } |
130 |
121 |
131 // Collect classes and styles. |
122 // Collect classes and styles. |
132 $attributes = array(); |
123 $attributes = array(); |
|
124 $styles = wp_style_engine_get_styles( array( 'border' => $border_block_styles ) ); |
133 |
125 |
134 if ( ! empty( $classes ) ) { |
126 if ( ! empty( $styles['classnames'] ) ) { |
135 $attributes['class'] = implode( ' ', $classes ); |
127 $attributes['class'] = $styles['classnames']; |
136 } |
128 } |
137 |
129 |
138 if ( ! empty( $styles ) ) { |
130 if ( ! empty( $styles['css'] ) ) { |
139 $attributes['style'] = implode( ' ', $styles ); |
131 $attributes['style'] = $styles['css']; |
140 } |
132 } |
141 |
133 |
142 return $attributes; |
134 return $attributes; |
143 } |
135 } |
144 |
136 |
158 * @param mixed $default_value Fallback value for feature support, defaults to false. |
150 * @param mixed $default_value Fallback value for feature support, defaults to false. |
159 * @return bool Whether the feature is supported. |
151 * @return bool Whether the feature is supported. |
160 */ |
152 */ |
161 function wp_has_border_feature_support( $block_type, $feature, $default_value = false ) { |
153 function wp_has_border_feature_support( $block_type, $feature, $default_value = false ) { |
162 // Check if all border support features have been opted into via `"__experimentalBorder": true`. |
154 // Check if all border support features have been opted into via `"__experimentalBorder": true`. |
163 if ( |
155 if ( $block_type instanceof WP_Block_Type ) { |
164 property_exists( $block_type, 'supports' ) && |
156 $block_type_supports_border = isset( $block_type->supports['__experimentalBorder'] ) |
165 ( true === _wp_array_get( $block_type->supports, array( '__experimentalBorder' ), $default_value ) ) |
157 ? $block_type->supports['__experimentalBorder'] |
166 ) { |
158 : $default_value; |
167 return true; |
159 if ( true === $block_type_supports_border ) { |
|
160 return true; |
|
161 } |
168 } |
162 } |
169 |
163 |
170 // Check if the specific feature has been opted into individually |
164 // Check if the specific feature has been opted into individually |
171 // via nested flag under `__experimentalBorder`. |
165 // via nested flag under `__experimentalBorder`. |
172 return block_has_support( $block_type, array( '__experimentalBorder', $feature ), $default_value ); |
166 return block_has_support( $block_type, array( '__experimentalBorder', $feature ), $default_value ); |