PluginProbe
Gutenberg / trunk
Gutenberg vtrunk
24.1.0 24.0.0 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 All 404 releases
← All changes | lib/block-supports/custom-css.php +46 -19 23.3.1 → trunk View file →
@@ -7,8 +7,10 @@
7 7
8 8 /**
9 9 * Render the custom CSS stylesheet and add class name to block as required.
10 10 *
11 + * @since 7.0.0
12 + *
11 13 * @param array $parsed_block The parsed block.
12 14 * @return array The same parsed block with custom CSS class name added if appropriate.
13 15 *
14 16 * @phpstan-param array{
@@ -46,9 +48,9 @@
46 48 $updated_class_name = is_string( $existing_class_name )
47 49 ? "$existing_class_name $class_name"
48 50 : $class_name;
49 51
50 - _wp_array_set( $parsed_block, array( 'attrs', 'className' ), $updated_class_name );
52 + $parsed_block['attrs']['className'] = $updated_class_name;
51 53
52 54 // Process the custom CSS using the same method as global styles.
53 55 $selector = '.' . $class_name;
54 56 $processed_css = WP_Theme_JSON_Gutenberg::process_blocks_custom_css( $custom_css, $selector );
@@ -53,15 +55,25 @@
53 55 $selector = '.' . $class_name;
54 56 $processed_css = WP_Theme_JSON_Gutenberg::process_blocks_custom_css( $custom_css, $selector );
55 57
56 58 if ( ! empty( $processed_css ) ) {
57 - /*
58 - * Register and add inline style for block custom CSS.
59 - * The style depends on global-styles to ensure custom CSS loads after
60 - * and can override global styles.
59 + /**
60 + * Reuse one handle so identical custom CSS is enqueued only once via
61 + * {@see wp_unique_id_from_values()}. Explicitly declare the `wp-block-library`
62 + * dependency so `global-styles` is guaranteed to print after it, preventing
63 + * block default styles from unintentionally overriding global styles.
61 64 */
62 - wp_register_style( 'wp-block-custom-css', false, array( 'global-styles' ) );
63 - wp_add_inline_style( 'wp-block-custom-css', $processed_css );
65 + $handle = 'wp-block-custom-css';
66 + if ( ! wp_style_is( $handle, 'registered' ) ) {
67 + wp_register_style( $handle, false, array( 'wp-block-library', 'global-styles' ) );
68 + }
69 + $after_styles = wp_styles()->get_data( $handle, 'after' );
70 + if ( ! is_array( $after_styles ) ) {
71 + $after_styles = array();
72 + }
73 + if ( ! in_array( $processed_css, $after_styles, true ) ) {
74 + wp_add_inline_style( $handle, $processed_css );
75 + }
64 76 }
65 77
66 78 return $parsed_block;
67 79 }
@@ -67,8 +79,10 @@
67 79 }
68 80
69 81 /**
70 82 * Enqueues the block custom CSS styles.
83 + *
84 + * @since 7.0.0
71 85 */
72 86 function gutenberg_enqueue_block_custom_css() {
73 87 wp_enqueue_style( 'wp-block-custom-css' );
74 88 }
@@ -78,11 +92,13 @@
78 92 *
79 93 * The class name is generated in {@see gutenberg_render_custom_css_support_styles()}
80 94 * and stored in block attributes. This filter adds it to the actual markup.
81 95 *
96 + * @since 7.0.0
97 + *
82 98 * @param string $block_content Rendered block content.
83 99 * @param array $block Block object.
84 - * @return string Filtered block content.
100 + * @return string Filtered block content.
85 101 *
86 102 * @phpstan-param array{
87 103 * attrs: array{
88 104 * className?: string,
@@ -91,34 +107,33 @@
91 107 * ...
92 108 * } $block
93 109 */
94 110 function gutenberg_render_custom_css_class_name( $block_content, $block ) {
95 - $class_name_attr = $block['attrs']['className'] ?? null;
96 -
97 - if ( ! is_string( $class_name_attr ) || ! str_contains( $class_name_attr, 'wp-custom-css-' ) ) {
111 + $class_name_attr = $block['attrs']['className'] ?? null;
112 + $class_name_prefix = 'wp-custom-css-';
113 + if ( ! is_string( $class_name_attr ) || ! str_contains( $class_name_attr, $class_name_prefix ) ) {
98 114 return $block_content;
99 115 }
100 116
101 117 // Parse out the 'wp-custom-css-*' class name added by gutenberg_render_custom_css_support_styles().
102 - $custom_class_name = null;
103 - $token_delimiter = " \t\f\r\n";
104 - $class_token = strtok( $class_name_attr, $token_delimiter );
118 + $matched_class_name = null;
119 + $token_delimiter = " \t\f\r\n";
120 + $class_token = strtok( $class_name_attr, $token_delimiter );
105 121 while ( false !== $class_token ) {
106 - if ( str_starts_with( $class_token, 'wp-custom-css-' ) ) {
107 - $custom_class_name = $class_token;
122 + if ( str_starts_with( $class_token, $class_name_prefix ) ) {
123 + $matched_class_name = $class_token;
108 124 break;
109 125 }
110 126 $class_token = strtok( $token_delimiter );
111 127 }
112 - if ( null === $custom_class_name ) {
128 + if ( null === $matched_class_name ) {
113 129 return $block_content;
114 130 }
115 131
116 132 $tags = new WP_HTML_Tag_Processor( $block_content );
117 -
118 133 if ( $tags->next_tag() ) {
119 134 $tags->add_class( 'has-custom-css' );
120 - $tags->add_class( $custom_class_name );
135 + $tags->add_class( $matched_class_name );
121 136 }
122 137
123 138 return $tags->get_updated_html();
124 139 }
@@ -141,8 +156,10 @@
141 156
142 157 /**
143 158 * Registers the style block attribute for block types that support it.
144 159 *
160 + * @since 7.0.0
161 + *
145 162 * @param WP_Block_Type $block_type Block Type.
146 163 */
147 164 function gutenberg_register_custom_css_support( $block_type ) {
148 165 // Setup attributes and styles within that if needed.
@@ -170,8 +187,10 @@
170 187 * Uses WP_Block_Parser::next_token() to scan block tokens and surgically
171 188 * replace only the attribute JSON that changed — no parse_blocks() +
172 189 * serialize_blocks() round-trip needed.
173 190 *
191 + * @since 7.0.0
192 + *
174 193 * @param string $content Post content to filter, expected to be escaped with slashes.
175 194 * @return string Filtered post content with block custom CSS removed.
176 195 */
177 196 function gutenberg_strip_custom_css_from_blocks( $content ) {
@@ -250,8 +269,10 @@
250 269 }
251 270
252 271 /**
253 272 * Adds the filters to strip custom CSS from block content on save.
273 + *
274 + * @since 7.0.0
254 275 * @access private
255 276 */
256 277 function gutenberg_custom_css_kses_init_filters() {
257 278 add_filter( 'content_save_pre', 'gutenberg_strip_custom_css_from_blocks', 8 );
@@ -259,8 +280,10 @@
259 280 }
260 281
261 282 /**
262 283 * Removes the filters that strip custom CSS from block content on save.
284 + *
285 + * @since 7.0.0
263 286 * @access private
264 287 */
265 288 function gutenberg_custom_css_remove_filters() {
266 289 remove_filter( 'content_save_pre', 'gutenberg_strip_custom_css_from_blocks', 8 );
@@ -268,8 +291,10 @@
268 291 }
269 292
270 293 /**
271 294 * Registers the custom CSS content filters if the user does not have the edit_css capability.
295 + *
296 + * @since 7.0.0
272 297 * @access private
273 298 */
274 299 function gutenberg_custom_css_kses_init() {
275 300 gutenberg_custom_css_remove_filters();
@@ -283,8 +308,10 @@
283 308 *
284 309 * This filter is the last being executed on force_filtered_html_on_import.
285 310 * If the input of the filter is true it means we are in an import situation and should
286 311 * enable the custom CSS filters, independently of the user capabilities.
312 + *
313 + * @since 7.0.0
287 314 * @access private
288 315 *
289 316 * @param mixed $arg Input argument of the filter.
290 317 * @return mixed Input argument of the filter.