PluginProbe
Gutenberg / 15.9.0
Gutenberg v15.9.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 / lib / experimental / interactivity-api / blocks.php

blocks.php in Gutenberg 15.9.0, at lib/experimental/interactivity-api/blocks.php

235 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Extend WordPress core navigation block to use the Interactivity API.
4 * Interactivity API directives are added using the Tag Processor while it is experimental.
5 *
6 * @package gutenberg
7 */
8
9 /**
10 * Adds Interactivity API directives to the File block markup using the Tag Processor.
11 *
12 * @param string $block_content Markup of the File block.
13 * @param array $block The full block, including name and attributes.
14 * @param WP_Block $instance The block instance.
15 *
16 * @return string File block markup with the directives injected when applicable.
17 */
18 function gutenberg_block_core_file_add_directives_to_content( $block_content, $block, $instance ) {
19 if ( empty( $instance->attributes['displayPreview'] ) ) {
20 return $block_content;
21 }
22 $processor = new WP_HTML_Tag_Processor( $block_content );
23 $processor->next_tag();
24 $processor->set_attribute( 'data-wp-island', '' );
25 $processor->next_tag( 'object' );
26 $processor->set_attribute( 'data-wp-bind.hidden', '!selectors.core.file.hasPdfPreview' );
27 $processor->set_attribute( 'hidden', true );
28 return $processor->get_updated_html();
29 }
30 add_filter( 'render_block_core/file', 'gutenberg_block_core_file_add_directives_to_content', 10, 3 );
31
32 /**
33 * Add Interactivity API directives to the navigation block markup using the Tag Processor
34 * The final HTML of the navigation block will look similar to this:
35 *
36 * <nav
37 * data-wp-island
38 * data-wp-context='{ "core": { "navigation": { "isMenuOpen": false, "overlay": true, "roleAttribute": "" } } }'
39 * >
40 * <button
41 * class="wp-block-navigation__responsive-container-open"
42 * data-wp-on.click="actions.core.navigation.openMenu"
43 * data-wp-on.keydown="actions.core.navigation.handleMenuKeydown"
44 * >
45 * <div
46 * class="wp-block-navigation__responsive-container"
47 * data-wp-class.has-modal-open="context.core.navigation.isMenuOpen"
48 * data-wp-class.is-menu-open="context.core.navigation.isMenuOpen"
49 * data-wp-bind.aria-hidden="!context.core.navigation.isMenuOpen"
50 * data-wp-effect="effects.core.navigation.initMenu"
51 * data-wp-on.keydown="actions.core.navigation.handleMenuKeydown"
52 * data-wp-on.focusout="actions.core.navigation.handleMenuFocusout"
53 * tabindex="-1"
54 * >
55 * <div class="wp-block-navigation__responsive-close">
56 * <div
57 * class="wp-block-navigation__responsive-dialog"
58 * data-wp-bind.aria-modal="context.core.navigation.isMenuOpen"
59 * data-wp-bind.role="selectors.core.navigation.roleAttribute"
60 * data-wp-effect="effects.core.navigation.focusFirstElement"
61 * >
62 * <button
63 * class="wp-block-navigation__responsive-container-close"
64 * data-wp-on.click="actions.core.navigation.closeMenu"
65 * >
66 * <svg>
67 * <button>
68 * MENU ITEMS
69 * </div>
70 * </div>
71 * </div>
72 * </nav>
73 *
74 * @param string $block_content Markup of the navigation block.
75 *
76 * @return string Navigation block markup with the proper directives
77 */
78 function gutenberg_block_core_navigation_add_directives_to_markup( $block_content ) {
79 $w = new WP_HTML_Tag_Processor( $block_content );
80 // Add directives to the `<nav>` element.
81 if ( $w->next_tag( 'nav' ) ) {
82 $w->set_attribute( 'data-wp-island', '' );
83 $w->set_attribute( 'data-wp-context', '{ "core": { "navigation": { "isMenuOpen": false, "overlay": true, "roleAttribute": "" } } }' );
84 };
85
86 // Add directives to the open menu button.
87 if ( $w->next_tag(
88 array(
89 'tag_name' => 'BUTTON',
90 'class_name' => 'wp-block-navigation__responsive-container-open',
91 )
92 ) ) {
93 $w->set_attribute( 'data-wp-on.click', 'actions.core.navigation.openMenu' );
94 $w->set_attribute( 'data-wp-on.keydown', 'actions.core.navigation.handleMenuKeydown' );
95 $w->remove_attribute( 'data-micromodal-trigger' );
96 } else {
97 // If the open modal button not found, we handle submenus immediately.
98 $w = new WP_HTML_Tag_Processor( $w->get_updated_html() );
99
100 gutenberg_block_core_navigation_add_directives_to_submenu( $w );
101
102 return $w->get_updated_html();
103 }
104
105 // Add directives to the menu container.
106 if ( $w->next_tag(
107 array(
108 'tag_name' => 'DIV',
109 'class_name' => 'wp-block-navigation__responsive-container',
110 )
111 ) ) {
112 $w->set_attribute( 'data-wp-class.has-modal-open', 'context.core.navigation.isMenuOpen' );
113 $w->set_attribute( 'data-wp-class.is-menu-open', 'context.core.navigation.isMenuOpen' );
114 $w->set_attribute( 'data-wp-bind.aria-hidden', '!context.core.navigation.isMenuOpen' );
115 $w->set_attribute( 'data-wp-effect', 'effects.core.navigation.initMenu' );
116 $w->set_attribute( 'data-wp-on.keydown', 'actions.core.navigation.handleMenuKeydown' );
117 $w->set_attribute( 'data-wp-on.focusout', 'actions.core.navigation.handleMenuFocusout' );
118 $w->set_attribute( 'tabindex', '-1' );
119 };
120
121 // Remove micromodal attribute.
122 if ( $w->next_tag(
123 array(
124 'tag_name' => 'DIV',
125 'class_name' => 'wp-block-navigation__responsive-close',
126 )
127 ) ) {
128 $w->remove_attribute( 'data-micromodal-close' );
129 };
130
131 // Add directives to the dialog container.
132 if ( $w->next_tag(
133 array(
134 'tag_name' => 'DIV',
135 'class_name' => 'wp-block-navigation__responsive-dialog',
136 )
137 ) ) {
138 $w->set_attribute( 'data-wp-bind.aria-modal', 'context.core.navigation.isMenuOpen' );
139 $w->set_attribute( 'data-wp-bind.role', 'selectors.core.navigation.roleAttribute' );
140 $w->set_attribute( 'data-wp-effect', 'effects.core.navigation.focusFirstElement' );
141 };
142
143 // Add directives to the close button.
144 if ( $w->next_tag(
145 array(
146 'tag_name' => 'BUTTON',
147 'class_name' => 'wp-block-navigation__responsive-container-close',
148 )
149 ) ) {
150 $w->set_attribute( 'data-wp-on.click', 'actions.core.navigation.closeMenu' );
151 $w->remove_attribute( 'data-micromodal-close' );
152 };
153
154 // Submenus.
155 gutenberg_block_core_navigation_add_directives_to_submenu( $w );
156
157 return $w->get_updated_html();
158 };
159
160 /**
161 * Add Interactivity API directives to the navigation-submenu and page-list blocks markup using the Tag Processor
162 * The final HTML of the navigation-submenu and the page-list blocks will look similar to this:
163 *
164 * <li
165 * class="has-child"
166 * data-wp-context='{ "core": { "navigation": { "isMenuOpen": false, "overlay": false } } }'
167 * data-wp-effect="effects.core.navigation.initMenu"
168 * data-wp-on.keydown="actions.core.navigation.handleMenuKeydown"
169 * data-wp-on.focusout="actions.core.navigation.handleMenuFocusout"
170 * >
171 * <button
172 * class="wp-block-navigation-submenu__toggle"
173 * data-wp-on.click="actions.core.navigation.openMenu"
174 * data-wp-bind.aria-expanded="context.core.navigation.isMenuOpen"
175 * >
176 * </button>
177 * <span>Title</span>
178 * <ul class="wp-block-navigation__submenu-container">
179 * SUBMENU ITEMS
180 * </ul>
181 * </li>
182 *
183 * @param string $w Markup of the navigation block.
184 *
185 * @return void
186 */
187 function gutenberg_block_core_navigation_add_directives_to_submenu( $w ) {
188 while ( $w->next_tag(
189 array(
190 'tag_name' => 'LI',
191 'class_name' => 'has-child',
192 )
193 ) ) {
194 // Add directives to the parent `<li>`.
195 $w->set_attribute( 'data-wp-context', '{ "core": { "navigation": { "isMenuOpen": false, "overlay": false } } }' );
196 $w->set_attribute( 'data-wp-effect', 'effects.core.navigation.initMenu' );
197 $w->set_attribute( 'data-wp-on.focusout', 'actions.core.navigation.handleMenuFocusout' );
198 $w->set_attribute( 'data-wp-on.keydown', 'actions.core.navigation.handleMenuKeydown' );
199
200 // Add directives to the toggle submenu button.
201 if ( $w->next_tag(
202 array(
203 'tag_name' => 'BUTTON',
204 'class_name' => 'wp-block-navigation-submenu__toggle',
205 )
206 ) ) {
207 $w->set_attribute( 'data-wp-on.click', 'actions.core.navigation.toggleMenu' );
208 $w->set_attribute( 'data-wp-bind.aria-expanded', 'context.core.navigation.isMenuOpen' );
209 };
210
211 // Iterate through subitems if exist.
212 gutenberg_block_core_navigation_add_directives_to_submenu( $w );
213 }
214 };
215
216 add_filter( 'render_block_core/navigation', 'gutenberg_block_core_navigation_add_directives_to_markup', 10, 1 );
217
218 /**
219 * Replaces view script for the File, Navigation, and Image blocks with version using Interactivity API.
220 *
221 * @param array $metadata Block metadata as read in via block.json.
222 *
223 * @return array Filtered block type metadata.
224 */
225 function gutenberg_block_update_interactive_view_script( $metadata ) {
226 if (
227 in_array( $metadata['name'], array( 'core/file', 'core/navigation', 'core/image' ), true ) &&
228 str_contains( $metadata['file'], 'build/block-library/blocks' )
229 ) {
230 $metadata['viewScript'] = array( 'file:./interactivity.min.js' );
231 }
232 return $metadata;
233 }
234 add_filter( 'block_type_metadata', 'gutenberg_block_update_interactive_view_script', 10, 1 );
235