Skip to content

Commit

Permalink
Try rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix committed Sep 28, 2020
1 parent 267bb9c commit e05e5a6
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 136 deletions.
40 changes: 15 additions & 25 deletions packages/rich-text/src/component/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* External dependencies
*/
import classnames from 'classnames';
import { find, isNil, pickBy } from 'lodash';
import { find, isNil } from 'lodash';

/**
* WordPress dependencies
Expand Down Expand Up @@ -95,19 +95,12 @@ const defaultStyle = { whiteSpace };

const EMPTY_ACTIVE_FORMATS = [];

function createPrepareEditableTree( props, prefix ) {
const fns = Object.keys( props ).reduce( ( accumulator, key ) => {
if ( key.startsWith( prefix ) ) {
accumulator.push( props[ key ] );
}

return accumulator;
}, [] );

function createPrepareEditableTree( fns ) {
return ( value ) =>
fns.reduce( ( accumulator, fn ) => {
return fn( accumulator, value.text );
}, value.formats );
fns.reduce(
( accumulator, fn ) => fn( accumulator, value.text ),
value.formats
);
}

/**
Expand Down Expand Up @@ -180,7 +173,13 @@ function RichText(
ref
) {
const [ activeFormats = [], setActiveFormats ] = useState();
const { formatTypes, dependencies, functions } = useFormatTypes( {
const {
formatTypes,
prepareHandlers,
valueHandlers,
changeHandlers,
dependencies,
} = useFormatTypes( {
clientId,
identifier,
} );
Expand Down Expand Up @@ -219,10 +218,7 @@ function RichText(
return string;
}

const prepare = createPrepareEditableTree(
functions,
'format_value_functions'
);
const prepare = createPrepareEditableTree( valueHandlers );

const result = create( {
html: string,
Expand Down Expand Up @@ -313,10 +309,7 @@ function RichText(
multilineTag,
multilineWrapperTags:
multilineTag === 'li' ? [ 'ul', 'ol' ] : undefined,
prepareEditableTree: createPrepareEditableTree(
functions,
'format_prepare_functions'
),
prepareEditableTree: createPrepareEditableTree( prepareHandlers ),
__unstableDomOnly: domOnly,
placeholder,
} );
Expand Down Expand Up @@ -920,9 +913,6 @@ function RichText(
applyRecord( newRecord );

const { start, end, activeFormats: newActiveFormats = [] } = newRecord;
const changeHandlers = pickBy( functions, ( v, key ) =>
key.startsWith( 'format_on_change_functions_' )
);

Object.values( changeHandlers ).forEach( ( changeHandler ) => {
changeHandler( newRecord.formats, newRecord.text );
Expand Down
187 changes: 76 additions & 111 deletions packages/rich-text/src/component/use-format-types.js
Original file line number Diff line number Diff line change
@@ -1,144 +1,109 @@
/**
* External dependencies
*/
import { mapKeys } from 'lodash';

/**
* WordPress dependencies
*/
import { useSelect, __unstableUseDispatchWithMap } from '@wordpress/data';
import { useMemo } from '@wordpress/element';

function formatTypesSelector( select ) {
return select( 'core/rich-text' ).getFormatTypes();
}

