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

List: simplify indent code & keep client ID #59216

Open
wants to merge 3 commits into
base: trunk
Choose a base branch
from
Open
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,41 @@
* WordPress dependencies
*/
import { useCallback } from '@wordpress/element';
import { useSelect, useDispatch } from '@wordpress/data';
import { useSelect, useDispatch, useRegistry } from '@wordpress/data';
import { store as blockEditorStore } from '@wordpress/block-editor';
import { createBlock, cloneBlock } from '@wordpress/blocks';
import { createBlock } from '@wordpress/blocks';

export default function useIndentListItem( clientId ) {
const { replaceBlocks, selectionChange, multiSelect } =
const registry = useRegistry();
const { insertBlock, moveBlocksToPosition, updateBlockListSettings } =
useDispatch( blockEditorStore );
const {
getBlock,
getPreviousBlockClientId,
getSelectionStart,
getSelectionEnd,
hasMultiSelection,
getMultiSelectedBlockClientIds,
getBlockRootClientId,
getBlockListSettings,
getSelectedBlockClientIds,
getBlockOrder,
} = useSelect( blockEditorStore );
return useCallback( () => {
const _hasMultiSelection = hasMultiSelection();
const clientIds = _hasMultiSelection
? getMultiSelectedBlockClientIds()
: [ clientId ];
const clonedBlocks = clientIds.map( ( _clientId ) =>
cloneBlock( getBlock( _clientId ) )
);
const clientIds = getSelectedBlockClientIds();
const previousSiblingId = getPreviousBlockClientId( clientId );
const newListItem = cloneBlock( getBlock( previousSiblingId ) );
// If the sibling has no innerBlocks, create a new `list` block.
if ( ! newListItem.innerBlocks?.length ) {
newListItem.innerBlocks = [ createBlock( 'core/list' ) ];
}
// A list item usually has one `list`, but it's possible to have
// more. So we need to preserve the previous `list` blocks and
// merge the new blocks to the last `list`.
newListItem.innerBlocks[
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not handled in your PR..

Trunk:

Screen.Recording.2024-03-01.at.4.54.25.PM.mov

This PR:

Screen.Recording.2024-03-01.at.4.53.30.PM.mov

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot reproduce this. My starting content:

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>Top<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>first level</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>hi<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>second level</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Observe this item!!!</strong></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>hi (2)<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>second level (2)</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

What I see:

list-nested-indent-outdent

newListItem.innerBlocks.length - 1
].innerBlocks.push( ...clonedBlocks );
const rootClientId = getBlockRootClientId( clientId );

// We get the selection start/end here, because when
// we replace blocks, the selection is updated too.
const selectionStart = getSelectionStart();
const selectionEnd = getSelectionEnd();
// Replace the previous sibling of the block being indented and the indented blocks,
// with a new block whose attributes are equal to the ones of the previous sibling and
// whose descendants are the children of the previous sibling, followed by the indented blocks.
replaceBlocks( [ previousSiblingId, ...clientIds ], [ newListItem ] );
if ( ! _hasMultiSelection ) {
selectionChange(
clonedBlocks[ 0 ].clientId,
selectionEnd.attributeKey,
selectionEnd.clientId === selectionStart.clientId
? selectionStart.offset
: selectionEnd.offset,
selectionEnd.offset
);
} else {
multiSelect(
clonedBlocks[ 0 ].clientId,
clonedBlocks[ clonedBlocks.length - 1 ].clientId
);
}
registry.batch( () => {
let nestedListId = getBlockOrder( previousSiblingId )[ 0 ];
if ( ! nestedListId ) {
const indentedList = createBlock( 'core/list' );
nestedListId = indentedList.clientId;
insertBlock( indentedList, 0, previousSiblingId, false );
// Immediately update the block list settings, otherwise blocks
// can't be moved here due to canInsert checks.
updateBlockListSettings(
nestedListId,
getBlockListSettings( rootClientId )
);
}
moveBlocksToPosition( clientIds, rootClientId, nestedListId );
} );

return true;
}, [ clientId ] );
Expand Down
Loading