PluginProbe
Gutenberg / 17.0.2
Gutenberg v17.0.2
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
← All changes | lib/blocks.php +241 -58 24.0.017.0.2 View file →
@@ -9,32 +9,167 @@
9 9 * Substitutes the implementation of a core-registered block type, if exists,
10 10 * with the built result from the plugin.
11 11 */
12 12 function gutenberg_reregister_core_block_types() {
13 + // Blocks directory may not exist if working from a fresh clone.
13 14 $blocks_dirs = array(
14 - __DIR__ . '/../build/scripts/block-library/',
15 - __DIR__ . '/../build/scripts/edit-widgets/blocks/',
16 - __DIR__ . '/../build/scripts/widgets/blocks/',
15 + __DIR__ . '/../build/block-library/blocks/' => array(
16 + 'block_folders' => array(
17 + 'audio',
18 + 'button',
19 + 'buttons',
20 + 'freeform',
21 + 'code',
22 + 'column',
23 + 'columns',
24 + 'details',
25 + 'form-input',
26 + 'form-submit-button',
27 + 'group',
28 + 'html',
29 + 'list',
30 + 'list-item',
31 + 'media-text',
32 + 'missing',
33 + 'more',
34 + 'nextpage',
35 + 'paragraph',
36 + 'preformatted',
37 + 'pullquote',
38 + 'quote',
39 + 'separator',
40 + 'social-links',
41 + 'spacer',
42 + 'table',
43 + 'table-of-contents',
44 + 'text-columns',
45 + 'verse',
46 + 'video',
47 + 'embed',
48 + ),
49 + 'block_names' => array(
50 + 'archives.php' => 'core/archives',
51 + 'avatar.php' => 'core/avatar',
52 + 'block.php' => 'core/block',
53 + 'calendar.php' => 'core/calendar',
54 + 'categories.php' => 'core/categories',
55 + 'cover.php' => 'core/cover',
56 + 'comment-author-avatar.php' => 'core/comment-author-avatar',
57 + 'comment-author-name.php' => 'core/comment-author-name',
58 + 'comment-content.php' => 'core/comment-content',
59 + 'comment-date.php' => 'core/comment-date',
60 + 'comment-edit-link.php' => 'core/comment-edit-link',
61 + 'comment-reply-link.php' => 'core/comment-reply-link',
62 + 'comment-template.php' => 'core/comment-template',
63 + 'comments-pagination.php' => 'core/comments-pagination',
64 + 'comments-pagination-next.php' => 'core/comments-pagination-next',
65 + 'comments-pagination-numbers.php' => 'core/comments-pagination-numbers',
66 + 'comments-pagination-previous.php' => 'core/comments-pagination-previous',
67 + 'comments-title.php' => 'core/comments-title',
68 + 'comments.php' => 'core/comments',
69 + 'footnotes.php' => 'core/footnotes',
70 + 'file.php' => 'core/file',
71 + 'form.php' => 'core/form',
72 + 'form-input.php' => 'core/form-input',
73 + 'form-submission-notification.php' => 'core/form-submission-notification',
74 + 'home-link.php' => 'core/home-link',
75 + 'image.php' => 'core/image',
76 + 'gallery.php' => 'core/gallery',
77 + 'heading.php' => 'core/heading',
78 + 'latest-comments.php' => 'core/latest-comments',
79 + 'latest-posts.php' => 'core/latest-posts',
80 + 'loginout.php' => 'core/loginout',
81 + 'navigation.php' => 'core/navigation',
82 + 'navigation-link.php' => 'core/navigation-link',
83 + 'navigation-submenu.php' => 'core/navigation-submenu',
84 + 'page-list.php' => 'core/page-list',
85 + 'page-list-item.php' => 'core/page-list-item',
86 + 'pattern.php' => 'core/pattern',
87 + 'post-author.php' => 'core/post-author',
88 + 'post-author-name.php' => 'core/post-author-name',
89 + 'post-author-biography.php' => 'core/post-author-biography',
90 + 'post-comment.php' => 'core/post-comment',
91 + 'post-comments-count.php' => 'core/post-comments-count',
92 + 'post-comments-form.php' => 'core/post-comments-form',
93 + 'post-comments-link.php' => 'core/post-comments-link',
94 + 'post-content.php' => 'core/post-content',
95 + 'post-date.php' => 'core/post-date',
96 + 'post-excerpt.php' => 'core/post-excerpt',
97 + 'post-featured-image.php' => 'core/post-featured-image',
98 + 'post-navigation-link.php' => 'core/post-navigation-link',
99 + 'post-terms.php' => 'core/post-terms',
100 + 'post-time-to-read.php' => 'core/post-time-to-read',
101 + 'post-title.php' => 'core/post-title',
102 + 'query.php' => 'core/query',
103 + 'post-template.php' => 'core/post-template',
104 + 'query-no-results.php' => 'core/query-no-results',
105 + 'query-pagination.php' => 'core/query-pagination',
106 + 'query-pagination-next.php' => 'core/query-pagination-next',
107 + 'query-pagination-numbers.php' => 'core/query-pagination-numbers',
108 + 'query-pagination-previous.php' => 'core/query-pagination-previous',
109 + 'query-title.php' => 'core/query-title',
110 + 'read-more.php' => 'core/read-more',
111 + 'rss.php' => 'core/rss',
112 + 'search.php' => 'core/search',
113 + 'shortcode.php' => 'core/shortcode',
114 + 'social-link.php' => 'core/social-link',
115 + 'site-logo.php' => 'core/site-logo',
116 + 'site-tagline.php' => 'core/site-tagline',
117 + 'site-title.php' => 'core/site-title',
118 + 'tag-cloud.php' => 'core/tag-cloud',
119 + 'template-part.php' => 'core/template-part',
120 + 'term-description.php' => 'core/term-description',
121 + ),
122 + ),
123 + __DIR__ . '/../build/edit-widgets/blocks/' => array(
124 + 'block_folders' => array(
125 + 'widget-area',
126 + ),
127 + 'block_names' => array(),
128 + ),
129 + __DIR__ . '/../build/widgets/blocks/' => array(
130 + 'block_folders' => array(
131 + 'legacy-widget',
132 + 'widget-group',
133 + ),
134 + 'block_names' => array(
135 + 'legacy-widget.php' => 'core/legacy-widget',
136 + 'widget-group.php' => 'core/widget-group',
137 + ),
138 + ),
17 139 );
140 + foreach ( $blocks_dirs as $blocks_dir => $details ) {
141 + $block_folders = $details['block_folders'];
142 + $block_names = $details['block_names'];
18 143
19 - foreach ( $blocks_dirs as $blocks_dir ) {
20 - $manifest_path = $blocks_dir . 'blocks-manifest.php';
21 - $blocks = require $manifest_path;
144 + foreach ( $block_folders as $folder_name ) {
145 + $block_json_file = $blocks_dir . $folder_name . '/block.json';
22 146
23 - foreach ( $blocks as $block_name_folder => $metadata ) {
24 - if ( ! is_array( $metadata ) || ! isset( $metadata['name'] ) ) {
147 + // Ideally, all paths to block metadata files should be listed in
148 + // WordPress core. In this place we should rather use filter
149 + // to replace paths with overrides defined by the plugin.
150 + $metadata = json_decode( file_get_contents( $block_json_file ), true );
151 + if ( ! is_array( $metadata ) || ! $metadata['name'] ) {
25 152 continue;
26 153 }
27 154
28 155 gutenberg_deregister_core_block_and_assets( $metadata['name'] );
29 - gutenberg_register_core_block_assets( $block_name_folder );
156 + gutenberg_register_core_block_assets( $folder_name );
157 + register_block_type_from_metadata( $block_json_file );
158 + }
30 159
31 - $php_file = $blocks_dir . $block_name_folder . '.php';
32 - if ( file_exists( $php_file ) ) {
33 - require_once $php_file;
34 - } else {
35 - register_block_type_from_metadata( $blocks_dir . $block_name_folder );
160 + foreach ( $block_names as $file => $sub_block_names ) {
161 + if ( ! file_exists( $blocks_dir . $file ) ) {
162 + continue;
36 163 }
164 +
165 + $sub_block_names_normalized = is_string( $sub_block_names ) ? array( $sub_block_names ) : $sub_block_names;
166 + foreach ( $sub_block_names_normalized as $block_name ) {
167 + gutenberg_deregister_core_block_and_assets( $block_name );
168 + gutenberg_register_core_block_assets( $block_name );
169 + }
170 +
171 + require_once $blocks_dir . $file;
37 172 }
38 173 }
39 174 }
40 175
@@ -39,15 +174,8 @@
39 174 }
40 175
41 176 add_action( 'init', 'gutenberg_reregister_core_block_types' );
42 177
43 -/*
44 - * Remove the WordPress core filter to avoid generating a second tabs ID for
45 - * every tabs block: `wp_unique_prefixed_id()` advances a counter, so running
46 - * both copies makes the numbering skip.
47 - */
48 -remove_filter( 'render_block_context', 'block_core_tabs_provide_context', 10 );
49 -
50 178 /**
51 179 * Adds the defer loading strategy to all registered blocks.
52 180 *
53 181 * This function would not be part of core merge. Instead, the register_block_script_handle() function would be patched
@@ -59,10 +187,10 @@
59 187 * @ @ -153,7 +153,8 @ @ function register_block_script_handle( $metadata, $field_name, $index = 0 ) {
60 188 * $script_handle,
61 189 * $script_uri,
62 190 * $script_dependencies,
63 - * - $script_asset['version'] ?? false
64 - * + $script_asset['version'] ?? false,
191 + * - isset( $script_asset['version'] ) ? $script_asset['version'] : false
192 + * + isset( $script_asset['version'] ) ? $script_asset['version'] : false,
65 193 * + array( 'strategy' => 'defer' )
66 194 * );
67 195 * if ( ! $result ) {
68 196 * return false;
@@ -110,17 +238,8 @@
110 238 *
111 239 * @return void
112 240 */
113 241 function gutenberg_register_core_block_assets( $block_name ) {
114 - static $gutenberg_url_root = null;
115 - // Running `gutenberg_url` inside of a loop can be expensive in systems with
116 - // many callbacks attached to the `plugins_url` hook.
117 - // Since all of the paths have the same root, we can instead retrieve the
118 - // corresponding URL root once, and manually concatenate the URL below.
119 - if ( is_null( $gutenberg_url_root ) ) {
120 - $gutenberg_url_root = gutenberg_url( '/' );
121 - }
122 -
123 242 if ( ! wp_should_load_separate_core_block_assets() ) {
124 243 return;
125 244 }
126 245
@@ -128,16 +247,14 @@
128 247
129 248 // When in production, use the plugin's version as the default asset version;
130 249 // else (for development or test) default to use the current time.
131 250 $default_version = defined( 'GUTENBERG_VERSION' ) && ! SCRIPT_DEBUG ? GUTENBERG_VERSION : time();
132 - $suffix = SCRIPT_DEBUG ? '' : '.min';
133 251
134 - $style_path = "build/styles/block-library/$block_name/";
135 - $stylesheet_url = $gutenberg_url_root . $style_path . 'style' . $suffix . '.css';
136 - $stylesheet_path = gutenberg_dir_path() . $style_path . ( is_rtl() ? 'style-rtl' . $suffix . '.css' : 'style' . $suffix . '.css' );
252 + $style_path = "build/block-library/blocks/$block_name/";
253 + $stylesheet_url = gutenberg_url( $style_path . 'style.css' );
254 + $stylesheet_path = gutenberg_dir_path() . $style_path . ( is_rtl() ? 'style-rtl.css' : 'style.css' );
137 255
138 256 if ( file_exists( $stylesheet_path ) ) {
139 -
140 257 wp_deregister_style( "wp-block-{$block_name}" );
141 258 wp_register_style(
142 259 "wp-block-{$block_name}",
143 260 $stylesheet_url,
@@ -144,9 +261,9 @@
144 261 array(),
145 262 $default_version
146 263 );
147 264 wp_style_add_data( "wp-block-{$block_name}", 'rtl', 'replace' );
148 - wp_style_add_data( "wp-block-{$block_name}", 'suffix', $suffix );
265 +
149 266 // Add a reference to the stylesheet's path to allow calculations for inlining styles in `wp_head`.
150 267 wp_style_add_data( "wp-block-{$block_name}", 'path', $stylesheet_path );
151 268 } else {
152 269 wp_register_style( "wp-block-{$block_name}", false, array() );
@@ -151,44 +268,62 @@
151 268 } else {
152 269 wp_register_style( "wp-block-{$block_name}", false, array() );
153 270 }
154 271
155 - /*
156 - * If the current theme supports wp-block-styles, dequeue the core styles
157 - * and enqueue the plugin ones instead.
158 - */
272 + // If the current theme supports wp-block-styles, dequeue the full stylesheet
273 + // and instead attach each block's theme-styles to their block styles stylesheet.
159 274 if ( current_theme_supports( 'wp-block-styles' ) ) {
160 275
276 + // Dequeue the full stylesheet.
277 + // Make sure this only runs once, it doesn't need to run for every block.
278 + static $stylesheet_removed;
279 + if ( ! $stylesheet_removed ) {
280 + add_action(
281 + 'wp_enqueue_scripts',
282 + static function () {
283 + wp_dequeue_style( 'wp-block-library-theme' );
284 + }
285 + );
286 + $stylesheet_removed = true;
287 + }
288 +
161 289 // Get the path to the block's stylesheet.
162 290 $theme_style_path = is_rtl()
163 - ? "build/styles/block-library/$block_name/theme-rtl{$suffix}.css"
164 - : "build/styles/block-library/$block_name/theme{$suffix}.css";
291 + ? "build/block-library/blocks/$block_name/theme-rtl.css"
292 + : "build/block-library/blocks/$block_name/theme.css";
165 293
166 294 // If the file exists, enqueue it.
167 295 if ( file_exists( gutenberg_dir_path() . $theme_style_path ) ) {
168 - wp_deregister_style( "wp-block-{$block_name}-theme" );
169 - wp_register_style(
170 - "wp-block-{$block_name}-theme",
171 - $gutenberg_url_root . $theme_style_path,
172 - array(),
173 - $default_version
174 - );
175 - wp_style_add_data( "wp-block-{$block_name}-theme", 'path', gutenberg_dir_path() . $theme_style_path );
176 - wp_style_add_data( "wp-block-{$block_name}-theme", 'suffix', $suffix );
296 +
297 + if ( file_exists( $stylesheet_path ) ) {
298 + // If there is a main stylesheet for this block, append the theme styles to main styles.
299 + wp_add_inline_style(
300 + "wp-block-{$block_name}",
301 + file_get_contents( gutenberg_dir_path() . $theme_style_path )
302 + );
303 + } else {
304 + // If there is no main stylesheet for this block, register theme style.
305 + wp_register_style(
306 + "wp-block-{$block_name}",
307 + gutenberg_url( $theme_style_path ),
308 + array(),
309 + $default_version
310 + );
311 + wp_style_add_data( "wp-block-{$block_name}", 'path', gutenberg_dir_path() . $theme_style_path );
312 + }
177 313 }
178 314 }
179 315
180 - $editor_style_path = "build/styles/block-library/$block_name/style-editor{$suffix}.css";
316 + $editor_style_path = "build/block-library/blocks/$block_name/style-editor.css";
181 317 if ( file_exists( gutenberg_dir_path() . $editor_style_path ) ) {
182 318 wp_deregister_style( "wp-block-{$block_name}-editor" );
183 319 wp_register_style(
184 320 "wp-block-{$block_name}-editor",
185 - $gutenberg_url_root . $editor_style_path,
321 + gutenberg_url( $editor_style_path ),
186 322 array(),
187 323 $default_version
188 324 );
189 325 wp_style_add_data( "wp-block-{$block_name}-editor", 'rtl', 'replace' );
190 - wp_style_add_data( "wp-block-{$block_name}-editor", 'suffix', $suffix );
191 326 } else {
192 327 wp_register_style( "wp-block-{$block_name}-editor", false );
193 328 }
194 329 }
@@ -204,9 +339,9 @@
204 339 *
205 340 * This shim is INTENTIONALLY left out of core, as Social Links have never
206 341 * landed there.
207 342 *
208 - * @link https://github.com/WordPress/gutenberg/pull/19887
343 + * @see https://github.com/WordPress/gutenberg/pull/19887
209 344 */
210 345 function gutenberg_register_legacy_social_link_blocks() {
211 346 $services = array(
212 347 'amazon',
@@ -303,11 +438,59 @@
303 438 }
304 439
305 440 add_filter( 'default_post_metadata', 'gutenberg_legacy_wp_block_post_meta', 10, 4 );
306 441
442 +/**
443 + * Complements the lightbox implementation for the 'core/image' block.
444 + *
445 + * This function is INTENTIONALLY left out of core as it only provides
446 + * backwards compatibility for the legacy lightbox syntax that was only
447 + * introduced in Gutenberg. The legacy syntax was using the `behaviors` key in
448 + * the block attrbutes and the `theme.json` file.
449 + *
450 + * @since 16.7.0
451 + *
452 + * @param array $block The block to check.
453 + * @return array The block with the legacyLightboxSettings set if available.
454 + */
455 +function gutenberg_should_render_lightbox( $block ) {
307 456
457 + if ( 'core/image' !== $block['blockName'] ) {
458 + return $block;
459 + }
308 460
461 + if ( isset( $block['attrs']['behaviors']['lightbox'] ) ) {
462 + $block['legacyLightboxSettings'] = $block['attrs']['behaviors']['lightbox'];
463 + }
464 +
465 + return $block;
466 +}
467 +
468 +add_filter( 'render_block_data', 'gutenberg_should_render_lightbox', 15, 1 );
469 +
309 470 /**
471 + * Registers the metadata block attribute for all block types.
472 + *
473 + * @param array $args Array of arguments for registering a block type.
474 + * @return array $args
475 + */
476 +function gutenberg_register_metadata_attribute( $args ) {
477 + // Setup attributes if needed.
478 + if ( ! isset( $args['attributes'] ) || ! is_array( $args['attributes'] ) ) {
479 + $args['attributes'] = array();
480 + }
481 +
482 + if ( ! array_key_exists( 'metadata', $args['attributes'] ) ) {
483 + $args['attributes']['metadata'] = array(
484 + 'type' => 'object',
485 + );
486 + }
487 +
488 + return $args;
489 +}
490 +add_filter( 'register_block_type_args', 'gutenberg_register_metadata_attribute' );
491 +
492 +/**
310 493 * Strips all HTML from the content of footnotes, and sanitizes the ID.
311 494 *
312 495 * This function expects slashed data on the footnotes content.
313 496 *
@@ -380,9 +563,9 @@
380 563 * @return string Input argument of the filter.
381 564 */
382 565 function _gutenberg_footnotes_force_filtered_html_on_import_filter( $arg ) {
383 566 if ( function_exists( '_wp_filter_post_meta_footnotes' ) ) {
384 - return $arg;
567 + return;
385 568 }
386 569 // force_filtered_html_on_import is true we need to init the global styles kses filters.
387 570 if ( $arg ) {
388 571 _gutenberg_footnotes_kses_init_filters();