From cca762e91ce6d1561bbe0ba2cfc68a6e62821ec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= Date: Thu, 21 Jul 2022 14:10:31 +0200 Subject: [PATCH 1/5] Add caret format --- .../format-library/src/default-formats.js | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/packages/format-library/src/default-formats.js b/packages/format-library/src/default-formats.js index 412ae23f4b686d..cfa75c2c019cc9 100644 --- a/packages/format-library/src/default-formats.js +++ b/packages/format-library/src/default-formats.js @@ -13,7 +13,39 @@ import { subscript } from './subscript'; import { superscript } from './superscript'; import { keyboard } from './keyboard'; +const caret = { + name: 'asblocks/caret', + title: 'Example', + tagName: 'mark', + className: 'caret', + attributes: { + id: 'id', + className: 'class', + }, + edit() { + return null; + }, + __experimentalGetPropsForEditableTreePreparation( + select, + { blockClientId } + ) { + // Just calling this, will make the text selection to be unreliable + // If you comment out this line, then everything works fine. + select( 'core/block-editor' ).getBlockName( blockClientId ); + + return { + carets: [], + }; + }, + __experimentalCreatePrepareEditableTree() { + return ( formats ) => { + return formats; + }; + }, +}; + export default [ + caret, bold, code, image, From 63a27685c44f75422684c6956fd073af2a0362c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= Date: Thu, 21 Jul 2022 16:02:45 +0200 Subject: [PATCH 2/5] Flatten selected keys --- .../components/rich-text/use-format-types.js | 54 +++++++++++++------ .../format-library/src/default-formats.js | 6 +-- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/packages/block-editor/src/components/rich-text/use-format-types.js b/packages/block-editor/src/components/rich-text/use-format-types.js index e341c1ee434b9f..9a732e19ba2d00 100644 --- a/packages/block-editor/src/components/rich-text/use-format-types.js +++ b/packages/block-editor/src/components/rich-text/use-format-types.js @@ -1,12 +1,13 @@ /** - * WordPress dependencies + * External dependencies */ -import { useMemo } from '@wordpress/element'; -import { useSelect, useDispatch } from '@wordpress/data'; +import { mapKeys } from 'lodash'; /** - * Internal dependencies + * WordPress dependencies */ +import { useMemo } from '@wordpress/element'; +import { useSelect, useDispatch } from '@wordpress/data'; import { store as richTextStore } from '@wordpress/rich-text'; function formatTypesSelector( select ) { @@ -32,6 +33,23 @@ const interactiveContentTags = new Set( [ 'video', ] ); +function prefixSelectKeys( selected, prefix ) { + if ( typeof selected !== 'object' ) { + return { [ prefix ]: selected }; + } + + return mapKeys( selected, ( value, key ) => `${ prefix }.${ key }` ); +} + +function getPrefixedKeys( selected, prefix ) { + return Object.keys( selected ) + .filter( ( key ) => key.startsWith( prefix + '.' ) ) + .reduce( ( accumulator, key ) => { + accumulator[ key.slice( prefix.length + 1 ) ] = selected[ key ]; + return accumulator; + }, {} ); +} + /** * This hook provides RichText with the `formatTypes` and its derived props from * experimental format type settings. @@ -68,18 +86,23 @@ export function useFormatTypes( { const keyedSelected = useSelect( ( select ) => formatTypes.reduce( ( accumulator, type ) => { - if ( type.__experimentalGetPropsForEditableTreePreparation ) { - accumulator[ type.name ] = + if ( ! type.__experimentalGetPropsForEditableTreePreparation ) { + return accumulator; + } + + return { + ...accumulator, + ...prefixSelectKeys( type.__experimentalGetPropsForEditableTreePreparation( select, { richTextIdentifier: identifier, blockClientId: clientId, } - ); - } - - return accumulator; + ), + type.name + ), + }; }, {} ), [ formatTypes, clientId, identifier ] ); @@ -89,11 +112,14 @@ export function useFormatTypes( { const changeHandlers = []; const dependencies = []; + for ( const key in keyedSelected ) { + dependencies.push( keyedSelected[ key ] ); + } + formatTypes.forEach( ( type ) => { if ( type.__experimentalCreatePrepareEditableTree ) { - const selected = keyedSelected[ type.name ]; const handler = type.__experimentalCreatePrepareEditableTree( - selected, + getPrefixedKeys( keyedSelected, type.name ), { richTextIdentifier: identifier, blockClientId: clientId, @@ -105,10 +131,6 @@ export function useFormatTypes( { } else { prepareHandlers.push( handler ); } - - for ( const key in selected ) { - dependencies.push( selected[ key ] ); - } } if ( type.__experimentalCreateOnChangeEditableValue ) { diff --git a/packages/format-library/src/default-formats.js b/packages/format-library/src/default-formats.js index cfa75c2c019cc9..2bfad3f67755e5 100644 --- a/packages/format-library/src/default-formats.js +++ b/packages/format-library/src/default-formats.js @@ -29,12 +29,8 @@ const caret = { select, { blockClientId } ) { - // Just calling this, will make the text selection to be unreliable - // If you comment out this line, then everything works fine. - select( 'core/block-editor' ).getBlockName( blockClientId ); - return { - carets: [], + carets: select( 'core/block-editor' ).getBlockName( blockClientId ), }; }, __experimentalCreatePrepareEditableTree() { From cc31df89b6f3c0cc9931296ccfe31d798d1672c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= Date: Thu, 21 Jul 2022 16:07:07 +0200 Subject: [PATCH 3/5] Allow non object --- .../src/components/rich-text/use-format-types.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/block-editor/src/components/rich-text/use-format-types.js b/packages/block-editor/src/components/rich-text/use-format-types.js index 9a732e19ba2d00..cf7d3848352b26 100644 --- a/packages/block-editor/src/components/rich-text/use-format-types.js +++ b/packages/block-editor/src/components/rich-text/use-format-types.js @@ -34,14 +34,12 @@ const interactiveContentTags = new Set( [ ] ); function prefixSelectKeys( selected, prefix ) { - if ( typeof selected !== 'object' ) { - return { [ prefix ]: selected }; - } - + if ( typeof selected !== 'object' ) return { [ prefix ]: selected }; return mapKeys( selected, ( value, key ) => `${ prefix }.${ key }` ); } function getPrefixedKeys( selected, prefix ) { + if ( selected[ prefix ] ) return selected[ prefix ]; return Object.keys( selected ) .filter( ( key ) => key.startsWith( prefix + '.' ) ) .reduce( ( accumulator, key ) => { From 0459cbbf02b120dbbc7c68d9651e0a64c9b80f5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= Date: Thu, 21 Jul 2022 16:40:04 +0200 Subject: [PATCH 4/5] Fix onChange --- .../block-editor/src/components/rich-text/use-format-types.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/rich-text/use-format-types.js b/packages/block-editor/src/components/rich-text/use-format-types.js index cf7d3848352b26..e22b23349b7f24 100644 --- a/packages/block-editor/src/components/rich-text/use-format-types.js +++ b/packages/block-editor/src/components/rich-text/use-format-types.js @@ -145,10 +145,11 @@ export function useFormatTypes( { ); } + const selected = getPrefixedKeys( keyedSelected, type.name ); changeHandlers.push( type.__experimentalCreateOnChangeEditableValue( { - ...( keyedSelected[ type.name ] || {} ), + ...( typeof selected === 'object' ? selected : {} ), ...dispatchers, }, { From b7f8fdc6e7e80829c3dbde76cf487db97c40b32d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= Date: Thu, 21 Jul 2022 18:21:41 +0200 Subject: [PATCH 5/5] Remove test --- .../components/rich-text/use-format-types.js | 6 ++-- .../format-library/src/default-formats.js | 28 ------------------- 2 files changed, 3 insertions(+), 31 deletions(-) diff --git a/packages/block-editor/src/components/rich-text/use-format-types.js b/packages/block-editor/src/components/rich-text/use-format-types.js index e22b23349b7f24..ff76cc59dd58d3 100644 --- a/packages/block-editor/src/components/rich-text/use-format-types.js +++ b/packages/block-editor/src/components/rich-text/use-format-types.js @@ -38,7 +38,7 @@ function prefixSelectKeys( selected, prefix ) { return mapKeys( selected, ( value, key ) => `${ prefix }.${ key }` ); } -function getPrefixedKeys( selected, prefix ) { +function getPrefixedSelectKeys( selected, prefix ) { if ( selected[ prefix ] ) return selected[ prefix ]; return Object.keys( selected ) .filter( ( key ) => key.startsWith( prefix + '.' ) ) @@ -117,7 +117,7 @@ export function useFormatTypes( { formatTypes.forEach( ( type ) => { if ( type.__experimentalCreatePrepareEditableTree ) { const handler = type.__experimentalCreatePrepareEditableTree( - getPrefixedKeys( keyedSelected, type.name ), + getPrefixedSelectKeys( keyedSelected, type.name ), { richTextIdentifier: identifier, blockClientId: clientId, @@ -145,7 +145,7 @@ export function useFormatTypes( { ); } - const selected = getPrefixedKeys( keyedSelected, type.name ); + const selected = getPrefixedSelectKeys( keyedSelected, type.name ); changeHandlers.push( type.__experimentalCreateOnChangeEditableValue( { diff --git a/packages/format-library/src/default-formats.js b/packages/format-library/src/default-formats.js index 2bfad3f67755e5..412ae23f4b686d 100644 --- a/packages/format-library/src/default-formats.js +++ b/packages/format-library/src/default-formats.js @@ -13,35 +13,7 @@ import { subscript } from './subscript'; import { superscript } from './superscript'; import { keyboard } from './keyboard'; -const caret = { - name: 'asblocks/caret', - title: 'Example', - tagName: 'mark', - className: 'caret', - attributes: { - id: 'id', - className: 'class', - }, - edit() { - return null; - }, - __experimentalGetPropsForEditableTreePreparation( - select, - { blockClientId } - ) { - return { - carets: select( 'core/block-editor' ).getBlockName( blockClientId ), - }; - }, - __experimentalCreatePrepareEditableTree() { - return ( formats ) => { - return formats; - }; - }, -}; - export default [ - caret, bold, code, image,