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

Borders: Use new border control components in block support #37770

Merged
merged 27 commits into from
Apr 14, 2022

Conversation

aaronrobertshaw
Copy link
Contributor

@aaronrobertshaw aaronrobertshaw commented Jan 7, 2022

Related:

Depends on:

Description

Updates the block support and global styles border panel to leverage the new BorderBoxControl component for specifying individual borders per side.

How has this been tested?

  1. Running unit tests
    • npm run test-unit-php /var/www/html/wp-content/plugins/gutenberg/phpunit/block-supports/border-test.php
    • npm run test-unit-php /var/www/html/wp-content/plugins/gutenberg/phpunit/class-wp-theme-json-test.php
  2. Manual testing via block editor
    1. Create a post, add a group block, and select it.
    2. Trial different border configurations via the new BorderBoxControl in the inspector controls sidebar
    3. Save the post and confirm correct display on the frontend
    4. Switch back to the editor and add a dynamic block that has border support and repeat testing borders
  3. Tested theme.json styling of individual borders
    • Update theme.json to configure various borders
        "core/group": {
		"border": {
			"left": {
				"color": "var(--wp--preset--color--primary)",
				"style": "dashed",
				"width": "3px"
			}
		}
	}
  1. Manual testing of global styles
    1. Within the site editor's global styles sidebar, navigate to Blocks > Group > Layout
    2. Adjust borders and confirm the various group blocks in the editor update visually
    3. Save global styles and view on the frontend
  2. Test other blocks that already opt into border support e.g. Search and Table blocks.
  3. Test that blocks that already had borders via block support continue to display correctly after applying this PR

Screenshots

Screen.Recording.2022-03-30.at.7.53.27.pm.mp4

Types of changes

Enhancement.

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • I've tested my changes with keyboard and screen readers.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR (please manually search all *.native.js files for terms that need renaming or removal).

