Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions src/wp-includes/block-supports/background.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ function wp_register_background_support( $block_type ) {
* @since 6.6.0 Removed requirement for `backgroundImage.source`. A file/url is the default.
* @since 6.7.0 Added support for `backgroundAttachment` output.
* @since 7.1.0 Added support for `background.gradient` output.
* @since 7.2.0 Added support for `background.backgroundClip` output.
*
* @access private
*
Expand All @@ -56,9 +57,10 @@ function wp_render_background_support( $block_content, $block ) {
$block_attributes = ( isset( $block['attrs'] ) && is_array( $block['attrs'] ) ) ? $block['attrs'] : array();
$has_background_image_support = block_has_support( $block_type, array( 'background', 'backgroundImage' ), false );
$has_background_gradient_support = block_has_support( $block_type, array( 'background', 'gradient' ), false );
$has_background_clip_support = block_has_support( $block_type, array( 'background', 'backgroundClip' ), false );

if (
( ! $has_background_image_support && ! $has_background_gradient_support ) ||
( ! $has_background_image_support && ! $has_background_gradient_support && ! $has_background_clip_support ) ||
! isset( $block_attributes['style']['background'] )
) {
return $block_content;
Expand All @@ -67,8 +69,9 @@ function wp_render_background_support( $block_content, $block ) {
// Check serialization skip for each feature individually.
$skip_background_image = ! $has_background_image_support || wp_should_skip_block_supports_serialization( $block_type, 'background', 'backgroundImage' );
$skip_background_gradient = ! $has_background_gradient_support || wp_should_skip_block_supports_serialization( $block_type, 'background', 'gradient' );
$skip_background_clip = ! $has_background_clip_support || wp_should_skip_block_supports_serialization( $block_type, 'background', 'backgroundClip' );

if ( $skip_background_image && $skip_background_gradient ) {
if ( $skip_background_image && $skip_background_gradient && $skip_background_clip ) {
return $block_content;
}

Expand All @@ -95,6 +98,10 @@ function wp_render_background_support( $block_content, $block ) {
$background_styles['gradient'] = $block_attributes['style']['background']['gradient'] ?? null;
}

if ( ! $skip_background_clip ) {
$background_styles['backgroundClip'] = $block_attributes['style']['background']['backgroundClip'] ?? null;
}

$styles = wp_style_engine_get_styles( array( 'background' => $background_styles ) );

if ( ! empty( $styles['css'] ) ) {
Expand All @@ -111,7 +118,17 @@ function wp_render_background_support( $block_content, $block ) {
}

$tags->set_attribute( 'style', $updated_style );
$tags->add_class( 'has-background' );

/*
* A background clipped to the text paints the text rather than the
* block's background, so the block has no background to announce.
*/
$is_text_clip = isset( $block_attributes['style']['background']['backgroundClip'] )
&& 'text' === $block_attributes['style']['background']['backgroundClip'];

if ( ! $is_text_clip ) {
$tags->add_class( 'has-background' );
}
}

return $tags->get_updated_html();
Expand Down
33 changes: 33 additions & 0 deletions src/wp-includes/class-wp-theme-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ class WP_Theme_JSON {
* @since 7.0.0 Added `dimensions.width` and `dimensions.height`.
* Added `text-indent` property.
* @since 7.1.0 Added `min-width` and `text-shadow`.
* @since 7.2.0 Added `background-clip`.
* @var array
*/
const PROPERTIES_METADATA = array(
Expand All @@ -260,6 +261,7 @@ class WP_Theme_JSON {
'background-repeat' => array( 'background', 'backgroundRepeat' ),
'background-size' => array( 'background', 'backgroundSize' ),
'background-attachment' => array( 'background', 'backgroundAttachment' ),
'background-clip' => array( 'background', 'backgroundClip' ),
'border-radius' => array( 'border', 'radius' ),
'border-top-left-radius' => array( 'border', 'radius', 'topLeft' ),
'border-top-right-radius' => array( 'border', 'radius', 'topRight' ),
Expand Down Expand Up @@ -418,13 +420,15 @@ class WP_Theme_JSON {
* Added support for `dimensions.width` and `dimensions.height`.
* Added support for `typography.textIndent`.
* @since 7.1.0 Added `viewport` property.
* @since 7.2.0 Added `background.backgroundClip` property.
* Added support for `background.gradient`, `dimensions.minWidth` and `blockVisibility.allowEditing`.
* @var array
*/
const VALID_SETTINGS = array(
'appearanceTools' => null,
'useRootPaddingAwareAlignments' => null,
'background' => array(
'backgroundClip' => null,
'backgroundImage' => null,
'backgroundSize' => null,
'gradient' => null,
Expand Down Expand Up @@ -567,10 +571,12 @@ class WP_Theme_JSON {
* @since 7.0.0 Added support for `dimensions.width` and `dimensions.height`.
* @since 7.1.0 Added support for `background.gradient`,`dimensions.minWidth`,
* and `typography.textShadow`.
* @since 7.2.0 Added support for `background.backgroundClip`.
* @var array
*/
const VALID_STYLES = array(
'background' => array(
'backgroundClip' => null,
'backgroundImage' => null,
'backgroundPosition' => null,
'backgroundRepeat' => null,
Expand Down Expand Up @@ -3118,6 +3124,33 @@ protected static function compute_style_properties( $styles, $settings = array()
'name' => $css_property,
'value' => $value,
);

/*
* Background clipping needs vendor prefixed properties for
* cross-browser support. The `text` value clips the background to
* the text and makes it visible through a transparent fill. The box
* values only reset the fill color, to cancel any inherited text
* clipping. `-webkit-background-clip` is an alias of
* `background-clip` in Chromium, so resetting it would discard the
* value set above.
*/
if ( 'background-clip' === $css_property ) {
if ( 'text' === $value ) {
$declarations[] = array(
'name' => '-webkit-background-clip',
'value' => 'text',
);
$declarations[] = array(
'name' => '-webkit-text-fill-color',
'value' => 'transparent',
);
} else {
$declarations[] = array(
'name' => '-webkit-text-fill-color',
'value' => 'unset',
);
}
}
}

// If a variable value is added to the root, the corresponding property should be removed.
Expand Down
5 changes: 5 additions & 0 deletions src/wp-includes/kses.php
Original file line number Diff line number Diff line change
Expand Up @@ -2637,6 +2637,7 @@ function kses_init() {
* @since 6.6.0 Added support for `grid-column`, `grid-row`, and `container-type`.
* @since 6.9.0 Added support for `white-space`.
* @since 7.1.0 Extended gradient support to allow any single-level nested function.
* @since 7.2.0 Added support for `background-clip`.
* Added support for transform functions, `clip-path` basic shapes,
* and URLs in the SVG element reference properties.
*
Expand All @@ -2662,6 +2663,7 @@ function safecss_filter_attr( $css, $deprecated = '' ) {
*
* @since 2.8.1
* @since 7.1.0 Added support for SVG presentation attributes.
* @since 7.2.0 Added support for `background-clip` and its vendor prefixed companions.
*
* @param string[] $attr Array of allowed CSS attributes.
*/
Expand All @@ -2676,6 +2678,9 @@ function safecss_filter_attr( $css, $deprecated = '' ) {
'background-size',
'background-attachment',
'background-blend-mode',
'background-clip',
'-webkit-background-clip',
'-webkit-text-fill-color',

'border',
'border-radius',
Expand Down
92 changes: 83 additions & 9 deletions src/wp-includes/style-engine/class-wp-style-engine.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ final class WP_Style_Engine {
*
* @since 6.1.0
* @since 7.1.0 Added `background.gradient` property.
* @since 7.2.0 Added `background.backgroundClip` property.
* @var array
*/
const BLOCK_STYLE_DEFINITIONS_METADATA = array(
Expand Down Expand Up @@ -96,6 +97,10 @@ final class WP_Style_Engine {
'has-background' => true,
),
),
'backgroundClip' => array(
'value_func' => array( self::class, 'get_background_clip_css_declarations' ),
'path' => array( 'background', 'backgroundClip' ),
),
),
'color' => array(
'text' => array(
Expand Down Expand Up @@ -125,17 +130,14 @@ final class WP_Style_Engine {
),
),
'gradient' => array(
'property_keys' => array(
'property_keys' => array(
'default' => 'background',
),
'path' => array( 'color', 'gradient' ),
'css_vars' => array(
'css_vars' => array(
'gradient' => '--wp--preset--gradient--$slug',
),
'classnames' => array(
'has-background' => true,
'has-$slug-gradient-background' => 'gradient',
),
'path' => array( 'color', 'gradient' ),
'classnames_func' => array( self::class, 'get_gradient_classnames' ),
),
),
'border' => array(
Expand Down Expand Up @@ -513,7 +515,7 @@ public static function parse_block_styles( $block_styles, $options ) {
continue;
}

$classnames = static::get_classnames( $style_value, $style_definition );
$classnames = static::get_classnames( $style_value, $style_definition, $options );
if ( ! empty( $classnames ) ) {
$parsed_styles['classnames'] = array_merge( $parsed_styles['classnames'], $classnames );
}
Expand All @@ -540,17 +542,23 @@ public static function parse_block_styles( $block_styles, $options ) {
* e.g. `var:preset|<PRESET_TYPE>|<PRESET_SLUG>`.
*
* @since 6.1.0
* @since 7.2.0 Added the `$options` parameter and support for `classnames_func`.
*
* @param string $style_value A single raw style value or CSS preset property
* from the `$block_styles` array.
* @param array $style_definition A single style definition from BLOCK_STYLE_DEFINITIONS_METADATA.
* @param array $options Optional. An array of options. Default empty array.
* @return string[] An array of CSS classnames, or empty array if there are none.
*/
protected static function get_classnames( $style_value, $style_definition ) {
protected static function get_classnames( $style_value, $style_definition, $options = array() ) {
if ( empty( $style_value ) ) {
return array();
}

if ( isset( $style_definition['classnames_func'] ) && is_callable( $style_definition['classnames_func'] ) ) {
return call_user_func( $style_definition['classnames_func'], $style_value, $style_definition, $options );
}

$classnames = array();
if ( ! empty( $style_definition['classnames'] ) ) {
foreach ( $style_definition['classnames'] as $classname => $property_key ) {
Expand Down Expand Up @@ -755,6 +763,72 @@ protected static function get_url_or_value_css_declaration( $style_value, $style
return $css_declarations;
}

/**
* Style value parser that returns the CSS declarations for background clipping.
*
* For the `text` value the background is clipped to the block's text, which
* requires the vendor prefixed properties and a transparent fill color. For
* the box values only the fill color is reset, to cancel any inherited text
* clipping. `-webkit-background-clip` is an alias of `background-clip` in
* Chromium, so resetting it there would discard the value set above.
*
* @since 7.2.0
*
* @param string $style_value A single raw style value from $block_styles array.
* @param array $style_definition A single style definition from BLOCK_STYLE_DEFINITIONS_METADATA.
* @return string[] An associative array of CSS definitions, e.g., array( "$property" => "$value", "$property" => "$value" ).
*/
protected static function get_background_clip_css_declarations( $style_value, $style_definition ) {
if ( empty( $style_value ) || ! is_string( $style_value ) ) {
return array();
}

$valid_values = array( 'border-box', 'padding-box', 'content-box', 'text' );

if ( ! in_array( $style_value, $valid_values, true ) ) {
return array();
}

$css_declarations = array(
'background-clip' => $style_value,
);

if ( 'text' === $style_value ) {
$css_declarations['-webkit-background-clip'] = 'text';
$css_declarations['-webkit-text-fill-color'] = 'transparent';
} else {
$css_declarations['-webkit-text-fill-color'] = 'unset';
}

return $css_declarations;
}

/**
* Returns the classnames for a gradient value.
*
* @since 7.2.0
*
* @param string $style_value The gradient style value.
* @param array $style_definition A single style definition from BLOCK_STYLE_DEFINITIONS_METADATA.
* @param array $options Optional. An array of options. Default empty array.
* @return string[] An array of CSS classnames, or empty array if there are none.
*/
protected static function get_gradient_classnames( $style_value, $style_definition, $options = array() ) {
if ( empty( $style_value ) ) {
return array();
}

$classnames = array( 'has-background' );

$slug = static::get_slug_from_preset_value( $style_value, 'gradient' );

if ( $slug ) {
$classnames[] = "has-{$slug}-gradient-background";
}

return $classnames;
}

/**
* Returns compiled CSS from CSS declarations.
*
Expand Down
Loading
Loading