-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Conversation
Size Change: +2.42 kB (0%) Total Size: 1.23 MB
ℹ️ View Unchanged
|
776891f
to
a650d77
Compare
10790d4
to
a14ebcf
Compare
a14ebcf
to
eb2e4b5
Compare
5d067c2
to
7be6d5d
Compare
6878b94
to
b44a979
Compare
@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 Prior to it landing in 5.9 we essentially had this class in the I'm not convinced the proposed changes required by this PR are ready for core as they could well change. |
The current PR seem to impact only the block supports which are out of the That said, if you want to change |
Thanks for the extra info @youknowriad
I omitted the changes to This is what I was attempting to convey in the PR description as quoted below:
Given the required changes to 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 cc/ @ramonjd |
7552f9d
to
f0506b9
Compare
4622e91
to
6325458
Compare
@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) |
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.
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 For the latter example, I'm seeing the use of prefixes I'm starting off naively and tested by copying over
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. |
6325458
to
2b01eb8
Compare
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 PRdiff --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 I can also see us needing to extend |
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. |
Co-authored-by: Ramon <ramonjd@users.noreply.github.com>
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.
ee1573a
to
ea485d5
Compare
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 |
@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 👍 |
@aaronrobertshaw Sweet, thank you! |
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?
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
BorderBoxControl
in the inspector controls sidebarScreenshots
Screen.Recording.2022-03-30.at.7.53.27.pm.mp4
Types of changes
Enhancement.
Checklist:
*.native.js
files for terms that need renaming or removal).