PluginProbe
Gutenberg / 23.3.0
Gutenberg v23.3.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 12.6.0 7.4.0 All 402 releases
gutenberg / build / scripts / block-library / search.php

search.php in Gutenberg 23.3.0, at build/scripts/block-library/search.php

642 lines 24.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Server-side rendering of the `core/search` block.
4 *
5 * @package WordPress
6 */
7
8 /**
9 * Dynamically renders the `core/search` block.
10 *
11 * @since 6.3.0 Using block.json `viewScript` to register script, and update `view_script_handles()` only when needed.
12 *
13 * @param array $attributes The block attributes.
14 *
15 * @return string The search block markup.
16 */
17 function gutenberg_render_block_core_search( $attributes ) {
18 // Older versions of the Search block defaulted the label and buttonText
19 // attributes to `__( 'Search' )` meaning that many posts contain `<!--
20 // wp:search /-->`. Support these by defaulting an undefined label and
21 // buttonText to `__( 'Search' )`.
22 $attributes = wp_parse_args(
23 $attributes,
24 array(
25 'label' => __( 'Search' ),
26 'buttonText' => __( 'Search' ),
27 )
28 );
29
30 $input_id = wp_unique_id( 'wp-block-search__input-' );
31 $classnames = gutenberg_classnames_for_block_core_search( $attributes );
32 $show_label = ! empty( $attributes['showLabel'] );
33 $use_icon_button = ! empty( $attributes['buttonUseIcon'] );
34 $show_button = ( ! empty( $attributes['buttonPosition'] ) && 'no-button' === $attributes['buttonPosition'] ) ? false : true;
35 $button_position = $show_button ? $attributes['buttonPosition'] : null;
36 $query_params = ( ! empty( $attributes['query'] ) ) ? $attributes['query'] : array();
37 $button = '';
38 $query_params_markup = '';
39 $inline_styles = gutenberg_styles_for_block_core_search( $attributes );
40 $color_classes = gutenberg_get_color_classes_for_block_core_search( $attributes );
41 $typography_classes = gutenberg_get_typography_classes_for_block_core_search( $attributes );
42 $is_button_inside = ! empty( $attributes['buttonPosition'] ) &&
43 'button-inside' === $attributes['buttonPosition'];
44 // Border color classes need to be applied to the elements that have a border color.
45 $border_color_classes = gutenberg_get_border_color_classes_for_block_core_search( $attributes );
46 // This variable is a constant and its value is always false at this moment.
47 // It is defined this way because some values depend on it, in case it changes in the future.
48 $open_by_default = false;
49
50 $label_inner_html = empty( $attributes['label'] ) ? __( 'Search' ) : wp_kses_post( $attributes['label'] );
51 $label = new WP_HTML_Tag_Processor( sprintf( '<label %1$s>%2$s</label>', $inline_styles['label'], $label_inner_html ) );
52 if ( $label->next_tag() ) {
53 $label->set_attribute( 'for', $input_id );
54 $label->add_class( 'wp-block-search__label' );
55 if ( $show_label && ! empty( $attributes['label'] ) ) {
56 if ( ! empty( $typography_classes ) ) {
57 $label->add_class( $typography_classes );
58 }
59 } else {
60 $label->add_class( 'screen-reader-text' );
61 }
62 }
63
64 $input = new WP_HTML_Tag_Processor( sprintf( '<input type="search" name="s" required %s/>', $inline_styles['input'] ) );
65 $input_classes = array( 'wp-block-search__input' );
66 if ( ! $is_button_inside && ! empty( $border_color_classes ) ) {
67 $input_classes[] = $border_color_classes;
68 }
69 if ( ! empty( $typography_classes ) ) {
70 $input_classes[] = $typography_classes;
71 }
72 if ( ! $show_button && ! empty( $color_classes ) ) {
73 $input_classes[] = $color_classes;
74 }
75 if ( $input->next_tag() ) {
76 $input->add_class( implode( ' ', $input_classes ) );
77 $input->set_attribute( 'id', $input_id );
78 $input->set_attribute( 'value', get_search_query( false ) );
79 $input->set_attribute( 'placeholder', $attributes['placeholder'] );
80
81 // If it's interactive, enqueue the script module and add the directives.
82 $is_expandable_searchfield = 'button-only' === $button_position;
83 if ( $is_expandable_searchfield ) {
84 wp_enqueue_script_module( '@wordpress/block-library/search/view' );
85
86 $input->set_attribute( 'data-wp-bind--aria-hidden', '!context.isSearchInputVisible' );
87 $input->set_attribute( 'data-wp-bind--tabindex', 'state.tabindex' );
88
89 // Adding these attributes manually is needed until the Interactivity API
90 // SSR logic is added to core.
91 $input->set_attribute( 'aria-hidden', 'true' );
92 $input->set_attribute( 'tabindex', '-1' );
93 }
94 }
95
96 if ( count( $query_params ) > 0 ) {
97 foreach ( $query_params as $param => $value ) {
98 $query_params_markup .= sprintf(
99 '<input type="hidden" name="%s" value="%s" />',
100 esc_attr( $param ),
101 esc_attr( $value )
102 );
103 }
104 }
105
106 if ( $show_button ) {
107 $button_classes = array( 'wp-block-search__button' );
108 $button_internal_markup = '';
109 if ( ! empty( $color_classes ) ) {
110 $button_classes[] = $color_classes;
111 }
112 if ( ! empty( $typography_classes ) ) {
113 $button_classes[] = $typography_classes;
114 }
115
116 if ( ! $is_button_inside && ! empty( $border_color_classes ) ) {
117 $button_classes[] = $border_color_classes;
118 }
119 if ( ! $use_icon_button ) {
120 if ( ! empty( $attributes['buttonText'] ) ) {
121 $button_internal_markup = wp_kses_post( $attributes['buttonText'] );
122 }
123 } else {
124 $button_classes[] = 'has-icon';
125 $button_internal_markup =
126 '<svg class="search-icon" viewBox="0 0 24 24" width="24" height="24">
127 <path d="M13 5c-3.3 0-6 2.7-6 6 0 1.4.5 2.7 1.3 3.7l-3.8 3.8 1.1 1.1 3.8-3.8c1 .8 2.3 1.3 3.7 1.3 3.3 0 6-2.7 6-6S16.3 5 13 5zm0 10.5c-2.5 0-4.5-2-4.5-4.5s2-4.5 4.5-4.5 4.5 2 4.5 4.5-2 4.5-4.5 4.5z"></path>
128 </svg>';
129 }
130
131 // Include the button element class.
132 $button_classes[] = wp_theme_get_element_class_name( 'button' );
133 $button = new WP_HTML_Tag_Processor( sprintf( '<button type="submit" %s>%s</button>', $inline_styles['button'], $button_internal_markup ) );
134
135 if ( $button->next_tag() ) {
136 $button->add_class( implode( ' ', $button_classes ) );
137 if ( 'button-only' === $attributes['buttonPosition'] ) {
138 $button->set_attribute( 'data-wp-bind--aria-label', 'state.ariaLabel' );
139 $button->set_attribute( 'data-wp-bind--aria-controls', 'state.ariaControls' );
140 $button->set_attribute( 'data-wp-bind--aria-expanded', 'context.isSearchInputVisible' );
141 $button->set_attribute( 'data-wp-bind--type', 'state.type' );
142 $button->set_attribute( 'data-wp-on--click', 'actions.openSearchInput' );
143
144 // Adding these attributes manually is needed until the Interactivity
145 // API SSR logic is added to core.
146 $button->set_attribute( 'aria-label', __( 'Expand search field' ) );
147 $button->set_attribute( 'aria-controls', 'wp-block-search__input-' . $input_id );
148 $button->set_attribute( 'aria-expanded', 'false' );
149 $button->set_attribute( 'type', 'button' );
150 } else {
151 $button->set_attribute( 'aria-label', wp_strip_all_tags( $attributes['buttonText'] ) );
152 }
153 }
154 }
155
156 $field_markup_classes = array(
157 'wp-block-search__inside-wrapper',
158 );
159 if ( $is_button_inside && ! empty( $border_color_classes ) ) {
160 $field_markup_classes[] = $border_color_classes;
161 }
162 $field_markup = sprintf(
163 '<div class="%s" %s>%s</div>',
164 esc_attr( implode( ' ', $field_markup_classes ) ),
165 $inline_styles['wrapper'],
166 $input . $query_params_markup . $button
167 );
168 $wrapper_attributes = get_block_wrapper_attributes(
169 array( 'class' => $classnames )
170 );
171 $form_directives = '';
172
173 // If it's interactive, add the directives.
174 if ( $is_expandable_searchfield ) {
175 $aria_label_expanded = __( 'Submit Search' );
176 $aria_label_collapsed = __( 'Expand search field' );
177 $form_context = wp_interactivity_data_wp_context(
178 array(
179 'isSearchInputVisible' => $open_by_default,
180 'inputId' => $input_id,
181 'ariaLabelExpanded' => $aria_label_expanded,
182 'ariaLabelCollapsed' => $aria_label_collapsed,
183 )
184 );
185 $form_directives = '
186 data-wp-interactive="core/search"
187 ' . $form_context . '
188 data-wp-class--wp-block-search__searchfield-hidden="!context.isSearchInputVisible"
189 data-wp-on--keydown="actions.handleSearchKeydown"
190 data-wp-on--focusout="actions.handleSearchFocusout"
191 ';
192 }
193
194 return sprintf(
195 '<form role="search" method="get" action="%1s" %2s %3s>%4s</form>',
196 esc_url( home_url( '/' ) ),
197 $wrapper_attributes,
198 $form_directives,
199 $label . $field_markup
200 );
201 }
202
203 /**
204 * Registers the `core/search` block on the server.
205 *
206 * @since 5.2.0
207 */
208 function gutenberg_register_block_core_search() {
209 register_block_type_from_metadata(
210 __DIR__ . '/search',
211 array(
212 'render_callback' => 'gutenberg_render_block_core_search',
213 )
214 );
215 }
216 add_action( 'init', 'gutenberg_register_block_core_search', 20 );
217
218 /**
219 * Builds the correct top level classnames for the 'core/search' block.
220 *
221 * @since 5.6.0
222 *
223 * @param array $attributes The block attributes.
224 *
225 * @return string The classnames used in the block.
226 */
227 function gutenberg_classnames_for_block_core_search( $attributes ) {
228 $classnames = array();
229
230 if ( ! empty( $attributes['buttonPosition'] ) ) {
231 if ( 'button-inside' === $attributes['buttonPosition'] ) {
232 $classnames[] = 'wp-block-search__button-inside';
233 }
234
235 if ( 'button-outside' === $attributes['buttonPosition'] ) {
236 $classnames[] = 'wp-block-search__button-outside';
237 }
238
239 if ( 'no-button' === $attributes['buttonPosition'] ) {
240 $classnames[] = 'wp-block-search__no-button';
241 }
242
243 if ( 'button-only' === $attributes['buttonPosition'] ) {
244 $classnames[] = 'wp-block-search__button-only wp-block-search__searchfield-hidden';
245 }
246 }
247
248 if ( isset( $attributes['buttonUseIcon'] ) ) {
249 if ( ! empty( $attributes['buttonPosition'] ) && 'no-button' !== $attributes['buttonPosition'] ) {
250 if ( $attributes['buttonUseIcon'] ) {
251 $classnames[] = 'wp-block-search__icon-button';
252 } else {
253 $classnames[] = 'wp-block-search__text-button';
254 }
255 }
256 }
257
258 return implode( ' ', $classnames );
259 }
260
261 /**
262 * This generates a CSS rule for the given border property and side if provided.
263 * Based on whether the Search block is configured to display the button inside
264 * or not, the generated rule is injected into the appropriate collection of
265 * styles for later application in the block's markup.
266 *
267 * @since 6.1.0
268 *
269 * @param array $attributes The block attributes.
270 * @param string $property Border property to generate rule for e.g. width or color.
271 * @param string $side Optional side border. The dictates the value retrieved and final CSS property.
272 * @param array $wrapper_styles Current collection of wrapper styles.
273 * @param array $button_styles Current collection of button styles.
274 * @param array $input_styles Current collection of input styles.
275 */
276 function gutenberg_apply_block_core_search_border_style( $attributes, $property, $side, &$wrapper_styles, &$button_styles, &$input_styles ) {
277 $is_button_inside = isset( $attributes['buttonPosition'] ) && 'button-inside' === $attributes['buttonPosition'];
278
279 $path = array( 'style', 'border', $property );
280
281 if ( $side ) {
282 array_splice( $path, 2, 0, $side );
283 }
284
285 $value = _wp_array_get( $attributes, $path, false );
286
287 if ( empty( $value ) ) {
288 return;
289 }
290
291 if ( 'color' === $property && $side ) {
292 $has_color_preset = str_contains( $value, 'var:preset|color|' );
293 if ( $has_color_preset ) {
294 $named_color_value = substr( $value, strrpos( $value, '|' ) + 1 );
295 $value = sprintf( 'var(--wp--preset--color--%s)', $named_color_value );
296 }
297 }
298
299 $property_suffix = $side ? sprintf( '%s-%s', $side, $property ) : $property;
300
301 if ( $is_button_inside ) {
302 $wrapper_styles[] = sprintf( 'border-%s: %s;', $property_suffix, esc_attr( $value ) );
303 } else {
304 $button_styles[] = sprintf( 'border-%s: %s;', $property_suffix, esc_attr( $value ) );
305 $input_styles[] = sprintf( 'border-%s: %s;', $property_suffix, esc_attr( $value ) );
306 }
307 }
308
309 /**
310 * This adds CSS rules for a given border property e.g. width or color. It
311 * injects rules into the provided wrapper, button and input style arrays for
312 * uniform "flat" borders or those with individual sides configured.
313 *
314 * @since 6.1.0
315 *
316 * @param array $attributes The block attributes.
317 * @param string $property Border property to generate rule for e.g. width or color.
318 * @param array $wrapper_styles Current collection of wrapper styles.
319 * @param array $button_styles Current collection of button styles.
320 * @param array $input_styles Current collection of input styles.
321 */
322 function gutenberg_apply_block_core_search_border_styles( $attributes, $property, &$wrapper_styles, &$button_styles, &$input_styles ) {
323 gutenberg_apply_block_core_search_border_style( $attributes, $property, null, $wrapper_styles, $button_styles, $input_styles );
324 gutenberg_apply_block_core_search_border_style( $attributes, $property, 'top', $wrapper_styles, $button_styles, $input_styles );
325 gutenberg_apply_block_core_search_border_style( $attributes, $property, 'right', $wrapper_styles, $button_styles, $input_styles );
326 gutenberg_apply_block_core_search_border_style( $attributes, $property, 'bottom', $wrapper_styles, $button_styles, $input_styles );
327 gutenberg_apply_block_core_search_border_style( $attributes, $property, 'left', $wrapper_styles, $button_styles, $input_styles );
328 }
329
330 /**
331 * Builds an array of inline styles for the search block.
332 *
333 * The result will contain one entry for shared styles such as those for the
334 * inner input or button and a second for the inner wrapper should the block
335 * be positioning the button "inside".
336 *
337 * @since 5.8.0
338 *
339 * @param array $attributes The block attributes.
340 *
341 * @return array Style HTML attribute.
342 */
343 function gutenberg_styles_for_block_core_search( $attributes ) {
344 $wrapper_styles = array();
345 $button_styles = array();
346 $input_styles = array();
347 $label_styles = array();
348 $is_button_inside = ! empty( $attributes['buttonPosition'] ) &&
349 'button-inside' === $attributes['buttonPosition'];
350 $show_label = ( isset( $attributes['showLabel'] ) ) && false !== $attributes['showLabel'];
351
352 // Add width styles.
353 $has_width = ! empty( $attributes['width'] ) && ! empty( $attributes['widthUnit'] );
354
355 if ( $has_width ) {
356 $wrapper_styles[] = sprintf(
357 'width: %d%s;',
358 esc_attr( $attributes['width'] ),
359 esc_attr( $attributes['widthUnit'] )
360 );
361 }
362
363 // Add border width and color styles.
364 gutenberg_apply_block_core_search_border_styles( $attributes, 'width', $wrapper_styles, $button_styles, $input_styles );
365 gutenberg_apply_block_core_search_border_styles( $attributes, 'color', $wrapper_styles, $button_styles, $input_styles );
366 gutenberg_apply_block_core_search_border_styles( $attributes, 'style', $wrapper_styles, $button_styles, $input_styles );
367
368 // Add border radius styles.
369 $has_border_radius = ! empty( $attributes['style']['border']['radius'] );
370
371 if ( $has_border_radius ) {
372 $default_padding = '4px';
373 $border_radius = $attributes['style']['border']['radius'];
374
375 if ( is_array( $border_radius ) ) {
376 // Apply styles for individual corner border radii.
377 foreach ( $border_radius as $key => $value ) {
378 // Get border-radius CSS variable from preset value if provided.
379 if ( is_string( $value ) && str_contains( $value, 'var:preset|border-radius|' ) ) {
380 $index_to_splice = strrpos( $value, '|' ) + 1;
381 $slug = _wp_to_kebab_case( substr( $value, $index_to_splice ) );
382 $value = "var(--wp--preset--border-radius--$slug)";
383 }
384
385 if ( null !== $value ) {
386 // Convert camelCase key to kebab-case.
387 $name = strtolower( preg_replace( '/(?<!^)[A-Z]/', '-$0', $key ) );
388
389 // Add shared styles for individual border radii for input & button.
390 $border_style = sprintf(
391 'border-%s-radius: %s;',
392 esc_attr( $name ),
393 esc_attr( $value )
394 );
395 $input_styles[] = $border_style;
396 $button_styles[] = $border_style;
397
398 // Add adjusted border radius styles for the wrapper element
399 // if button is positioned inside.
400 if ( $is_button_inside && ( intval( $value ) !== 0 || str_contains( $value, 'var(--wp--preset--border-radius--' ) ) ) {
401 $wrapper_styles[] = sprintf(
402 'border-%s-radius: calc(%s + %s);',
403 esc_attr( $name ),
404 esc_attr( $value ),
405 $default_padding
406 );
407 }
408 }
409 }
410 } else {
411 // Numeric check is for backwards compatibility purposes.
412 $border_radius = is_numeric( $border_radius ) ? $border_radius . 'px' : $border_radius;
413 // Get border-radius CSS variable from preset value if provided.
414 if ( is_string( $border_radius ) && str_contains( $border_radius, 'var:preset|border-radius|' ) ) {
415 $index_to_splice = strrpos( $border_radius, '|' ) + 1;
416 $slug = _wp_to_kebab_case( substr( $border_radius, $index_to_splice ) );
417 $border_radius = "var(--wp--preset--border-radius--$slug)";
418 }
419
420 $border_style = sprintf( 'border-radius: %s;', esc_attr( $border_radius ) );
421 $input_styles[] = $border_style;
422 $button_styles[] = $border_style;
423
424 if ( $is_button_inside && intval( $border_radius ) !== 0 ) {
425 // Adjust wrapper border radii to maintain visual consistency
426 // with inner elements when button is positioned inside.
427 $wrapper_styles[] = sprintf(
428 'border-radius: calc(%s + %s);',
429 esc_attr( $border_radius ),
430 $default_padding
431 );
432 }
433 }
434 }
435
436 $use_input_for_colors = ! empty( $attributes['buttonPosition'] ) && 'no-button' === $attributes['buttonPosition'];
437
438 // Add color styles.
439 $has_text_color = ! empty( $attributes['style']['color']['text'] );
440 if ( $has_text_color ) {
441 $text_color_style = sprintf( 'color: %s;', $attributes['style']['color']['text'] );
442 if ( $use_input_for_colors ) {
443 $input_styles[] = $text_color_style;
444 } else {
445 $button_styles[] = $text_color_style;
446 }
447 }
448
449 $has_background_color = ! empty( $attributes['style']['color']['background'] );
450 if ( $has_background_color ) {
451 $background_color_style = sprintf( 'background-color: %s;', $attributes['style']['color']['background'] );
452 if ( $use_input_for_colors ) {
453 $input_styles[] = $background_color_style;
454 } else {
455 $button_styles[] = $background_color_style;
456 }
457 }
458
459 $has_custom_gradient = ! empty( $attributes['style']['color']['gradient'] );
460 if ( $has_custom_gradient ) {
461 $custom_gradient_style = sprintf( 'background: %s;', $attributes['style']['color']['gradient'] );
462 if ( $use_input_for_colors ) {
463 $input_styles[] = $custom_gradient_style;
464 } else {
465 $button_styles[] = $custom_gradient_style;
466 }
467 }
468
469 // Get typography styles to be shared across inner elements.
470 $typography_styles = esc_attr( get_typography_gutenberg_styles_for_block_core_search( $attributes ) );
471 if ( ! empty( $typography_styles ) ) {
472 $label_styles [] = $typography_styles;
473 $button_styles[] = $typography_styles;
474 $input_styles [] = $typography_styles;
475 }
476
477 // Typography text-decoration is only applied to the label and button.
478 if ( ! empty( $attributes['style']['typography']['textDecoration'] ) ) {
479 $text_decoration_value = sprintf( 'text-decoration: %s;', esc_attr( $attributes['style']['typography']['textDecoration'] ) );
480 $button_styles[] = $text_decoration_value;
481 // Input opts out of text decoration.
482 if ( $show_label ) {
483 $label_styles[] = $text_decoration_value;
484 }
485 }
486
487 return array(
488 'input' => ! empty( $input_styles ) ? sprintf( ' style="%s"', esc_attr( safecss_filter_attr( implode( ' ', $input_styles ) ) ) ) : '',
489 'button' => ! empty( $button_styles ) ? sprintf( ' style="%s"', esc_attr( safecss_filter_attr( implode( ' ', $button_styles ) ) ) ) : '',
490 'wrapper' => ! empty( $wrapper_styles ) ? sprintf( ' style="%s"', esc_attr( safecss_filter_attr( implode( ' ', $wrapper_styles ) ) ) ) : '',
491 'label' => ! empty( $label_styles ) ? sprintf( ' style="%s"', esc_attr( safecss_filter_attr( implode( ' ', $label_styles ) ) ) ) : '',
492 );
493 }
494
495 /**
496 * Returns typography classnames depending on whether there are named font sizes/families.
497 *
498 * @since 6.1.0
499 *
500 * @param array $attributes The block attributes.
501 *
502 * @return string The typography color classnames to be applied to the block elements.
503 */
504 function gutenberg_get_typography_classes_for_block_core_search( $attributes ) {
505 $typography_classes = array();
506 $has_named_font_family = ! empty( $attributes['fontFamily'] );
507 $has_named_font_size = ! empty( $attributes['fontSize'] );
508
509 if ( $has_named_font_size ) {
510 $typography_classes[] = sprintf( 'has-%s-font-size', esc_attr( $attributes['fontSize'] ) );
511 }
512
513 if ( $has_named_font_family ) {
514 $typography_classes[] = sprintf( 'has-%s-font-family', esc_attr( $attributes['fontFamily'] ) );
515 }
516
517 return implode( ' ', $typography_classes );
518 }
519
520 /**
521 * Returns typography styles to be included in an HTML style tag.
522 * This excludes text-decoration, which is applied only to the label and button elements of the search block.
523 *
524 * @since 6.1.0
525 *
526 * @param array $attributes The block attributes.
527 *
528 * @return string A string of typography CSS declarations.
529 */
530 function get_typography_gutenberg_styles_for_block_core_search( $attributes ) {
531 $typography_styles = array();
532
533 // Add typography styles.
534 if ( ! empty( $attributes['style']['typography']['fontSize'] ) ) {
535 $typography_styles[] = sprintf(
536 'font-size: %s;',
537 gutenberg_get_typography_font_size_value(
538 array(
539 'size' => $attributes['style']['typography']['fontSize'],
540 )
541 )
542 );
543
544 }
545
546 if ( ! empty( $attributes['style']['typography']['fontFamily'] ) ) {
547 $typography_styles[] = sprintf( 'font-family: %s;', $attributes['style']['typography']['fontFamily'] );
548 }
549
550 if ( ! empty( $attributes['style']['typography']['letterSpacing'] ) ) {
551 $typography_styles[] = sprintf( 'letter-spacing: %s;', $attributes['style']['typography']['letterSpacing'] );
552 }
553
554 if ( ! empty( $attributes['style']['typography']['fontWeight'] ) ) {
555 $typography_styles[] = sprintf( 'font-weight: %s;', $attributes['style']['typography']['fontWeight'] );
556 }
557
558 if ( ! empty( $attributes['style']['typography']['fontStyle'] ) ) {
559 $typography_styles[] = sprintf( 'font-style: %s;', $attributes['style']['typography']['fontStyle'] );
560 }
561
562 if ( ! empty( $attributes['style']['typography']['lineHeight'] ) ) {
563 $typography_styles[] = sprintf( 'line-height: %s;', $attributes['style']['typography']['lineHeight'] );
564 }
565
566 if ( ! empty( $attributes['style']['typography']['textTransform'] ) ) {
567 $typography_styles[] = sprintf( 'text-transform: %s;', $attributes['style']['typography']['textTransform'] );
568 }
569
570 return implode( '', $typography_styles );
571 }
572
573 /**
574 * Returns border color classnames depending on whether there are named or custom border colors.
575 *
576 * @since 5.9.0
577 *
578 * @param array $attributes The block attributes.
579 *
580 * @return string The border color classnames to be applied to the block elements.
581 */
582 function gutenberg_get_border_color_classes_for_block_core_search( $attributes ) {
583 $border_color_classes = array();
584 $has_custom_border_color = ! empty( $attributes['style']['border']['color'] );
585 $has_named_border_color = ! empty( $attributes['borderColor'] );
586
587 if ( $has_custom_border_color || $has_named_border_color ) {
588 $border_color_classes[] = 'has-border-color';
589 }
590
591 if ( $has_named_border_color ) {
592 $border_color_classes[] = sprintf( 'has-%s-border-color', esc_attr( $attributes['borderColor'] ) );
593 }
594
595 return implode( ' ', $border_color_classes );
596 }
597
598 /**
599 * Returns color classnames depending on whether there are named or custom text and background colors.
600 *
601 * @since 5.9.0
602 *
603 * @param array $attributes The block attributes.
604 *
605 * @return string The color classnames to be applied to the block elements.
606 */
607 function gutenberg_get_color_classes_for_block_core_search( $attributes ) {
608 $classnames = array();
609
610 // Text color.
611 $has_named_text_color = ! empty( $attributes['textColor'] );
612 $has_custom_text_color = ! empty( $attributes['style']['color']['text'] );
613 if ( $has_named_text_color ) {
614 $classnames[] = sprintf( 'has-text-color has-%s-color', $attributes['textColor'] );
615 } elseif ( $has_custom_text_color ) {
616 // If a custom 'textColor' was selected instead of a preset, still add the generic `has-text-color` class.
617 $classnames[] = 'has-text-color';
618 }
619
620 // Background color.
621 $has_named_background_color = ! empty( $attributes['backgroundColor'] );
622 $has_custom_background_color = ! empty( $attributes['style']['color']['background'] );
623 $has_named_gradient = ! empty( $attributes['gradient'] );
624 $has_custom_gradient = ! empty( $attributes['style']['color']['gradient'] );
625 if (
626 $has_named_background_color ||
627 $has_custom_background_color ||
628 $has_named_gradient ||
629 $has_custom_gradient
630 ) {
631 $classnames[] = 'has-background';
632 }
633 if ( $has_named_background_color ) {
634 $classnames[] = sprintf( 'has-%s-background-color', $attributes['backgroundColor'] );
635 }
636 if ( $has_named_gradient ) {
637 $classnames[] = sprintf( 'has-%s-gradient-background', $attributes['gradient'] );
638 }
639
640 return implode( ' ', $classnames );
641 }
642