PluginProbe
Gutenberg / 16.6.0
Gutenberg v16.6.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 12.6.0 All 403 releases
gutenberg / build / block-library / blocks / navigation-submenu.php

navigation-submenu.php in Gutenberg 16.6.0, at build/block-library/blocks/navigation-submenu.php

253 lines 8.9 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/navigation-submenu` block.
4 *
5 * @package WordPress
6 */
7
8 /**
9 * Build an array with CSS classes and inline styles defining the font sizes
10 * which will be applied to the navigation markup in the front-end.
11 *
12 * @param array $context Navigation block context.
13 * @return array Font size CSS classes and inline styles.
14 */
15 function gutenberg_block_core_navigation_submenu_build_css_font_sizes( $context ) {
16 // CSS classes.
17 $font_sizes = array(
18 'css_classes' => array(),
19 'inline_styles' => '',
20 );
21
22 $has_named_font_size = array_key_exists( 'fontSize', $context );
23 $has_custom_font_size = isset( $context['style']['typography']['fontSize'] );
24
25 if ( $has_named_font_size ) {
26 // Add the font size class.
27 $font_sizes['css_classes'][] = sprintf( 'has-%s-font-size', $context['fontSize'] );
28 } elseif ( $has_custom_font_size ) {
29 // Add the custom font size inline style.
30 $font_sizes['inline_styles'] = sprintf(
31 'font-size: %s;',
32 gutenberg_get_typography_font_size_value(
33 array(
34 'size' => $context['style']['typography']['fontSize'],
35 )
36 )
37 );
38 }
39
40 return $font_sizes;
41 }
42
43 /**
44 * Returns the top-level submenu SVG chevron icon.
45 *
46 * @return string
47 */
48 function gutenberg_block_core_navigation_submenu_render_submenu_icon() {
49 return '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none" aria-hidden="true" focusable="false"><path d="M1.50002 4L6.00002 8L10.5 4" stroke-width="1.5"></path></svg>';
50 }
51
52 /**
53 * Renders the `core/navigation-submenu` block.
54 *
55 * @param array $attributes The block attributes.
56 * @param string $content The saved content.
57 * @param WP_Block $block The parsed block.
58 *
59 * @return string Returns the post content with the legacy widget added.
60 */
61 function gutenberg_render_block_core_navigation_submenu( $attributes, $content, $block ) {
62 $navigation_link_has_id = isset( $attributes['id'] ) && is_numeric( $attributes['id'] );
63 $is_post_type = isset( $attributes['kind'] ) && 'post-type' === $attributes['kind'];
64 $is_post_type = $is_post_type || isset( $attributes['type'] ) && ( 'post' === $attributes['type'] || 'page' === $attributes['type'] );
65
66 // Don't render the block's subtree if it is a draft.
67 if ( $is_post_type && $navigation_link_has_id && 'publish' !== get_post_status( $attributes['id'] ) ) {
68 return '';
69 }
70
71 // Don't render the block's subtree if it has no label.
72 if ( empty( $attributes['label'] ) ) {
73 return '';
74 }
75
76 $font_sizes = gutenberg_block_core_navigation_submenu_build_css_font_sizes( $block->context );
77 $style_attribute = $font_sizes['inline_styles'];
78
79 $css_classes = trim( implode( ' ', $font_sizes['css_classes'] ) );
80 $has_submenu = count( $block->inner_blocks ) > 0;
81 $kind = empty( $attributes['kind'] ) ? 'post_type' : str_replace( '-', '_', $attributes['kind'] );
82 $is_active = ! empty( $attributes['id'] ) && get_queried_object_id() === (int) $attributes['id'] && ! empty( get_queried_object()->$kind );
83
84 $show_submenu_indicators = isset( $block->context['showSubmenuIcon'] ) && $block->context['showSubmenuIcon'];
85 $open_on_click = isset( $block->context['openSubmenusOnClick'] ) && $block->context['openSubmenusOnClick'];
86 $open_on_hover_and_click = isset( $block->context['openSubmenusOnClick'] ) && ! $block->context['openSubmenusOnClick'] &&
87 $show_submenu_indicators;
88
89 $wrapper_attributes = get_block_wrapper_attributes(
90 array(
91 'class' => $css_classes . ' wp-block-navigation-item' . ( $has_submenu ? ' has-child' : '' ) .
92 ( $open_on_click ? ' open-on-click' : '' ) . ( $open_on_hover_and_click ? ' open-on-hover-click' : '' ) .
93 ( $is_active ? ' current-menu-item' : '' ),
94 'style' => $style_attribute,
95 )
96 );
97
98 $label = '';
99
100 if ( isset( $attributes['label'] ) ) {
101 $label .= wp_kses_post( $attributes['label'] );
102 }
103
104 $aria_label = sprintf(
105 /* translators: Accessibility text. %s: Parent page title. */
106 __( '%s submenu' ),
107 wp_strip_all_tags( $label )
108 );
109
110 $html = '<li ' . $wrapper_attributes . '>';
111
112 // If Submenus open on hover, we render an anchor tag with attributes.
113 // If submenu icons are set to show, we also render a submenu button, so the submenu can be opened on click.
114 if ( ! $open_on_click ) {
115 $item_url = isset( $attributes['url'] ) ? $attributes['url'] : '';
116 // Start appending HTML attributes to anchor tag.
117 $html .= '<a class="wp-block-navigation-item__content"';
118
119 // The href attribute on a and area elements is not required;
120 // when those elements do not have href attributes they do not create hyperlinks.
121 // But also The href attribute must have a value that is a valid URL potentially
122 // surrounded by spaces.
123 // see: https://html.spec.whatwg.org/multipage/links.html#links-created-by-a-and-area-elements.
124 if ( ! empty( $item_url ) ) {
125 $html .= ' href="' . esc_url( $item_url ) . '"';
126 }
127
128 if ( $is_active ) {
129 $html .= ' aria-current="page"';
130 }
131
132 if ( isset( $attributes['opensInNewTab'] ) && true === $attributes['opensInNewTab'] ) {
133 $html .= ' target="_blank" ';
134 }
135
136 if ( isset( $attributes['rel'] ) ) {
137 $html .= ' rel="' . esc_attr( $attributes['rel'] ) . '"';
138 } elseif ( isset( $attributes['nofollow'] ) && $attributes['nofollow'] ) {
139 $html .= ' rel="nofollow"';
140 }
141
142 if ( isset( $attributes['title'] ) ) {
143 $html .= ' title="' . esc_attr( $attributes['title'] ) . '"';
144 }
145
146 $html .= '>';
147 // End appending HTML attributes to anchor tag.
148
149 $html .= $label;
150
151 $html .= '</a>';
152 // End anchor tag content.
153
154 if ( $show_submenu_indicators ) {
155 // The submenu icon is rendered in a button here
156 // so that there's a clickable element to open the submenu.
157 $html .= '<button aria-label="' . esc_attr( $aria_label ) . '" class="wp-block-navigation__submenu-icon wp-block-navigation-submenu__toggle" aria-expanded="false">' . gutenberg_block_core_navigation_submenu_render_submenu_icon() . '</button>';
158 }
159 } else {
160 // If menus open on click, we render the parent as a button.
161 $html .= '<button aria-label="' . esc_attr( $aria_label ) . '" class="wp-block-navigation-item__content wp-block-navigation-submenu__toggle" aria-expanded="false">';
162
163 // Wrap title with span to isolate it from submenu icon.
164 $html .= '<span class="wp-block-navigation-item__label">';
165
166 $html .= $label;
167
168 $html .= '</span>';
169
170 $html .= '</button>';
171
172 $html .= '<span class="wp-block-navigation__submenu-icon">' . gutenberg_block_core_navigation_submenu_render_submenu_icon() . '</span>';
173
174 }
175
176 if ( $has_submenu ) {
177 // Copy some attributes from the parent block to this one.
178 // Ideally this would happen in the client when the block is created.
179 if ( array_key_exists( 'overlayTextColor', $block->context ) ) {
180 $attributes['textColor'] = $block->context['overlayTextColor'];
181 }
182 if ( array_key_exists( 'overlayBackgroundColor', $block->context ) ) {
183 $attributes['backgroundColor'] = $block->context['overlayBackgroundColor'];
184 }
185 if ( array_key_exists( 'customOverlayTextColor', $block->context ) ) {
186 $attributes['style']['color']['text'] = $block->context['customOverlayTextColor'];
187 }
188 if ( array_key_exists( 'customOverlayBackgroundColor', $block->context ) ) {
189 $attributes['style']['color']['background'] = $block->context['customOverlayBackgroundColor'];
190 }
191
192 // This allows us to be able to get a response from gutenberg_apply_colors_support.
193 $block->block_type->supports['color'] = true;
194 $colors_supports = gutenberg_apply_colors_support( $block->block_type, $attributes );
195 $css_classes = 'wp-block-navigation__submenu-container';
196 if ( array_key_exists( 'class', $colors_supports ) ) {
197 $css_classes .= ' ' . $colors_supports['class'];
198 }
199
200 $style_attribute = '';
201 if ( array_key_exists( 'style', $colors_supports ) ) {
202 $style_attribute = $colors_supports['style'];
203 }
204
205 $inner_blocks_html = '';
206 foreach ( $block->inner_blocks as $inner_block ) {
207 $inner_blocks_html .= $inner_block->render();
208 }
209
210 if ( strpos( $inner_blocks_html, 'current-menu-item' ) ) {
211 $tag_processor = new WP_HTML_Tag_Processor( $html );
212 while ( $tag_processor->next_tag( array( 'class_name' => 'wp-block-navigation-item__content' ) ) ) {
213 $tag_processor->add_class( 'current-menu-ancestor' );
214 }
215 $html = $tag_processor->get_updated_html();
216 }
217
218 $wrapper_attributes = get_block_wrapper_attributes(
219 array(
220 'class' => $css_classes,
221 'style' => $style_attribute,
222 )
223 );
224
225 $html .= sprintf(
226 '<ul %s>%s</ul>',
227 $wrapper_attributes,
228 $inner_blocks_html
229 );
230
231 }
232
233 $html .= '</li>';
234
235 return $html;
236 }
237
238 /**
239 * Register the navigation submenu block.
240 *
241 * @uses gutenberg_render_block_core_navigation_submenu()
242 * @throws WP_Error An WP_Error exception parsing the block definition.
243 */
244 function gutenberg_register_block_core_navigation_submenu() {
245 register_block_type_from_metadata(
246 __DIR__ . '/navigation-submenu',
247 array(
248 'render_callback' => 'gutenberg_render_block_core_navigation_submenu',
249 )
250 );
251 }
252 add_action( 'init', 'gutenberg_register_block_core_navigation_submenu', 20 );
253