Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Block Supports: Try stabilizing default controls to top-level property #67729

Draft
wants to merge 6 commits into
base: trunk
Choose a base branch
from

Conversation

aaronrobertshaw
Copy link
Contributor

@aaronrobertshaw aaronrobertshaw commented Dec 9, 2024

Related:

⚠️ ⚠️ ⚠️This PR is for discussion purposes only and isn't intended to be merged ⚠️ ⚠️⚠️

What?

This PR is a proof of concept to see what it would take to stabilize current supports.feature.__experimentalDefaultControls config to its own top-level defaultControls property instead of being stabilized within the supports.feature object.

Why?

There's a desire to configure non-block-support controls via the defaultControls property. This makes a touch more sense if it is a top-level block type property.

How?

Requires core updates to works (at least to my current knowledge)

  • When stabilizing __experimentalDefaults move the config to a new top-level defaultControls property
  • If existing config for a feature within defaultControls exists. That already stable config in defaultControls will be used
  • Unlike the current approach to stabilization within supports, this approach can't determine the order the experimental or stable default controls config was defined in so is slightly more "dumb" and would be a little more prone to ignoring plugin or theme filtered default controls. It is also then an exception to how the rest of the experimental block supports are stabilized.
  • This update will require extenders to do more than just switch keys from __experimentalDefaultControls to defaultControls within a current getBlockSupport() call. Now, the config no longer exists within block supports, they'll need to update to calling a new util getBlockDefaultControls.

Testing Instructions

Proper testing instructions are TBA once it's confirmed we want to go in this direction.

  1. Apply core patch from diff below
Core diff needed (I think 🙂 )
diff --git a/src/wp-admin/includes/post.php b/src/wp-admin/includes/post.php
index e5e1e5d147..0a16e08bd2 100644
--- a/src/wp-admin/includes/post.php
+++ b/src/wp-admin/includes/post.php
@@ -2317,6 +2317,7 @@ function get_block_editor_server_block_settings() {
 		'example'          => 'example',
 		'variations'       => 'variations',
 		'allowed_blocks'   => 'allowedBlocks',
+		'default_controls' => 'defaultControls',
 	);
 
 	foreach ( $block_registry->get_all_registered() as $block_name => $block_type ) {
diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php
index 94c4dfa43a..7b954aa971 100644
--- a/src/wp-includes/blocks.php
+++ b/src/wp-includes/blocks.php
@@ -486,6 +486,7 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) {
 		'variations'      => 'variations',
 		'example'         => 'example',
 		'allowedBlocks'   => 'allowed_blocks',
+		'defaultControls' => 'default_controls',
 	);
 	$textdomain        = ! empty( $metadata['textdomain'] ) ? $metadata['textdomain'] : null;
 	$i18n_schema       = get_block_metadata_i18n_schema();
