Skip to content

Commit

Permalink
Make duotone selectors fallback and be scoped
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronrobertshaw committed Mar 29, 2023
1 parent 52953c7 commit 520ea49
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 63 deletions.
84 changes: 47 additions & 37 deletions lib/compat/wordpress-6.3/get-global-styles-and-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,7 @@ function wp_get_block_css_selector( $block_type, $target = 'root', $fallback = f

$has_selectors = ! empty( $block_type->selectors );

// Duotone (No fallback selectors for Duotone).
if ( 'filter.duotone' === $target || array( 'filter', 'duotone' ) === $target ) {
// If selectors API in use, only use it's value or null.
if ( $has_selectors ) {
return _wp_array_get( $block_type->selectors, array( 'filter', 'duotone' ), null );
}

// Selectors API, not available, check for old experimental selector.
return _wp_array_get( $block_type->supports, array( 'color', '__experimentalDuotone' ), null );
}

// Root Selector.

// Calculated before returning as it can be used as fallback for
// feature selectors later on.
// Root Selector ( can be used as a fallback ).
$root_selector = null;

if ( $has_selectors && isset( $block_type->selectors['root'] ) ) {
Expand All @@ -59,16 +45,58 @@ function wp_get_block_css_selector( $block_type, $target = 'root', $fallback = f
return $root_selector;
}

$fallback_selector = $fallback ? $root_selector : null;

// Helper to scope old experimental selectors.
$scope_selector = function( $scope, $selector ) {
$scopes = explode( ',', $scope );
$selectors = explode( ',', $selector );

$selectors_scoped = array();
foreach ( $scopes as $outer ) {
foreach ( $selectors as $inner ) {
$outer = trim( $outer );
$inner = trim( $inner );
if ( ! empty( $outer ) && ! empty( $inner ) ) {
$selectors_scoped[] = $outer . ' ' . $inner;
} elseif ( empty( $outer ) ) {
$selectors_scoped[] = $inner;
} elseif ( empty( $inner ) ) {
$selectors_scoped[] = $outer;
}
}
}

return implode( ', ', $selectors_scoped );
};

// Duotone ( may fallback to root selector ).
if ( 'filter.duotone' === $target || array( 'filter', 'duotone' ) === $target ) {
// If selectors API in use, only use it's value, fallback, or null.
if ( $has_selectors ) {
return _wp_array_get( $block_type->selectors, array( 'filter', 'duotone' ), $fallback_selector );
}

// Selectors API, not available, check for old experimental selector.
$duotone_selector = _wp_array_get( $block_type->supports, array( 'color', '__experimentalDuotone' ), null );

// Nothing to work with, provide fallback or null.
if ( null === $duotone_selector ) {
return $fallback_selector;
}

// Scope the duotone selector by the block's root selector.
return $scope_selector( $root_selector, $duotone_selector );
}

// If target is not `root` or `duotone` we have a feature or subfeature
// as the target. If the target is a string convert to an array.
if ( is_string( $target ) ) {
$target = explode( '.', $target );
}

// Feature Selectors ( May fallback to root selector ).
// Feature Selectors ( may fallback to root selector ).
if ( 1 === count( $target ) ) {
$fallback_selector = $fallback ? $root_selector : null;

// Prefer the selectors API if available.
if ( $has_selectors ) {
// Look for selector under `feature.root`.
Expand All @@ -95,25 +123,7 @@ function wp_get_block_css_selector( $block_type, $target = 'root', $fallback = f
}

// Scope the feature selector by the block's root selector.
$scopes = explode( ',', $root_selector );
$selectors = explode( ',', $feature_selector );

$selectors_scoped = array();
foreach ( $scopes as $outer ) {
foreach ( $selectors as $inner ) {
$outer = trim( $outer );
$inner = trim( $inner );
if ( ! empty( $outer ) && ! empty( $inner ) ) {
$selectors_scoped[] = $outer . ' ' . $inner;
} elseif ( empty( $outer ) ) {
$selectors_scoped[] = $inner;
} elseif ( empty( $inner ) ) {
$selectors_scoped[] = $outer;
}
}
}

return implode( ', ', $selectors_scoped );
return $scope_selector( $root_selector, $feature_selector );
}

// Subfeature selector
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,7 @@ export function getBlockCSSSelector(
const hasSelectors = ! isEmpty( selectors );
const path = Array.isArray( target ) ? target.join( '.' ) : target;

// Duotone ( no fallback selectors for Duotone ).
if ( path === 'filter.duotone' ) {
// If selectors API in use, only use its value or null.
if ( hasSelectors ) {
return get( selectors, path, null );
}

// Selectors API, not available, check for old experimental selector.
return get( supports, 'color.__experimentalDuotone', null );
}

// Root selector.

// Calculated before returning as it can be used as a fallback for feature
// selectors later on.
// Root selector ( can be used as fallback ).
let rootSelector = null;

if ( hasSelectors && selectors.root ) {
Expand All @@ -68,14 +54,36 @@ export function getBlockCSSSelector(
return rootSelector;
}

const fallbackSelector = fallback ? rootSelector : null;

// Duotone ( may fallback to root selector ).
if ( path === 'filter.duotone' ) {
// If selectors API in use, only use its value, fallback, or null.
if ( hasSelectors ) {
return get( selectors, path, fallbackSelector );
}

// Selectors API, not available, check for old experimental selector.
const duotoneSelector = get(
supports,
'color.__experimentalDuotone',
null
);

// If nothing to work with, provide fallback selector if available.
if ( ! duotoneSelector ) {
return fallbackSelector;
}

return scopeSelector( rootSelector, duotoneSelector );
}

// If target is not `root` or `duotone` we have a feature or subfeature
// as the target. If the target is a string convert to an array.
const pathArray = Array.isArray( target ) ? target : target.split( '.' );

// Feature selectors ( may fallback to root selector );
if ( pathArray.length === 1 ) {
const fallbackSelector = fallback ? rootSelector : null;

// Prefer the selectors API if available.
if ( hasSelectors ) {
// Get selector from either `feature.root` or shorthand path.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { getCSSRules } from '@wordpress/style-engine';
/**
* Internal dependencies
*/
import { PRESET_METADATA, ROOT_BLOCK_SELECTOR, scopeSelector } from './utils';
import { PRESET_METADATA, ROOT_BLOCK_SELECTOR } from './utils';
import { getBlockCSSSelector } from './get-block-css-selector';
import { getTypographyFontSizeValue } from './typography-utils';
import { GlobalStylesContext } from './context';
Expand Down Expand Up @@ -856,10 +856,9 @@ export const toStyles = (
if ( duotoneDeclarations.length > 0 ) {
ruleset =
ruleset +
`${ scopeSelector(
selector,
duotoneSelector
) }{${ duotoneDeclarations.join( ';' ) };}`;
`${ duotoneSelector }{${ duotoneDeclarations.join(
';'
) };}`;
}
}

Expand Down
8 changes: 5 additions & 3 deletions packages/block-editor/src/hooks/duotone.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
__unstableDuotoneStylesheet as DuotoneStylesheet,
__unstableDuotoneUnsetStylesheet as DuotoneUnsetStylesheet,
} from '../components/duotone';
import { getBlockCSSSelector } from '../components/global-styles/get-block-css-selector';
import { store as blockEditorStore } from '../store';

const EMPTY_ARRAY = [];
Expand Down Expand Up @@ -273,9 +274,10 @@ function BlockDuotoneStyles( { name, duotoneStyle, id } ) {
colors = getColorsFromDuotonePreset( colors, duotonePalette );
}

const duotoneSupportSelectors =
getBlockType( name ).selectors?.filter?.duotone ||
getBlockSupport( name, 'color.__experimentalDuotone' );
const duotoneSupportSelectors = getBlockCSSSelector(
getBlockType( name ),
'filter.duotone'
);

// Extra .editor-styles-wrapper specificity is needed in the editor
// since we're not using inline styles to apply the filter. We need to
Expand Down
24 changes: 23 additions & 1 deletion phpunit/class-wp-get-block-css-selectors-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public function test_get_duotone_selector_via_experimental_property() {
);

$selector = wp_get_block_css_selector( $block_type, 'filter.duotone' );
$this->assertEquals( '.experimental-duotone', $selector );
$this->assertEquals( '.wp-block-test-experimental-duotone-selector .experimental-duotone', $selector );
}

public function test_no_duotone_selector_set() {
Expand All @@ -115,6 +115,28 @@ public function test_no_duotone_selector_set() {
$this->assertEquals( null, $selector );
}

public function test_fallback_duotone_selector() {
$block_type = self::register_test_block(
'test/fallback-duotone-selector',
array( 'root' => '.fallback-root-selector' ),
null
);

$selector = wp_get_block_css_selector( $block_type, 'filter.duotone', true );
$this->assertEquals( '.fallback-root-selector', $selector );
}

public function test_fallback_duotone_selector_to_generated_class() {
$block_type = self::register_test_block(
'test/fallback-duotone-selector',
array(),
null
);

$selector = wp_get_block_css_selector( $block_type, 'filter.duotone', true );
$this->assertEquals( '.wp-block-test-fallback-duotone-selector', $selector );
}

public function test_get_feature_selector_via_selectors_api() {
$block_type = self::register_test_block(
'test/feature-selector',
Expand Down

0 comments on commit 520ea49

Please sign in to comment.