@aaronrobertshaw aaronrobertshaw added [Status] In Progress Tracking issues with work in progress [Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi labels Jan 7, 2022
@aaronrobertshaw aaronrobertshaw self-assigned this Jan 7, 2022
@github-actions
Copy link

github-actions bot commented Jan 7, 2022

Size Change: +2.42 kB (0%)

Total Size: 1.23 MB

Filename Size Change
build/block-editor/index.min.js 150 kB +484 B (0%)
build/block-editor/style-rtl.css 15.7 kB +148 B (+1%)
build/block-editor/style.css 15.6 kB +143 B (+1%)
build/block-library/blocks/table/editor-rtl.css 504 B +33 B (+7%) 🔍
build/block-library/blocks/table/editor.css 504 B +32 B (+7%) 🔍
build/block-library/blocks/table/style-rtl.css 625 B +144 B (+30%) 🚨
build/block-library/blocks/table/style.css 625 B +144 B (+30%) 🚨
build/block-library/common-rtl.css 993 B +59 B (+6%) 🔍
build/block-library/common.css 990 B +58 B (+6%) 🔍
build/block-library/editor-rtl.css 10.2 kB +33 B (0%)
build/block-library/editor.css 10.2 kB +33 B (0%)
build/block-library/index.min.js 175 kB +97 B (0%)
build/block-library/style-rtl.css 11.5 kB +197 B (+2%)
build/block-library/style.css 11.5 kB +194 B (+2%)
build/blocks/index.min.js 47 kB +133 B (0%)
build/edit-site/index.min.js 47 kB +10 B (0%)
build/edit-site/style-rtl.css 8.02 kB +239 B (+3%)
build/edit-site/style.css 8.01 kB +241 B (+3%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 993 B
build/admin-manifest/index.min.js 1.24 kB
build/annotations/index.min.js 2.77 kB
build/api-fetch/index.min.js 2.27 kB
build/autop/index.min.js 2.15 kB
build/blob/index.min.js 487 B
build/block-directory/index.min.js 6.49 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/default-editor-styles-rtl.css 378 B
build/block-editor/default-editor-styles.css 378 B
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 65 B
build/block-library/blocks/archives/style.css 65 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 111 B
build/block-library/blocks/audio/style.css 111 B
build/block-library/blocks/audio/theme-rtl.css 125 B
build/block-library/blocks/audio/theme.css 125 B
build/block-library/blocks/avatar/editor-rtl.css 116 B
build/block-library/blocks/avatar/editor.css 116 B
build/block-library/blocks/avatar/style-rtl.css 59 B
build/block-library/blocks/avatar/style.css 59 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 445 B
build/block-library/blocks/button/editor.css 445 B
build/block-library/blocks/button/style-rtl.css 560 B
build/block-library/blocks/button/style.css 560 B
build/block-library/blocks/buttons/editor-rtl.css 292 B
build/block-library/blocks/buttons/editor.css 292 B
build/block-library/blocks/buttons/style-rtl.css 275 B
build/block-library/blocks/buttons/style.css 275 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 103 B
build/block-library/blocks/code/style.css 103 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 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 406 B
build/block-library/blocks/columns/style.css 406 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-template/style-rtl.css 127 B
build/block-library/blocks/comment-template/style.css 127 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-query-loop/editor-rtl.css 95 B
build/block-library/blocks/comments-query-loop/editor.css 95 B
build/block-library/blocks/cover/editor-rtl.css 546 B
build/block-library/blocks/cover/editor.css 547 B
build/block-library/blocks/cover/style-rtl.css 1.56 kB
build/block-library/blocks/cover/style.css 1.56 kB
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 417 B
build/block-library/blocks/embed/style.css 417 B
build/block-library/blocks/embed/theme-rtl.css 124 B
build/block-library/blocks/embed/theme.css 124 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 255 B
build/block-library/blocks/file/style.css 255 B
build/block-library/blocks/file/view.min.js 353 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 961 B
build/block-library/blocks/gallery/editor.css 964 B
build/block-library/blocks/gallery/style-rtl.css 1.51 kB
build/block-library/blocks/gallery/style.css 1.51 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 333 B
build/block-library/blocks/group/editor.css 333 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 76 B
build/block-library/blocks/heading/style.css 76 B
build/block-library/blocks/html/editor-rtl.css 332 B
build/block-library/blocks/html/editor.css 333 B
build/block-library/blocks/image/editor-rtl.css 731 B
build/block-library/blocks/image/editor.css 730 B
build/block-library/blocks/image/style-rtl.css 529 B
build/block-library/blocks/image/style.css 535 B
build/block-library/blocks/image/theme-rtl.css 124 B
build/block-library/blocks/image/theme.css 124 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 199 B
build/block-library/blocks/latest-posts/editor.css 198 B
build/block-library/blocks/latest-posts/style-rtl.css 447 B
build/block-library/blocks/latest-posts/style.css 446 B
build/block-library/blocks/list/style-rtl.css 88 B
build/block-library/blocks/list/style.css 88 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 493 B
build/block-library/blocks/media-text/style.css 490 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 708 B
build/block-library/blocks/navigation-link/editor.css 706 B
build/block-library/blocks/navigation-link/style-rtl.css 115 B
build/block-library/blocks/navigation-link/style.css 115 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation-submenu/view.min.js 375 B
build/block-library/blocks/navigation/editor-rtl.css 2.03 kB
build/block-library/blocks/navigation/editor.css 2.04 kB
build/block-library/blocks/navigation/style-rtl.css 1.93 kB
build/block-library/blocks/navigation/style.css 1.92 kB
build/block-library/blocks/navigation/view.min.js 2.85 kB
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 363 B
build/block-library/blocks/page-list/editor.css 363 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 260 B
build/block-library/blocks/paragraph/style.css 260 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/style-rtl.css 446 B
build/block-library/blocks/post-comments-form/style.css 446 B
build/block-library/blocks/post-comments/style-rtl.css 521 B
build/block-library/blocks/post-comments/style.css 521 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 721 B
build/block-library/blocks/post-featured-image/editor.css 721 B
build/block-library/blocks/post-featured-image/style-rtl.css 153 B
build/block-library/blocks/post-featured-image/style.css 153 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 323 B
build/block-library/blocks/post-template/style.css 323 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 80 B
build/block-library/blocks/post-title/style.css 80 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 370 B
build/block-library/blocks/pullquote/style.css 370 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 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 234 B
build/block-library/blocks/query-pagination/style.css 231 B
build/block-library/blocks/query/editor-rtl.css 369 B
build/block-library/blocks/query/editor.css 369 B
build/block-library/blocks/quote/style-rtl.css 213 B
build/block-library/blocks/quote/style.css 213 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 132 B
build/block-library/blocks/read-more/style.css 132 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 397 B
build/block-library/blocks/search/style.css 398 B
build/block-library/blocks/search/theme-rtl.css 64 B
build/block-library/blocks/search/theme.css 64 B
build/block-library/blocks/separator/editor-rtl.css 140 B
build/block-library/blocks/separator/editor.css 140 B
build/block-library/blocks/separator/style-rtl.css 233 B
build/block-library/blocks/separator/style.css 233 B
build/block-library/blocks/separator/theme-rtl.css 194 B
build/block-library/blocks/separator/theme.css 194 B
build/block-library/blocks/shortcode/editor-rtl.css 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 759 B
build/block-library/blocks/site-logo/editor.css 759 B
build/block-library/blocks/site-logo/style-rtl.css 181 B
build/block-library/blocks/site-logo/style.css 181 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 177 B
build/block-library/blocks/social-link/editor.css 177 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.37 kB
build/block-library/blocks/social-links/style.css 1.36 kB
build/block-library/blocks/spacer/editor-rtl.css 332 B
build/block-library/blocks/spacer/editor.css 332 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/theme-rtl.css 188 B
build/block-library/blocks/table/theme.css 188 B
build/block-library/blocks/tag-cloud/style-rtl.css 226 B
build/block-library/blocks/tag-cloud/style.css 227 B
build/block-library/blocks/template-part/editor-rtl.css 149 B
build/block-library/blocks/template-part/editor.css 149 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 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 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 571 B
build/block-library/blocks/video/editor.css 572 B
build/block-library/blocks/video/style-rtl.css 173 B
build/block-library/blocks/video/style.css 173 B
build/block-library/blocks/video/theme-rtl.css 124 B
build/block-library/blocks/video/theme.css 124 B
build/block-library/reset-rtl.css 478 B
build/block-library/reset.css 478 B
build/block-library/theme-rtl.css 689 B
build/block-library/theme.css 694 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/components/index.min.js 223 kB
build/components/style-rtl.css 14.9 kB
build/components/style.css 14.9 kB
build/compose/index.min.js 11.2 kB
build/core-data/index.min.js 14.5 kB
build/customize-widgets/index.min.js 11 kB
build/customize-widgets/style-rtl.css 1.39 kB
build/customize-widgets/style.css 1.39 kB
build/data-controls/index.min.js 663 B
build/data/index.min.js 8.64 kB
build/date/index.min.js 32 kB
build/deprecated/index.min.js 518 B
build/dom-ready/index.min.js 336 B
build/dom/index.min.js 4.58 kB
build/edit-navigation/index.min.js 15.8 kB
build/edit-navigation/style-rtl.css 4.04 kB
build/edit-navigation/style.css 4.05 kB
build/edit-post/classic-rtl.css 546 B
build/edit-post/classic.css 547 B
build/edit-post/index.min.js 30 kB
build/edit-post/style-rtl.css 7.18 kB
build/edit-post/style.css 7.18 kB
build/edit-widgets/index.min.js 16.3 kB
build/edit-widgets/style-rtl.css 4.4 kB
build/edit-widgets/style.css 4.39 kB
build/editor/index.min.js 38.4 kB
build/editor/style-rtl.css 3.71 kB
build/editor/style.css 3.71 kB
build/element/index.min.js 4.29 kB
build/escape-html/index.min.js 548 B
build/format-library/index.min.js 6.62 kB
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.66 kB
build/html-entities/index.min.js 454 B
build/i18n/index.min.js 3.79 kB
build/is-shallow-equal/index.min.js 535 B
build/keyboard-shortcuts/index.min.js 1.83 kB
build/keycodes/index.min.js 1.41 kB
build/list-reusable-blocks/index.min.js 1.75 kB
build/list-reusable-blocks/style-rtl.css 838 B
build/list-reusable-blocks/style.css 838 B
build/media-utils/index.min.js 2.94 kB
build/notices/index.min.js 957 B
build/nux/index.min.js 2.12 kB
build/nux/style-rtl.css 751 B
build/nux/style.css 749 B
build/plugins/index.min.js 1.98 kB
build/preferences/index.min.js 1.2 kB
build/primitives/index.min.js 949 B
build/priority-queue/index.min.js 611 B
build/react-i18n/index.min.js 704 B
build/react-refresh-entry/index.min.js 8.44 kB
build/react-refresh-runtime/index.min.js 7.31 kB
build/redux-routine/index.min.js 2.69 kB
build/reusable-blocks/index.min.js 2.24 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 11.2 kB
build/server-side-render/index.min.js 1.61 kB
build/shortcode/index.min.js 1.52 kB
build/token-list/index.min.js 668 B
build/url/index.min.js 1.99 kB
build/vendors/react-dom.min.js 38.5 kB
build/vendors/react.min.js 4.34 kB
build/viewport/index.min.js 1.08 kB
build/warning/index.min.js 280 B
build/widgets/index.min.js 7.21 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.07 kB

compressed-size-action

@aaronrobertshaw aaronrobertshaw force-pushed the try/individual-border-support branch 3 times, most recently from 10790d4 to a14ebcf Compare January 25, 2022 07:36
@aaronrobertshaw aaronrobertshaw force-pushed the try/combined-border-controls branch 3 times, most recently from 5d067c2 to 7be6d5d Compare February 1, 2022 03:55
@aaronrobertshaw aaronrobertshaw force-pushed the try/individual-border-support branch 2 times, most recently from 6878b94 to b44a979 Compare February 1, 2022 04:22
@aaronrobertshaw aaronrobertshaw changed the title [WIP] Borders: Use new border control components in block support Borders: Use new border control components in block support Feb 1, 2022
@aaronrobertshaw
Copy link
Contributor Author

@oandregal or @youknowriad would you be able to point me in the right direction as to the best approach to adding new features and configuration to the WP_Theme_JSON class?

Prior to it landing in 5.9 we essentially had this class in the lib/compat/wordpress-5.9 directory. Is there a means of adding my required updates to the lib/compat/wordpress-6.0 folder or must every tweak to this now go via a core PR?

I'm not convinced the proposed changes required by this PR are ready for core as they could well change.

@youknowriad
Copy link
Contributor

The current PR seem to impact only the block supports which are out of the lib/compat folder because we just replace them on Core on each release, so no problem here.

That said, if you want to change WP_Theme_JSON class itself, I'm not sure about the solution here. We can try to target a Gutenberg_WP_Theme_JSON class in Gutenberg and extend WP_Theme_JSON as base class maybe. That said it all depends on the change.

@aaronrobertshaw
Copy link
Contributor Author

Thanks for the extra info @youknowriad

The current PR seem to impact only the block supports which are out of the lib/compat folder because we just replace them on Core on each release, so no problem here.

I omitted the changes to WP_Theme_JSON from this PR because currently they need to be applied in core I believe.

This is what I was attempting to convey in the PR description as quoted below:

The theme.json and global styles updates in this PR require the theme.json's VALID_STYLES, PROPERTIES_METADATA, and PRESETS_METADATA to be updated.

The required changes can be found in this commit. Upon confirmation of the correct approach I will either make the updates within this PR if possible or create a core trac ticket and associated PR that will become a dependency of this PR.


That said it all depends on the change.

Given the required changes to WP_Theme_JSON do you have a preferred solution?

Others are also currently working on new block supports that will extend to theme.json and Global Styles. I think at the least we need a convenient means of modifying the various config arrays within the WP_Theme_JSON class from Gutenberg.

cc/ @ramonjd

@aaronrobertshaw aaronrobertshaw force-pushed the try/combined-border-controls branch 2 times, most recently from 7552f9d to f0506b9 Compare February 3, 2022 04:46
@youknowriad
Copy link
Contributor

@aaronrobertshaw Unfortunately, I don't have a solution here, we need to come up with something like with any core extension. Would something like this be enough? #38323 (comment)

@ramonjd
Copy link
Member

ramonjd commented Feb 4, 2022

I'm not sure we can extend the base classes and get away with it, as I think we'd be in a similar situation to the one @ntsekouras describes.

VALID_STYLES and other private constants are used, for example, in private static function sanitize(), which wouldn't be accessible outside the class definition (in an extended class for example).

I'm not experienced enough in dealing with compat files yet, but I think, just to update the private constants, we're going to have to copy over quite a bunch of things, including ensuring that the plugin priortizes the compat/6.0 files over WP 5.9, e.g., making sure that methods such as wp_get_global_styles use the compat/6.0 WP_Theme_JSON_Resolver_Gutenberg .

For the latter example, I'm seeing the use of prefixes gutenberg_ and wp_ to distinguish between Gutenberg and core methods.

I'm starting off naively and tested by copying over WP_Theme_JSON_Gutenberg, which is a dependency of WP_Theme_JSON_Resolver_Gutenberg, which is used in lots of places like get-global-styles-and-settings.php. It's slow going, but for me, it's a matter of:

  1. finding where classes/methods references each other and how they're used in core
  2. copying relevant files into compat/6.0, load them up, updating names
  3. Logging... :)

I get the impression a lot of experience and knowledge was gained in relation to compatibility best practices during the 5.9 release, so I'm doing things the hard way.

@oandregal
Copy link
Member

Hey, I have #38625 to unblock making changes to theme.json classes for some PRs. I plan on doing the same changes tomorrow to unblock this PR (either in #38625 or in a different one, depending on how people feel).

@aaronrobertshaw
Copy link
Contributor Author

Hey, I have #38625 to unblock making changes to theme.json classes for some PRs.

Thanks for the work on unblocking theme.json class changes @oandregal, it's greatly appreciated 👍

I've taken it for a quick test drive by:

After taking care of the above everything worked well for me.

Example diff of local changes testing the above for this PR
diff --git a/lib/compat/wordpress-5.9/class-wp-theme-json-gutenberg.php b/lib/compat/wordpress-5.9/class-wp-theme-json-5-9.php
similarity index 98%
rename from lib/compat/wordpress-5.9/class-wp-theme-json-gutenberg.php
rename to lib/compat/wordpress-5.9/class-wp-theme-json-5-9.php
index 9d10266d05..b7e9c3bc66 100644
--- a/lib/compat/wordpress-5.9/class-wp-theme-json-gutenberg.php
+++ b/lib/compat/wordpress-5.9/class-wp-theme-json-5-9.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * WP_Theme_JSON_Gutenberg class
+ * WP_Theme_JSON_5_9 class
  *
  * @package gutenberg
  */
@@ -14,14 +14,14 @@
  *
  * @access private
  */
-class WP_Theme_JSON_Gutenberg {
+class WP_Theme_JSON_5_9 {
 
 	/**
 	 * Container of data in theme.json format.
 	 *
 	 * @var array
 	 */
-	private $theme_json = null;
+	protected $theme_json = null;
 
 	/**
 	 * Holds block metadata extracted from block.json
@@ -342,7 +342,7 @@ class WP_Theme_JSON_Gutenberg {
 		// Internally, presets are keyed by origin.
 		$nodes = self::get_setting_nodes( $this->theme_json );
 		foreach ( $nodes as $node ) {
-			foreach ( self::PRESETS_METADATA as $preset_metadata ) {
+			foreach ( static::PRESETS_METADATA as $preset_metadata ) {
 				$path   = array_merge( $node['path'], $preset_metadata['path'] );
 				$preset = _wp_array_get( $this->theme_json, $path, null );
 				if ( null !== $preset ) {
@@ -426,11 +426,11 @@ class WP_Theme_JSON_Gutenberg {
 			return $output;
 		}
 
-		$output = array_intersect_key( $input, array_flip( self::VALID_TOP_LEVEL_KEYS ) );
+		$output = array_intersect_key( $input, array_flip( static::VALID_TOP_LEVEL_KEYS ) );
 
 		// Some styles are only meant to be available at the top-level (e.g.: blockGap),
 		// hence, the schema for blocks & elements should not have them.
-		$styles_non_top_level = self::VALID_STYLES;
+		$styles_non_top_level = static::VALID_STYLES;
 		foreach ( array_keys( $styles_non_top_level ) as $section ) {
 			foreach ( array_keys( $styles_non_top_level[ $section ] ) as $prop ) {
 				if ( 'top' === $styles_non_top_level[ $section ][ $prop ] ) {
@@ -452,7 +452,7 @@ class WP_Theme_JSON_Gutenberg {
 			$schema_styles_blocks[ $block ]             = $styles_non_top_level;
 			$schema_styles_blocks[ $block ]['elements'] = $schema_styles_elements;
 		}
-		$schema['styles']             = self::VALID_STYLES;
+		$schema['styles']             = static::VALID_STYLES;
 		$schema['styles']['blocks']   = $schema_styles_blocks;
 		$schema['styles']['elements'] = $schema_styles_elements;
 		$schema['settings']           = self::VALID_SETTINGS;
@@ -928,7 +928,7 @@ class WP_Theme_JSON_Gutenberg {
 		}
 
 		$stylesheet = '';
-		foreach ( self::PRESETS_METADATA as $preset_metadata ) {
+		foreach ( static::PRESETS_METADATA as $preset_metadata ) {
 			$slugs = self::get_settings_slugs( $settings, $preset_metadata, $origins );
 			foreach ( $preset_metadata['classes'] as $class => $property ) {
 				foreach ( $slugs as $slug ) {
@@ -1101,7 +1101,7 @@ class WP_Theme_JSON_Gutenberg {
 	 */
 	private static function compute_preset_vars( $settings, $origins ) {
 		$declarations = array();
-		foreach ( self::PRESETS_METADATA as $preset_metadata ) {
+		foreach ( static::PRESETS_METADATA as $preset_metadata ) {
 			$values_by_slug = self::get_settings_values_by_slug( $settings, $preset_metadata, $origins );
 			foreach ( $values_by_slug as $slug => $value ) {
 				$declarations[] = array(
@@ -1216,7 +1216,11 @@ class WP_Theme_JSON_Gutenberg {
 	 * @param array $properties Properties metadata.
 	 * @return array Returns the modified $declarations.
 	 */
-	private static function compute_style_properties( $styles, $settings = array(), $properties = self::PROPERTIES_METADATA ) {
+	private static function compute_style_properties( $styles, $settings = array(), $properties = null ) {
+		if ( is_null( $properties ) ) {
+			$properties = static::PROPERTIES_METADATA;
+		}
+
 		$declarations = array();
 		if ( empty( $styles ) ) {
 			return $declarations;
@@ -1457,7 +1461,7 @@ class WP_Theme_JSON_Gutenberg {
 			}
 
 			// Replace the presets.
-			foreach ( self::PRESETS_METADATA as $preset ) {
+			foreach ( static::PRESETS_METADATA as $preset ) {
 				$override_preset = self::should_override_preset( $this->theme_json, $node['path'], $preset['override'] );
 
 				foreach ( self::VALID_ORIGINS as $origin ) {
@@ -1528,7 +1532,7 @@ class WP_Theme_JSON_Gutenberg {
 	}
 
 	/**
-	 * Returns whether a presets should be overriden or not.
+	 * Returns whether a presets should be overridden or not.
 	 *
 	 * @param array      $theme_json The theme.json like structure to inspect.
 	 * @param array      $path Path to inspect.
@@ -1543,8 +1547,8 @@ class WP_Theme_JSON_Gutenberg {
 		// The relationship between whether to override the defaults
 		// and whether the defaults are enabled is inverse:
 		//
-		// - If defaults are enabled  => theme presets should not be overriden
-		// - If defaults are disabled => theme presets should be overriden
+		// - If defaults are enabled  => theme presets should not be overridden
+		// - If defaults are disabled => theme presets should be overridden
 		//
 		// For example, a theme sets defaultPalette to false,
 		// making the default palette hidden from the user.
@@ -1587,7 +1591,7 @@ class WP_Theme_JSON_Gutenberg {
 	private static function get_default_slugs( $data, $node_path ) {
 		$slugs = array();
 
-		foreach ( self::PRESETS_METADATA as $metadata ) {
+		foreach ( static::PRESETS_METADATA as $metadata ) {
 			$path   = array_merge( $node_path, $metadata['path'], array( 'default' ) );
 			$preset = _wp_array_get( $data, $path, null );
 			if ( ! isset( $preset ) ) {
@@ -1633,7 +1637,7 @@ class WP_Theme_JSON_Gutenberg {
 	 * Removes the preset values whose slug is equal to any of given slugs.
 	 *
 	 * @param array $node The node with the presets to validate.
-	 * @param array $slugs The slugs that should not be overriden.
+	 * @param array $slugs The slugs that should not be overridden.
 	 *
 	 * @return array The new node
 	 */
@@ -1718,7 +1722,7 @@ class WP_Theme_JSON_Gutenberg {
 	 */
 	private static function remove_insecure_settings( $input ) {
 		$output = array();
-		foreach ( self::PRESETS_METADATA as $preset_metadata ) {
+		foreach ( static::PRESETS_METADATA as $preset_metadata ) {
 			foreach ( self::VALID_ORIGINS as $origin ) {
 				$path_with_origin = array_merge( $preset_metadata['path'], array( $origin ) );
 				$presets          = _wp_array_get( $input, $path_with_origin, null );
@@ -1777,7 +1781,7 @@ class WP_Theme_JSON_Gutenberg {
 
 		foreach ( $declarations as $declaration ) {
 			if ( self::is_safe_css_declaration( $declaration['name'], $declaration['value'] ) ) {
-				$path = self::PROPERTIES_METADATA[ $declaration['name'] ];
+				$path = static::PROPERTIES_METADATA[ $declaration['name'] ];
 
 				// Check the value isn't an array before adding so as to not
 				// double up shorthand and longhand styles.
diff --git a/lib/compat/wordpress-5.9/class-wp-theme-json-resolver-gutenberg.php b/lib/compat/wordpress-5.9/class-wp-theme-json-resolver-gutenberg.php
index 022d5f0cf2..4ed51bc90b 100644
--- a/lib/compat/wordpress-5.9/class-wp-theme-json-resolver-gutenberg.php
+++ b/lib/compat/wordpress-5.9/class-wp-theme-json-resolver-gutenberg.php
@@ -22,28 +22,28 @@ class WP_Theme_JSON_Resolver_Gutenberg {
 	 *
 	 * @var WP_Theme_JSON_Gutenberg
 	 */
-	private static $core = null;
+	protected static $core = null;
 
 	/**
 	 * Container for data coming from the theme.
 	 *
 	 * @var WP_Theme_JSON_Gutenberg
 	 */
-	private static $theme = null;
+	protected static $theme = null;
 
 	/**
 	 * Whether or not the theme supports theme.json.
 	 *
 	 * @var bool
 	 */
-	private static $theme_has_support = null;
+	protected static $theme_has_support = null;
 
 	/**
 	 * Container for data coming from the user.
 	 *
 	 * @var WP_Theme_JSON_Gutenberg
 	 */
-	private static $user = null;
+	protected static $user = null;
 
 	/**
 	 * Stores the ID of the custom post type
@@ -51,14 +51,14 @@ class WP_Theme_JSON_Resolver_Gutenberg {
 	 *
 	 * @var integer
 	 */
-	private static $user_custom_post_type_id = null;
+	protected static $user_custom_post_type_id = null;
 
 	/**
 	 * Container to keep loaded i18n schema for `theme.json`.
 	 *
 	 * @var array
 	 */
-	private static $i18n_schema = null;
+	protected static $i18n_schema = null;
 
 	/**
 	 * Processes a file that adheres to the theme.json
@@ -68,7 +68,7 @@ class WP_Theme_JSON_Resolver_Gutenberg {
 	 * @param string $file_path Path to file. Empty if no file.
 	 * @return array Contents that adhere to the theme.json schema.
 	 */
-	private static function read_json_file( $file_path ) {
+	protected static function read_json_file( $file_path ) {
 		$config = array();
 		if ( $file_path ) {
 			$decoded_file = wp_json_file_decode( $file_path, array( 'associative' => true ) );
@@ -100,7 +100,7 @@ class WP_Theme_JSON_Resolver_Gutenberg {
 	 *                           Default 'default'.
 	 * @return array Returns the modified $theme_json_structure.
 	 */
-	private static function translate( $theme_json, $domain = 'default' ) {
+	protected static function translate( $theme_json, $domain = 'default' ) {
 		if ( null === self::$i18n_schema ) {
 			$i18n_schema       = wp_json_file_decode( __DIR__ . '/theme-i18n.json' );
 			self::$i18n_schema = null === $i18n_schema ? array() : $i18n_schema;
@@ -391,7 +391,7 @@ class WP_Theme_JSON_Resolver_Gutenberg {
 	 * @param bool   $template  Optional. Use template theme directory. Default false.
 	 * @return string The whole file path or empty if the file doesn't exist.
 	 */
-	private static function get_file_path_from_theme( $file_name, $template = false ) {
+	protected static function get_file_path_from_theme( $file_name, $template = false ) {
 		$path      = $template ? get_template_directory() : get_stylesheet_directory();
 		$candidate = $path . '/' . $file_name;
 
diff --git a/lib/compat/wordpress-6.0/class-wp-theme-json-gutenberg.php b/lib/compat/wordpress-6.0/class-wp-theme-json-gutenberg.php
new file mode 100644
index 0000000000..2a65bb82a7
--- /dev/null
+++ b/lib/compat/wordpress-6.0/class-wp-theme-json-gutenberg.php
@@ -0,0 +1,171 @@
+<?php
+/**
+ * WP_Theme_JSON_Gutenberg class
+ *
+ * @package gutenberg
+ */
+
+/**
+ * Class that encapsulates the processing of structures that adhere to the theme.json spec.
+ *
+ * This class is for internal core usage and is not supposed to be used by extenders (plugins and/or themes).
+ * This is a low-level API that may need to do breaking changes. Please,
+ * use get_global_settings, get_global_styles, and get_global_stylesheet instead.
+ *
+ * @access private
+ */
+class WP_Theme_JSON_Gutenberg extends WP_Theme_JSON_5_9 {
+	const PRESETS_METADATA = array(
+		array(
+			'path'              => array( 'color', 'palette' ),
+			'override'          => array( 'color', 'defaultPalette' ),
+			'use_default_names' => false,
+			'value_key'         => 'color',
+			'css_vars'          => '--wp--preset--color--$slug',
+			'classes'           => array(
+				'.has-$slug-color'               => 'color',
+				'.has-$slug-background-color'    => 'background-color',
+				'.has-$slug-border-color'        => 'border-color',
+				'.has-$slug-border-top-color'    => 'border-top-color',
+				'.has-$slug-border-right-color'  => 'border-right-color',
+				'.has-$slug-border-bottom-color' => 'border-bottom-color',
+				'.has-$slug-border-left-color'   => 'border-left-color',
+			),
+			'properties'        => array( 'color', 'background-color', 'border-color' ),
+		),
+		array(
+			'path'              => array( 'color', 'gradients' ),
+			'override'          => array( 'color', 'defaultGradients' ),
+			'use_default_names' => false,
+			'value_key'         => 'gradient',
+			'css_vars'          => '--wp--preset--gradient--$slug',
+			'classes'           => array( '.has-$slug-gradient-background' => 'background' ),
+			'properties'        => array( 'background' ),
+		),
+		array(
+			'path'              => array( 'color', 'duotone' ),
+			'override'          => true,
+			'use_default_names' => false,
+			'value_func'        => 'wp_render_duotone_filter_preset',
+			'css_vars'          => '--wp--preset--duotone--$slug',
+			'classes'           => array(),
+			'properties'        => array( 'filter' ),
+		),
+		array(
+			'path'              => array( 'typography', 'fontSizes' ),
+			'override'          => true,
+			'use_default_names' => true,
+			'value_key'         => 'size',
+			'css_vars'          => '--wp--preset--font-size--$slug',
+			'classes'           => array( '.has-$slug-font-size' => 'font-size' ),
+			'properties'        => array( 'font-size' ),
+		),
+		array(
+			'path'              => array( 'typography', 'fontFamilies' ),
+			'override'          => true,
+			'use_default_names' => false,
+			'value_key'         => 'fontFamily',
+			'css_vars'          => '--wp--preset--font-family--$slug',
+			'classes'           => array( '.has-$slug-font-family' => 'font-family' ),
+			'properties'        => array( 'font-family' ),
+		),
+	);
+
+	const PROPERTIES_METADATA = array(
+		'background'                 => array( 'color', 'gradient' ),
+		'background-color'           => array( 'color', 'background' ),
+		'border-radius'              => array( 'border', 'radius' ),
+		'border-top-left-radius'     => array( 'border', 'radius', 'topLeft' ),
+		'border-top-right-radius'    => array( 'border', 'radius', 'topRight' ),
+		'border-bottom-left-radius'  => array( 'border', 'radius', 'bottomLeft' ),
+		'border-bottom-right-radius' => array( 'border', 'radius', 'bottomRight' ),
+		'border-color'               => array( 'border', 'color' ),
+		'border-width'               => array( 'border', 'width' ),
+		'border-style'               => array( 'border', 'style' ),
+		'border-top-color'           => array( 'border', 'top', 'color' ),
+		'border-top-width'           => array( 'border', 'top', 'width' ),
+		'border-top-style'           => array( 'border', 'top', 'style' ),
+		'border-right-color'         => array( 'border', 'right', 'color' ),
+		'border-right-width'         => array( 'border', 'right', 'width' ),
+		'border-right-style'         => array( 'border', 'right', 'style' ),
+		'border-bottom-color'        => array( 'border', 'bottom', 'color' ),
+		'border-bottom-width'        => array( 'border', 'bottom', 'width' ),
+		'border-bottom-style'        => array( 'border', 'bottom', 'style' ),
+		'border-left-color'          => array( 'border', 'left', 'color' ),
+		'border-left-width'          => array( 'border', 'left', 'width' ),
+		'border-left-style'          => array( 'border', 'left', 'style' ),
+		'color'                      => array( 'color', 'text' ),
+		'font-family'                => array( 'typography', 'fontFamily' ),
+		'font-size'                  => array( 'typography', 'fontSize' ),
+		'font-style'                 => array( 'typography', 'fontStyle' ),
+		'font-weight'                => array( 'typography', 'fontWeight' ),
+		'letter-spacing'             => array( 'typography', 'letterSpacing' ),
+		'line-height'                => array( 'typography', 'lineHeight' ),
+		'margin'                     => array( 'spacing', 'margin' ),
+		'margin-top'                 => array( 'spacing', 'margin', 'top' ),
+		'margin-right'               => array( 'spacing', 'margin', 'right' ),
+		'margin-bottom'              => array( 'spacing', 'margin', 'bottom' ),
+		'margin-left'                => array( 'spacing', 'margin', 'left' ),
+		'padding'                    => array( 'spacing', 'padding' ),
+		'padding-top'                => array( 'spacing', 'padding', 'top' ),
+		'padding-right'              => array( 'spacing', 'padding', 'right' ),
+		'padding-bottom'             => array( 'spacing', 'padding', 'bottom' ),
+		'padding-left'               => array( 'spacing', 'padding', 'left' ),
+		'--wp--style--block-gap'     => array( 'spacing', 'blockGap' ),
+		'text-decoration'            => array( 'typography', 'textDecoration' ),
+		'text-transform'             => array( 'typography', 'textTransform' ),
+		'filter'                     => array( 'filter', 'duotone' ),
+	);
+
+	const VALID_STYLES = array(
+		'border'     => array(
+			'color'  => null,
+			'radius' => null,
+			'style'  => null,
+			'width'  => null,
+			'top'    => array(
+				'color' => null,
+				'style' => null,
+				'width' => null,
+			),
+			'right'  => array(
+				'color' => null,
+				'style' => null,
+				'width' => null,
+			),
+			'bottom' => array(
+				'color' => null,
+				'style' => null,
+				'width' => null,
+			),
+			'left'   => array(
+				'color' => null,
+				'style' => null,
+				'width' => null,
+			),
+		),
+		'color'      => array(
+			'background' => null,
+			'gradient'   => null,
+			'text'       => null,
+		),
+		'filter'     => array(
+			'duotone' => null,
+		),
+		'spacing'    => array(
+			'margin'   => null,
+			'padding'  => null,
+			'blockGap' => 'top',
+		),
+		'typography' => array(
+			'fontFamily'     => null,
+			'fontSize'       => null,
+			'fontStyle'      => null,
+			'fontWeight'     => null,
+			'letterSpacing'  => null,
+			'lineHeight'     => null,
+			'textDecoration' => null,
+			'textTransform'  => null,
+		),
+	);
+}
diff --git a/lib/load.php b/lib/load.php
index 7b62bd40d9..0d85cdf652 100644
--- a/lib/load.php
+++ b/lib/load.php
@@ -85,7 +85,7 @@ require __DIR__ . '/compat/wordpress-5.9/template-parts.php';
 require __DIR__ . '/compat/wordpress-5.9/theme-templates.php';
 require __DIR__ . '/editor-settings.php';
 require __DIR__ . '/compat/wordpress-5.9/class-wp-theme-json-schema-gutenberg.php';
-require __DIR__ . '/compat/wordpress-5.9/class-wp-theme-json-gutenberg.php';
+require __DIR__ . '/compat/wordpress-5.9/class-wp-theme-json-5-9.php';
 require __DIR__ . '/compat/wordpress-5.9/class-wp-theme-json-resolver-gutenberg.php';
 require __DIR__ . '/compat/wordpress-5.9/theme.php';
 require __DIR__ . '/compat/wordpress-5.9/admin-menu.php';
@@ -99,6 +99,7 @@ require __DIR__ . '/compat/wordpress-5.9/move-theme-editor-menu-item.php';
 require __DIR__ . '/compat/wordpress-6.0/post-lock.php';
 require __DIR__ . '/compat/wordpress-6.0/blocks.php';
 require __DIR__ . '/compat/wordpress-6.0/class-gutenberg-rest-global-styles-controller.php';
+require __DIR__ . '/compat/wordpress-6.0/class-wp-theme-json-gutenberg.php';
 require __DIR__ . '/compat/wordpress-6.0/rest-api.php';
 require __DIR__ . '/compat/experimental/blocks.php';
 

In addition, to allowing PRESETS_METADATA, PROPERTIES_METADATA, and VALID_STYLES arrays to be configured, we'll also need VALID_SETTINGS so that new block supports such as height and width can be added.

I can also see us needing to extend ELEMENTS, perhaps for example to add img.

@oandregal
Copy link
Member

oandregal commented Feb 9, 2022

Thanks for the tests, Aaron! I've prepared #38671 with the changes we need to backport to 5.9.1. The rest would need to be done in this PR.

aaronrobertshaw and others added 12 commits April 13, 2022 14:24
This change is approach was driven by a desire to not add any new block support related attributes and css classes. The prior implementation added a lot of additional CSS classes, bloated the block class lists, and would have needed migration and backwards compatibility support.

This new approach relies on being able to add inline styles with `var()` calls to use preset colors so switching themes still updates colors as expected and without the need to update blocks.

This approach is intended to be temporary until the new styles engine implements a cleaner result and the preset vars are required to be stored in the border color properties.
@bradhogan
Copy link

New borders working great on the columns block. Is there any reason why it's not available in the cover block? Any way to add that @aaronrobertshaw

@aaronrobertshaw
Copy link
Contributor Author

@bradley2083 I currently have an open PR (#31370) adding borders to the Cover block but there are some edge cases I'm trying to solve. Mainly the use of the resizable box in the editor causes some problems due to differences in box-sizing.

I'm hoping to have that PR updated later this afternoon. Feel free to follow progress on that and thanks for the feedback 👍

@bradhogan
Copy link

@aaronrobertshaw Sweet, thank you!

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 Needs User Documentation Needs new user documentation [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants