PluginProbe
Gutenberg / 23.5.2
Gutenberg v23.5.2
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / lib / block-supports / dimensions.php

dimensions.php in Gutenberg 23.5.2, at lib/block-supports/dimensions.php

187 lines 5.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Dimensions block support flag.
4 *
5 * This does not include the `spacing` block support even though that visually
6 * appears under the "Dimensions" panel in the editor. It remains in its
7 * original `spacing.php` file for compatibility with core.
8 *
9 * @package gutenberg
10 */
11
12 /**
13 * Registers the style block attribute for block types that support it.
14 *
15 * @param WP_Block_Type $block_type Block Type.
16 */
17 function gutenberg_register_dimensions_support( $block_type ) {
18 // Setup attributes and styles within that if needed.
19 if ( ! $block_type->attributes ) {
20 $block_type->attributes = array();
21 }
22
23 // Check for existing style attribute definition e.g. from block.json.
24 if ( array_key_exists( 'style', $block_type->attributes ) ) {
25 return;
26 }
27
28 $has_dimensions_support = block_has_support( $block_type, array( 'dimensions' ), false );
29
30 if ( $has_dimensions_support ) {
31 $block_type->attributes['style'] = array(
32 'type' => 'object',
33 );
34 }
35 }
36
37 /**
38 * Add CSS classes for block dimensions to the incoming attributes array.
39 * This will be applied to the block markup in the front-end.
40 *
41 * @param WP_Block_Type $block_type Block Type.
42 * @param array $block_attributes Block attributes.
43 *
44 * @return array Block dimensions CSS classes and inline styles.
45 */
46 function gutenberg_apply_dimensions_support( $block_type, $block_attributes ) {
47 $attributes = array();
48
49 if ( wp_should_skip_block_supports_serialization( $block_type, 'dimensions' ) ) {
50 return $attributes;
51 }
52
53 $block_styles = $block_attributes['style'] ?? null;
54
55 if ( ! $block_styles ) {
56 return $attributes;
57 }
58
59 $dimensions_block_styles = array();
60 $supported_features = array( 'minHeight', 'minWidth', 'height', 'width' );
61
62 foreach ( $supported_features as $feature ) {
63 $has_support = block_has_support( $block_type, array( 'dimensions', $feature ), false );
64 $skip_serialization = wp_should_skip_block_supports_serialization( $block_type, 'dimensions', $feature );
65
66 $dimensions_block_styles[ $feature ] = null;
67
68 if ( $has_support && ! $skip_serialization ) {
69 $dimensions_block_styles[ $feature ] = $block_styles['dimensions'][ $feature ] ?? null;
70 }
71 }
72
73 $styles = gutenberg_style_engine_get_styles( array( 'dimensions' => $dimensions_block_styles ) );
74
75 if ( ! empty( $styles['css'] ) ) {
76 $attributes['style'] = $styles['css'];
77 }
78
79 return $attributes;
80 }
81
82 /**
83 * Checks whether an aspectRatio block-support value is explicitly set.
84 *
85 * @param mixed $aspect_ratio Aspect-ratio value.
86 * @return bool Whether the value is an explicit aspect ratio.
87 */
88 function gutenberg_is_explicit_aspect_ratio_value( $aspect_ratio ) {
89 if ( ! is_string( $aspect_ratio ) && ! is_numeric( $aspect_ratio ) ) {
90 return false;
91 }
92
93 $aspect_ratio = strtolower( trim( (string) $aspect_ratio ) );
94
95 return '' !== $aspect_ratio && 'auto' !== $aspect_ratio;
96 }
97
98 /**
99 * Renders server-side dimensions styles to the block wrapper.
100 * This block support uses the `render_block` hook to ensure that
101 * it is also applied to non-server-rendered blocks.
102 *
103 * @param string $block_content Rendered block content.
104 * @param array $block Block object.
105 * @return string Filtered block content.
106 */
107 function gutenberg_render_dimensions_support( $block_content, $block ) {
108 $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
109 $block_attributes = ( isset( $block['attrs'] ) && is_array( $block['attrs'] ) ) ? $block['attrs'] : array();
110 $has_aspect_ratio_support = block_has_support( $block_type, array( 'dimensions', 'aspectRatio' ), false );
111
112 if (
113 ! $has_aspect_ratio_support ||
114 wp_should_skip_block_supports_serialization( $block_type, 'dimensions', 'aspectRatio' )
115 ) {
116 return $block_content;
117 }
118
119 $dimensions_block_styles = array();
120 $dimensions_block_styles['aspectRatio'] = $block_attributes['style']['dimensions']['aspectRatio'] ?? null;
121
122 // To ensure the aspect ratio does not get overridden by `minHeight` or `height` unset any existing rule.
123 if (
124 gutenberg_is_explicit_aspect_ratio_value( $dimensions_block_styles['aspectRatio'] )
125 ) {
126 $dimensions_block_styles['minHeight'] = 'unset';
127 $dimensions_block_styles['height'] = 'unset';
128 } elseif (
129 isset( $block_attributes['style']['dimensions']['minHeight'] ) ||
130 isset( $block_attributes['minHeight'] ) ||
131 isset( $block_attributes['style']['dimensions']['height'] ) ||
132 isset( $block_attributes['height'] )
133 ) {
134 $dimensions_block_styles['aspectRatio'] = 'unset';
135 }
136
137 $styles = gutenberg_style_engine_get_styles( array( 'dimensions' => $dimensions_block_styles ) );
138
139 if ( ! empty( $styles['css'] ) ) {
140 // Inject dimensions styles to the first element, presuming it's the wrapper, if it exists.
141 $tags = new WP_HTML_Tag_Processor( $block_content );
142
143 if ( $tags->next_tag() ) {
144 $existing_style = $tags->get_attribute( 'style' );
145 $updated_style = '';
146
147 if ( ! empty( $existing_style ) ) {
148 $updated_style = $existing_style;
149 if ( ! str_ends_with( $existing_style, ';' ) ) {
150 $updated_style .= ';';
151 }
152 }
153
154 $updated_style .= $styles['css'];
155 $tags->set_attribute( 'style', $updated_style );
156
157 if ( ! empty( $styles['classnames'] ) ) {
158 foreach ( explode( ' ', $styles['classnames'] ) as $class_name ) {
159 if (
160 str_contains( $class_name, 'aspect-ratio' ) &&
161 ! gutenberg_is_explicit_aspect_ratio_value( $block_attributes['style']['dimensions']['aspectRatio'] ?? null )
162 ) {
163 continue;
164 }
165 $tags->add_class( $class_name );
166 }
167 }
168 }
169
170 return $tags->get_updated_html();
171 }
172
173 return $block_content;
174 }
175
176 remove_filter( 'render_block', 'wp_render_dimensions_support', 10 );
177 add_filter( 'render_block', 'gutenberg_render_dimensions_support', 10, 2 );
178
179 // Register the block support.
180 WP_Block_Supports::get_instance()->register(
181 'dimensions',
182 array(
183 'register_attribute' => 'gutenberg_register_dimensions_support',
184 'apply' => 'gutenberg_apply_dimensions_support',
185 )
186 );
187