Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy load block edit functions #55585

Draft
wants to merge 27 commits into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
059287a
Lazy load block edit functions
jsnajdr Oct 24, 2023
767ab94
fix `editor/blocks/buttons.spec.js` to wait for block after insert
flootr Nov 29, 2023
143e999
fix a few more tests to wait for blocks to appear
flootr Dec 7, 2023
c6be29c
sync load `edit` for heading, list(-item), p, quote
flootr Dec 7, 2023
bcb552f
Revert "sync load `edit` for heading, list(-item), p, quote"
flootr Dec 7, 2023
3d6e555
Experiment: capture input in suspense placeholder
jsnajdr Dec 13, 2023
1ea02d5
Revert "Experiment: capture input in suspense placeholder"
jsnajdr Feb 1, 2024
e38f3f2
lazyEdit function, async transform with after-content
jsnajdr Feb 2, 2024
2a57f9d
Spinner: change role to status so that it's not picked up by role=img…
jsnajdr Feb 5, 2024
1293bd4
Migrate all blocks to lazyEdit
jsnajdr Feb 6, 2024
8da9ec7
Common lazyLoadBlock function to force block lazyEdit load
jsnajdr Feb 6, 2024
5e2233f
useInputRules: track into which lazy loaded block are we currently ty…
jsnajdr Feb 7, 2024
d2d3699
Fix LinkControl unit tests
tyxla Feb 7, 2024
3166afa
Fix role in test snapshot too
tyxla Feb 7, 2024
3ac83c5
Set caret at the end of the inserted content
jsnajdr Feb 7, 2024
822a95a
Memoize creating lazyEdit components globally, not per component
jsnajdr Feb 8, 2024
69b797d
use-bindings-attributes: create init function
jsnajdr Feb 15, 2024
f2cc5d4
Block tree reducer: avoid repetitive Map.get
jsnajdr Feb 15, 2024
3edf8e5
Block tree reducer: avoid nested update for insertUsage
jsnajdr Feb 15, 2024
4dc653f
Block tree reducer: more concise lastBlockInserted
jsnajdr Feb 15, 2024
f023b3d
BlockListBlock: extract functions from the vast withDispatch callback
jsnajdr Feb 15, 2024
623301e
Quote: check if deeply nested child block is selected
jsnajdr Feb 29, 2024
62f6dfd
BlockList: extract block edit functions as thunk actions
jsnajdr Mar 4, 2024
c5e643a
List e2e tests: fix a typo in name
jsnajdr Mar 4, 2024
fbf5ac9
Don't modify state when setting identical selection
jsnajdr Mar 4, 2024
67862ad
synchronizeBlocksWithTemplate: extract common functions
jsnajdr Mar 6, 2024
b007e3c
Universal edit placeholder
jsnajdr Mar 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/block-editor/src/autocompleters/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ function createBlockCompleter() {
name,
initialAttributes,
innerBlocks,
template,
syncStatus,
content,
} = inserterItem;
Expand All @@ -136,7 +137,7 @@ function createBlockCompleter() {
name,
initialAttributes,
createBlocksFromInnerBlocksTemplate(
innerBlocks
innerBlocks || template
)
),
};
Expand Down
94 changes: 86 additions & 8 deletions packages/block-editor/src/components/block-edit/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,18 @@ import {
getBlockDefaultClassName,
hasBlockSupport,
getBlockType,
getBlockEdit,
} from '@wordpress/blocks';
import { useContext, useMemo } from '@wordpress/element';
import { AsyncModeProvider, useDispatch, useSelect } from '@wordpress/data';
import { useContext, useMemo, useRef } from '@wordpress/element';

/**
* Internal dependencies
*/
import BlockContext from '../block-context';
import RichText from '../rich-text';
import { store as blockEditorStore } from '../../store';
import { unlock } from '../../lock-unlock';

/**
* Default value used for blocks which do not define their own context needs,
Expand All @@ -29,20 +34,93 @@ import BlockContext from '../block-context';
*/
const DEFAULT_BLOCK_CONTEXT = {};

function useSelectedChildBlock( clientId ) {
return useSelect(
( select ) => {
const {
getSelectionStart,
isBlockSelected,
hasSelectedInnerBlock,
getBlockAttributes,
getBlockName,
} = select( blockEditorStore );

const isSelected =
isBlockSelected( clientId ) ||
hasSelectedInnerBlock( clientId, true );

if ( ! isSelected ) {
return {
selClientId: null,
selBlockName: null,
selContent: undefined,
};
}

const sClientId = getSelectionStart().clientId;
return {
selClientId: sClientId,
selBlockName: getBlockName( sClientId ),
selContent: getBlockAttributes( sClientId ).content,
};
},
[ clientId ]
);
}
function FallbackRichEdit( { clientId } ) {
const ref = useRef();
const { selClientId, selBlockName, selContent } =
useSelectedChildBlock( clientId );
const { updateBlockAttributes, replaceEdit } = unlock(
useDispatch( blockEditorStore )
);

if ( ! selClientId ) {
return null;
}

const onChange = ( value ) =>
updateBlockAttributes( [ selClientId ], { content: value } );

const onReplace = ( blocks, indexToSelect, initialPos ) =>
replaceEdit( selClientId, blocks, indexToSelect, initialPos );

return (
<div className="block-placeholder">
<RichText
ref={ ref }
identifier="content"
clientId={ selClientId }
blockName={ selBlockName }
value={ selContent }
onChange={ onChange }
onReplace={ onReplace }
__unstableAllowPrefixTransformations={
selBlockName === 'core/paragraph'
}
/>
</div>
);
}

function FallbackEdit( { clientId } ) {
return (
<AsyncModeProvider value={ false }>
<FallbackRichEdit clientId={ clientId } />
</AsyncModeProvider>
);
}

const Edit = ( props ) => {
const { name } = props;
const blockType = getBlockType( name );

if ( ! blockType ) {
const Component = getBlockEdit( blockType );
if ( ! Component ) {
return null;
}

// `edit` and `save` are functions or components describing the markup
// with which a block is displayed. If `blockType` is valid, assign
// them preferentially as the render value for the block.
const Component = blockType.edit || blockType.save;

return <Component { ...props } />;
return <Component FallbackEdit={ FallbackEdit } { ...props } />;
};

const EditWithFilters = withFilters( 'editor.BlockEdit' )( Edit );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* WordPress dependencies
*/
import { withFilters } from '@wordpress/components';
import { getBlockType } from '@wordpress/blocks';
import { getBlockType, getBlockEdit } from '@wordpress/blocks';
import { useContext, useMemo } from '@wordpress/element';

/**
Expand Down Expand Up @@ -37,12 +37,11 @@ export const Edit = ( props ) => {
: DEFAULT_BLOCK_CONTEXT;
}, [ blockType, blockContext ] );

if ( ! blockType ) {
const Component = getBlockEdit( blockType );
if ( ! Component ) {
return null;
}

const Component = blockType.edit;

return <Component { ...props } context={ context } />;
};

Expand Down
Loading
Loading