/**
* This higher-order component provides RichText with the `formatTypes` prop
* and its derived props from experimental format type settings.
*
* @param {WPComponent} RichText The rich text component to add props for.
* This hook provides RichText with the `formatTypes` and its derived props from
* experimental format type settings.
*
* @return {WPComponent} New enhanced component.
* @param {Object} $0 Options
* @param {string} $0.clientId Block client ID.
* @param {string} $0.identifier Block attribute.
*/
export function useFormatTypes( { clientId, identifier } ) {
const formatTypes = useSelect( formatTypesSelector, [] );
const selectProps = useSelect(
( select ) => {
return formatTypes.reduce( ( acc, settings ) => {
if (
! settings.__experimentalGetPropsForEditableTreePreparation
) {
return acc;
const keyedSelected = useSelect(
( select ) =>
formatTypes.reduce( ( accumulator, type ) => {
if ( type.__experimentalGetPropsForEditableTreePreparation ) {
accumulator[
type.name
] = type.__experimentalGetPropsForEditableTreePreparation(
select,
{
richTextIdentifier: identifier,
blockClientId: clientId,
}
);
}

const selectPrefix = `format_prepare_props_(${ settings.name })_`;
return {
...acc,
...mapKeys(
settings.__experimentalGetPropsForEditableTreePreparation(
select,
{
richTextIdentifier: identifier,
blockClientId: clientId,
}
),
( value, key ) => selectPrefix + key
),
};
}, {} );
},
return accumulator;
}, {} ),
[ formatTypes, clientId, identifier ]
);
const dispatchProps = __unstableUseDispatchWithMap(
( dispatch ) => {
return formatTypes.reduce( ( acc, settings ) => {
if (
! settings.__experimentalGetPropsForEditableTreeChangeHandler
) {
return acc;
const keyedDispatchers = __unstableUseDispatchWithMap(
( dispatch ) =>
formatTypes.reduce( ( accumulator, type ) => {
if ( type.__experimentalGetPropsForEditableTreeChangeHandler ) {
accumulator[
type.name
] = type.__experimentalGetPropsForEditableTreeChangeHandler(
dispatch,
{
richTextIdentifier: identifier,
blockClientId: clientId,
}
);
}

const dispatchPrefix = `format_on_change_props_(${ settings.name })_`;
return {
...acc,
...mapKeys(
settings.__experimentalGetPropsForEditableTreeChangeHandler(
dispatch,
{
richTextIdentifier: identifier,
blockClientId: clientId,
}
),
( value, key ) => dispatchPrefix + key
),
};
}, {} );
},
return accumulator;
}, {} ),
[ formatTypes, clientId, identifier ]
);
const functions = useMemo( () => {
return formatTypes.reduce( ( acc, settings ) => {
if ( ! settings.__experimentalCreatePrepareEditableTree ) {
return acc;
}

const args = {
richTextIdentifier: identifier,
blockClientId: clientId,
};
const combined = {
...selectProps,
...dispatchProps,
};

const { name } = settings;
const selectPrefix = `format_prepare_props_(${ name })_`;
const dispatchPrefix = `format_on_change_props_(${ name })_`;
const propsByPrefix = Object.keys( combined ).reduce(
( accumulator, key ) => {
if ( key.startsWith( selectPrefix ) ) {
accumulator[ key.slice( selectPrefix.length ) ] =
combined[ key ];
}

if ( key.startsWith( dispatchPrefix ) ) {
accumulator[ key.slice( dispatchPrefix.length ) ] =
combined[ key ];
}
const prepareHandlers = [];
const valueHandlers = [];
const changeHandlers = [];
const dependencies = [];

return accumulator;
},
{}
formatTypes.forEach( ( type ) => {
if ( type.__experimentalCreatePrepareEditableTree ) {
const selected = keyedSelected[ type.name ];
const handler = type.__experimentalCreatePrepareEditableTree(
selected,
{
richTextIdentifier: identifier,
blockClientId: clientId,
}
);

if ( settings.__experimentalCreateOnChangeEditableValue ) {
return {
...acc,
[ `format_value_functions_(${ name })` ]: settings.__experimentalCreatePrepareEditableTree(
propsByPrefix,
args
),
[ `format_on_change_functions_(${ name })` ]: settings.__experimentalCreateOnChangeEditableValue(
propsByPrefix,
args
),
};
if ( type.__experimentalCreateOnChangeEditableValue ) {
valueHandlers.push( handler );
} else {
prepareHandlers.push( handler );
}

return {
...acc,
[ `format_prepare_functions_(${ name })` ]: settings.__experimentalCreatePrepareEditableTree(
propsByPrefix,
args
),
};
}, {} );
}, [ formatTypes, clientId, identifier, selectProps, dispatchProps ] );
for ( const key in selected ) {
dependencies.push( selected[ key ] );
}
}

if ( type.__experimentalCreateOnChangeEditableValue ) {
changeHandlers.push(
type.__experimentalCreateOnChangeEditableValue(
{
...( keyedSelected[ type.name ] || {} ),
...( keyedDispatchers[ type.name ] || {} ),
},
{
richTextIdentifier: identifier,
blockClientId: clientId,
}
)
);
}
} );

return {
dependencies: Object.values( selectProps ),
functions,
formatTypes,
prepareHandlers,
valueHandlers,
changeHandlers,
dependencies,
};
}
4 changes: 4 additions & 0 deletions packages/rich-text/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import createSelector from 'rememo';
import { find } from 'lodash';

export function getKeyedFormatTypes( state ) {
return state.formatTypes;
}

/**
* Returns all the available format types.
*
Expand Down

0 comments on commit e05e5a6

Please sign in to comment.