Skip to content

Commit

Permalink
Consolidate block editor initializations (#27954)
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowriad authored Jan 11, 2021
1 parent 4be4eb7 commit 9953cee
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 182 deletions.
1 change: 1 addition & 0 deletions packages/blocks/src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export {
getSaveElement,
getSaveContent,
getBlockProps as __unstableGetBlockProps,
__unstableSerializeAndClean,
} from './serializer';

// Validation is the process of comparing a block source with its output before
Expand Down
25 changes: 24 additions & 1 deletion packages/blocks/src/api/serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { isEmpty, reduce, isObject, castArray, startsWith } from 'lodash';
import { Component, cloneElement, renderToString } from '@wordpress/element';
import { hasFilter, applyFilters } from '@wordpress/hooks';
import isShallowEqual from '@wordpress/is-shallow-equal';
import { removep } from '@wordpress/autop';

/**
* Internal dependencies
Expand All @@ -19,7 +20,7 @@ import {
getUnregisteredTypeHandlerName,
hasBlockSupport,
} from './registration';
import { normalizeBlockType } from './utils';
import { isUnmodifiedDefaultBlock, normalizeBlockType } from './utils';
import BlockContentProvider from '../block-content-provider';

/**
Expand Down Expand Up @@ -349,6 +350,28 @@ export function serializeBlock( block, { isInnerBlocks = false } = {} ) {
return getCommentDelimitedContent( blockName, saveAttributes, saveContent );
}

export function __unstableSerializeAndClean( blocks ) {
// A single unmodified default block is assumed to
// be equivalent to an empty post.
if ( blocks.length === 1 && isUnmodifiedDefaultBlock( blocks[ 0 ] ) ) {
blocks = [];
}

let content = serialize( blocks );

// For compatibility, treat a post consisting of a
// single freeform block as legacy content and apply
// pre-block-editor removep'd content formatting.
if (
blocks.length === 1 &&
blocks[ 0 ].name === getFreeformContentHandlerName()
) {
content = removep( content );
}

return content;
}

/**
* Takes a block or set of blocks and returns the serialized post content.
*
Expand Down
58 changes: 44 additions & 14 deletions packages/core-data/src/entity-provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
useEffect,
} from '@wordpress/element';
import { useSelect, useDispatch } from '@wordpress/data';
import { parse, serialize } from '@wordpress/blocks';
import { parse, __unstableSerializeAndClean } from '@wordpress/blocks';

const EMPTY_ARRAY = [];

Expand Down Expand Up @@ -137,16 +137,26 @@ export function useEntityProp( kind, type, prop, _id ) {
export function useEntityBlockEditor( kind, type, { id: _id } = {} ) {
const providerId = useEntityId( kind, type );
const id = _id ?? providerId;
const { content, blocks } = useSelect(
( select ) => {
const { getEditedEntityRecord } = select( 'core' );
const editedEntity = getEditedEntityRecord( kind, type, id );
return {
blocks: editedEntity.blocks,
content: editedEntity.content,
};
},
[ kind, type, id ]
);
const { __unstableCreateUndoLevel, editEntityRecord } = useDispatch(
'core'
);

const [ content, setContent ] = useEntityProp( kind, type, 'content', id );
const [ blocks, onInput ] = useEntityProp( kind, type, 'blocks', id );

const { editEntityRecord } = useDispatch( 'core' );
useEffect( () => {
// Load the blocks from the content if not already in state
// Guard against other instances that might have
// set content to a function already.
if ( content && typeof content !== 'function' ) {
// set content to a function already or the blocks are already in state.
if ( content && typeof content !== 'function' && ! blocks ) {
const parsedContent = parse( content );
editEntityRecord(
kind,
Expand All @@ -161,14 +171,34 @@ export function useEntityBlockEditor( kind, type, { id: _id } = {} ) {
}, [ content ] );

const onChange = useCallback(
( nextBlocks ) => {
onInput( nextBlocks );
// Use a function edit to avoid serializing often.
setContent( ( { blocks: blocksToSerialize } ) =>
serialize( blocksToSerialize )
);
( newBlocks, options ) => {
const { selectionStart, selectionEnd } = options;
const edits = { blocks: newBlocks, selectionStart, selectionEnd };

const noChange = blocks === edits.blocks;
if ( noChange ) {
return __unstableCreateUndoLevel( kind, type, id );
}

// We create a new function here on every persistent edit
// to make sure the edit makes the post dirty and creates
// a new undo level.
edits.content = ( { blocks: blocksForSerialization = [] } ) =>
__unstableSerializeAndClean( blocksForSerialization );

editEntityRecord( kind, type, id, edits );
},
[ onInput, setContent ]
[ kind, type, id, blocks ]
);

const onInput = useCallback(
( newBlocks, options ) => {
const { selectionStart, selectionEnd } = options;
const edits = { blocks: newBlocks, selectionStart, selectionEnd };
editEntityRecord( kind, type, id, edits );
},
[ kind, type, id ]
);

return [ blocks ?? EMPTY_ARRAY, onInput, onChange ];
}
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ describe( 'Reusable blocks', () => {
);
paragraphBlock.focus();
await pressKeyWithModifier( 'primary', 'a' );
await page.keyboard.press( 'ArrowRight' );
await page.keyboard.press( 'End' );
await page.keyboard.type( ' modified' );

// Wait for async mode to dispatch the update.
Expand Down
21 changes: 9 additions & 12 deletions packages/editor/src/components/provider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { useEffect, useLayoutEffect, useMemo } from '@wordpress/element';
import { useDispatch, useSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { EntityProvider } from '@wordpress/core-data';
import { EntityProvider, useEntityBlockEditor } from '@wordpress/core-data';
import {
BlockEditorProvider,
BlockContextProvider,
Expand All @@ -17,7 +17,6 @@ import { store as noticesStore } from '@wordpress/notices';
*/
import withRegistryProvider from './with-registry-provider';
import ConvertToGroupButtons from '../convert-to-group-buttons';
import usePostContentEditor from './use-post-content-editor';
import { store as editorStore } from '../../store';
import useBlockEditorSettings from './use-block-editor-settings';

Expand Down Expand Up @@ -48,7 +47,11 @@ function EditorProvider( {
};
}, [] );
const { id, type } = __unstableTemplate ?? post;
const blockEditorProps = usePostContentEditor( type, id );
const [ blocks, onInput, onChange ] = useEntityBlockEditor(
'postType',
type,
{ id }
);
const editorSettings = useBlockEditorSettings(
settings,
!! __unstableTemplate
Expand All @@ -58,7 +61,6 @@ function EditorProvider( {
setupEditor,
updateEditorSettings,
__experimentalTearDownEditor,
__unstableSetupTemplate,
} = useDispatch( editorStore );
const { createWarningNotice } = useDispatch( noticesStore );

Expand Down Expand Up @@ -99,13 +101,6 @@ function EditorProvider( {
updateEditorSettings( settings );
}, [ settings ] );

// Synchronize the template as it changes
useEffect( () => {
if ( __unstableTemplate ) {
__unstableSetupTemplate( __unstableTemplate );
}
}, [ __unstableTemplate?.id ] );

if ( ! isReady ) {
return null;
}
Expand All @@ -115,7 +110,9 @@ function EditorProvider( {
<EntityProvider kind="postType" type={ post.type } id={ post.id }>
<BlockContextProvider value={ defaultBlockContext }>
<BlockEditorProvider
{ ...blockEditorProps }
value={ blocks }
onChange={ onChange }
onInput={ onInput }
selectionStart={ selectionStart }
selectionEnd={ selectionEnd }
settings={ editorSettings }
Expand Down
77 changes: 0 additions & 77 deletions packages/editor/src/components/provider/use-post-content-editor.js

This file was deleted.

30 changes: 6 additions & 24 deletions packages/editor/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import { has } from 'lodash';
import deprecated from '@wordpress/deprecated';
import { controls } from '@wordpress/data';
import { apiFetch } from '@wordpress/data-controls';
import { parse, synchronizeBlocksWithTemplate } from '@wordpress/blocks';
import {
parse,
synchronizeBlocksWithTemplate,
__unstableSerializeAndClean,
} from '@wordpress/blocks';
import { store as noticesStore } from '@wordpress/notices';

/**
Expand All @@ -21,7 +25,6 @@ import {
getNotificationArgumentsForSaveFail,
getNotificationArgumentsForTrashFail,
} from './utils/notice-builder';
import serializeBlocks from './utils/serialize-blocks';

/**
* Returns an action generator used in signalling that editor has initialized with
Expand Down Expand Up @@ -73,27 +76,6 @@ export function* setupEditor( post, edits, template ) {
}
}

/**
* Initiliazes an FSE template into the core-data store.
* We could avoid this action entirely by having a fallback if the edit is undefined.
*
* @param {Object} template Template object.
*/
export function* __unstableSetupTemplate( template ) {
const blocks = parse( template.content.raw );
yield controls.dispatch(
'core',
'editEntityRecord',
'postType',
template.type,
template.id,
{
blocks,
},
{ undoIgnore: true }
);
}

/**
* Returns an action object signalling that the editor is being destroyed and
* that any necessary state or side-effect cleanup should occur.
Expand Down Expand Up @@ -645,7 +627,7 @@ export function* resetEditorBlocks( blocks, options = {} ) {
// to make sure the edit makes the post dirty and creates
// a new undo level.
edits.content = ( { blocks: blocksForSerialization = [] } ) =>
serializeBlocks( blocksForSerialization );
__unstableSerializeAndClean( blocksForSerialization );
}
yield* editPost( edits );
}
Expand Down
4 changes: 2 additions & 2 deletions packages/editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
getFreeformContentHandlerName,
getDefaultBlockName,
isUnmodifiedDefaultBlock,
__unstableSerializeAndClean,
} from '@wordpress/blocks';
import { isInTheFuture, getDate } from '@wordpress/date';
import { addQueryArgs } from '@wordpress/url';
Expand All @@ -38,7 +39,6 @@ import {
AUTOSAVE_PROPERTIES,
} from './constants';
import { getPostRawValue } from './reducer';
import serializeBlocks from './utils/serialize-blocks';
import { cleanForSlug } from '../utils/url';

/**
Expand Down Expand Up @@ -991,7 +991,7 @@ export const getEditedPostContent = createRegistrySelector(
if ( typeof record.content === 'function' ) {
return record.content( record );
} else if ( record.blocks ) {
return serializeBlocks( record.blocks );
return __unstableSerializeAndClean( record.blocks );
} else if ( record.content ) {
return record.content;
}
Expand Down
Loading

0 comments on commit 9953cee

Please sign in to comment.