Skip to content
Merged
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 @@ -92,19 +92,21 @@ export default function EditContents( { clientId } ) {
stopEditingContentOnlySection,
} = useContentOnlySectionEdit( clientId );

const { block, onNavigateToEntityRecord } = useSelect(
const { block, onNavigateToEntityRecord, canEdit } = useSelect(
( select ) => {
const { getBlock, getSettings } = select( blockEditorStore );
const { getBlock, getSettings, canEditBlock } =
select( blockEditorStore );
return {
block: getBlock( clientId ),
onNavigateToEntityRecord:
getSettings().onNavigateToEntityRecord,
canEdit: canEditBlock( clientId ),
};
},
[ clientId ]
);

if ( ! isWithinSection && ! isWithinEditedSection ) {
if ( ! canEdit || ( ! isWithinSection && ! isWithinEditedSection ) ) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import clsx from 'clsx';
* WordPress dependencies
*/
import { useState } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import { debounce, useViewportMatch } from '@wordpress/compose';
import {
Button,
Expand All @@ -24,11 +25,16 @@ import BlockStylesPreviewPanel from './preview-panel';
import useStylesForBlocks from './use-styles-for-block';
import { useToolsPanelDropdownMenuProps } from '../global-styles/utils';
import { getDefaultStyle } from './utils';
import { store as blockEditorStore } from '../../store';

const noop = () => {};

// Block Styles component for the Settings Sidebar.
function BlockStyles( { clientId, onSwitch = noop, onHoverClassName = noop } ) {
const canEdit = useSelect(
( select ) => select( blockEditorStore ).canEditBlock( clientId ),
[ clientId ]
);
const {
onSelect,
stylesToRender,
Expand All @@ -43,7 +49,7 @@ function BlockStyles( { clientId, onSwitch = noop, onHoverClassName = noop } ) {
const isMobileViewport = useViewportMatch( 'medium', '<' );
const dropdownMenuProps = useToolsPanelDropdownMenuProps();

if ( ! stylesToRender || stylesToRender.length === 0 ) {
if ( ! canEdit || ! stylesToRender || stylesToRender.length === 0 ) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,41 +146,46 @@ function VariationsToggleGroupControl( {

function __experimentalBlockVariationTransforms( { blockClientId } ) {
const { updateBlockAttributes } = useDispatch( blockEditorStore );
const { activeBlockVariation, variations, isContentOnly, isSection } =
useSelect(
( select ) => {
const { getActiveBlockVariation, getBlockVariations } =
select( blocksStore );

const {
getBlockName,
getBlockAttributes,
getBlockEditingMode,
isSectionBlock,
} = unlock( select( blockEditorStore ) );

const name = blockClientId && getBlockName( blockClientId );

const { hasContentRoleAttribute } = unlock(
select( blocksStore )
);
const isContentBlock = hasContentRoleAttribute( name );

return {
activeBlockVariation: getActiveBlockVariation(
name,
getBlockAttributes( blockClientId ),
'transform'
),
variations: name && getBlockVariations( name, 'transform' ),
isContentOnly:
getBlockEditingMode( blockClientId ) ===
'contentOnly' && ! isContentBlock,
isSection: isSectionBlock( blockClientId ),
};
},
[ blockClientId ]
);
const {
activeBlockVariation,
variations,
canEdit,
isContentOnly,
isSection,
} = useSelect(
( select ) => {
const { getActiveBlockVariation, getBlockVariations } =
select( blocksStore );

const {
getBlockName,
getBlockAttributes,
getBlockEditingMode,
isSectionBlock,
} = unlock( select( blockEditorStore ) );
const { canEditBlock } = select( blockEditorStore );

const name = blockClientId && getBlockName( blockClientId );

const { hasContentRoleAttribute } = unlock( select( blocksStore ) );
const isContentBlock = hasContentRoleAttribute( name );

return {
activeBlockVariation: getActiveBlockVariation(
name,
getBlockAttributes( blockClientId ),
'transform'
),
variations: name && getBlockVariations( name, 'transform' ),
canEdit: canEditBlock( blockClientId ),
isContentOnly:
getBlockEditingMode( blockClientId ) === 'contentOnly' &&
! isContentBlock,
isSection: isSectionBlock( blockClientId ),
};
},
[ blockClientId ]
);

const selectedValue = activeBlockVariation?.name;

Expand All @@ -205,7 +210,7 @@ function __experimentalBlockVariationTransforms( { blockClientId } ) {
} );
};

if ( ! variations?.length || isContentOnly || isSection ) {
if ( ! variations?.length || ! canEdit || isContentOnly || isSection ) {
return null;
}

Expand Down
14 changes: 8 additions & 6 deletions packages/editor/src/components/editor-interface/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import clsx from 'clsx';
* WordPress dependencies
*/
import { InterfaceSkeleton, ComplementaryArea } from '@wordpress/interface';
import { useSelect } from '@wordpress/data';
import { useSelect, useDispatch } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { store as preferencesStore } from '@wordpress/preferences';
import { BlockBreadcrumb, BlockToolbar } from '@wordpress/block-editor';
Expand Down Expand Up @@ -82,6 +82,7 @@ export default function EditorInterface( {
stylesPath,
showStylebook,
isRevisionsMode,
showDiff,
} = useSelect( ( select ) => {
const { get } = select( preferencesStore );
const {
Expand All @@ -94,6 +95,7 @@ export default function EditorInterface( {
getStylesPath,
getShowStylebook,
isRevisionsMode: _isRevisionsMode,
isShowingRevisionDiff,
} = unlock( select( editorStore ) );
const editorSettings = getEditorSettings();

Expand Down Expand Up @@ -121,8 +123,11 @@ export default function EditorInterface( {
getCurrentPostType() === 'attachment' &&
window?.__experimentalMediaEditor,
isRevisionsMode: _isRevisionsMode(),
showDiff: isShowingRevisionDiff(),
};
}, [] );
const { setShowRevisionDiff } = unlock( useDispatch( editorStore ) );

// Runs unconditionally so join/leave/save notifications are dispatched
// regardless of viewport width or whether the header centre area is visible.
useCollaboratorNotifications( postId, postType );
Expand Down Expand Up @@ -152,9 +157,6 @@ export default function EditorInterface( {
[ entitiesSavedStatesCallback ]
);

// Local state for diff toggle in revisions mode.
const [ showDiff, setShowDiff ] = useState( true );

// When in revisions mode, render the revisions interface.
if ( isRevisionsMode ) {
return (
Expand All @@ -164,10 +166,10 @@ export default function EditorInterface( {
header={
<RevisionsHeader
showDiff={ showDiff }
onToggleDiff={ () => setShowDiff( ! showDiff ) }
onToggleDiff={ () => setShowRevisionDiff( ! showDiff ) }
/>
}
content={ <RevisionsCanvas showDiff={ showDiff } /> }
content={ <RevisionsCanvas /> }
sidebar={ <ComplementaryArea.Slot scope="core" /> }
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,9 @@ import clsx from 'clsx';
* WordPress dependencies
*/
import { Spinner } from '@wordpress/components';
import {
privateApis as blockEditorPrivateApis,
store as blockEditorStore,
} from '@wordpress/block-editor';
import { createBlock, parse } from '@wordpress/blocks';
import { EntityProvider } from '@wordpress/core-data';
import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';
import { useSelect } from '@wordpress/data';
import { useEffect, useMemo, useRef } from '@wordpress/element';
import { useEffect } from '@wordpress/element';
import { addFilter } from '@wordpress/hooks';

/**
Expand All @@ -28,12 +23,8 @@ import {
unregisterDiffFormatTypes,
} from './diff-format-types';
import { useDiffMarkers } from './diff-markers';
import { preserveClientIds } from './preserve-client-ids';
import { diffRevisionContent } from './block-diff';

const { ExperimentalBlockEditorProvider, usePrivateStyleOverride } = unlock(
blockEditorPrivateApis
);
const { usePrivateStyleOverride } = unlock( blockEditorPrivateApis );

// SVG filter for removed blocks: grayscale + red tint
const REVISION_REMOVED_FILTER_SVG = `
Expand Down Expand Up @@ -151,104 +142,35 @@ function CanvasContent( { showDiff } ) {

/**
* Canvas component that renders a post revision in read-only mode.
* Block preparation and settings are handled by the parent EditorProvider.
*
* @param {Object} props Component props.
* @param {boolean} props.showDiff Whether to show diff highlighting.
* @return {React.JSX.Element} The revisions canvas component.
*/
export default function RevisionsCanvas( { showDiff } ) {
export default function RevisionsCanvas() {
useEffect( () => {
registerDiffFormatTypes();
return () => {
unregisterDiffFormatTypes();
};
}, [] );

const { revision, previousRevision, postType, blockEditorSettings } =
useSelect( ( select ) => {
const {
getCurrentRevision,
getPreviousRevision,
getCurrentPostType,
} = unlock( select( editorStore ) );
return {
revision: getCurrentRevision(),
previousRevision: getPreviousRevision(),
postType: getCurrentPostType(),
blockEditorSettings: select( blockEditorStore ).getSettings(),
};
}, [] );

// Track previously rendered blocks to preserve clientIds between renders.
const previousBlocksRef = useRef( [] );

const blocks = useMemo( () => {
const currentContent = revision?.content?.raw ?? '';

let parsedBlocks;
if ( showDiff ) {
const previousContent = previousRevision?.content?.raw || '';
// diffRevisionContent handles both normal diffing and the case
// where there's no previous revision (oldest revision shows all as added).
parsedBlocks = diffRevisionContent(
currentContent,
previousContent
);
} else {
// When diff is disabled, just parse the current revision content.
parsedBlocks = parse( currentContent );
}

if ( postType === 'wp_navigation' ) {
parsedBlocks = [
createBlock(
'core/navigation',
{ templateLock: false },
parsedBlocks
),
];
}

// Preserve clientIds from previous render to prevent React unmount/remount.
const blocksWithStableIds = preserveClientIds(
parsedBlocks,
previousBlocksRef.current
const { revision, showDiff } = useSelect( ( select ) => {
const { getCurrentRevision, isShowingRevisionDiff } = unlock(
select( editorStore )
);

// Update ref for next render.
previousBlocksRef.current = blocksWithStableIds;

return blocksWithStableIds;
}, [
revision?.content?.raw,
previousRevision?.content?.raw,
postType,
showDiff,
] );

const settings = useMemo(
() => ( {
...blockEditorSettings,
isPreviewMode: true,
} ),
[ blockEditorSettings ]
);
return {
revision: getCurrentRevision(),
showDiff: isShowingRevisionDiff(),
};
}, [] );

return revision ? (
// EntityProvider without kind/type/id inherits those from the
// parent context. Only revisionId is added so that useEntityProp
// reads from the revision record instead of the current entity.
<EntityProvider revisionId={ revision.id }>
<ExperimentalBlockEditorProvider
value={ blocks }
settings={ settings }
>
<DiffStyleOverrides showDiff={ showDiff } />
<div className="editor-revisions-canvas__content">
<CanvasContent showDiff={ showDiff } />
</div>
</ExperimentalBlockEditorProvider>
</EntityProvider>
<>
<DiffStyleOverrides showDiff={ showDiff } />
<div className="editor-revisions-canvas__content">
<CanvasContent showDiff={ showDiff } />
</div>
</>
) : (
<div className="editor-revisions-canvas__loading">
<Spinner />
Expand Down
Loading
Loading