-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract the getSupportedStyles selector to the blocks store as a priv…
…ate selector
- Loading branch information
1 parent
b329b48
commit 0ecc13c
Showing
18 changed files
with
394 additions
and
162 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/experiments'; | ||
|
||
export const { lock, unlock } = | ||
__dangerousOptInToUnstableAPIsOnlyForCoreModules( | ||
'I know using unstable features means my plugin or theme will inevitably break on the next WordPress release.', | ||
'@wordpress/blocks' | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import createSelector from 'rememo'; | ||
import { get } from 'lodash'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { getBlockType } from './selectors'; | ||
import { __EXPERIMENTAL_STYLE_PROPERTY as STYLE_PROPERTY } from '../api/constants'; | ||
|
||
const ROOT_BLOCK_SUPPORTS = [ | ||
'background', | ||
'backgroundColor', | ||
'color', | ||
'linkColor', | ||
'buttonColor', | ||
'fontFamily', | ||
'fontSize', | ||
'fontStyle', | ||
'fontWeight', | ||
'lineHeight', | ||
'padding', | ||
'contentSize', | ||
'wideSize', | ||
'blockGap', | ||
'textDecoration', | ||
'textTransform', | ||
'letterSpacing', | ||
]; | ||
|
||
function filterElementBlockSupports( blockSuppots, name, element ) { | ||
return blockSuppots.filter( ( support ) => { | ||
if ( support === 'fontSize' && element === 'heading' ) { | ||
return false; | ||
} | ||
|
||
// This is only available for links | ||
if ( support === 'textDecoration' && ! name && element !== 'link' ) { | ||
return false; | ||
} | ||
|
||
// This is only available for heading | ||
if ( | ||
support === 'textTransform' && | ||
! name && | ||
[ 'heading', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ].includes( | ||
element | ||
) | ||
) { | ||
return false; | ||
} | ||
|
||
// This is only available for headings | ||
if ( | ||
support === 'letterSpacing' && | ||
! name && | ||
[ 'heading', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ].includes( | ||
element | ||
) | ||
) { | ||
return false; | ||
} | ||
|
||
return true; | ||
} ); | ||
} | ||
|
||
export const getSupportedStyles = createSelector( | ||
( state, name, element ) => { | ||
if ( ! name ) { | ||
return filterElementBlockSupports( | ||
ROOT_BLOCK_SUPPORTS, | ||
name, | ||
element | ||
); | ||
} | ||
|
||
const blockType = getBlockType( state, name ); | ||
|
||
if ( ! blockType ) { | ||
return []; | ||
} | ||
|
||
const supportKeys = []; | ||
|
||
// Check for blockGap support. | ||
// Block spacing support doesn't map directly to a single style property, so needs to be handled separately. | ||
// Also, only allow `blockGap` support if serialization has not been skipped, to be sure global spacing can be applied. | ||
if ( | ||
blockType?.supports?.spacing?.blockGap && | ||
blockType?.supports?.spacing?.__experimentalSkipSerialization !== | ||
true && | ||
! blockType?.supports?.spacing?.__experimentalSkipSerialization?.some?.( | ||
( spacingType ) => spacingType === 'blockGap' | ||
) | ||
) { | ||
supportKeys.push( 'blockGap' ); | ||
} | ||
|
||
Object.keys( STYLE_PROPERTY ).forEach( ( styleName ) => { | ||
if ( ! STYLE_PROPERTY[ styleName ].support ) { | ||
return; | ||
} | ||
|
||
// Opting out means that, for certain support keys like background color, | ||
// blocks have to explicitly set the support value false. If the key is | ||
// unset, we still enable it. | ||
if ( STYLE_PROPERTY[ styleName ].requiresOptOut ) { | ||
if ( | ||
STYLE_PROPERTY[ styleName ].support[ 0 ] in | ||
blockType.supports && | ||
get( | ||
blockType.supports, | ||
STYLE_PROPERTY[ styleName ].support | ||
) !== false | ||
) { | ||
return supportKeys.push( styleName ); | ||
} | ||
} | ||
|
||
if ( | ||
get( | ||
blockType.supports, | ||
STYLE_PROPERTY[ styleName ].support, | ||
false | ||
) | ||
) { | ||
return supportKeys.push( styleName ); | ||
} | ||
} ); | ||
|
||
return filterElementBlockSupports( supportKeys, name, element ); | ||
}, | ||
( state, name ) => [ state.blockTypes[ name ] ] | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import deepFreeze from 'deep-freeze'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { getSupportedStyles } from '../private-selectors'; | ||
|
||
const keyBlocksByName = ( blocks ) => | ||
blocks.reduce( | ||
( result, block ) => ( { ...result, [ block.name ]: block } ), | ||
{} | ||
); | ||
|
||
describe( 'private selectors', () => { | ||
describe( 'getSupportedStyles', () => { | ||
const getState = ( blocks ) => { | ||
return deepFreeze( { | ||
blockTypes: keyBlocksByName( blocks ), | ||
} ); | ||
}; | ||
|
||
it( 'return the list of globally supported panels (no block name)', () => { | ||
const supports = getSupportedStyles( getState( [] ) ); | ||
|
||
expect( supports ).toEqual( [ | ||
'background', | ||
'backgroundColor', | ||
'color', | ||
'linkColor', | ||
'buttonColor', | ||
'fontFamily', | ||
'fontSize', | ||
'fontStyle', | ||
'fontWeight', | ||
'lineHeight', | ||
'padding', | ||
'contentSize', | ||
'wideSize', | ||
'blockGap', | ||
] ); | ||
} ); | ||
|
||
it( 'return the list of globally supported panels including link specific styles', () => { | ||
const supports = getSupportedStyles( getState( [] ), null, 'link' ); | ||
|
||
expect( supports ).toEqual( [ | ||
'background', | ||
'backgroundColor', | ||
'color', | ||
'linkColor', | ||
'buttonColor', | ||
'fontFamily', | ||
'fontSize', | ||
'fontStyle', | ||
'fontWeight', | ||
'lineHeight', | ||
'padding', | ||
'contentSize', | ||
'wideSize', | ||
'blockGap', | ||
'textDecoration', | ||
] ); | ||
} ); | ||
|
||
it( 'return the list of globally supported panels including heading specific styles', () => { | ||
const supports = getSupportedStyles( | ||
getState( [] ), | ||
null, | ||
'heading' | ||
); | ||
|
||
expect( supports ).toEqual( [ | ||
'background', | ||
'backgroundColor', | ||
'color', | ||
'linkColor', | ||
'buttonColor', | ||
'fontFamily', | ||
'fontStyle', | ||
'fontWeight', | ||
'lineHeight', | ||
'padding', | ||
'contentSize', | ||
'wideSize', | ||
'blockGap', | ||
'textTransform', | ||
'letterSpacing', | ||
] ); | ||
} ); | ||
|
||
it( 'return an empty list for unknown blocks', () => { | ||
const supports = getSupportedStyles( | ||
getState( [] ), | ||
'unkown/block' | ||
); | ||
|
||
expect( supports ).toEqual( [] ); | ||
} ); | ||
|
||
it( 'return empty by default for blocks without support keys', () => { | ||
const supports = getSupportedStyles( | ||
getState( [ | ||
{ | ||
name: 'core/example-block', | ||
supports: {}, | ||
}, | ||
] ), | ||
'core/example-block' | ||
); | ||
|
||
expect( supports ).toEqual( [] ); | ||
} ); | ||
|
||
it( 'return the allowed styles according to the blocks support keys', () => { | ||
const supports = getSupportedStyles( | ||
getState( [ | ||
{ | ||
name: 'core/example-block', | ||
supports: { | ||
typography: { | ||
__experimentalFontFamily: true, | ||
__experimentalFontStyle: true, | ||
__experimentalFontWeight: true, | ||
__experimentalTextDecoration: true, | ||
__experimentalTextTransform: true, | ||
__experimentalLetterSpacing: true, | ||
fontSize: true, | ||
lineHeight: true, | ||
}, | ||
}, | ||
}, | ||
] ), | ||
'core/example-block' | ||
); | ||
|
||
expect( supports ).toEqual( [ | ||
'fontFamily', | ||
'fontSize', | ||
'fontStyle', | ||
'fontWeight', | ||
'lineHeight', | ||
'textDecoration', | ||
'textTransform', | ||
'letterSpacing', | ||
] ); | ||
} ); | ||
} ); | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.