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 / build / scripts / block-library / search.php

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

666 lines 25.3 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 /*
195 * The semantic <search> landmark wrapper is opt-in to preserve back
196 * compatibility with themes targeting <form role="search">. The block
197 * exposes a per-instance HTML element selector with three values:
198 *
199 * - 'search' forces the <search> wrapper
200 * - 'form' forces the original <form role="search"> markup
201 * - empty defers to the 'search-element' html5 sub-feature
202 * ( add_theme_support( 'html5', array( 'search-element' ) ) ),
203 * matching the opt-in added to get_search_form() in core
204 */
205 $tag_name = $attributes['tagName'] ?? '';
206 $use_search_element = 'search' === $tag_name || ( '' === $tag_name && current_theme_supports( 'html5', 'search-element' ) );
207
208 /*
209 * Only the wrapper markup differs between the semantic <search> landmark
210 * and the classic <form role="search">. Positional specifiers keep a
211 * single argument list usable by both formats, since the action URL
212 * precedes the wrapper attributes in the <search> variant.
213 */
214 $format = $use_search_element
215 ? '<search %2$s %3$s><form method="get" action="%1$s">%4$s</form></search>'
216 : '<form role="search" method="get" action="%1$s" %2$s %3$s>%4$s</form>';
217
218 return sprintf(
219 $format,
220 esc_url( home_url( '/' ) ),
221 $wrapper_attributes,
222 $form_directives,
223 $label . $field_markup
224 );
225 }
226
227 /**
228 * Registers the `core/search` block on the server.
229 *
230 * @since 5.2.0
231 */
232 function gutenberg_register_block_core_search() {
233 register_block_type_from_metadata(
234 __DIR__ . '/search',
235 array(
236 'render_callback' => 'gutenberg_render_block_core_search',
237 )
238 );
239 }
240 add_action( 'init', 'gutenberg_register_block_core_search', 20 );
241
242 /**
243 * Builds the correct top level classnames for the 'core/search' block.
244 *
245 * @since 5.6.0
246 *
247 * @param array $attributes The block attributes.
248 *
249 * @return string The classnames used in the block.
250 */
251 function gutenberg_classnames_for_block_core_search( $attributes ) {
252 $classnames = array();
253
254 if ( ! empty( $attributes['buttonPosition'] ) ) {
255 if ( 'button-inside' === $attributes['buttonPosition'] ) {
256 $classnames[] = 'wp-block-search__button-inside';
257 }
258
259 if ( 'button-outside' === $attributes['buttonPosition'] ) {
260 $classnames[] = 'wp-block-search__button-outside';
261 }
262
263 if ( 'no-button' === $attributes['buttonPosition'] ) {
264 $classnames[] = 'wp-block-search__no-button';
265 }
266
267 if ( 'button-only' === $attributes['buttonPosition'] ) {
268 $classnames[] = 'wp-block-search__button-only wp-block-search__searchfield-hidden';
269 }
270 }
271
272 if ( isset( $attributes['buttonUseIcon'] ) ) {
273 if ( ! empty( $attributes['buttonPosition'] ) && 'no-button' !== $attributes['buttonPosition'] ) {
274 if ( $attributes['buttonUseIcon'] ) {
275 $classnames[] = 'wp-block-search__icon-button';
276 } else {
277 $classnames[] = 'wp-block-search__text-button';
278 }
279 }
280 }
281
282 return implode( ' ', $classnames );
283 }
284
285 /**
286 * This generates a CSS rule for the given border property and side if provided.
287 * Based on whether the Search block is configured to display the button inside
288 * or not, the generated rule is injected into the appropriate collection of
289 * styles for later application in the block's markup.
290 *
291 * @since 6.1.0
292 *
293 * @param array $attributes The block attributes.
294 * @param string $property Border property to generate rule for e.g. width or color.
295 * @param string $side Optional side border. The dictates the value retrieved and final CSS property.
296 * @param array $wrapper_styles Current collection of wrapper styles.
297 * @param array $button_styles Current collection of button styles.
298 * @param array $input_styles Current collection of input styles.
299 */
300 function gutenberg_apply_block_core_search_border_style( $attributes, $property, $side, &$wrapper_styles, &$button_styles, &$input_styles ) {
301 $is_button_inside = isset( $attributes['buttonPosition'] ) && 'button-inside' === $attributes['buttonPosition'];
302
303 $path = array( 'style', 'border', $property );
304
305 if ( $side ) {
306 array_splice( $path, 2, 0, $side );
307 }
308
309 $value = _wp_array_get( $attributes, $path, false );
310
311 if ( empty( $value ) ) {
312 return;
313 }
314
315 if ( 'color' === $property && $side ) {
316 $has_color_preset = str_contains( $value, 'var:preset|color|' );
317 if ( $has_color_preset ) {
318 $named_color_value = substr( $value, strrpos( $value, '|' ) + 1 );
319 $value = sprintf( 'var(--wp--preset--color--%s)', $named_color_value );
320 }
321 }
322
323 $property_suffix = $side ? sprintf( '%s-%s', $side, $property ) : $property;
324
325 if ( $is_button_inside ) {
326 $wrapper_styles[] = sprintf( 'border-%s: %s;', $property_suffix, esc_attr( $value ) );
327 } else {
328 $button_styles[] = sprintf( 'border-%s: %s;', $property_suffix, esc_attr( $value ) );
329 $input_styles[] = sprintf( 'border-%s: %s;', $property_suffix, esc_attr( $value ) );
330 }
331 }
332
333 /**
334 * This adds CSS rules for a given border property e.g. width or color. It
335 * injects rules into the provided wrapper, button and input style arrays for
336 * uniform "flat" borders or those with individual sides configured.
337 *
338 * @since 6.1.0
339 *
340 * @param array $attributes The block attributes.
341 * @param string $property Border property to generate rule for e.g. width or color.
342 * @param array $wrapper_styles Current collection of wrapper styles.
343 * @param array $button_styles Current collection of button styles.
344 * @param array $input_styles Current collection of input styles.
345 */
346 function gutenberg_apply_block_core_search_border_styles( $attributes, $property, &$wrapper_styles, &$button_styles, &$input_styles ) {
347 gutenberg_apply_block_core_search_border_style( $attributes, $property, null, $wrapper_styles, $button_styles, $input_styles );
348 gutenberg_apply_block_core_search_border_style( $attributes, $property, 'top', $wrapper_styles, $button_styles, $input_styles );
349 gutenberg_apply_block_core_search_border_style( $attributes, $property, 'right', $wrapper_styles, $button_styles, $input_styles );
350 gutenberg_apply_block_core_search_border_style( $attributes, $property, 'bottom', $wrapper_styles, $button_styles, $input_styles );
351 gutenberg_apply_block_core_search_border_style( $attributes, $property, 'left', $wrapper_styles, $button_styles, $input_styles );
352 }
353
354 /**
355 * Builds an array of inline styles for the search block.
356 *
357 * The result will contain one entry for shared styles such as those for the
358 * inner input or button and a second for the inner wrapper should the block
359 * be positioning the button "inside".
360 *
361 * @since 5.8.0
362 *
363 * @param array $attributes The block attributes.
364 *
365 * @return array Style HTML attribute.
366 */
367 function gutenberg_styles_for_block_core_search( $attributes ) {
368 $wrapper_styles = array();
369 $button_styles = array();
370 $input_styles = array();
371 $label_styles = array();
372 $is_button_inside = ! empty( $attributes['buttonPosition'] ) &&
373 'button-inside' === $attributes['buttonPosition'];
374 $show_label = ( isset( $attributes['showLabel'] ) ) && false !== $attributes['showLabel'];
375
376 // Add width styles.
377 $has_width = ! empty( $attributes['width'] ) && ! empty( $attributes['widthUnit'] );
378
379 if ( $has_width ) {
380 $wrapper_styles[] = sprintf(
381 'width: %d%s;',
382 esc_attr( $attributes['width'] ),
383 esc_attr( $attributes['widthUnit'] )
384 );
385 }
386
387 // Add border width and color styles.
388 gutenberg_apply_block_core_search_border_styles( $attributes, 'width', $wrapper_styles, $button_styles, $input_styles );
389 gutenberg_apply_block_core_search_border_styles( $attributes, 'color', $wrapper_styles, $button_styles, $input_styles );
390 gutenberg_apply_block_core_search_border_styles( $attributes, 'style', $wrapper_styles, $button_styles, $input_styles );
391
392 // Add border radius styles.
393 $has_border_radius = ! empty( $attributes['style']['border']['radius'] );
394
395 if ( $has_border_radius ) {
396 $default_padding = '4px';
397 $border_radius = $attributes['style']['border']['radius'];
398
399 if ( is_array( $border_radius ) ) {
400 // Apply styles for individual corner border radii.
401 foreach ( $border_radius as $key => $value ) {
402 // Get border-radius CSS variable from preset value if provided.
403 if ( is_string( $value ) && str_contains( $value, 'var:preset|border-radius|' ) ) {
404 $index_to_splice = strrpos( $value, '|' ) + 1;
405 $slug = _wp_to_kebab_case( substr( $value, $index_to_splice ) );
406 $value = "var(--wp--preset--border-radius--$slug)";
407 }
408
409 if ( null !== $value ) {
410 // Convert camelCase key to kebab-case.
411 $name = strtolower( preg_replace( '/(?<!^)[A-Z]/', '-$0', $key ) );
412
413 // Add shared styles for individual border radii for input & button.
414 $border_style = sprintf(
415 'border-%s-radius: %s;',
416 esc_attr( $name ),
417 esc_attr( $value )
418 );
419 $input_styles[] = $border_style;
420 $button_styles[] = $border_style;
421
422 // Add adjusted border radius styles for the wrapper element
423 // if button is positioned inside.
424 if ( $is_button_inside && ( intval( $value ) !== 0 || str_contains( $value, 'var(--wp--preset--border-radius--' ) ) ) {
425 $wrapper_styles[] = sprintf(
426 'border-%s-radius: calc(%s + %s);',
427 esc_attr( $name ),
428 esc_attr( $value ),
429 $default_padding
430 );
431 }
432 }
433 }
434 } else {
435 // Numeric check is for backwards compatibility purposes.
436 $border_radius = is_numeric( $border_radius ) ? $border_radius . 'px' : $border_radius;
437 // Get border-radius CSS variable from preset value if provided.
438 if ( is_string( $border_radius ) && str_contains( $border_radius, 'var:preset|border-radius|' ) ) {
439 $index_to_splice = strrpos( $border_radius, '|' ) + 1;
440 $slug = _wp_to_kebab_case( substr( $border_radius, $index_to_splice ) );
441 $border_radius = "var(--wp--preset--border-radius--$slug)";
442 }
443
444 $border_style = sprintf( 'border-radius: %s;', esc_attr( $border_radius ) );
445 $input_styles[] = $border_style;
446 $button_styles[] = $border_style;
447
448 if ( $is_button_inside && intval( $border_radius ) !== 0 ) {
449 // Adjust wrapper border radii to maintain visual consistency
450 // with inner elements when button is positioned inside.
451 $wrapper_styles[] = sprintf(
452 'border-radius: calc(%s + %s);',
453 esc_attr( $border_radius ),
454 $default_padding
455 );
456 }
457 }
458 }
459
460 $use_input_for_colors = ! empty( $attributes['buttonPosition'] ) && 'no-button' === $attributes['buttonPosition'];
461
462 // Add color styles.
463 $has_text_color = ! empty( $attributes['style']['color']['text'] );
464 if ( $has_text_color ) {
465 $text_color_style = sprintf( 'color: %s;', $attributes['style']['color']['text'] );
466 if ( $use_input_for_colors ) {
467 $input_styles[] = $text_color_style;
468 } else {
469 $button_styles[] = $text_color_style;
470 }
471 }
472
473 $has_background_color = ! empty( $attributes['style']['color']['background'] );
474 if ( $has_background_color ) {
475 $background_color_style = sprintf( 'background-color: %s;', $attributes['style']['color']['background'] );
476 if ( $use_input_for_colors ) {
477 $input_styles[] = $background_color_style;
478 } else {
479 $button_styles[] = $background_color_style;
480 }
481 }
482
483 $has_custom_gradient = ! empty( $attributes['style']['color']['gradient'] );
484 if ( $has_custom_gradient ) {
485 $custom_gradient_style = sprintf( 'background: %s;', $attributes['style']['color']['gradient'] );
486 if ( $use_input_for_colors ) {
487 $input_styles[] = $custom_gradient_style;
488 } else {
489 $button_styles[] = $custom_gradient_style;
490 }
491 }
492
493 // Get typography styles to be shared across inner elements.
494 $typography_styles = esc_attr( get_typography_gutenberg_styles_for_block_core_search( $attributes ) );
495 if ( ! empty( $typography_styles ) ) {
496 $label_styles [] = $typography_styles;
497 $button_styles[] = $typography_styles;
498 $input_styles [] = $typography_styles;
499 }
500
501 // Typography text-decoration is only applied to the label and button.
502 if ( ! empty( $attributes['style']['typography']['textDecoration'] ) ) {
503 $text_decoration_value = sprintf( 'text-decoration: %s;', esc_attr( $attributes['style']['typography']['textDecoration'] ) );
504 $button_styles[] = $text_decoration_value;
505 // Input opts out of text decoration.
506 if ( $show_label ) {
507 $label_styles[] = $text_decoration_value;
508 }
509 }
510
511 return array(
512 'input' => ! empty( $input_styles ) ? sprintf( ' style="%s"', esc_attr( safecss_filter_attr( implode( ' ', $input_styles ) ) ) ) : '',
513 'button' => ! empty( $button_styles ) ? sprintf( ' style="%s"', esc_attr( safecss_filter_attr( implode( ' ', $button_styles ) ) ) ) : '',
514 'wrapper' => ! empty( $wrapper_styles ) ? sprintf( ' style="%s"', esc_attr( safecss_filter_attr( implode( ' ', $wrapper_styles ) ) ) ) : '',
515 'label' => ! empty( $label_styles ) ? sprintf( ' style="%s"', esc_attr( safecss_filter_attr( implode( ' ', $label_styles ) ) ) ) : '',
516 );
517 }
518
519 /**
520 * Returns typography classnames depending on whether there are named font sizes/families.
521 *
522 * @since 6.1.0
523 *
524 * @param array $attributes The block attributes.
525 *
526 * @return string The typography color classnames to be applied to the block elements.
527 */
528 function gutenberg_get_typography_classes_for_block_core_search( $attributes ) {
529 $typography_classes = array();
530 $has_named_font_family = ! empty( $attributes['fontFamily'] );
531 $has_named_font_size = ! empty( $attributes['fontSize'] );
532
533 if ( $has_named_font_size ) {
534 $typography_classes[] = sprintf( 'has-%s-font-size', esc_attr( $attributes['fontSize'] ) );
535 }
536
537 if ( $has_named_font_family ) {
538 $typography_classes[] = sprintf( 'has-%s-font-family', esc_attr( $attributes['fontFamily'] ) );
539 }
540
541 return implode( ' ', $typography_classes );
542 }
543
544 /**
545 * Returns typography styles to be included in an HTML style tag.
546 * This excludes text-decoration, which is applied only to the label and button elements of the search block.
547 *
548 * @since 6.1.0
549 *
550 * @param array $attributes The block attributes.
551 *
552 * @return string A string of typography CSS declarations.
553 */
554 function get_typography_gutenberg_styles_for_block_core_search( $attributes ) {
555 $typography_styles = array();
556
557 // Add typography styles.
558 if ( ! empty( $attributes['style']['typography']['fontSize'] ) ) {
559 $typography_styles[] = sprintf(
560 'font-size: %s;',
561 gutenberg_get_typography_font_size_value(
562 array(
563 'size' => $attributes['style']['typography']['fontSize'],
564 )
565 )
566 );
567
568 }
569
570 if ( ! empty( $attributes['style']['typography']['fontFamily'] ) ) {
571 $typography_styles[] = sprintf( 'font-family: %s;', $attributes['style']['typography']['fontFamily'] );
572 }
573
574 if ( ! empty( $attributes['style']['typography']['letterSpacing'] ) ) {
575 $typography_styles[] = sprintf( 'letter-spacing: %s;', $attributes['style']['typography']['letterSpacing'] );
576 }
577
578 if ( ! empty( $attributes['style']['typography']['fontWeight'] ) ) {
579 $typography_styles[] = sprintf( 'font-weight: %s;', $attributes['style']['typography']['fontWeight'] );
580 }
581
582 if ( ! empty( $attributes['style']['typography']['fontStyle'] ) ) {
583 $typography_styles[] = sprintf( 'font-style: %s;', $attributes['style']['typography']['fontStyle'] );
584 }
585
586 if ( ! empty( $attributes['style']['typography']['lineHeight'] ) ) {
587 $typography_styles[] = sprintf( 'line-height: %s;', $attributes['style']['typography']['lineHeight'] );
588 }
589
590 if ( ! empty( $attributes['style']['typography']['textTransform'] ) ) {
591 $typography_styles[] = sprintf( 'text-transform: %s;', $attributes['style']['typography']['textTransform'] );
592 }
593
594 return implode( '', $typography_styles );
595 }
596
597 /**
598 * Returns border color classnames depending on whether there are named or custom border colors.
599 *
600 * @since 5.9.0
601 *
602 * @param array $attributes The block attributes.
603 *
604 * @return string The border color classnames to be applied to the block elements.
605 */
606 function gutenberg_get_border_color_classes_for_block_core_search( $attributes ) {
607 $border_color_classes = array();
608 $has_custom_border_color = ! empty( $attributes['style']['border']['color'] );
609 $has_named_border_color = ! empty( $attributes['borderColor'] );
610
611 if ( $has_custom_border_color || $has_named_border_color ) {
612 $border_color_classes[] = 'has-border-color';
613 }
614
615 if ( $has_named_border_color ) {
616 $border_color_classes[] = sprintf( 'has-%s-border-color', esc_attr( $attributes['borderColor'] ) );
617 }
618
619 return implode( ' ', $border_color_classes );
620 }
621
622 /**
623 * Returns color classnames depending on whether there are named or custom text and background colors.
624 *
625 * @since 5.9.0
626 *
627 * @param array $attributes The block attributes.
628 *
629 * @return string The color classnames to be applied to the block elements.
630 */
631 function gutenberg_get_color_classes_for_block_core_search( $attributes ) {
632 $classnames = array();
633
634 // Text color.
635 $has_named_text_color = ! empty( $attributes['textColor'] );
636 $has_custom_text_color = ! empty( $attributes['style']['color']['text'] );
637 if ( $has_named_text_color ) {
638 $classnames[] = sprintf( 'has-text-color has-%s-color', $attributes['textColor'] );
639 } elseif ( $has_custom_text_color ) {
640 // If a custom 'textColor' was selected instead of a preset, still add the generic `has-text-color` class.
641 $classnames[] = 'has-text-color';
642 }
643
644 // Background color.
645 $has_named_background_color = ! empty( $attributes['backgroundColor'] );
646 $has_custom_background_color = ! empty( $attributes['style']['color']['background'] );
647 $has_named_gradient = ! empty( $attributes['gradient'] );
648 $has_custom_gradient = ! empty( $attributes['style']['color']['gradient'] );
649 if (
650 $has_named_background_color ||
651 $has_custom_background_color ||
652 $has_named_gradient ||
653 $has_custom_gradient
654 ) {
655 $classnames[] = 'has-background';
656 }
657 if ( $has_named_background_color ) {
658 $classnames[] = sprintf( 'has-%s-background-color', $attributes['backgroundColor'] );
659 }
660 if ( $has_named_gradient ) {
661 $classnames[] = sprintf( 'has-%s-gradient-background', $attributes['gradient'] );
662 }
663
664 return implode( ' ', $classnames );
665 }
666