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

Move sectionRootClientId to block editor state #64544

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
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 @@ -32,8 +32,11 @@ function ZoomOutModeInserters() {
getSelectedBlockClientId,
getHoveredBlockClientId,
isBlockInsertionPointVisible,
} = select( blockEditorStore );
const { sectionRootClientId: root } = unlock( getSettings() );
getSectionRootClientId,
} = unlock( select( blockEditorStore ) );

const root = getSectionRootClientId();

return {
hasSelection: !! getSelectionStart().clientId,
blockInsertionPoint: getBlockInsertionPoint(),
Expand Down
4 changes: 2 additions & 2 deletions packages/block-editor/src/components/inner-blocks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ export function useInnerBlocksProps( props = {}, options = {} ) {
getBlockEditingMode,
getBlockSettings,
isDragging,
getSettings,
getSectionRootClientId,
} = unlock( select( blockEditorStore ) );
let _isDropZoneDisabled;

Expand All @@ -225,7 +225,7 @@ export function useInnerBlocksProps( props = {}, options = {} ) {
// In zoom out mode, we want to disable the drop zone for the sections.
// The inner blocks belonging to the section drop zone is
// already disabled by the blocks themselves being disabled.
const { sectionRootClientId } = unlock( getSettings() );
const sectionRootClientId = getSectionRootClientId();

_isDropZoneDisabled = clientId !== sectionRootClientId;
}
Expand Down
9 changes: 3 additions & 6 deletions packages/block-editor/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ import {
__experimentalUpdateSettings,
privateRemoveBlocks,
} from './private-actions';
import { STORE_NAME } from './constants';
import { unlock } from '../lock-unlock';

/** @typedef {import('../components/use-on-block-drop/types').WPDropOperation} WPDropOperation */

Expand Down Expand Up @@ -1670,13 +1668,12 @@ export const setNavigationMode =
*/
export const __unstableSetEditorMode =
( mode ) =>
( { dispatch, select, registry } ) => {
( { dispatch, select } ) => {
// When switching to zoom-out mode, we need to select the parent section
if ( mode === 'zoom-out' ) {
const firstSelectedClientId = select.getBlockSelectionStart();
const { sectionRootClientId } = unlock(
registry.select( STORE_NAME ).getSettings()
);
const sectionRootClientId = select.getSectionRootClientId();

if ( firstSelectedClientId ) {
let sectionClientId;

Expand Down
12 changes: 12 additions & 0 deletions packages/block-editor/src/store/private-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,3 +383,15 @@ export const modifyContentLockBlock =
focusModeToRevert
);
};

/**
* Sets the sectionRootClientId of the block editor.
*
* @param {string} clientId The client id of the block.
*/
export function setSectionRootClientId( clientId ) {
return {
type: 'SET_SECTION_ROOT_CLIENT_ID',
clientId,
};
}
14 changes: 14 additions & 0 deletions packages/block-editor/src/store/private-selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -543,3 +543,17 @@ export const getBlockStyles = createSelector(
export function isZoomOutMode( state ) {
return state.editorMode === 'zoom-out';
}

/**
* Returns the clientID of the element that is
* considered to be the root for inserting new
* "sections" into the editor. This can be thought
* of as the "content" of the current editor.
*
* @param {Object} state Editor state.
*
* @return {string} The client ID of the section root.
*/
export function getSectionRootClientId( state = '' ) {
return state.sectionRootClientId;
}
Comment on lines +557 to +559
Copy link
Contributor Author

@getdave getdave Aug 16, 2024

Choose a reason for hiding this comment

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

Suggested change
export function getSectionRootClientId( state = '' ) {
return state.sectionRootClientId;
}
export function getSectionRootClientId( state = '' ) {
let sectionRootClientId = state.sectionRootClientId;
// Default to the main block if no section root is set.
if ( ! sectionRootClientId ) {
const blocks = getBlocksByName( state, 'core/group' );
sectionRootClientId =
blocks.find(
( clientId ) =>
getBlockAttributes( state, clientId )?.tagName === 'main'
) ?? '';
}
return sectionRootClientId;
}

I wonder if we can default the the algorithm which prefers the <main> tag?

Then if an individual editor needs to customise the behaviour it can dispatch the setSectionRootClientId() action.

Bear in the mind we'd need to account for this part of the existing algorithm in the editor package:

if ( mode === 'template-locked' ) {
	_sectionRootClientId =
		getBlocksByName( 'core/post-content' )?.[ 0 ] ?? '';
}

8 changes: 8 additions & 0 deletions packages/block-editor/src/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2087,6 +2087,13 @@ export function hoveredBlockClientId( state = false, action ) {
return state;
}

export function sectionRootClientId( state = null, action ) {
if ( action.type === 'SET_SECTION_ROOT_CLIENT_ID' ) {
return action.clientId;
}
return state;
}

const combinedReducers = combineReducers( {
blocks,
isDragging,
Expand Down Expand Up @@ -2120,6 +2127,7 @@ const combinedReducers = combineReducers( {
openedBlockSettingsMenu,
registeredInserterMediaCategories,
hoveredBlockClientId,
sectionRootClientId,
} );

function withAutomaticChangeReset( reducer ) {
Expand Down
11 changes: 6 additions & 5 deletions packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
getContentLockingParent,
getTemporarilyEditingAsBlocks,
getTemporarilyEditingFocusModeToRevert,
getSectionRootClientId,
} from './private-selectors';

/**
Expand Down Expand Up @@ -2057,9 +2058,8 @@ export const getInserterItems = createRegistrySelector( ( select ) =>
if ( ! item.rootClientId ) {
let sectionRootClientId;
try {
sectionRootClientId = unlock(
getSettings( state )
).sectionRootClientId;
sectionRootClientId =
getSectionRootClientId( state );
} catch ( e ) {}
if (
sectionRootClientId &&
Expand Down Expand Up @@ -2827,7 +2827,8 @@ export function __unstableHasActiveBlockOverlayActive( state, clientId ) {

// In zoom-out mode, the block overlay is always active for section level blocks.
if ( editorMode === 'zoom-out' ) {
const { sectionRootClientId } = unlock( getSettings( state ) );
const sectionRootClientId = getSectionRootClientId( state );

if ( sectionRootClientId ) {
const sectionClientIds = getBlockOrder(
state,
Expand Down Expand Up @@ -2920,7 +2921,7 @@ export const getBlockEditingMode = createRegistrySelector(
// sections.
const editorMode = __unstableGetEditorMode( state );
if ( editorMode === 'zoom-out' ) {
const { sectionRootClientId } = unlock( getSettings( state ) );
const sectionRootClientId = getSectionRootClientId( state );
if ( clientId === '' /* ROOT_CONTAINER_CLIENT_ID */ ) {
return sectionRootClientId ? 'disabled' : 'contentOnly';
}
Expand Down
8 changes: 5 additions & 3 deletions packages/editor/src/components/inserter-sidebar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ export default function InserterSidebar() {
getBlockInsertionPoint,
getBlockRootClientId,
__unstableGetEditorMode,
getSettings,
} = select( blockEditorStore );
getSectionRootClientId,
} = unlock( select( blockEditorStore ) );

const { get } = select( preferencesStore );
const { getActiveComplementaryArea } = select( interfaceStore );
const getBlockSectionRootClientId = () => {
if ( __unstableGetEditorMode() === 'zoom-out' ) {
const { sectionRootClientId } = unlock( getSettings() );
const sectionRootClientId = getSectionRootClientId();

if ( sectionRootClientId ) {
return sectionRootClientId;
}
Expand Down
39 changes: 39 additions & 0 deletions packages/editor/src/components/provider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
BlockEditorProvider,
BlockContextProvider,
privateApis as blockEditorPrivateApis,
store as blockEditorStore,
} from '@wordpress/block-editor';
import { store as noticesStore } from '@wordpress/notices';
import { privateApis as editPatternsPrivateApis } from '@wordpress/patterns';
Expand Down Expand Up @@ -222,6 +223,37 @@ export const ExperimentalEditorProvider = withRegistryProvider(
setEditedPost,
setRenderingMode,
} = unlock( useDispatch( editorStore ) );

const { computedSectionRootClientId } = useSelect(
( select ) => {
const { getBlockAttributes, getBlocksByName } =
select( blockEditorStore );

let _sectionRootClientId;

if ( mode === 'template-locked' ) {
_sectionRootClientId =
getBlocksByName( 'core/post-content' )?.[ 0 ] ?? '';
} else {
_sectionRootClientId =
getBlocksByName( 'core/group' ).find(
( clientId ) =>
getBlockAttributes( clientId )?.tagName ===
'main'
) ?? '';
}

return {
computedSectionRootClientId: _sectionRootClientId,
};
},
[ mode ]
);
Comment on lines +227 to +251
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Essentially this is the algorithm that determines the section "root" based on things that are specific to WordPress. For example the core/post-content block is likely WP-specific and so we can't embed this logic in the block editor package.

We could move this into a hook to better name the concept and make the code easier to reason about.

What I'm really interested to agree on is whether this is the best location to be doing such setup logic?


const { setSectionRootClientId } = unlock(
useDispatch( blockEditorStore )
);

const { createWarningNotice } = useDispatch( noticesStore );

// Ideally this should be synced on each change and not just something you do once.
Expand Down Expand Up @@ -271,6 +303,13 @@ export const ExperimentalEditorProvider = withRegistryProvider(
setRenderingMode( settings.defaultRenderingMode ?? 'post-only' );
}, [ settings.defaultRenderingMode, setRenderingMode ] );

// Sets the section root client id once it is computed.
useEffect( () => {
if ( computedSectionRootClientId ) {
setSectionRootClientId( computedSectionRootClientId );
}
}, [ computedSectionRootClientId, setSectionRootClientId ] );

useHideBlocksFromInserter( post.type, mode );

// Register the editor commands.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,15 @@ import { __ } from '@wordpress/i18n';
import { store as preferencesStore } from '@wordpress/preferences';
import { useViewportMatch } from '@wordpress/compose';
import { store as blocksStore } from '@wordpress/blocks';
import {
privateApis,
store as blockEditorStore,
} from '@wordpress/block-editor';
import { privateApis } from '@wordpress/block-editor';

/**
* Internal dependencies
*/
import inserterMediaCategories from '../media-categories';
import { mediaUpload } from '../../utils';
import { store as editorStore } from '../../store';
import { lock, unlock } from '../../lock-unlock';
import { unlock } from '../../lock-unlock';
import { useGlobalStylesContext } from '../global-styles-provider';

const EMPTY_BLOCKS_LIST = [];
Expand Down Expand Up @@ -74,7 +71,6 @@ const BLOCK_EDITOR_SETTINGS = [
'postContentAttributes',
'postsPerPage',
'readOnly',
'sectionRootClientId',
'styles',
'titlePlaceholder',
'supportsLayout',
Expand All @@ -95,14 +91,13 @@ const {
/**
* React hook used to compute the block editor settings to use for the post editor.
*
* @param {Object} settings EditorProvider settings prop.
* @param {string} postType Editor root level post type.
* @param {string} postId Editor root level post ID.
* @param {string} renderingMode Editor rendering mode.
* @param {Object} settings EditorProvider settings prop.
* @param {string} postType Editor root level post type.
* @param {string} postId Editor root level post ID.
*
* @return {Object} Block Editor Settings.
*/
function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
function useBlockEditorSettings( settings, postType, postId ) {
const isLargeViewport = useViewportMatch( 'medium' );
const {
allowRightClickOverrides,
Expand All @@ -119,7 +114,6 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
pageForPosts,
userPatternCategories,
restBlockPatternCategories,
sectionRootClientId,
} = useSelect(
( select ) => {
const {
Expand All @@ -131,28 +125,14 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
} = select( coreStore );
const { get } = select( preferencesStore );
const { getBlockTypes } = select( blocksStore );
const { getBlocksByName, getBlockAttributes } =
select( blockEditorStore );

const siteSettings = canUser( 'read', {
kind: 'root',
name: 'site',
} )
? getEntityRecord( 'root', 'site' )
: undefined;

function getSectionRootBlock() {
if ( renderingMode === 'template-locked' ) {
return getBlocksByName( 'core/post-content' )?.[ 0 ] ?? '';
}

return (
getBlocksByName( 'core/group' ).find(
( clientId ) =>
getBlockAttributes( clientId )?.tagName === 'main'
) ?? ''
);
}

return {
allowRightClickOverrides: get(
'core',
Expand Down Expand Up @@ -183,10 +163,9 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
pageForPosts: siteSettings?.page_for_posts,
userPatternCategories: getUserPatternCategories(),
restBlockPatternCategories: getBlockPatternCategories(),
sectionRootClientId: getSectionRootBlock(),
};
},
[ postType, postId, isLargeViewport, renderingMode ]
[ postType, postId, isLargeViewport ]
);

const { merged: mergedGlobalStyles } = useGlobalStylesContext();
Expand Down Expand Up @@ -326,9 +305,7 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
: settings.template,
__experimentalSetIsInserterOpened: setIsInserterOpened,
};
lock( blockEditorSettings, {
sectionRootClientId,
} );

return blockEditorSettings;
}, [
allowedBlockTypes,
Expand All @@ -351,7 +328,6 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) {
pageForPosts,
postType,
setIsInserterOpened,
sectionRootClientId,
globalStylesData,
globalStylesLinksData,
] );
Expand Down
Loading