@wordpress/block-library 8.25.1-next.79a6196f.0 → 8.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/build/avatar/edit.js +2 -2
- package/build/avatar/edit.js.map +1 -1
- package/build/block/edit.js +75 -12
- package/build/block/edit.js.map +1 -1
- package/build/block/{v1/edit.native.js → edit.native.js} +4 -4
- package/build/block/edit.native.js.map +1 -0
- package/build/block/index.js +5 -3
- package/build/block/index.js.map +1 -1
- package/build/button/edit.js +24 -6
- package/build/button/edit.js.map +1 -1
- package/build/button/index.js +1 -0
- package/build/button/index.js.map +1 -1
- package/build/button/save.js +3 -1
- package/build/button/save.js.map +1 -1
- package/build/embed/edit.js +3 -2
- package/build/embed/edit.js.map +1 -1
- package/build/file/index.js +0 -1
- package/build/file/index.js.map +1 -1
- package/build/footnotes/edit.js +2 -1
- package/build/footnotes/edit.js.map +1 -1
- package/build/footnotes/format.js +17 -19
- package/build/footnotes/format.js.map +1 -1
- package/build/heading/edit.js +2 -1
- package/build/heading/edit.js.map +1 -1
- package/build/heading/edit.native.js +141 -0
- package/build/heading/edit.native.js.map +1 -0
- package/build/heading/index.js +1 -0
- package/build/heading/index.js.map +1 -1
- package/build/image/edit.js +8 -4
- package/build/image/edit.js.map +1 -1
- package/build/image/image.js +33 -7
- package/build/image/image.js.map +1 -1
- package/build/image/index.js +6 -3
- package/build/image/index.js.map +1 -1
- package/build/more/index.js +4 -0
- package/build/more/index.js.map +1 -1
- package/build/navigation/edit/index.js +2 -2
- package/build/navigation/edit/index.js.map +1 -1
- package/build/navigation/index.js +0 -1
- package/build/navigation/index.js.map +1 -1
- package/build/paragraph/edit.js +2 -1
- package/build/paragraph/edit.js.map +1 -1
- package/build/paragraph/index.js +1 -1
- package/build/paragraph/transforms.js +1 -1
- package/build/post-content/edit.js +2 -2
- package/build/post-content/edit.js.map +1 -1
- package/build/post-date/edit.js +1 -1
- package/build/post-date/edit.js.map +1 -1
- package/build/post-navigation-link/edit.js +43 -2
- package/build/post-navigation-link/edit.js.map +1 -1
- package/build/post-navigation-link/index.js +8 -0
- package/build/post-navigation-link/index.js.map +1 -1
- package/build/pullquote/index.js +4 -0
- package/build/pullquote/index.js.map +1 -1
- package/build/query/edit/inspector-controls/index.js +3 -3
- package/build/query/edit/inspector-controls/index.js.map +1 -1
- package/build/query/edit/query-content.js +2 -2
- package/build/query/edit/query-content.js.map +1 -1
- package/build/query/edit/query-placeholder.js +6 -7
- package/build/query/edit/query-placeholder.js.map +1 -1
- package/build/query/index.js +1 -2
- package/build/query/index.js.map +1 -1
- package/build/query/variations.js +8 -1
- package/build/query/variations.js.map +1 -1
- package/build/query/view.js +31 -12
- package/build/query/view.js.map +1 -1
- package/build/search/index.js +0 -1
- package/build/search/index.js.map +1 -1
- package/build/table-of-contents/hooks.js +2 -2
- package/build/table-of-contents/hooks.js.map +1 -1
- package/build/template-part/edit/advanced-controls.js +1 -4
- package/build/template-part/edit/advanced-controls.js.map +1 -1
- package/build/template-part/edit/index.js +39 -17
- package/build/template-part/edit/index.js.map +1 -1
- package/build/video/edit.native.js +7 -2
- package/build/video/edit.native.js.map +1 -1
- package/build/video/transforms.js +17 -0
- package/build/video/transforms.js.map +1 -1
- package/build-module/avatar/edit.js +2 -2
- package/build-module/avatar/edit.js.map +1 -1
- package/build-module/block/edit.js +74 -11
- package/build-module/block/edit.js.map +1 -1
- package/build-module/block/{v1/edit.native.js → edit.native.js} +3 -3
- package/build-module/block/edit.native.js.map +1 -0
- package/build-module/block/index.js +5 -3
- package/build-module/block/index.js.map +1 -1
- package/build-module/button/edit.js +25 -7
- package/build-module/button/edit.js.map +1 -1
- package/build-module/button/index.js +1 -0
- package/build-module/button/index.js.map +1 -1
- package/build-module/button/save.js +4 -2
- package/build-module/button/save.js.map +1 -1
- package/build-module/embed/edit.js +3 -2
- package/build-module/embed/edit.js.map +1 -1
- package/build-module/file/index.js +0 -1
- package/build-module/file/index.js.map +1 -1
- package/build-module/footnotes/edit.js +2 -1
- package/build-module/footnotes/edit.js.map +1 -1
- package/build-module/footnotes/format.js +17 -19
- package/build-module/footnotes/format.js.map +1 -1
- package/build-module/heading/edit.js +3 -2
- package/build-module/heading/edit.js.map +1 -1
- package/build-module/heading/edit.native.js +132 -0
- package/build-module/heading/edit.native.js.map +1 -0
- package/build-module/heading/index.js +1 -0
- package/build-module/heading/index.js.map +1 -1
- package/build-module/image/edit.js +9 -5
- package/build-module/image/edit.js.map +1 -1
- package/build-module/image/image.js +33 -7
- package/build-module/image/image.js.map +1 -1
- package/build-module/image/index.js +6 -3
- package/build-module/image/index.js.map +1 -1
- package/build-module/more/index.js +4 -0
- package/build-module/more/index.js.map +1 -1
- package/build-module/navigation/edit/index.js +1 -1
- package/build-module/navigation/edit/index.js.map +1 -1
- package/build-module/navigation/index.js +0 -1
- package/build-module/navigation/index.js.map +1 -1
- package/build-module/paragraph/edit.js +3 -2
- package/build-module/paragraph/edit.js.map +1 -1
- package/build-module/paragraph/index.js +1 -1
- package/build-module/paragraph/transforms.js +1 -1
- package/build-module/post-content/edit.js +1 -1
- package/build-module/post-content/edit.js.map +1 -1
- package/build-module/post-date/edit.js +1 -1
- package/build-module/post-date/edit.js.map +1 -1
- package/build-module/post-navigation-link/edit.js +44 -3
- package/build-module/post-navigation-link/edit.js.map +1 -1
- package/build-module/post-navigation-link/index.js +8 -0
- package/build-module/post-navigation-link/index.js.map +1 -1
- package/build-module/pullquote/index.js +4 -0
- package/build-module/pullquote/index.js.map +1 -1
- package/build-module/query/edit/inspector-controls/index.js +4 -4
- package/build-module/query/edit/inspector-controls/index.js.map +1 -1
- package/build-module/query/edit/query-content.js +2 -2
- package/build-module/query/edit/query-content.js.map +1 -1
- package/build-module/query/edit/query-placeholder.js +7 -8
- package/build-module/query/edit/query-placeholder.js.map +1 -1
- package/build-module/query/index.js +1 -2
- package/build-module/query/index.js.map +1 -1
- package/build-module/query/variations.js +8 -1
- package/build-module/query/variations.js.map +1 -1
- package/build-module/query/view.js +30 -9
- package/build-module/query/view.js.map +1 -1
- package/build-module/search/index.js +0 -1
- package/build-module/search/index.js.map +1 -1
- package/build-module/table-of-contents/hooks.js +2 -2
- package/build-module/table-of-contents/hooks.js.map +1 -1
- package/build-module/template-part/edit/advanced-controls.js +1 -4
- package/build-module/template-part/edit/advanced-controls.js.map +1 -1
- package/build-module/template-part/edit/index.js +38 -16
- package/build-module/template-part/edit/index.js.map +1 -1
- package/build-module/video/edit.native.js +7 -2
- package/build-module/video/edit.native.js.map +1 -1
- package/build-module/video/transforms.js +17 -0
- package/build-module/video/transforms.js.map +1 -1
- package/build-style/common-rtl.css +4 -2
- package/build-style/common.css +4 -2
- package/build-style/cover/style-rtl.css +1 -2
- package/build-style/cover/style.css +1 -2
- package/build-style/editor-rtl.css +6 -4
- package/build-style/editor.css +6 -4
- package/build-style/gallery/style-rtl.css +2 -4
- package/build-style/gallery/style.css +2 -4
- package/build-style/image/editor-rtl.css +6 -0
- package/build-style/image/editor.css +6 -0
- package/build-style/page-list/editor-rtl.css +0 -4
- package/build-style/page-list/editor.css +0 -4
- package/build-style/pullquote/style-rtl.css +10 -1
- package/build-style/pullquote/style.css +10 -1
- package/build-style/search/style-rtl.css +2 -1
- package/build-style/search/style.css +2 -1
- package/build-style/style-rtl.css +19 -11
- package/build-style/style.css +19 -11
- package/build-style/video/style-rtl.css +1 -2
- package/build-style/video/style.css +1 -2
- package/package.json +34 -32
- package/src/avatar/edit.js +16 -18
- package/src/block/block.json +3 -0
- package/src/block/edit.js +96 -14
- package/src/block/{v1/edit.native.js → edit.native.js} +4 -4
- package/src/block/index.js +2 -3
- package/src/block/index.php +3 -31
- package/src/button/block.json +1 -0
- package/src/button/edit.js +76 -43
- package/src/button/save.js +3 -0
- package/src/embed/edit.js +3 -2
- package/src/file/block.json +0 -1
- package/src/file/index.php +11 -57
- package/src/footnotes/edit.js +2 -1
- package/src/footnotes/format.js +34 -31
- package/src/footnotes/index.php +20 -11
- package/src/heading/block.json +1 -0
- package/src/heading/edit.js +18 -14
- package/src/heading/edit.native.js +144 -0
- package/src/image/block.json +7 -3
- package/src/image/edit.js +19 -6
- package/src/image/editor.scss +6 -1
- package/src/image/image.js +101 -42
- package/src/image/index.js +6 -0
- package/src/image/index.php +14 -51
- package/src/more/index.js +6 -0
- package/src/navigation/block.json +0 -1
- package/src/navigation/edit/index.js +2 -2
- package/src/navigation/index.php +777 -28
- package/src/navigation-link/index.php +78 -16
- package/src/page-list/editor.scss +0 -4
- package/src/paragraph/block.json +1 -1
- package/src/paragraph/edit.js +23 -19
- package/src/post-content/edit.js +2 -2
- package/src/post-date/edit.js +38 -33
- package/src/post-navigation-link/block.json +8 -0
- package/src/post-navigation-link/edit.js +63 -1
- package/src/post-navigation-link/index.php +17 -3
- package/src/post-terms/index.php +13 -4
- package/src/pullquote/block.json +4 -0
- package/src/pullquote/style.scss +13 -1
- package/src/query/block.json +1 -2
- package/src/query/edit/inspector-controls/index.js +137 -146
- package/src/query/edit/query-content.js +9 -7
- package/src/query/edit/query-placeholder.js +11 -11
- package/src/query/index.php +33 -71
- package/src/query/variations.js +4 -0
- package/src/query/view.js +24 -19
- package/src/search/block.json +0 -1
- package/src/search/index.php +18 -36
- package/src/table-of-contents/hooks.js +2 -2
- package/src/template-part/edit/advanced-controls.js +2 -3
- package/src/template-part/edit/index.js +77 -50
- package/src/template-part/index.php +2 -2
- package/src/video/edit.native.js +5 -2
- package/src/video/test/edit.native.js +38 -0
- package/src/video/transforms.js +32 -0
- package/tsconfig.json +1 -0
- package/build/block/v1/edit.js +0 -116
- package/build/block/v1/edit.js.map +0 -1
- package/build/block/v1/edit.native.js.map +0 -1
- package/build-module/block/v1/edit.js +0 -108
- package/build-module/block/v1/edit.js.map +0 -1
- package/build-module/block/v1/edit.native.js.map +0 -1
- package/src/block/v1/edit.js +0 -163
package/src/navigation/index.php
CHANGED
|
@@ -5,6 +5,648 @@
|
|
|
5
5
|
* @package WordPress
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Helper functions used to render the navigation block.
|
|
10
|
+
*/
|
|
11
|
+
class WP_Navigation_Block_Renderer {
|
|
12
|
+
/**
|
|
13
|
+
* Used to determine which blocks are wrapped in an <li>.
|
|
14
|
+
*
|
|
15
|
+
* @var array
|
|
16
|
+
*/
|
|
17
|
+
private static $nav_blocks_wrapped_in_list_item = array(
|
|
18
|
+
'core/navigation-link',
|
|
19
|
+
'core/home-link',
|
|
20
|
+
'core/site-title',
|
|
21
|
+
'core/site-logo',
|
|
22
|
+
'core/navigation-submenu',
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Used to determine which blocks need an <li> wrapper.
|
|
27
|
+
*
|
|
28
|
+
* @var array
|
|
29
|
+
*/
|
|
30
|
+
private static $needs_list_item_wrapper = array(
|
|
31
|
+
'core/site-title',
|
|
32
|
+
'core/site-logo',
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Keeps track of all the navigation names that have been seen.
|
|
37
|
+
*
|
|
38
|
+
* @var array
|
|
39
|
+
*/
|
|
40
|
+
private static $seen_menu_names = array();
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Returns whether or not this is responsive navigation.
|
|
44
|
+
*
|
|
45
|
+
* @param array $attributes The block attributes.
|
|
46
|
+
* @return bool Returns whether or not this is responsive navigation.
|
|
47
|
+
*/
|
|
48
|
+
private static function is_responsive( $attributes ) {
|
|
49
|
+
/**
|
|
50
|
+
* This is for backwards compatibility after the `isResponsive` attribute was been removed.
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
$has_old_responsive_attribute = ! empty( $attributes['isResponsive'] ) && $attributes['isResponsive'];
|
|
54
|
+
return isset( $attributes['overlayMenu'] ) && 'never' !== $attributes['overlayMenu'] || $has_old_responsive_attribute;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Returns whether or not a navigation has a submenu.
|
|
59
|
+
*
|
|
60
|
+
* @param WP_Block_List $inner_blocks The list of inner blocks.
|
|
61
|
+
* @return bool Returns whether or not a navigation has a submenu.
|
|
62
|
+
*/
|
|
63
|
+
private static function has_submenus( $inner_blocks ) {
|
|
64
|
+
foreach ( $inner_blocks as $inner_block ) {
|
|
65
|
+
$inner_block_content = $inner_block->render();
|
|
66
|
+
$p = new WP_HTML_Tag_Processor( $inner_block_content );
|
|
67
|
+
if ( $p->next_tag(
|
|
68
|
+
array(
|
|
69
|
+
'name' => 'LI',
|
|
70
|
+
'class_name' => 'has-child',
|
|
71
|
+
)
|
|
72
|
+
) ) {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Determine whether the navigation blocks is interactive.
|
|
81
|
+
*
|
|
82
|
+
* @param array $attributes The block attributes.
|
|
83
|
+
* @param WP_Block_List $inner_blocks The list of inner blocks.
|
|
84
|
+
* @return bool Returns whether or not to load the view script.
|
|
85
|
+
*/
|
|
86
|
+
private static function is_interactive( $attributes, $inner_blocks ) {
|
|
87
|
+
$has_submenus = static::has_submenus( $inner_blocks );
|
|
88
|
+
$is_responsive_menu = static::is_responsive( $attributes );
|
|
89
|
+
return ( $has_submenus && ( $attributes['openSubmenusOnClick'] || $attributes['showSubmenuIcon'] ) ) || $is_responsive_menu;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Returns whether or not a block needs a list item wrapper.
|
|
94
|
+
*
|
|
95
|
+
* @param WP_Block $block The block.
|
|
96
|
+
* @return bool Returns whether or not a block needs a list item wrapper.
|
|
97
|
+
*/
|
|
98
|
+
private static function does_block_need_a_list_item_wrapper( $block ) {
|
|
99
|
+
return in_array( $block->name, static::$needs_list_item_wrapper, true );
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Returns the markup for a single inner block.
|
|
104
|
+
*
|
|
105
|
+
* @param WP_Block $inner_block The inner block.
|
|
106
|
+
* @return string Returns the markup for a single inner block.
|
|
107
|
+
*/
|
|
108
|
+
private static function get_markup_for_inner_block( $inner_block ) {
|
|
109
|
+
$inner_block_content = $inner_block->render();
|
|
110
|
+
if ( ! empty( $inner_block_content ) ) {
|
|
111
|
+
if ( static::does_block_need_a_list_item_wrapper( $inner_block ) ) {
|
|
112
|
+
return '<li class="wp-block-navigation-item">' . $inner_block_content . '</li>';
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return $inner_block_content;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Returns the html for the inner blocks of the navigation block.
|
|
121
|
+
*
|
|
122
|
+
* @param array $attributes The block attributes.
|
|
123
|
+
* @param WP_Block_List $inner_blocks The list of inner blocks.
|
|
124
|
+
* @return string Returns the html for the inner blocks of the navigation block.
|
|
125
|
+
*/
|
|
126
|
+
private static function get_inner_blocks_html( $attributes, $inner_blocks ) {
|
|
127
|
+
$has_submenus = static::has_submenus( $inner_blocks );
|
|
128
|
+
$is_interactive = static::is_interactive( $attributes, $inner_blocks );
|
|
129
|
+
|
|
130
|
+
$style = static::get_styles( $attributes );
|
|
131
|
+
$class = static::get_classes( $attributes );
|
|
132
|
+
$container_attributes = get_block_wrapper_attributes(
|
|
133
|
+
array(
|
|
134
|
+
'class' => 'wp-block-navigation__container ' . $class,
|
|
135
|
+
'style' => $style,
|
|
136
|
+
)
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
$inner_blocks_html = '';
|
|
140
|
+
$is_list_open = false;
|
|
141
|
+
|
|
142
|
+
foreach ( $inner_blocks as $inner_block ) {
|
|
143
|
+
$is_list_item = in_array( $inner_block->name, static::$nav_blocks_wrapped_in_list_item, true );
|
|
144
|
+
|
|
145
|
+
if ( $is_list_item && ! $is_list_open ) {
|
|
146
|
+
$is_list_open = true;
|
|
147
|
+
$inner_blocks_html .= sprintf(
|
|
148
|
+
'<ul %1$s>',
|
|
149
|
+
$container_attributes
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if ( ! $is_list_item && $is_list_open ) {
|
|
154
|
+
$is_list_open = false;
|
|
155
|
+
$inner_blocks_html .= '</ul>';
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
$inner_blocks_html .= static::get_markup_for_inner_block( $inner_block );
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if ( $is_list_open ) {
|
|
162
|
+
$inner_blocks_html .= '</ul>';
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Add directives to the submenu if needed.
|
|
166
|
+
if ( $has_submenus && $is_interactive ) {
|
|
167
|
+
$tags = new WP_HTML_Tag_Processor( $inner_blocks_html );
|
|
168
|
+
$inner_blocks_html = block_core_navigation_add_directives_to_submenu( $tags, $attributes );
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return $inner_blocks_html;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Gets the inner blocks for the navigation block from the navigation post.
|
|
176
|
+
*
|
|
177
|
+
* @param array $attributes The block attributes.
|
|
178
|
+
* @return WP_Block_List Returns the inner blocks for the navigation block.
|
|
179
|
+
*/
|
|
180
|
+
private static function get_inner_blocks_from_navigation_post( $attributes ) {
|
|
181
|
+
$navigation_post = get_post( $attributes['ref'] );
|
|
182
|
+
if ( ! isset( $navigation_post ) ) {
|
|
183
|
+
return new WP_Block_List( array(), $attributes );
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Only published posts are valid. If this is changed then a corresponding change
|
|
187
|
+
// must also be implemented in `use-navigation-menu.js`.
|
|
188
|
+
if ( 'publish' === $navigation_post->post_status ) {
|
|
189
|
+
$parsed_blocks = parse_blocks( $navigation_post->post_content );
|
|
190
|
+
|
|
191
|
+
// 'parse_blocks' includes a null block with '\n\n' as the content when
|
|
192
|
+
// it encounters whitespace. This code strips it.
|
|
193
|
+
$blocks = block_core_navigation_filter_out_empty_blocks( $parsed_blocks );
|
|
194
|
+
|
|
195
|
+
if ( function_exists( 'get_hooked_blocks' ) ) {
|
|
196
|
+
// Run Block Hooks algorithm to inject hooked blocks.
|
|
197
|
+
$markup = block_core_navigation_insert_hooked_blocks( $blocks, $navigation_post );
|
|
198
|
+
$root_nav_block = parse_blocks( $markup )[0];
|
|
199
|
+
|
|
200
|
+
$blocks = isset( $root_nav_block['innerBlocks'] ) ? $root_nav_block['innerBlocks'] : $blocks;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// TODO - this uses the full navigation block attributes for the
|
|
204
|
+
// context which could be refined.
|
|
205
|
+
return new WP_Block_List( $blocks, $attributes );
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Gets the inner blocks for the navigation block from the fallback.
|
|
211
|
+
*
|
|
212
|
+
* @param array $attributes The block attributes.
|
|
213
|
+
* @return WP_Block_List Returns the inner blocks for the navigation block.
|
|
214
|
+
*/
|
|
215
|
+
private static function get_inner_blocks_from_fallback( $attributes ) {
|
|
216
|
+
$fallback_blocks = block_core_navigation_get_fallback_blocks();
|
|
217
|
+
|
|
218
|
+
// Fallback my have been filtered so do basic test for validity.
|
|
219
|
+
if ( empty( $fallback_blocks ) || ! is_array( $fallback_blocks ) ) {
|
|
220
|
+
return new WP_Block_List( array(), $attributes );
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return new WP_Block_List( $fallback_blocks, $attributes );
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Gets the inner blocks for the navigation block.
|
|
228
|
+
*
|
|
229
|
+
* @param array $attributes The block attributes.
|
|
230
|
+
* @param WP_Block $block The parsed block.
|
|
231
|
+
* @return WP_Block_List Returns the inner blocks for the navigation block.
|
|
232
|
+
*/
|
|
233
|
+
private static function get_inner_blocks( $attributes, $block ) {
|
|
234
|
+
$inner_blocks = $block->inner_blocks;
|
|
235
|
+
|
|
236
|
+
// Ensure that blocks saved with the legacy ref attribute name (navigationMenuId) continue to render.
|
|
237
|
+
if ( array_key_exists( 'navigationMenuId', $attributes ) ) {
|
|
238
|
+
$attributes['ref'] = $attributes['navigationMenuId'];
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// If:
|
|
242
|
+
// - the gutenberg plugin is active
|
|
243
|
+
// - `__unstableLocation` is defined
|
|
244
|
+
// - we have menu items at the defined location
|
|
245
|
+
// - we don't have a relationship to a `wp_navigation` Post (via `ref`).
|
|
246
|
+
// ...then create inner blocks from the classic menu assigned to that location.
|
|
247
|
+
if (
|
|
248
|
+
defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN &&
|
|
249
|
+
array_key_exists( '__unstableLocation', $attributes ) &&
|
|
250
|
+
! array_key_exists( 'ref', $attributes ) &&
|
|
251
|
+
! empty( block_core_navigation_get_menu_items_at_location( $attributes['__unstableLocation'] ) )
|
|
252
|
+
) {
|
|
253
|
+
$inner_blocks = block_core_navigation_get_inner_blocks_from_unstable_location( $attributes );
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Load inner blocks from the navigation post.
|
|
257
|
+
if ( array_key_exists( 'ref', $attributes ) ) {
|
|
258
|
+
$inner_blocks = static::get_inner_blocks_from_navigation_post( $attributes );
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// If there are no inner blocks then fallback to rendering an appropriate fallback.
|
|
262
|
+
if ( empty( $inner_blocks ) ) {
|
|
263
|
+
$inner_blocks = static::get_inner_blocks_from_fallback( $attributes );
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Filter navigation block $inner_blocks.
|
|
268
|
+
* Allows modification of a navigation block menu items.
|
|
269
|
+
*
|
|
270
|
+
* @since 6.1.0
|
|
271
|
+
*
|
|
272
|
+
* @param \WP_Block_List $inner_blocks
|
|
273
|
+
*/
|
|
274
|
+
$inner_blocks = apply_filters( 'block_core_navigation_render_inner_blocks', $inner_blocks );
|
|
275
|
+
|
|
276
|
+
$post_ids = block_core_navigation_get_post_ids( $inner_blocks );
|
|
277
|
+
if ( $post_ids ) {
|
|
278
|
+
_prime_post_caches( $post_ids, false, false );
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return $inner_blocks;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Gets the name of the current navigation, if it has one.
|
|
286
|
+
*
|
|
287
|
+
* @param array $attributes The block attributes.
|
|
288
|
+
* @return string Returns the name of the navigation.
|
|
289
|
+
*/
|
|
290
|
+
private static function get_navigation_name( $attributes ) {
|
|
291
|
+
|
|
292
|
+
$navigation_name = $attributes['ariaLabel'] ?? '';
|
|
293
|
+
|
|
294
|
+
// Load the navigation post.
|
|
295
|
+
if ( array_key_exists( 'ref', $attributes ) ) {
|
|
296
|
+
$navigation_post = get_post( $attributes['ref'] );
|
|
297
|
+
if ( ! isset( $navigation_post ) ) {
|
|
298
|
+
return $navigation_name;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Only published posts are valid. If this is changed then a corresponding change
|
|
302
|
+
// must also be implemented in `use-navigation-menu.js`.
|
|
303
|
+
if ( 'publish' === $navigation_post->post_status ) {
|
|
304
|
+
$navigation_name = $navigation_post->post_title;
|
|
305
|
+
|
|
306
|
+
// This is used to count the number of times a navigation name has been seen,
|
|
307
|
+
// so that we can ensure every navigation has a unique id.
|
|
308
|
+
if ( isset( static::$seen_menu_names[ $navigation_name ] ) ) {
|
|
309
|
+
++static::$seen_menu_names[ $navigation_name ];
|
|
310
|
+
} else {
|
|
311
|
+
static::$seen_menu_names[ $navigation_name ] = 1;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return $navigation_name;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Returns the layout class for the navigation block.
|
|
321
|
+
*
|
|
322
|
+
* @param array $attributes The block attributes.
|
|
323
|
+
* @return string Returns the layout class for the navigation block.
|
|
324
|
+
*/
|
|
325
|
+
private static function get_layout_class( $attributes ) {
|
|
326
|
+
$layout_justification = array(
|
|
327
|
+
'left' => 'items-justified-left',
|
|
328
|
+
'right' => 'items-justified-right',
|
|
329
|
+
'center' => 'items-justified-center',
|
|
330
|
+
'space-between' => 'items-justified-space-between',
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
$layout_class = '';
|
|
334
|
+
if (
|
|
335
|
+
isset( $attributes['layout']['justifyContent'] ) &&
|
|
336
|
+
isset( $layout_justification[ $attributes['layout']['justifyContent'] ] )
|
|
337
|
+
) {
|
|
338
|
+
$layout_class .= $layout_justification[ $attributes['layout']['justifyContent'] ];
|
|
339
|
+
}
|
|
340
|
+
if ( isset( $attributes['layout']['orientation'] ) && 'vertical' === $attributes['layout']['orientation'] ) {
|
|
341
|
+
$layout_class .= ' is-vertical';
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if ( isset( $attributes['layout']['flexWrap'] ) && 'nowrap' === $attributes['layout']['flexWrap'] ) {
|
|
345
|
+
$layout_class .= ' no-wrap';
|
|
346
|
+
}
|
|
347
|
+
return $layout_class;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Return classes for the navigation block.
|
|
352
|
+
*
|
|
353
|
+
* @param array $attributes The block attributes.
|
|
354
|
+
* @return string Returns the classes for the navigation block.
|
|
355
|
+
*/
|
|
356
|
+
private static function get_classes( $attributes ) {
|
|
357
|
+
// Restore legacy classnames for submenu positioning.
|
|
358
|
+
$layout_class = static::get_layout_class( $attributes );
|
|
359
|
+
$colors = block_core_navigation_build_css_colors( $attributes );
|
|
360
|
+
$font_sizes = block_core_navigation_build_css_font_sizes( $attributes );
|
|
361
|
+
$is_responsive_menu = static::is_responsive( $attributes );
|
|
362
|
+
|
|
363
|
+
// Manually add block support text decoration as CSS class.
|
|
364
|
+
$text_decoration = $attributes['style']['typography']['textDecoration'] ?? null;
|
|
365
|
+
$text_decoration_class = sprintf( 'has-text-decoration-%s', $text_decoration );
|
|
366
|
+
|
|
367
|
+
// Sets the is-collapsed class when the navigation is set to always use the overlay.
|
|
368
|
+
// This saves us from needing to do this check in the view.js file (see the collapseNav function).
|
|
369
|
+
$is_collapsed_class = static::is_always_overlay( $attributes ) ? array( 'is-collapsed' ) : array();
|
|
370
|
+
|
|
371
|
+
$classes = array_merge(
|
|
372
|
+
$colors['css_classes'],
|
|
373
|
+
$font_sizes['css_classes'],
|
|
374
|
+
$is_responsive_menu ? array( 'is-responsive' ) : array(),
|
|
375
|
+
$layout_class ? array( $layout_class ) : array(),
|
|
376
|
+
$text_decoration ? array( $text_decoration_class ) : array(),
|
|
377
|
+
$is_collapsed_class
|
|
378
|
+
);
|
|
379
|
+
return implode( ' ', $classes );
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
private static function is_always_overlay( $attributes ) {
|
|
383
|
+
return isset( $attributes['overlayMenu'] ) && 'always' === $attributes['overlayMenu'];
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Get styles for the navigation block.
|
|
388
|
+
*
|
|
389
|
+
* @param array $attributes The block attributes.
|
|
390
|
+
* @return string Returns the styles for the navigation block.
|
|
391
|
+
*/
|
|
392
|
+
private static function get_styles( $attributes ) {
|
|
393
|
+
$colors = block_core_navigation_build_css_colors( $attributes );
|
|
394
|
+
$font_sizes = block_core_navigation_build_css_font_sizes( $attributes );
|
|
395
|
+
$block_styles = isset( $attributes['styles'] ) ? $attributes['styles'] : '';
|
|
396
|
+
return $block_styles . $colors['inline_styles'] . $font_sizes['inline_styles'];
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Get the responsive container markup
|
|
401
|
+
*
|
|
402
|
+
* @param array $attributes The block attributes.
|
|
403
|
+
* @param WP_Block_List $inner_blocks The list of inner blocks.
|
|
404
|
+
* @param string $inner_blocks_html The markup for the inner blocks.
|
|
405
|
+
* @return string Returns the container markup.
|
|
406
|
+
*/
|
|
407
|
+
private static function get_responsive_container_markup( $attributes, $inner_blocks, $inner_blocks_html ) {
|
|
408
|
+
$is_interactive = static::is_interactive( $attributes, $inner_blocks );
|
|
409
|
+
$colors = block_core_navigation_build_css_colors( $attributes );
|
|
410
|
+
$modal_unique_id = wp_unique_id( 'modal-' );
|
|
411
|
+
|
|
412
|
+
$responsive_container_classes = array(
|
|
413
|
+
'wp-block-navigation__responsive-container',
|
|
414
|
+
implode( ' ', $colors['overlay_css_classes'] ),
|
|
415
|
+
);
|
|
416
|
+
$open_button_classes = array(
|
|
417
|
+
'wp-block-navigation__responsive-container-open',
|
|
418
|
+
);
|
|
419
|
+
|
|
420
|
+
$should_display_icon_label = isset( $attributes['hasIcon'] ) && true === $attributes['hasIcon'];
|
|
421
|
+
$toggle_button_icon = '<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><rect x="4" y="7.5" width="16" height="1.5" /><rect x="4" y="15" width="16" height="1.5" /></svg>';
|
|
422
|
+
if ( isset( $attributes['icon'] ) ) {
|
|
423
|
+
if ( 'menu' === $attributes['icon'] ) {
|
|
424
|
+
$toggle_button_icon = '<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 5v1.5h14V5H5zm0 7.8h14v-1.5H5v1.5zM5 19h14v-1.5H5V19z" /></svg>';
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
$toggle_button_content = $should_display_icon_label ? $toggle_button_icon : __( 'Menu' );
|
|
428
|
+
$toggle_close_button_icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M13 11.8l6.1-6.3-1-1-6.1 6.2-6.1-6.2-1 1 6.1 6.3-6.5 6.7 1 1 6.5-6.6 6.5 6.6 1-1z"></path></svg>';
|
|
429
|
+
$toggle_close_button_content = $should_display_icon_label ? $toggle_close_button_icon : __( 'Close' );
|
|
430
|
+
$toggle_aria_label_open = $should_display_icon_label ? 'aria-label="' . __( 'Open menu' ) . '"' : ''; // Open button label.
|
|
431
|
+
$toggle_aria_label_close = $should_display_icon_label ? 'aria-label="' . __( 'Close menu' ) . '"' : ''; // Close button label.
|
|
432
|
+
|
|
433
|
+
// Add Interactivity API directives to the markup if needed.
|
|
434
|
+
$open_button_directives = '';
|
|
435
|
+
$responsive_container_directives = '';
|
|
436
|
+
$responsive_dialog_directives = '';
|
|
437
|
+
$close_button_directives = '';
|
|
438
|
+
if ( $is_interactive ) {
|
|
439
|
+
$open_button_directives = '
|
|
440
|
+
data-wp-on--click="actions.openMenuOnClick"
|
|
441
|
+
data-wp-on--keydown="actions.handleMenuKeydown"
|
|
442
|
+
';
|
|
443
|
+
$responsive_container_directives = '
|
|
444
|
+
data-wp-class--has-modal-open="state.isMenuOpen"
|
|
445
|
+
data-wp-class--is-menu-open="state.isMenuOpen"
|
|
446
|
+
data-wp-watch="callbacks.initMenu"
|
|
447
|
+
data-wp-on--keydown="actions.handleMenuKeydown"
|
|
448
|
+
data-wp-on--focusout="actions.handleMenuFocusout"
|
|
449
|
+
tabindex="-1"
|
|
450
|
+
';
|
|
451
|
+
$responsive_dialog_directives = '
|
|
452
|
+
data-wp-bind--aria-modal="state.ariaModal"
|
|
453
|
+
data-wp-bind--aria-label="state.ariaLabel"
|
|
454
|
+
data-wp-bind--role="state.roleAttribute"
|
|
455
|
+
';
|
|
456
|
+
$close_button_directives = '
|
|
457
|
+
data-wp-on--click="actions.closeMenuOnClick"
|
|
458
|
+
';
|
|
459
|
+
$responsive_container_content_directives = '
|
|
460
|
+
data-wp-watch="callbacks.focusFirstElement"
|
|
461
|
+
';
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
return sprintf(
|
|
465
|
+
'<button aria-haspopup="dialog" %3$s class="%6$s" %10$s>%8$s</button>
|
|
466
|
+
<div class="%5$s" style="%7$s" id="%1$s" %11$s>
|
|
467
|
+
<div class="wp-block-navigation__responsive-close" tabindex="-1">
|
|
468
|
+
<div class="wp-block-navigation__responsive-dialog" %12$s>
|
|
469
|
+
<button %4$s class="wp-block-navigation__responsive-container-close" %13$s>%9$s</button>
|
|
470
|
+
<div class="wp-block-navigation__responsive-container-content" %14$s id="%1$s-content">
|
|
471
|
+
%2$s
|
|
472
|
+
</div>
|
|
473
|
+
</div>
|
|
474
|
+
</div>
|
|
475
|
+
</div>',
|
|
476
|
+
esc_attr( $modal_unique_id ),
|
|
477
|
+
$inner_blocks_html,
|
|
478
|
+
$toggle_aria_label_open,
|
|
479
|
+
$toggle_aria_label_close,
|
|
480
|
+
esc_attr( implode( ' ', $responsive_container_classes ) ),
|
|
481
|
+
esc_attr( implode( ' ', $open_button_classes ) ),
|
|
482
|
+
esc_attr( safecss_filter_attr( $colors['overlay_inline_styles'] ) ),
|
|
483
|
+
$toggle_button_content,
|
|
484
|
+
$toggle_close_button_content,
|
|
485
|
+
$open_button_directives,
|
|
486
|
+
$responsive_container_directives,
|
|
487
|
+
$responsive_dialog_directives,
|
|
488
|
+
$close_button_directives,
|
|
489
|
+
$responsive_container_content_directives
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* Get the wrapper attributes
|
|
495
|
+
*
|
|
496
|
+
* @param array $attributes The block attributes.
|
|
497
|
+
* @param WP_Block_List $inner_blocks A list of inner blocks.
|
|
498
|
+
* @return string Returns the navigation block markup.
|
|
499
|
+
*/
|
|
500
|
+
private static function get_nav_wrapper_attributes( $attributes, $inner_blocks ) {
|
|
501
|
+
$nav_menu_name = static::get_unique_navigation_name( $attributes );
|
|
502
|
+
$is_interactive = static::is_interactive( $attributes, $inner_blocks );
|
|
503
|
+
$is_responsive_menu = static::is_responsive( $attributes );
|
|
504
|
+
$style = static::get_styles( $attributes );
|
|
505
|
+
$class = static::get_classes( $attributes );
|
|
506
|
+
$wrapper_attributes = get_block_wrapper_attributes(
|
|
507
|
+
array(
|
|
508
|
+
'class' => $class,
|
|
509
|
+
'style' => $style,
|
|
510
|
+
'aria-label' => $nav_menu_name,
|
|
511
|
+
)
|
|
512
|
+
);
|
|
513
|
+
|
|
514
|
+
if ( $is_responsive_menu ) {
|
|
515
|
+
$nav_element_directives = static::get_nav_element_directives( $is_interactive, $attributes );
|
|
516
|
+
$wrapper_attributes .= ' ' . $nav_element_directives;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
return $wrapper_attributes;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Gets the nav element directives.
|
|
524
|
+
*
|
|
525
|
+
* @param bool $is_interactive Whether the block is interactive.
|
|
526
|
+
* @param array $attributes The block attributes.
|
|
527
|
+
* @return string the directives for the navigation element.
|
|
528
|
+
*/
|
|
529
|
+
private static function get_nav_element_directives( $is_interactive, $attributes ) {
|
|
530
|
+
if ( ! $is_interactive ) {
|
|
531
|
+
return '';
|
|
532
|
+
}
|
|
533
|
+
// When adding to this array be mindful of security concerns.
|
|
534
|
+
$nav_element_context = wp_json_encode(
|
|
535
|
+
array(
|
|
536
|
+
'overlayOpenedBy' => array(),
|
|
537
|
+
'type' => 'overlay',
|
|
538
|
+
'roleAttribute' => '',
|
|
539
|
+
'ariaLabel' => __( 'Menu' ),
|
|
540
|
+
),
|
|
541
|
+
JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP
|
|
542
|
+
);
|
|
543
|
+
$nav_element_directives = '
|
|
544
|
+
data-wp-interactive=\'{"namespace":"core/navigation"}\'
|
|
545
|
+
data-wp-context=\'' . $nav_element_context . '\'
|
|
546
|
+
';
|
|
547
|
+
|
|
548
|
+
/*
|
|
549
|
+
* When the navigation's 'overlayMenu' attribute is set to 'always', JavaScript
|
|
550
|
+
* is not needed for collapsing the menu because the class is set manually.
|
|
551
|
+
*/
|
|
552
|
+
if ( ! static::is_always_overlay( $attributes ) ) {
|
|
553
|
+
$nav_element_directives .= 'data-wp-init="callbacks.initNav"';
|
|
554
|
+
$nav_element_directives .= ' '; // space separator
|
|
555
|
+
$nav_element_directives .= 'data-wp-class--is-collapsed="context.isCollapsed"';
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
return $nav_element_directives;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* Handle view script module loading.
|
|
563
|
+
*
|
|
564
|
+
* @param array $attributes The block attributes.
|
|
565
|
+
* @param WP_Block $block The parsed block.
|
|
566
|
+
* @param WP_Block_List $inner_blocks The list of inner blocks.
|
|
567
|
+
*/
|
|
568
|
+
private static function handle_view_script_module_loading( $attributes, $block, $inner_blocks ) {
|
|
569
|
+
if ( static::is_interactive( $attributes, $inner_blocks ) ) {
|
|
570
|
+
wp_enqueue_script_module( '@wordpress/block-library/navigation-block' );
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Returns the markup for the navigation block.
|
|
576
|
+
*
|
|
577
|
+
* @param array $attributes The block attributes.
|
|
578
|
+
* @param WP_Block_List $inner_blocks The list of inner blocks.
|
|
579
|
+
* @return string Returns the navigation wrapper markup.
|
|
580
|
+
*/
|
|
581
|
+
private static function get_wrapper_markup( $attributes, $inner_blocks ) {
|
|
582
|
+
$inner_blocks_html = static::get_inner_blocks_html( $attributes, $inner_blocks );
|
|
583
|
+
if ( static::is_responsive( $attributes ) ) {
|
|
584
|
+
return static::get_responsive_container_markup( $attributes, $inner_blocks, $inner_blocks_html );
|
|
585
|
+
}
|
|
586
|
+
return $inner_blocks_html;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Returns a unique name for the navigation.
|
|
591
|
+
*
|
|
592
|
+
* @param array $attributes The block attributes.
|
|
593
|
+
* @return string Returns a unique name for the navigation.
|
|
594
|
+
*/
|
|
595
|
+
private static function get_unique_navigation_name( $attributes ) {
|
|
596
|
+
$nav_menu_name = static::get_navigation_name( $attributes );
|
|
597
|
+
|
|
598
|
+
// If the menu name has been used previously then append an ID
|
|
599
|
+
// to the name to ensure uniqueness across a given post.
|
|
600
|
+
if ( isset( static::$seen_menu_names[ $nav_menu_name ] ) && static::$seen_menu_names[ $nav_menu_name ] > 1 ) {
|
|
601
|
+
$count = static::$seen_menu_names[ $nav_menu_name ];
|
|
602
|
+
$nav_menu_name = $nav_menu_name . ' ' . ( $count );
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
return $nav_menu_name;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/**
|
|
609
|
+
* Renders the navigation block.
|
|
610
|
+
*
|
|
611
|
+
* @param array $attributes The block attributes.
|
|
612
|
+
* @param string $content The saved content.
|
|
613
|
+
* @param WP_Block $block The parsed block.
|
|
614
|
+
* @return string Returns the navigation block markup.
|
|
615
|
+
*/
|
|
616
|
+
public static function render( $attributes, $content, $block ) {
|
|
617
|
+
/**
|
|
618
|
+
* Deprecated:
|
|
619
|
+
* The rgbTextColor and rgbBackgroundColor attributes
|
|
620
|
+
* have been deprecated in favor of
|
|
621
|
+
* customTextColor and customBackgroundColor ones.
|
|
622
|
+
* Move the values from old attrs to the new ones.
|
|
623
|
+
*/
|
|
624
|
+
if ( isset( $attributes['rgbTextColor'] ) && empty( $attributes['textColor'] ) ) {
|
|
625
|
+
$attributes['customTextColor'] = $attributes['rgbTextColor'];
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
if ( isset( $attributes['rgbBackgroundColor'] ) && empty( $attributes['backgroundColor'] ) ) {
|
|
629
|
+
$attributes['customBackgroundColor'] = $attributes['rgbBackgroundColor'];
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
unset( $attributes['rgbTextColor'], $attributes['rgbBackgroundColor'] );
|
|
633
|
+
|
|
634
|
+
$inner_blocks = static::get_inner_blocks( $attributes, $block );
|
|
635
|
+
// Prevent navigation blocks referencing themselves from rendering.
|
|
636
|
+
if ( block_core_navigation_block_contains_core_navigation( $inner_blocks ) ) {
|
|
637
|
+
return '';
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
static::handle_view_script_module_loading( $attributes, $block, $inner_blocks );
|
|
641
|
+
|
|
642
|
+
return sprintf(
|
|
643
|
+
'<nav %1$s>%2$s</nav>',
|
|
644
|
+
static::get_nav_wrapper_attributes( $attributes, $inner_blocks ),
|
|
645
|
+
static::get_wrapper_markup( $attributes, $inner_blocks )
|
|
646
|
+
);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
|
|
8
650
|
// These functions are used for the __unstableLocation feature and only active
|
|
9
651
|
// when the gutenberg plugin is active.
|
|
10
652
|
if ( defined( 'IS_GUTENBERG_PLUGIN' ) && IS_GUTENBERG_PLUGIN ) {
|
|
@@ -349,6 +991,17 @@ function block_core_navigation_get_fallback_blocks() {
|
|
|
349
991
|
// Normalizing blocks may result in an empty array of blocks if they were all `null` blocks.
|
|
350
992
|
// In this case default to the (Page List) fallback.
|
|
351
993
|
$fallback_blocks = ! empty( $maybe_fallback ) ? $maybe_fallback : $fallback_blocks;
|
|
994
|
+
|
|
995
|
+
if ( function_exists( 'get_hooked_blocks' ) ) {
|
|
996
|
+
// Run Block Hooks algorithm to inject hooked blocks.
|
|
997
|
+
// We have to run it here because we need the post ID of the Navigation block to track ignored hooked blocks.
|
|
998
|
+
$markup = block_core_navigation_insert_hooked_blocks( $fallback_blocks, $navigation_post );
|
|
999
|
+
$blocks = parse_blocks( $markup );
|
|
1000
|
+
|
|
1001
|
+
if ( isset( $blocks[0]['innerBlocks'] ) ) {
|
|
1002
|
+
$fallback_blocks = $blocks[0]['innerBlocks'];
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
352
1005
|
}
|
|
353
1006
|
|
|
354
1007
|
/**
|
|
@@ -360,7 +1013,7 @@ function block_core_navigation_get_fallback_blocks() {
|
|
|
360
1013
|
*
|
|
361
1014
|
* @since 5.9.0
|
|
362
1015
|
*
|
|
363
|
-
* @param array[] default fallback blocks provided by the default block mechanic.
|
|
1016
|
+
* @param array[] $fallback_blocks default fallback blocks provided by the default block mechanic.
|
|
364
1017
|
*/
|
|
365
1018
|
return apply_filters( 'block_core_navigation_render_fallback', $fallback_blocks );
|
|
366
1019
|
}
|
|
@@ -427,14 +1080,12 @@ function register_block_core_navigation() {
|
|
|
427
1080
|
)
|
|
428
1081
|
);
|
|
429
1082
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
);
|
|
437
|
-
}
|
|
1083
|
+
wp_register_script_module(
|
|
1084
|
+
'@wordpress/block-library/navigation-block',
|
|
1085
|
+
gutenberg_url( '/build/interactivity/navigation.min.js' ),
|
|
1086
|
+
array( '@wordpress/interactivity' ),
|
|
1087
|
+
defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : get_bloginfo( 'version' )
|
|
1088
|
+
);
|
|
438
1089
|
}
|
|
439
1090
|
|
|
440
1091
|
add_action( 'init', 'register_block_core_navigation' );
|
|
@@ -473,25 +1124,6 @@ function block_core_navigation_typographic_presets_backcompatibility( $parsed_bl
|
|
|
473
1124
|
|
|
474
1125
|
add_filter( 'render_block_data', 'block_core_navigation_typographic_presets_backcompatibility' );
|
|
475
1126
|
|
|
476
|
-
/**
|
|
477
|
-
* Ensure that the view script has the `wp-interactivity` dependency.
|
|
478
|
-
*
|
|
479
|
-
* @since 6.4.0
|
|
480
|
-
*
|
|
481
|
-
* @global WP_Scripts $wp_scripts
|
|
482
|
-
*/
|
|
483
|
-
function block_core_navigation_ensure_interactivity_dependency() {
|
|
484
|
-
global $wp_scripts;
|
|
485
|
-
if (
|
|
486
|
-
isset( $wp_scripts->registered['wp-block-navigation-view'] ) &&
|
|
487
|
-
! in_array( 'wp-interactivity', $wp_scripts->registered['wp-block-navigation-view']->deps, true )
|
|
488
|
-
) {
|
|
489
|
-
$wp_scripts->registered['wp-block-navigation-view']->deps[] = 'wp-interactivity';
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
add_action( 'wp_print_scripts', 'block_core_navigation_ensure_interactivity_dependency' );
|
|
494
|
-
|
|
495
1127
|
/**
|
|
496
1128
|
* Turns menu item data into a nested array of parsed blocks
|
|
497
1129
|
*
|
|
@@ -710,3 +1342,120 @@ function block_core_navigation_get_most_recently_published_navigation() {
|
|
|
710
1342
|
|
|
711
1343
|
return null;
|
|
712
1344
|
}
|
|
1345
|
+
|
|
1346
|
+
/**
|
|
1347
|
+
* Insert hooked blocks into a Navigation block.
|
|
1348
|
+
*
|
|
1349
|
+
* Given a Navigation block's inner blocks and its corresponding `wp_navigation` post object,
|
|
1350
|
+
* this function inserts hooked blocks into it, and returns the serialized inner blocks in a
|
|
1351
|
+
* mock Navigation block wrapper.
|
|
1352
|
+
*
|
|
1353
|
+
* If there are any hooked blocks that need to be inserted as the Navigation block's first or last
|
|
1354
|
+
* children, the `wp_navigation` post's `_wp_ignored_hooked_blocks` meta is checked to see if any
|
|
1355
|
+
* of those hooked blocks should be exempted from insertion.
|
|
1356
|
+
*
|
|
1357
|
+
* @param array $inner_blocks Parsed inner blocks of a Navigation block.
|
|
1358
|
+
* @param WP_Post $post `wp_navigation` post object corresponding to the block.
|
|
1359
|
+
* @return string Serialized inner blocks in mock Navigation block wrapper, with hooked blocks inserted, if any.
|
|
1360
|
+
*/
|
|
1361
|
+
function block_core_navigation_insert_hooked_blocks( $inner_blocks, $post = null ) {
|
|
1362
|
+
$before_block_visitor = null;
|
|
1363
|
+
$after_block_visitor = null;
|
|
1364
|
+
$hooked_blocks = get_hooked_blocks();
|
|
1365
|
+
$attributes = array();
|
|
1366
|
+
|
|
1367
|
+
if ( isset( $post->ID ) ) {
|
|
1368
|
+
$ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true );
|
|
1369
|
+
if ( ! empty( $ignored_hooked_blocks ) ) {
|
|
1370
|
+
$ignored_hooked_blocks = json_decode( $ignored_hooked_blocks, true );
|
|
1371
|
+
$attributes['metadata'] = array(
|
|
1372
|
+
'ignoredHookedBlocks' => $ignored_hooked_blocks,
|
|
1373
|
+
);
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
$mock_anchor_parent_block = array(
|
|
1378
|
+
'blockName' => 'core/navigation',
|
|
1379
|
+
'attrs' => $attributes,
|
|
1380
|
+
'innerBlocks' => $inner_blocks,
|
|
1381
|
+
'innerContent' => array_fill( 0, count( $inner_blocks ), null ),
|
|
1382
|
+
);
|
|
1383
|
+
$before_block_visitor = null;
|
|
1384
|
+
$after_block_visitor = null;
|
|
1385
|
+
|
|
1386
|
+
if ( ! empty( $hooked_blocks ) || has_filter( 'hooked_block_types' ) ) {
|
|
1387
|
+
$before_block_visitor = make_before_block_visitor( $hooked_blocks, $post );
|
|
1388
|
+
$after_block_visitor = make_after_block_visitor( $hooked_blocks, $post );
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
return traverse_and_serialize_block( $mock_anchor_parent_block, $before_block_visitor, $after_block_visitor );
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
/**
|
|
1395
|
+
* Updates the post meta with the list of ignored hooked blocks when the navigation is created or updated via the REST API.
|
|
1396
|
+
*
|
|
1397
|
+
* @param WP_Post $post Post object.
|
|
1398
|
+
*/
|
|
1399
|
+
function block_core_navigation_update_ignore_hooked_blocks_meta( $post ) {
|
|
1400
|
+
if ( ! isset( $post->ID ) ) {
|
|
1401
|
+
return;
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
// We run the Block Hooks mechanism so it will return the list of ignored hooked blocks
|
|
1405
|
+
// in the mock root Navigation block's metadata attribute.
|
|
1406
|
+
// We ignore the rest of the returned `$markup`; `$post->post_content` already has the hooked
|
|
1407
|
+
// blocks inserted, whereas `$markup` will have them inserted twice.
|
|
1408
|
+
$blocks = parse_blocks( $post->post_content );
|
|
1409
|
+
$markup = block_core_navigation_insert_hooked_blocks( $blocks, $post );
|
|
1410
|
+
$root_nav_block = parse_blocks( $markup )[0];
|
|
1411
|
+
$ignored_hooked_blocks = isset( $root_nav_block['attrs']['metadata']['ignoredHookedBlocks'] )
|
|
1412
|
+
? $root_nav_block['attrs']['metadata']['ignoredHookedBlocks']
|
|
1413
|
+
: array();
|
|
1414
|
+
|
|
1415
|
+
if ( ! empty( $ignored_hooked_blocks ) ) {
|
|
1416
|
+
$existing_ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true );
|
|
1417
|
+
if ( ! empty( $existing_ignored_hooked_blocks ) ) {
|
|
1418
|
+
$existing_ignored_hooked_blocks = json_decode( $existing_ignored_hooked_blocks, true );
|
|
1419
|
+
$ignored_hooked_blocks = array_unique( array_merge( $ignored_hooked_blocks, $existing_ignored_hooked_blocks ) );
|
|
1420
|
+
}
|
|
1421
|
+
update_post_meta( $post->ID, '_wp_ignored_hooked_blocks', json_encode( $ignored_hooked_blocks ) );
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
// Injection of hooked blocks into the Navigation block relies on some functions present in WP >= 6.4
|
|
1426
|
+
// that are not present in Gutenberg's WP 6.4 compatibility layer.
|
|
1427
|
+
if ( function_exists( 'get_hooked_blocks' ) ) {
|
|
1428
|
+
add_action( 'rest_insert_wp_navigation', 'block_core_navigation_update_ignore_hooked_blocks_meta', 10, 3 );
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
/**
|
|
1432
|
+
* Hooks into the REST API response for the core/navigation block and adds the first and last inner blocks.
|
|
1433
|
+
*
|
|
1434
|
+
* @param WP_REST_Response $response The response object.
|
|
1435
|
+
* @param WP_Post $post Post object.
|
|
1436
|
+
* @param WP_REST_Request $request Request object.
|
|
1437
|
+
* @return WP_REST_Response The response object.
|
|
1438
|
+
*/
|
|
1439
|
+
function block_core_navigation_insert_hooked_blocks_into_rest_response( $response, $post ) {
|
|
1440
|
+
if ( ! isset( $response->data['content']['raw'] ) || ! isset( $response->data['content']['rendered'] ) ) {
|
|
1441
|
+
return $response;
|
|
1442
|
+
}
|
|
1443
|
+
$parsed_blocks = parse_blocks( $response->data['content']['raw'] );
|
|
1444
|
+
$content = block_core_navigation_insert_hooked_blocks( $parsed_blocks, $post );
|
|
1445
|
+
|
|
1446
|
+
// Remove mock Navigation block wrapper.
|
|
1447
|
+
$start = strpos( $content, '-->' ) + strlen( '-->' );
|
|
1448
|
+
$end = strrpos( $content, '<!--' );
|
|
1449
|
+
$content = substr( $content, $start, $end - $start );
|
|
1450
|
+
|
|
1451
|
+
$response->data['content']['raw'] = $content;
|
|
1452
|
+
$response->data['content']['rendered'] = apply_filters( 'the_content', $content );
|
|
1453
|
+
|
|
1454
|
+
return $response;
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
// Injection of hooked blocks into the Navigation block relies on some functions present in WP >= 6.4
|
|
1458
|
+
// that are not present in Gutenberg's WP 6.4 compatibility layer.
|
|
1459
|
+
if ( function_exists( 'get_hooked_blocks' ) ) {
|
|
1460
|
+
add_filter( 'rest_prepare_wp_navigation', 'block_core_navigation_insert_hooked_blocks_into_rest_response', 10, 3 );
|
|
1461
|
+
}
|