diff --git a/src/wp-includes/class-wp-block-type.php b/src/wp-includes/class-wp-block-type.php
index 6916f6a462..5941fc8c53 100644
--- a/src/wp-includes/class-wp-block-type.php
+++ b/src/wp-includes/class-wp-block-type.php
@@ -150,6 +150,14 @@ class WP_Block_Type {
 	 */
 	public $supports = null;
 
+	/**
+	 * Default UI controls.
+	 *
+	 * @since 6.8.0
+	 * @var array|null
+	 */
+	public $default_controls = null;
+
 	/**
 	 * Structured data for the block preview.
 	 *
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php
index 263f2a8ef2..947003874e 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php
@@ -298,6 +298,7 @@ class WP_REST_Block_Types_Controller extends WP_REST_Controller {
 				'view_style_handles',
 				'variations',
 				'block_hooks',
+				'default_controls',
 			),
 			$deprecated_fields
 		);
@@ -762,6 +763,14 @@ class WP_REST_Block_Types_Controller extends WP_REST_Controller {
 					'context'           => array( 'embed', 'view', 'edit' ),
 					'readonly'          => true,
 				),
+				'default_controls'       => array(
+					'description' => __( 'UI controls to display by default.' ),
+					'type'        => 'object',
+					'default'     => array(),
+					'properties'  => array(),
+					'context'     => array( 'embed', 'view', 'edit' ),
+					'readonly'    => true,
+				),
 			),
 		);
 
  1. Checkout this PR
  2. Edit a post and add in several blocks that contain different default control configurations
  3. Crosscheck the controls shown by default in the block inspector against the block's block.json configuration.

Screenshots or screencast

There should be no visual difference if this PR hasn't broken something 😅

@aaronrobertshaw aaronrobertshaw added [Type] Enhancement A suggestion for improvement. [Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi labels Dec 9, 2024
@aaronrobertshaw aaronrobertshaw self-assigned this Dec 9, 2024
Copy link

github-actions bot commented Dec 9, 2024

Size Change: +141 B (+0.01%)

Total Size: 1.83 MB

Filename Size Change
build/block-directory/index.min.js 7.27 kB +9 B (+0.12%)
build/block-editor/index.min.js 258 kB -5 B (0%)
build/blocks/index.min.js 53.1 kB +137 B (+0.26%)
ℹ️ View Unchanged
Filename Size
build-module/a11y/index.min.js 482 B
build-module/block-library/file/view.min.js 447 B
build-module/block-library/form/view.min.js 533 B
build-module/block-library/image/view.min.js 1.78 kB
build-module/block-library/navigation/view.min.js 1.16 kB
build-module/block-library/query/view.min.js 742 B
build-module/block-library/search/view.min.js 616 B
build-module/interactivity-router/index.min.js 3.04 kB
build-module/interactivity/debug.min.js 17.2 kB
build-module/interactivity/index.min.js 13.6 kB
build/a11y/index.min.js 952 B
build/annotations/index.min.js 2.26 kB
build/api-fetch/index.min.js 2.32 kB
build/autop/index.min.js 2.12 kB
build/blob/index.min.js 579 B
build/block-directory/style-rtl.css 1 kB
build/block-directory/style.css 1 kB
build/block-editor/content-rtl.css 4.47 kB
build/block-editor/content.css 4.46 kB
build/block-editor/default-editor-styles-rtl.css 394 B
build/block-editor/default-editor-styles.css 394 B
build/block-editor/style-rtl.css 15.6 kB
build/block-editor/style.css 15.6 kB
build/block-library/blocks/archives/editor-rtl.css 84 B
build/block-library/blocks/archives/editor.css 83 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 149 B
build/block-library/blocks/audio/editor.css 151 B
build/block-library/blocks/audio/style-rtl.css 132 B
build/block-library/blocks/audio/style.css 132 B
build/block-library/blocks/audio/theme-rtl.css 134 B
build/block-library/blocks/audio/theme.css 134 B
build/block-library/blocks/avatar/editor-rtl.css 115 B
build/block-library/blocks/avatar/editor.css 115 B
build/block-library/blocks/avatar/style-rtl.css 104 B
build/block-library/blocks/avatar/style.css 104 B
build/block-library/blocks/button/editor-rtl.css 265 B
build/block-library/blocks/button/editor.css 265 B
build/block-library/blocks/button/style-rtl.css 555 B
build/block-library/blocks/button/style.css 555 B
build/block-library/blocks/buttons/editor-rtl.css 291 B
build/block-library/blocks/buttons/editor.css 291 B
build/block-library/blocks/buttons/style-rtl.css 345 B
build/block-library/blocks/buttons/style.css 345 B
build/block-library/blocks/calendar/style-rtl.css 240 B
build/block-library/blocks/calendar/style.css 240 B
build/block-library/blocks/categories/editor-rtl.css 132 B
build/block-library/blocks/categories/editor.css 131 B
build/block-library/blocks/categories/style-rtl.css 152 B
build/block-library/blocks/categories/style.css 152 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 139 B
build/block-library/blocks/code/style.css 139 B
build/block-library/blocks/code/theme-rtl.css 122 B
build/block-library/blocks/code/theme.css 122 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 420 B
build/block-library/blocks/columns/style.css 420 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 124 B
build/block-library/blocks/comment-author-avatar/editor.css 124 B
build/block-library/blocks/comment-author-name/style-rtl.css 72 B
build/block-library/blocks/comment-author-name/style.css 72 B
build/block-library/blocks/comment-content/style-rtl.css 120 B
build/block-library/blocks/comment-content/style.css 120 B
build/block-library/blocks/comment-date/style-rtl.css 65 B
build/block-library/blocks/comment-date/style.css 65 B
build/block-library/blocks/comment-edit-link/style-rtl.css 70 B
build/block-library/blocks/comment-edit-link/style.css 70 B
build/block-library/blocks/comment-reply-link/style-rtl.css 71 B
build/block-library/blocks/comment-reply-link/style.css 71 B
build/block-library/blocks/comment-template/style-rtl.css 200 B
build/block-library/blocks/comment-template/style.css 199 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 238 B
build/block-library/blocks/comments-pagination/editor.css 231 B
build/block-library/blocks/comments-pagination/style-rtl.css 245 B
build/block-library/blocks/comments-pagination/style.css 241 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 842 B
build/block-library/blocks/comments/editor.css 842 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 637 B
build/block-library/blocks/cover/editor-rtl.css 631 B
build/block-library/blocks/cover/editor.css 631 B
build/block-library/blocks/cover/style-rtl.css 1.7 kB
build/block-library/blocks/cover/style.css 1.69 kB
build/block-library/blocks/details/editor-rtl.css 65 B
build/block-library/blocks/details/editor.css 65 B
build/block-library/blocks/details/style-rtl.css 86 B
build/block-library/blocks/details/style.css 86 B
build/block-library/blocks/embed/editor-rtl.css 331 B
build/block-library/blocks/embed/editor.css 331 B
build/block-library/blocks/embed/style-rtl.css 419 B
build/block-library/blocks/embed/style.css 419 B
build/block-library/blocks/embed/theme-rtl.css 133 B
build/block-library/blocks/embed/theme.css 133 B
build/block-library/blocks/file/editor-rtl.css 326 B
build/block-library/blocks/file/editor.css 326 B
build/block-library/blocks/file/style-rtl.css 278 B
build/block-library/blocks/file/style.css 279 B
build/block-library/blocks/footnotes/style-rtl.css 198 B
build/block-library/blocks/footnotes/style.css 197 B
build/block-library/blocks/form-input/editor-rtl.css 229 B
build/block-library/blocks/form-input/editor.css 229 B
build/block-library/blocks/form-input/style-rtl.css 357 B
build/block-library/blocks/form-input/style.css 357 B
build/block-library/blocks/form-submission-notification/editor-rtl.css 344 B
build/block-library/blocks/form-submission-notification/editor.css 341 B
build/block-library/blocks/form-submit-button/style-rtl.css 69 B
build/block-library/blocks/form-submit-button/style.css 69 B
build/block-library/blocks/freeform/editor-rtl.css 2.6 kB
build/block-library/blocks/freeform/editor.css 2.6 kB
build/block-library/blocks/gallery/editor-rtl.css 946 B
build/block-library/blocks/gallery/editor.css 951 B
build/block-library/blocks/gallery/style-rtl.css 1.83 kB
build/block-library/blocks/gallery/style.css 1.82 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 334 B
build/block-library/blocks/group/editor.css 334 B
build/block-library/blocks/group/style-rtl.css 103 B
build/block-library/blocks/group/style.css 103 B
build/block-library/blocks/group/theme-rtl.css 79 B
build/block-library/blocks/group/theme.css 79 B
build/block-library/blocks/heading/style-rtl.css 188 B
build/block-library/blocks/heading/style.css 188 B
build/block-library/blocks/html/editor-rtl.css 346 B
build/block-library/blocks/html/editor.css 347 B
build/block-library/blocks/image/editor-rtl.css 799 B
build/block-library/blocks/image/editor.css 799 B
build/block-library/blocks/image/style-rtl.css 1.6 kB
build/block-library/blocks/image/style.css 1.59 kB
build/block-library/blocks/image/theme-rtl.css 137 B
build/block-library/blocks/image/theme.css 137 B
build/block-library/blocks/latest-comments/style-rtl.css 355 B
build/block-library/blocks/latest-comments/style.css 354 B
build/block-library/blocks/latest-posts/editor-rtl.css 139 B
build/block-library/blocks/latest-posts/editor.css 138 B
build/block-library/blocks/latest-posts/style-rtl.css 520 B
build/block-library/blocks/latest-posts/style.css 520 B
build/block-library/blocks/list/style-rtl.css 107 B
build/block-library/blocks/list/style.css 107 B
build/block-library/blocks/loginout/style-rtl.css 61 B
build/block-library/blocks/loginout/style.css 61 B
build/block-library/blocks/media-text/editor-rtl.css 321 B
build/block-library/blocks/media-text/editor.css 320 B
build/block-library/blocks/media-text/style-rtl.css 552 B
build/block-library/blocks/media-text/style.css 550 B
build/block-library/blocks/more/editor-rtl.css 427 B
build/block-library/blocks/more/editor.css 427 B
build/block-library/blocks/navigation-link/editor-rtl.css 644 B
build/block-library/blocks/navigation-link/editor.css 645 B
build/block-library/blocks/navigation-link/style-rtl.css 192 B
build/block-library/blocks/navigation-link/style.css 191 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 295 B
build/block-library/blocks/navigation-submenu/editor.css 294 B
build/block-library/blocks/navigation/editor-rtl.css 2.2 kB
build/block-library/blocks/navigation/editor.css 2.2 kB
build/block-library/blocks/navigation/style-rtl.css 2.24 kB
build/block-library/blocks/navigation/style.css 2.23 kB
build/block-library/blocks/nextpage/editor-rtl.css 392 B
build/block-library/blocks/nextpage/editor.css 392 B
build/block-library/blocks/page-list/editor-rtl.css 378 B
build/block-library/blocks/page-list/editor.css 378 B
build/block-library/blocks/page-list/style-rtl.css 192 B
build/block-library/blocks/page-list/style.css 192 B
build/block-library/blocks/paragraph/editor-rtl.css 236 B
build/block-library/blocks/paragraph/editor.css 236 B
build/block-library/blocks/paragraph/style-rtl.css 341 B
build/block-library/blocks/paragraph/style.css 340 B
build/block-library/blocks/post-author-biography/style-rtl.css 74 B
build/block-library/blocks/post-author-biography/style.css 74 B
build/block-library/blocks/post-author-name/style-rtl.css 69 B
build/block-library/blocks/post-author-name/style.css 69 B
build/block-library/blocks/post-author/editor-rtl.css 107 B
build/block-library/blocks/post-author/editor.css 107 B
build/block-library/blocks/post-author/style-rtl.css 188 B
build/block-library/blocks/post-author/style.css 189 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 527 B
build/block-library/blocks/post-comments-form/style.css 528 B
build/block-library/blocks/post-content/style-rtl.css 61 B
build/block-library/blocks/post-content/style.css 61 B
build/block-library/blocks/post-date/style-rtl.css 62 B
build/block-library/blocks/post-date/style.css 62 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 155 B
build/block-library/blocks/post-excerpt/style.css 155 B
build/block-library/blocks/post-featured-image/editor-rtl.css 729 B
build/block-library/blocks/post-featured-image/editor.css 726 B
build/block-library/blocks/post-featured-image/style-rtl.css 347 B
build/block-library/blocks/post-featured-image/style.css 347 B
build/block-library/blocks/post-navigation-link/style-rtl.css 215 B
build/block-library/blocks/post-navigation-link/style.css 214 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 399 B
build/block-library/blocks/post-template/style.css 398 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-time-to-read/style-rtl.css 70 B
build/block-library/blocks/post-time-to-read/style.css 70 B
build/block-library/blocks/post-title/style-rtl.css 162 B
build/block-library/blocks/post-title/style.css 162 B
build/block-library/blocks/preformatted/style-rtl.css 125 B
build/block-library/blocks/preformatted/style.css 125 B
build/block-library/blocks/pullquote/editor-rtl.css 134 B
build/block-library/blocks/pullquote/editor.css 134 B
build/block-library/blocks/pullquote/style-rtl.css 351 B
build/block-library/blocks/pullquote/style.css 350 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 121 B
build/block-library/blocks/query-pagination-numbers/editor.css 118 B
build/block-library/blocks/query-pagination/editor-rtl.css 154 B
build/block-library/blocks/query-pagination/editor.css 154 B
build/block-library/blocks/query-pagination/style-rtl.css 237 B
build/block-library/blocks/query-pagination/style.css 237 B
build/block-library/blocks/query-title/style-rtl.css 64 B
build/block-library/blocks/query-title/style.css 64 B
build/block-library/blocks/query/editor-rtl.css 527 B
build/block-library/blocks/query/editor.css 527 B
build/block-library/blocks/quote/style-rtl.css 238 B
build/block-library/blocks/quote/style.css 238 B
build/block-library/blocks/quote/theme-rtl.css 233 B
build/block-library/blocks/quote/theme.css 236 B
build/block-library/blocks/read-more/style-rtl.css 138 B
build/block-library/blocks/read-more/style.css 138 B
build/block-library/blocks/rss/editor-rtl.css 101 B
build/block-library/blocks/rss/editor.css 101 B
build/block-library/blocks/rss/style-rtl.css 288 B
build/block-library/blocks/rss/style.css 287 B
build/block-library/blocks/search/editor-rtl.css 199 B
build/block-library/blocks/search/editor.css 199 B
build/block-library/blocks/search/style-rtl.css 660 B
build/block-library/blocks/search/style.css 658 B
build/block-library/blocks/search/theme-rtl.css 113 B
build/block-library/blocks/search/theme.css 113 B
build/block-library/blocks/separator/editor-rtl.css 100 B
build/block-library/blocks/separator/editor.css 100 B
build/block-library/blocks/separator/style-rtl.css 248 B
build/block-library/blocks/separator/style.css 248 B
build/block-library/blocks/separator/theme-rtl.css 195 B
build/block-library/blocks/separator/theme.css 195 B
build/block-library/blocks/shortcode/editor-rtl.css 286 B
build/block-library/blocks/shortcode/editor.css 286 B
build/block-library/blocks/site-logo/editor-rtl.css 806 B
build/block-library/blocks/site-logo/editor.css 803 B
build/block-library/blocks/site-logo/style-rtl.css 218 B
build/block-library/blocks/site-logo/style.css 218 B
build/block-library/blocks/site-tagline/editor-rtl.css 87 B
build/block-library/blocks/site-tagline/editor.css 87 B
build/block-library/blocks/site-tagline/style-rtl.css 65 B
build/block-library/blocks/site-tagline/style.css 65 B
build/block-library/blocks/site-title/editor-rtl.css 85 B
build/block-library/blocks/site-title/editor.css 85 B
build/block-library/blocks/site-title/style-rtl.css 143 B
build/block-library/blocks/site-title/style.css 143 B
build/block-library/blocks/social-link/editor-rtl.css 309 B
build/block-library/blocks/social-link/editor.css 309 B
build/block-library/blocks/social-links/editor-rtl.css 727 B
build/block-library/blocks/social-links/editor.css 724 B
build/block-library/blocks/social-links/style-rtl.css 1.51 kB
build/block-library/blocks/social-links/style.css 1.51 kB
build/block-library/blocks/spacer/editor-rtl.css 346 B
build/block-library/blocks/spacer/editor.css 346 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table-of-contents/style-rtl.css 83 B
build/block-library/blocks/table-of-contents/style.css 83 B
build/block-library/blocks/table/editor-rtl.css 394 B
build/block-library/blocks/table/editor.css 394 B
build/block-library/blocks/table/style-rtl.css 640 B
build/block-library/blocks/table/style.css 639 B
build/block-library/blocks/table/theme-rtl.css 152 B
build/block-library/blocks/table/theme.css 152 B
build/block-library/blocks/tag-cloud/editor-rtl.css 144 B
build/block-library/blocks/tag-cloud/editor.css 144 B
build/block-library/blocks/tag-cloud/style-rtl.css 266 B
build/block-library/blocks/tag-cloud/style.css 265 B
build/block-library/blocks/template-part/editor-rtl.css 368 B
build/block-library/blocks/template-part/editor.css 368 B
build/block-library/blocks/template-part/theme-rtl.css 113 B
build/block-library/blocks/template-part/theme.css 113 B
build/block-library/blocks/term-description/style-rtl.css 126 B
build/block-library/blocks/term-description/style.css 126 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 165 B
build/block-library/blocks/text-columns/style.css 165 B
build/block-library/blocks/verse/style-rtl.css 98 B
build/block-library/blocks/verse/style.css 98 B
build/block-library/blocks/video/editor-rtl.css 441 B
build/block-library/blocks/video/editor.css 442 B
build/block-library/blocks/video/style-rtl.css 192 B
build/block-library/blocks/video/style.css 192 B
build/block-library/blocks/video/theme-rtl.css 134 B
build/block-library/blocks/video/theme.css 134 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/common-rtl.css 1.08 kB
build/block-library/common.css 1.08 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/editor-rtl.css 11.8 kB
build/block-library/editor.css 11.8 kB
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/index.min.js 222 kB
build/block-library/reset-rtl.css 472 B
build/block-library/reset.css 472 B
build/block-library/style-rtl.css 15 kB
build/block-library/style.css 15 kB
build/block-library/theme-rtl.css 708 B
build/block-library/theme.css 712 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/commands/index.min.js 16.1 kB
build/commands/style-rtl.css 955 B
build/commands/style.css 952 B
build/components/index.min.js 228 kB
build/components/style-rtl.css 12.4 kB
build/components/style.css 12.4 kB
build/compose/index.min.js 12.7 kB
build/core-commands/index.min.js 3.09 kB
build/core-data/index.min.js 74.3 kB
build/customize-widgets/index.min.js 11 kB
build/customize-widgets/style-rtl.css 1.35 kB
build/customize-widgets/style.css 1.35 kB
build/data-controls/index.min.js 641 B
build/data/index.min.js 8.69 kB
build/date/index.min.js 18 kB
build/deprecated/index.min.js 458 B
build/dom-ready/index.min.js 325 B
build/dom/index.min.js 4.66 kB
build/edit-post/classic-rtl.css 578 B
build/edit-post/classic.css 580 B
build/edit-post/index.min.js 13.4 kB
build/edit-post/style-rtl.css 2.75 kB
build/edit-post/style.css 2.75 kB
build/edit-site/index.min.js 220 kB
build/edit-site/posts-rtl.css 7.42 kB
build/edit-site/posts.css 7.43 kB
build/edit-site/style-rtl.css 13.7 kB
build/edit-site/style.css 13.7 kB
build/edit-widgets/index.min.js 17.7 kB
build/edit-widgets/style-rtl.css 4.09 kB
build/edit-widgets/style.css 4.09 kB
build/editor/index.min.js 114 kB
build/editor/style-rtl.css 9.28 kB
build/editor/style.css 9.28 kB
build/element/index.min.js 4.82 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 8.05 kB
build/format-library/style-rtl.css 476 B
build/format-library/style.css 476 B
build/hooks/index.min.js 1.65 kB
build/html-entities/index.min.js 445 B
build/i18n/index.min.js 3.58 kB
build/is-shallow-equal/index.min.js 526 B
build/keyboard-shortcuts/index.min.js 1.31 kB
build/keycodes/index.min.js 1.46 kB
build/list-reusable-blocks/index.min.js 2.13 kB
build/list-reusable-blocks/style-rtl.css 852 B
build/list-reusable-blocks/style.css 852 B
build/media-utils/index.min.js 3.58 kB
build/notices/index.min.js 946 B
build/nux/index.min.js 1.62 kB
build/nux/style-rtl.css 749 B
build/nux/style.css 745 B
build/patterns/index.min.js 7.37 kB
build/patterns/style-rtl.css 687 B
build/patterns/style.css 685 B
build/plugins/index.min.js 1.86 kB
build/preferences-persistence/index.min.js 2.06 kB
build/preferences/index.min.js 2.9 kB
build/preferences/style-rtl.css 554 B
build/preferences/style.css 554 B
build/primitives/index.min.js 829 B
build/priority-queue/index.min.js 1.54 kB
build/private-apis/index.min.js 972 B
build/react-i18n/index.min.js 630 B
build/react-refresh-entry/index.min.js 9.47 kB
build/react-refresh-runtime/index.min.js 6.76 kB
build/redux-routine/index.min.js 2.7 kB
build/reusable-blocks/index.min.js 2.55 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10.3 kB
build/router/index.min.js 5.42 kB
build/server-side-render/index.min.js 1.94 kB
build/shortcode/index.min.js 1.4 kB
build/style-engine/index.min.js 2.04 kB
build/token-list/index.min.js 581 B
build/url/index.min.js 3.9 kB
build/vendors/react-dom.min.js 41.7 kB
build/vendors/react-jsx-runtime.min.js 556 B
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 965 B
build/vips/index.min.js 36.2 kB
build/warning/index.min.js 250 B
build/widgets/index.min.js 7.16 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.03 kB

compressed-size-action

@aaronrobertshaw
Copy link
Contributor Author

@youknowriad this PoC should give some indication as to what is required to move default controls configuration to a top-level property.

I got a little lost trying to get something working here, so there's a good chance I'm missing something, or there's a better way of doing this. That uncertainty and going in circles trying to understand how our block types are handled across the server and editor doesn't leave me with much confidence to foresee issues with this approach.

The biggest catches I've found so far are:

  1. Unlike the other experimental block supports that have been stabilized, with this approach to default controls we have even less ability to determine the correct value after filters have been applied to block type args.
  2. Due to the above, the stabilization of default controls would behave slightly differently from the other recently stabilised experimental supports.
  3. If we can't find an alternative approach to the core updates I found I needed, to get defaultControls as a top-level property working, would we need to delay stabilizing defaultControls until those core updates are in the minimum supported version of WP?

As noted earlier, I'm a bit confused around what exactly is needed on the core side of things right now, so take that last point with a grain of salt.

I can take a closer look at this tomorrow with a fresh set of eyes and mind. Following that though, I'll be AFK on and off for the next couple of weeks. It might take me some time to wrangle this if we decide to go ahead with the top-level property.

Any thoughts?

@youknowriad
Copy link
Contributor

It seems some kind of hacky backwards compatibility code is needed regardless of where the feature end up. I would love a recap of the "public" APIs that we need to maintain backward compatibility for. It's a bit hard to read the changes here, but my understanding is that we're shiming in multiple places and ideally we should only do it in a single place.

@aaronrobertshaw
Copy link
Contributor Author

It seems some kind of hacky backwards compatibility code is needed regardless of where the feature end up

It felt that way during my explorations today.

There are several things required to introduce a top-level block type property on the core side (see diff in PR description) as well as in Gutenberg (see 06a44a9).

On the core side I needed to add defaultControls/default_controls to the:

I don't know how easy it would be, or even if it's possible, to override all that within Gutenberg for backwards compatibility.

I would love a recap of the "public" APIs that we need to maintain backward compatibility for.

I'll give it a go, if I've gone down the wrong track here let me know 🙂

The current plan for stabilization of experimental supports started with #63401, which involved stabilizing the block supports :

Experimental support keys were to be replaced with stable counterparts. The following key maps reflect what is being stabilized in these overall efforts.

export const EXPERIMENTAL_SUPPORTS_MAP = {
	__experimentalBorder: 'border',
};

export const COMMON_EXPERIMENTAL_PROPERTIES = {
	__experimentalDefaultControls: 'defaultControls',
	__experimentalSkipSerialization: 'skipSerialization',
};

export const EXPERIMENTAL_SUPPORT_PROPERTIES = {
	typography: {
		__experimentalFontFamily: 'fontFamily',
		__experimentalFontStyle: 'fontStyle',
		__experimentalFontWeight: 'fontWeight',
		__experimentalLetterSpacing: 'letterSpacing',
		__experimentalTextDecoration: 'textDecoration',
		__experimentalTextTransform: 'textTransform',
	},
};

The bulk of those should be relatively painless because it is only the key changing, not where they live. For extenders developing custom blocks that opt into these block supports they won't need to change anything immediately. Ideally, though, they'll migrate their custom block's block.json or block type definitions to use the stable support keys.

If 3rd parties are filtering block type args or metadata, they'll continue to function for the most part. The main edge case here is where there are multiple plugins/themes filtering the same supports using a mix of experimental and stable keys to change the same support. That scenario can't be accounted for 100% so the approach taken will check the insertion order in the config to make a "best guess" as to which value was updated last and use that.

If plugins or themes are checking block supports in custom code, they'll need to update that code to check the stable key.

This all would apply to defaultControls too if it remains within supports. Moving it to a sibling of supports instead means not only having to wrangle adding the new block type property and making sure that works in Gutenberg for older WordPress releases, but also requiring some extra changes to minimise the updates forced upon plugins and themes e.g. how they check for default controls.

During my tinkering today, I also looked at monkey patching getBlockSupport to retrieve the stabilized support values but shelved it as too great a hack. It could be revisited, or an alternative found if we want to limit the need for plugins to update keys in their custom checks for block supports.

FWIW a quick search suggests that 1656 plugins are using __experimentalDefaultControls in some shape or form.

I hope that wall of text helps paint a clearer picture 🙏

@youknowriad
Copy link
Contributor

I don't know how easy it would be, or even if it's possible, to override all that within Gutenberg for backwards compatibility.

I think these changes are ok (the core ones) but I do believe we should be able to do that in Gutenberg, unrelated to defaultControls. it shouldn't be a pain point for us to introduce a new optional key to block.json

If 3rd parties are filtering block type args or metadata, they'll continue to function for the most part. The main edge case here is where there are multiple plugins/themes filtering the same supports using a mix of experimental and stable keys to change the same support. That scenario can't be accounted for 100% so the approach taken will check the insertion order in the config to make a "best guess" as to which value was updated last and use that.

My main thinking here is that we should not be patching the "defaultControls" at registration time (both server and client). (I guess the same reasoning can apply to block supports and any deprecated property). Instead, we should be patching the selectors we use to retrieve these. In simpler words:

  • The selectors (both php and JS) to retrieve the default controls should look in both places (stable and deprecated ones) and "merge them". If deprecated places are found, we should trigger a deprecated call in the selector.

Doing this at the selector level prevents any potential hacks we need to do to support registration/filtering...


These are obviously just theoretical thoughts, maybe there's a flaw in this reasoning as I know these things are complex. Also it seems the same issues apply to "defaultControls" and "block supports" stabilization regardless of whether the stable keys live, so I would say this cumbersome deprecation shouldn't be impacting the decision on where to put "defaultControls" (Correct me if I'm wrong).

It seems the main difference between top-level or not, is the difficulty to add a top level property in Gutenberg (overriding Core).

@aaronrobertshaw
Copy link
Contributor Author

Appreciate the continued guidance @youknowriad, thanks 🙇

we should be able to do that in Gutenberg, unrelated to defaultControls. it shouldn't be a pain point for us to introduce a new optional key to block.json

Agreed, it shouldn't be a pain point. I'd say a large part of the issue is I'm not very familiar with this area so it's tougher to know what needs doing and how. I'm hopeful I can figure it out, it might just take some time.

Doing this at the selector level prevents any potential hacks we need to do to support registration/filtering...

If I understand correctly, we'll face the same edge cases around filtered values. Wherever we fetch and merge the stable and experimental values, we need to decide on how that is done.

  • Do we continue with the current approach of using the insertion order of experimental vs stable keys to mitigate potentially losing experimental key values set by filters, while plugins migrate to stable keys?
  • Should we have opted for a simpler, clearer, but more limited option of preferring stable key values over experimental ones?

I would say this cumbersome deprecation shouldn't be impacting the decision on where to put "defaultControls" (Correct me if I'm wrong).

If the decision purely comes down to where makes the most sense for defaultControls. The expansion of that API's scope to include non-block-support controls tilts the decision in favour of the top-level property, in my opinion.

The hope with the block supports stabilization was to have this all in place early in the 6.8 release cycle. If we revisit the approach to handle all this within selectors (which I'm on board with), it will push back when this all lands until into the new year.

It seems the main difference between top-level or not, is the difficulty to add a top level property in Gutenberg (overriding Core).

That's it in a nutshell.

@aaronrobertshaw
Copy link
Contributor Author

It seems the main difference between top-level or not, is the difficulty to add a top level property in Gutenberg (overriding Core).

I've taken another run at overriding core to add the default controls property within Gutenberg. In 0f4914a I've managed to avoid all but one core update.

What I haven't been able to solve yet is updating the fields to pick in core's get_block_editor_server_block_settings function. It seems the results of that function are primarily used to provide JSON encoded block type data to wp.blocks.unstable__bootstrapServerSideBlockDefinitions() calls, e.g. here for the block editor.

After 0f4914a and very quick initial tests, it appears that if I define defaultControls in a Gutenberg block's block.json file, that data is available and used correctly.

Given that, my latest plan is to remove the stabilization of experimental block supports from the register_block_type_args filter and JS processBlockType and instead add deprecation warnings in those places if a block type contains a deprecated experimental support flag. Following that, I'll explore the proposed approach and update the JS selectors and PHP util functions to collect and merge the experimental and stable values, trigger deprecation warnings etc.

Happy for nudges in the right direction if I'm heading down the wrong track.

@ramonjd
Copy link
Member

ramonjd commented Dec 10, 2024

Thanks for looking into this @aaronrobertshaw and exploring the options.

The hope with the block supports stabilization was to have this all in place early in the 6.8 release cycle. If we revisit the approach to handle all this within selectors (which I'm on board with), it will push back when this all lands until into the new year.

That sounds like a good option if it takes the pressure off, and gives folks time to come up with robust approach.

We haven't committed the core patch yet, so it can be put on ice at any time.

@youknowriad
Copy link
Contributor

Your proposed plan sounds good to me.

Do we continue with the current approach of using the insertion order of experimental vs stable keys to mitigate potentially losing experimental key values set by filters, while plugins migrate to stable keys?
Should we have opted for a simpler, clearer, but more limited option of preferring stable key values over experimental ones?

Insertion order seems as arbitrary as preferring stable keys no? What are we hoping to gain by doing this?

@aaronrobertshaw
Copy link
Contributor Author

Insertion order seems as arbitrary as preferring stable keys no? What are we hoping to gain by doing this?

It is arbitrary, true, but a little more flexible than simply preferring the stable key values.

The plan to date has been to update all the core blocks to use the stable block supports as soon as this stabilization is solid. That is partly due to our block library effectively forming part of our overall documentation and setting examples for 3rd parties.

If we prefer stable over experimental values, all plugins that filter these supports would see their filters fail to take effect. Using the insertion order helps alleviate that for the majority of use cases.

It doesn't solve an edge case where multiple filters of the same support config use a mix of experimental and stable keys, however, this scenario is much more contrived than a plugin being slow to migrate its filters to use stable keys.

In other words, by using the insertion order, we can provide some backward compatibility for the following situation:

  1. Core blocks use stable block support keys
  2. Plugin or theme filters a core block to disable a particular block support using the experimental support key
  3. The expected filtered value is still used

Given that scenario, do you have a preferred approach?

@youknowriad
Copy link
Contributor

If we prefer stable over experimental values, all plugins that filter these supports would see their filters fail to take effect. Using the insertion order helps alleviate that for the majority of use cases.

What if the order is reversed?

@aaronrobertshaw
Copy link
Contributor Author

What if the order is reversed?

Do you mean our order of preference? So preferring experimental key values over stable?

We'd have a similar scenario/problem.

  1. Custom block uses experimental key
  2. Theme filters the block supports using the (soon to be) documented stable key
  3. The filtered value that used the stable key wouldn't take effect

Using the insertion order approach with the above scenario:

  1. The block would start with the experimental key for its support
  2. After the filter is applied it will now have both the experimental and stable support keys in that order.
  3. Preferring the last inserted key as our best guess for the last updated value, the filter's stable key value would be used matching the expected outcome

Likewise, using the other scenario:

  • Core blocks use stable block support keys
  • Plugin or theme filters a core block to disable a particular block support using the experimental support key
  • The expected filtered value is still used

The block starts with the stable key, then gets the experimental afterwards via the filter. The experimental key is inserted last and so is preferred over the original stable one. Leaving us with the expected value, that of the filter.

To illustrate the edge case where this falls over, imagine the following:

  1. Core block uses stable support key
  2. Plugin applies a filter using the experimental key
  3. Theme applies a second filter using the original stable key

Here, the block starts with the stable key and the experimental key is added later by the plugin filter. Using the insertion order to determine/guess which value was updated last fails here as it would indicate the experimental key should be used. The expected outcome would be for the theme's filtered value to be used.

Apologies I wasn't clearer before when referring to the insertion order. Hopefully, I've done a better job communicating this time around.

@youknowriad
Copy link
Contributor

I see. Thanks for detailing. I think it's your call if you want to keep the "insertion order" behavior or not (depending on how complex it is). Personally, I'm ok optimizing for the common case which sounds like:

  • plugin disabling stuff using __experimental
  • core blocks move toe stable

@aaronrobertshaw
Copy link
Contributor Author

@youknowriad I've been attempting to implement a selectors-based approach to stabilizing block supports and it is proving more difficult than hoped for. I'd like to propose a few options to move forward below and would love to get your thoughts.

Possible options:

  1. Keep the existing approach migrating experimental properties, including default controls, at block type registration
  2. Tweak the existing approach but skip stabilizing default controls until they can be a top-level property
  3. Revert all the block support stabilization that has already been merged into Gutenberg

Keeping the existing migrate-on-registration approach

Pros:

  • It's already in place in Gutenberg and seems to work fine
  • Keeping defaultControls under supports means that stabilization can happen straight away rather than wait on core updates for multiple releases
  • Most common uses of block support keys e.g. block type support definition, block type metadata filters etc. will continue to work
  • Only requires changing experimental keys to stable ones in our codebase instead of changing the method supports are queried (from direct checks to using a selector or util function).

Cons:

  • defaultControls would still live under supports
  • Requires any 3rd parties manually checking for formerly experimental support keys to update to the stable key.
    • This is only an issue for 3rd party plugins that query supports directly on the block type object and try to do something based on that. I struggled to find any use cases matching this when searching WP Directory.
    • We could offset this somewhat by still updating selectors but that comes with its own issues I'll touch on later. I'm not convinced we have to optimise for the above use case
  • With the lack of time before 6.8 we probably don't have enough for adequate communication and warning before requiring third party updates.

Existing migrate-on-registration approach but skip stabilizing defaultControls

Pros:

  • It's pretty much already in place only requiring a small tweak to remove the default controls stabilization
  • Doesn't lock defaultControls into living under supports
  • This draft PR already serves as a guide on how we can stabilize defaultControls to a top-level property once core supports it

Cons:

  • Mostly the same cons as the previous option in that it requires 3rd party updates and communication time

Revert existing block support stabilization to buy time to find cleaner solution

Pros:

  • We aren't committed yet to any particular direction
  • Provides plenty of time to communicate any potential required updates by 3rd parties
  • We can focus on more impactful updates for end users in 6.8
  • Allows the opportunity to update core now to add defaultControls as a top-level block type property which would allow Gutenberg to stabilize default controls in 7.0 and maintain backwards compatibility for the previous two WP versions.

Cons:

  • The current approach to stabilization has already been merged and released in Gutenberg
  • It's possible some early adopters could have begun updating their code to use stable support keys
  • Some communication has recently gone out to the community advertising block support stabilization e.g. the December What's New for Developers blog post.
    • This isn't to say we can't backtrack. Just that we have more communication to do to avoid confusion

Selectors-based Approach

Here's a bit of a TL;DR on the issues encountered with updating selectors to handle stabilization.

  • This approach involves more updates than the migration-on-registration approach, not less
  • Trying to retrieve supports from multiple locations looks like it could introduce some performance concerns
  • Attempting to support values being in two places at once doesn't really fit with things like our style properties config, global style generation etc that in some parts is still manually looking up values on a supplied block type
  • There are as many, or more, places in core to update to use util functions like block_has_support than there are uses of experimental keys to simply switch
  • It strikes me as easier to convince 3rd parties to switch an experimental key to stable if they are manually querying a block type supports object than getting them to switch to use getBlockSupport, block_has_support etc.
  • Updating multiple selectors e.g. getBlockSupport, getSupportedStyles, block_has_support etc requires a little more untangling if we ever want to be able to remove this code in future. The existing approach only has a 6.8 compat filter, a function within processBlockType, and a stabilization function within the block type class in core.

Summary

On their own, most of the issues or cons listed above aren't major. With possibly the exception of needing more time to communicate required changes for 3rd parties.

I'm genuinely at a bit of a loss as to how to stabilize these supports in a cleaner fashion than we already have in Gutenberg or in any way that won't require 3rd parties to tweak something.

I'll be AFK for the next couple of weeks, into the new year, so the revert option is looking like the best course of action to me right now. I'd be more than happy to hear alternative opinions though!

Given that, I can get a PR together to revert the stabilization of supports already merged in Gutenberg. If we decide to pull the trigger on that, perhaps @ramonjd might be able to hit merge on the revert for me while I'm away 🙏

@ramonjd
Copy link
Member

ramonjd commented Dec 20, 2024

Huge kudos to all the work so far @aaronrobertshaw

And it's great to have our options laid out like this, I appreciate the diligence and clear communication.

migrating experimental properties, including default controls, at block type registration

Just wanted to note that WordPress has previous form with regards to this approach. See the wp_migrate_old_typography_shape callback to the block_type_metadata hook. It's applied in register_block_type_from_metadata.

defaultControls would still live under supports

What is the basis for this requirement? It seems separate to me. We're talking about stabilization, not API enhancements.

Blocks could happily live without it in the meantime.

I understand it might make sense to bundle it in with stabilization changes, if it creates too much tech debt later to try to patch in (?).

In that case, it's a solid case for reverting this and doing things more methodically and safely.

Revert existing block support stabilization to buy time to find cleaner solution
With the lack of time before 6.8 we probably don't have enough for adequate communication and warning before requiring third party updates.

I think we should feel comfortable in saying we need more time.

Nothing is broken, except maybe a few promises made by other folks, no API will change.

Gutenberg, as every knew from day one, is an experimental plugin, and so long as it's not in Core I think we have licence to revert things that don't make sense, or that jeopardize backwards compatibility.

@aaronrobertshaw
Copy link
Contributor Author

A revert PR for the original approach is up in #68163.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants