From 776face89c88d915e6d39e0f46e92b029da683a6 Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Wed, 1 Feb 2023 17:42:32 +1000 Subject: [PATCH 1/3] Avatar: Fix application of borders --- lib/block-supports/border.php | 54 +++++++++++++ packages/block-library/src/avatar/index.php | 75 +++---------------- packages/block-library/src/avatar/style.scss | 3 + .../src/post-featured-image/index.php | 43 +---------- 4 files changed, 69 insertions(+), 106 deletions(-) diff --git a/lib/block-supports/border.php b/lib/block-supports/border.php index 486f6d99b64890..15dfa0634771dd 100644 --- a/lib/block-supports/border.php +++ b/lib/block-supports/border.php @@ -154,6 +154,60 @@ function gutenberg_has_border_feature_support( $block_type, $feature, $default = return block_has_support( $block_type, array( '__experimentalBorder', $feature ), $default ); } +/** + * Generates CSS class names and styles to apply border support styles for + * blocks that skip serialization of the border block support. This is useful + * for dynamic blocks that need to apply the border classes and styles to an + * inner element. + * + * @param array $attributes The block attributes. + * @return array The border support classnames and styles for the block. + */ +function gutenberg_get_border_support_attributes( $attributes ) { + $border_styles = array(); + $sides = array( 'top', 'right', 'bottom', 'left' ); + + // Border radius. + if ( isset( $attributes['style']['border']['radius'] ) ) { + $border_styles['radius'] = $attributes['style']['border']['radius']; + } + + // Border style. + if ( isset( $attributes['style']['border']['style'] ) ) { + $border_styles['style'] = $attributes['style']['border']['style']; + } + + // Border width. + if ( isset( $attributes['style']['border']['width'] ) ) { + $border_styles['width'] = $attributes['style']['border']['width']; + } + + // Border color. + $preset_color = array_key_exists( 'borderColor', $attributes ) ? "var:preset|color|{$attributes['borderColor']}" : null; + $custom_color = _wp_array_get( $attributes, array( 'style', 'border', 'color' ), null ); + $border_styles['color'] = $preset_color ? $preset_color : $custom_color; + + // Individual border styles e.g. top, left etc. + foreach ( $sides as $side ) { + $border = _wp_array_get( $attributes, array( 'style', 'border', $side ), null ); + $border_styles[ $side ] = array( + 'color' => isset( $border['color'] ) ? $border['color'] : null, + 'style' => isset( $border['style'] ) ? $border['style'] : null, + 'width' => isset( $border['width'] ) ? $border['width'] : null, + ); + } + + $styles = wp_style_engine_get_styles( array( 'border' => $border_styles ) ); + $attributes = array(); + if ( ! empty( $styles['classnames'] ) ) { + $attributes['class'] = $styles['classnames']; + } + if ( ! empty( $styles['css'] ) ) { + $attributes['style'] = $styles['css']; + } + return $attributes; +} + // Register the block support. WP_Block_Supports::get_instance()->register( 'border', diff --git a/packages/block-library/src/avatar/index.php b/packages/block-library/src/avatar/index.php index 25f3ad88dcbab6..e4ef2b210f19e6 100644 --- a/packages/block-library/src/avatar/index.php +++ b/packages/block-library/src/avatar/index.php @@ -16,67 +16,14 @@ function render_block_core_avatar( $attributes, $content, $block ) { $size = isset( $attributes['size'] ) ? $attributes['size'] : 96; $wrapper_attributes = get_block_wrapper_attributes(); + $border_attributes = gutenberg_get_border_support_attributes( $attributes ); - $image_styles = array(); - - // Add border width styles. - $has_border_width = ! empty( $attributes['style']['border']['width'] ); - - if ( $has_border_width ) { - $border_width = $attributes['style']['border']['width']; - $image_styles[] = sprintf( 'border-width: %s;', esc_attr( $border_width ) ); - } - - // Add border radius styles. - $has_border_radius = ! empty( $attributes['style']['border']['radius'] ); - - if ( $has_border_radius ) { - $border_radius = $attributes['style']['border']['radius']; - - if ( is_array( $border_radius ) ) { - // Apply styles for individual corner border radii. - foreach ( $border_radius as $key => $value ) { - if ( null !== $value ) { - $name = _wp_to_kebab_case( $key ); - // Add shared styles for individual border radii. - $border_style = sprintf( - 'border-%s-radius: %s;', - esc_attr( $name ), - esc_attr( $value ) - ); - $image_styles[] = $border_style; - } - } - } else { - $border_style = sprintf( 'border-radius: %s;', esc_attr( $border_radius ) ); - $image_styles[] = $border_style; - } - } - - // Add border color styles. - $has_border_color = ! empty( $attributes['style']['border']['color'] ); - - if ( $has_border_color ) { - $border_color = $attributes['style']['border']['color']; - $image_styles[] = sprintf( 'border-color: %s;', esc_attr( $border_color ) ); - } - - // Add border style (solid, dashed, dotted ). - $has_border_style = ! empty( $attributes['style']['border']['style'] ); - - if ( $has_border_style ) { - $border_style = $attributes['style']['border']['style']; - $image_styles[] = sprintf( 'border-style: %s;', esc_attr( $border_style ) ); - } - - // Add border classes to the avatar image for both custom colors and palette colors. - $image_classes = ''; - if ( $has_border_color || isset( $attributes['borderColor'] ) ) { - $image_classes .= 'has-border-color'; - } - if ( isset( $attributes['borderColor'] ) ) { - $image_classes .= ' has-' . $attributes['borderColor'] . '-border-color'; - } + $image_classes = ! empty( $border_attributes['class'] ) + ? "wp-block-avatar__image {$border_attributes['class']}" + : 'wp-block-avatar__image'; + $image_styles = ! empty( $border_attributes['style'] ) + ? sprintf( ' style="%s"', safecss_filter_attr( $border_attributes['style'] ) ) + : ''; if ( ! isset( $block->context['commentId'] ) ) { $author_id = isset( $attributes['userId'] ) ? $attributes['userId'] : get_post_field( 'post_author', $block->context['postId'] ); @@ -89,8 +36,8 @@ function render_block_core_avatar( $attributes, $content, $block ) { '', $alt, array( - 'extra_attr' => isset( $image_styles ) ? sprintf( ' style="%s"', safecss_filter_attr( implode( ' ', $image_styles ) ) ) : '', - 'class' => "wp-block-avatar__image $image_classes ", + 'extra_attr' => $image_styles, + 'class' => $image_classes, ) ); if ( isset( $attributes['isLink'] ) && $attributes['isLink'] ) { @@ -116,8 +63,8 @@ function render_block_core_avatar( $attributes, $content, $block ) { '', $alt, array( - 'extra_attr' => isset( $image_styles ) ? sprintf( ' style="%s"', safecss_filter_attr( implode( ' ', $image_styles ) ) ) : '', - 'class' => "wp-block-avatar__image $image_classes", + 'extra_attr' => $image_styles, + 'class' => $image_classes, ) ); if ( isset( $attributes['isLink'] ) && $attributes['isLink'] && isset( $comment->comment_author_url ) && '' !== $comment->comment_author_url ) { diff --git a/packages/block-library/src/avatar/style.scss b/packages/block-library/src/avatar/style.scss index 1939b86b52d166..1f1bd7c97e8426 100644 --- a/packages/block-library/src/avatar/style.scss +++ b/packages/block-library/src/avatar/style.scss @@ -1,6 +1,9 @@ .wp-block-avatar { // This block has customizable padding, border-box makes that more predictable. box-sizing: border-box; + img { + box-sizing: border-box; + } &.aligncenter { text-align: center; diff --git a/packages/block-library/src/post-featured-image/index.php b/packages/block-library/src/post-featured-image/index.php index 8da66accd3032c..ec96c2e01a25e4 100644 --- a/packages/block-library/src/post-featured-image/index.php +++ b/packages/block-library/src/post-featured-image/index.php @@ -154,48 +154,7 @@ function get_block_core_post_featured_image_overlay_element_markup( $attributes * @return array The border-related classnames and styles for the block. */ function get_block_core_post_featured_image_border_attributes( $attributes ) { - $border_styles = array(); - $sides = array( 'top', 'right', 'bottom', 'left' ); - - // Border radius. - if ( isset( $attributes['style']['border']['radius'] ) ) { - $border_styles['radius'] = $attributes['style']['border']['radius']; - } - - // Border style. - if ( isset( $attributes['style']['border']['style'] ) ) { - $border_styles['style'] = $attributes['style']['border']['style']; - } - - // Border width. - if ( isset( $attributes['style']['border']['width'] ) ) { - $border_styles['width'] = $attributes['style']['border']['width']; - } - - // Border color. - $preset_color = array_key_exists( 'borderColor', $attributes ) ? "var:preset|color|{$attributes['borderColor']}" : null; - $custom_color = _wp_array_get( $attributes, array( 'style', 'border', 'color' ), null ); - $border_styles['color'] = $preset_color ? $preset_color : $custom_color; - - // Individual border styles e.g. top, left etc. - foreach ( $sides as $side ) { - $border = _wp_array_get( $attributes, array( 'style', 'border', $side ), null ); - $border_styles[ $side ] = array( - 'color' => isset( $border['color'] ) ? $border['color'] : null, - 'style' => isset( $border['style'] ) ? $border['style'] : null, - 'width' => isset( $border['width'] ) ? $border['width'] : null, - ); - } - - $styles = wp_style_engine_get_styles( array( 'border' => $border_styles ) ); - $attributes = array(); - if ( ! empty( $styles['classnames'] ) ) { - $attributes['class'] = $styles['classnames']; - } - if ( ! empty( $styles['css'] ) ) { - $attributes['style'] = $styles['css']; - } - return $attributes; + return gutenberg_get_border_support_attributes( $attributes ); } /** From 83686bbd1bdc8de338c3c51280b848dea9eb69cc Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Thu, 2 Feb 2023 11:57:35 +1000 Subject: [PATCH 2/3] Avoid use of gutenberg prefix in block-library --- lib/block-supports/border.php | 54 ------------------- packages/block-library/src/avatar/index.php | 54 ++++++++++++++++++- .../src/post-featured-image/index.php | 43 ++++++++++++++- 3 files changed, 95 insertions(+), 56 deletions(-) diff --git a/lib/block-supports/border.php b/lib/block-supports/border.php index 15dfa0634771dd..486f6d99b64890 100644 --- a/lib/block-supports/border.php +++ b/lib/block-supports/border.php @@ -154,60 +154,6 @@ function gutenberg_has_border_feature_support( $block_type, $feature, $default = return block_has_support( $block_type, array( '__experimentalBorder', $feature ), $default ); } -/** - * Generates CSS class names and styles to apply border support styles for - * blocks that skip serialization of the border block support. This is useful - * for dynamic blocks that need to apply the border classes and styles to an - * inner element. - * - * @param array $attributes The block attributes. - * @return array The border support classnames and styles for the block. - */ -function gutenberg_get_border_support_attributes( $attributes ) { - $border_styles = array(); - $sides = array( 'top', 'right', 'bottom', 'left' ); - - // Border radius. - if ( isset( $attributes['style']['border']['radius'] ) ) { - $border_styles['radius'] = $attributes['style']['border']['radius']; - } - - // Border style. - if ( isset( $attributes['style']['border']['style'] ) ) { - $border_styles['style'] = $attributes['style']['border']['style']; - } - - // Border width. - if ( isset( $attributes['style']['border']['width'] ) ) { - $border_styles['width'] = $attributes['style']['border']['width']; - } - - // Border color. - $preset_color = array_key_exists( 'borderColor', $attributes ) ? "var:preset|color|{$attributes['borderColor']}" : null; - $custom_color = _wp_array_get( $attributes, array( 'style', 'border', 'color' ), null ); - $border_styles['color'] = $preset_color ? $preset_color : $custom_color; - - // Individual border styles e.g. top, left etc. - foreach ( $sides as $side ) { - $border = _wp_array_get( $attributes, array( 'style', 'border', $side ), null ); - $border_styles[ $side ] = array( - 'color' => isset( $border['color'] ) ? $border['color'] : null, - 'style' => isset( $border['style'] ) ? $border['style'] : null, - 'width' => isset( $border['width'] ) ? $border['width'] : null, - ); - } - - $styles = wp_style_engine_get_styles( array( 'border' => $border_styles ) ); - $attributes = array(); - if ( ! empty( $styles['classnames'] ) ) { - $attributes['class'] = $styles['classnames']; - } - if ( ! empty( $styles['css'] ) ) { - $attributes['style'] = $styles['css']; - } - return $attributes; -} - // Register the block support. WP_Block_Supports::get_instance()->register( 'border', diff --git a/packages/block-library/src/avatar/index.php b/packages/block-library/src/avatar/index.php index e4ef2b210f19e6..2af3821096405b 100644 --- a/packages/block-library/src/avatar/index.php +++ b/packages/block-library/src/avatar/index.php @@ -16,7 +16,7 @@ function render_block_core_avatar( $attributes, $content, $block ) { $size = isset( $attributes['size'] ) ? $attributes['size'] : 96; $wrapper_attributes = get_block_wrapper_attributes(); - $border_attributes = gutenberg_get_border_support_attributes( $attributes ); + $border_attributes = get_block_core_avatar_border_attributes( $attributes ); $image_classes = ! empty( $border_attributes['class'] ) ? "wp-block-avatar__image {$border_attributes['class']}" @@ -79,6 +79,58 @@ function render_block_core_avatar( $attributes, $content, $block ) { return sprintf( '
%2s
', $wrapper_attributes, $avatar_block ); } +/** + * Generates class names and styles to apply the border support styles for + * the Avatar block. + * + * @param array $attributes The block attributes. + * @return array The border-related classnames and styles for the block. + */ +function get_block_core_avatar_border_attributes( $attributes ) { + $border_styles = array(); + $sides = array( 'top', 'right', 'bottom', 'left' ); + + // Border radius. + if ( isset( $attributes['style']['border']['radius'] ) ) { + $border_styles['radius'] = $attributes['style']['border']['radius']; + } + + // Border style. + if ( isset( $attributes['style']['border']['style'] ) ) { + $border_styles['style'] = $attributes['style']['border']['style']; + } + + // Border width. + if ( isset( $attributes['style']['border']['width'] ) ) { + $border_styles['width'] = $attributes['style']['border']['width']; + } + + // Border color. + $preset_color = array_key_exists( 'borderColor', $attributes ) ? "var:preset|color|{$attributes['borderColor']}" : null; + $custom_color = _wp_array_get( $attributes, array( 'style', 'border', 'color' ), null ); + $border_styles['color'] = $preset_color ? $preset_color : $custom_color; + + // Individual border styles e.g. top, left etc. + foreach ( $sides as $side ) { + $border = _wp_array_get( $attributes, array( 'style', 'border', $side ), null ); + $border_styles[ $side ] = array( + 'color' => isset( $border['color'] ) ? $border['color'] : null, + 'style' => isset( $border['style'] ) ? $border['style'] : null, + 'width' => isset( $border['width'] ) ? $border['width'] : null, + ); + } + + $styles = wp_style_engine_get_styles( array( 'border' => $border_styles ) ); + $attributes = array(); + if ( ! empty( $styles['classnames'] ) ) { + $attributes['class'] = $styles['classnames']; + } + if ( ! empty( $styles['css'] ) ) { + $attributes['style'] = $styles['css']; + } + return $attributes; +} + /** * Registers the `core/avatar` block on the server. */ diff --git a/packages/block-library/src/post-featured-image/index.php b/packages/block-library/src/post-featured-image/index.php index ec96c2e01a25e4..8da66accd3032c 100644 --- a/packages/block-library/src/post-featured-image/index.php +++ b/packages/block-library/src/post-featured-image/index.php @@ -154,7 +154,48 @@ function get_block_core_post_featured_image_overlay_element_markup( $attributes * @return array The border-related classnames and styles for the block. */ function get_block_core_post_featured_image_border_attributes( $attributes ) { - return gutenberg_get_border_support_attributes( $attributes ); + $border_styles = array(); + $sides = array( 'top', 'right', 'bottom', 'left' ); + + // Border radius. + if ( isset( $attributes['style']['border']['radius'] ) ) { + $border_styles['radius'] = $attributes['style']['border']['radius']; + } + + // Border style. + if ( isset( $attributes['style']['border']['style'] ) ) { + $border_styles['style'] = $attributes['style']['border']['style']; + } + + // Border width. + if ( isset( $attributes['style']['border']['width'] ) ) { + $border_styles['width'] = $attributes['style']['border']['width']; + } + + // Border color. + $preset_color = array_key_exists( 'borderColor', $attributes ) ? "var:preset|color|{$attributes['borderColor']}" : null; + $custom_color = _wp_array_get( $attributes, array( 'style', 'border', 'color' ), null ); + $border_styles['color'] = $preset_color ? $preset_color : $custom_color; + + // Individual border styles e.g. top, left etc. + foreach ( $sides as $side ) { + $border = _wp_array_get( $attributes, array( 'style', 'border', $side ), null ); + $border_styles[ $side ] = array( + 'color' => isset( $border['color'] ) ? $border['color'] : null, + 'style' => isset( $border['style'] ) ? $border['style'] : null, + 'width' => isset( $border['width'] ) ? $border['width'] : null, + ); + } + + $styles = wp_style_engine_get_styles( array( 'border' => $border_styles ) ); + $attributes = array(); + if ( ! empty( $styles['classnames'] ) ) { + $attributes['class'] = $styles['classnames']; + } + if ( ! empty( $styles['css'] ) ) { + $attributes['style'] = $styles['css']; + } + return $attributes; } /** From 5fed75db0dfa679b5ef9adace62515f20f37dd9e Mon Sep 17 00:00:00 2001 From: Aaron Robertshaw <60436221+aaronrobertshaw@users.noreply.github.com> Date: Thu, 2 Feb 2023 14:19:11 +1000 Subject: [PATCH 3/3] Improve escaping of border styles --- packages/block-library/src/avatar/index.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/avatar/index.php b/packages/block-library/src/avatar/index.php index 2af3821096405b..1566fe6edfebc3 100644 --- a/packages/block-library/src/avatar/index.php +++ b/packages/block-library/src/avatar/index.php @@ -18,11 +18,16 @@ function render_block_core_avatar( $attributes, $content, $block ) { $wrapper_attributes = get_block_wrapper_attributes(); $border_attributes = get_block_core_avatar_border_attributes( $attributes ); + // Class gets passed through `esc_attr` via `get_avatar`. $image_classes = ! empty( $border_attributes['class'] ) ? "wp-block-avatar__image {$border_attributes['class']}" : 'wp-block-avatar__image'; - $image_styles = ! empty( $border_attributes['style'] ) - ? sprintf( ' style="%s"', safecss_filter_attr( $border_attributes['style'] ) ) + + // Unlike class, `get_avatar` doesn't filter the styles via `esc_attr`. + // The style engine does pass the border styles through + // `safecss_filter_attr` however. + $image_styles = ! empty( $border_attributes['style'] ) + ? sprintf( ' style="%s"', esc_attr( $border_attributes['style'] ) ) : ''; if ( ! isset( $block->context['commentId'] ) ) {