Skip to content

Commit

Permalink
Don't allow multiple CTA / attachment block to be pasted. (#3601)
Browse files Browse the repository at this point in the history
  • Loading branch information
spacedmonkey authored and swissspidy committed Oct 23, 2019
1 parent 80430f5 commit b3149bc
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,30 @@ import { withDispatch, useSelect, useDispatch } from '@wordpress/data';
/**
* Internal dependencies
*/
import { copyTextToClipBoard, ensureAllowedBlocksOnPaste, isPageBlock } from '../../helpers';
import { copyTextToClipBoard, isPageBlock, useIsBlockAllowedOnPage, useDisplayPasteError } from '../../helpers';

function CopyPasteHandler( { children, onCopy, clientId, isSelected } ) {
const {
isFirstPage,
canUserUseUnfilteredHTML,
getCopiedMarkupState,
blocksOnPage,
} = useSelect(
( select ) => {
const {
getBlockOrder,
getSettings,
} = select( 'core/block-editor' );
const { getSettings, getBlockOrder } = select( 'core/block-editor' );
const { __experimentalCanUserUseUnfilteredHTML } = getSettings();
const { getCopiedMarkup } = select( 'amp/story' );
return {
isFirstPage: getBlockOrder().indexOf( clientId ) === 0,
canUserUseUnfilteredHTML: __experimentalCanUserUseUnfilteredHTML,
getCopiedMarkupState: getCopiedMarkup,
blocksOnPage: getBlockOrder( clientId ),
};
}, [ clientId ]
},
[ clientId ]
);

const { insertBlocks } = useDispatch( 'core/block-editor' );
const { insertBlock } = useDispatch( 'core/block-editor' );
const isBlockAllowedOnPage = useIsBlockAllowedOnPage();
const displayPasteError = useDisplayPasteError();

const onPaste = ( event ) => {
// Ignore if the Page is not the selected page.
Expand Down Expand Up @@ -77,9 +75,17 @@ function CopyPasteHandler( { children, onCopy, clientId, isSelected } ) {
canUserUseUnfilteredHTML,
} );

if ( content.length > 0 ) {
insertBlocks( ensureAllowedBlocksOnPaste( content, clientId, isFirstPage ), blocksOnPage.length, clientId );
if ( ! clientId || ! content.length ) {
return;
}

content.forEach( ( pastedBlock ) => {
if ( isBlockAllowedOnPage( pastedBlock.name, clientId ) ) {
insertBlock( pastedBlock, blocksOnPage.length, clientId );
} else {
displayPasteError( pastedBlock.name );
}
} );
};

return (
Expand Down
35 changes: 21 additions & 14 deletions assets/src/stories-editor/components/context-menu/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ import { useDispatch, useSelect } from '@wordpress/data';
import './edit.css';
import {
copyTextToClipBoard,
ensureAllowedBlocksOnPaste,
isPageBlock,
useIsBlockAllowedOnPage,
useMoveBlockToPage,
useDisplayPasteError,
} from '../../helpers';
import { ALLOWED_MOVABLE_BLOCKS, DISABLE_DUPLICATE_BLOCKS } from '../../constants';
import useOutsideClickChecker from './outside-click-checker';
Expand Down Expand Up @@ -63,7 +63,6 @@ const ContextMenu = ( props ) => {
const {
removeBlock,
insertBlock,
insertBlocks,
updateBlockAttributes,
} = useDispatch( 'core/block-editor' );

Expand All @@ -72,6 +71,7 @@ const ContextMenu = ( props ) => {
const { __experimentalCanUserUseUnfilteredHTML: canUserUseUnfilteredHTML, isRTL } = getSettings();

const isBlockAllowedOnPage = useIsBlockAllowedOnPage();
const displayPasteError = useDisplayPasteError();

const copyBlock = ( clientId ) => {
const block = getBlock( clientId );
Expand Down Expand Up @@ -109,20 +109,27 @@ const ContextMenu = ( props ) => {
return;
}

const isFirstPage = getBlockOrder().indexOf( pageClientId ) === 0;
const blocksOnPage = getBlockOrder( pageClientId );
insertBlocks( ensureAllowedBlocksOnPaste( content, pageClientId, isFirstPage ), blocksOnPage.length, pageClientId )
.then( ( { blocks } ) => {
for ( const block of blocks ) {
if ( ALLOWED_MOVABLE_BLOCKS.includes( block.name ) ) {
updateBlockAttributes( block.clientId, {
positionTop: insidePercentageY,
positionLeft: insidePercentageX,
content.forEach( ( pastedBlock ) => {
if ( isBlockAllowedOnPage( pastedBlock.name, pageClientId ) ) {
insertBlock( pastedBlock, blocksOnPage.length, pageClientId )
.then( ( { blocks } ) => {
blocks.forEach( ( block ) => {
if ( ALLOWED_MOVABLE_BLOCKS.includes( block.name ) ) {
updateBlockAttributes( block.clientId, {
positionTop: insidePercentageY,
positionLeft: insidePercentageX,
} );
}
} );
}
}
} )
.catch( () => {} );
} )
.catch( () => {
displayPasteError( pastedBlock.name );
} );
} else {
displayPasteError( pastedBlock.name );
}
} );
};

const cutBlock = ( clientId ) => {
Expand Down
40 changes: 0 additions & 40 deletions assets/src/stories-editor/helpers/ensureAllowedBlocksOnPaste.js

This file was deleted.

2 changes: 1 addition & 1 deletion assets/src/stories-editor/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ export { default as processMedia } from './processMedia';
export { default as addVideoAriaLabel } from './addVideoAriaLabel';
export { default as getCallToActionBlock } from './getCallToActionBlock';
export { default as getPageAttachmentBlock } from './getPageAttachmentBlock';
export { default as ensureAllowedBlocksOnPaste } from './ensureAllowedBlocksOnPaste';
export { default as isPageBlock } from './isPageBlock';
export { default as copyTextToClipBoard } from './copyTextToClipBoard';
export { default as getPosterImageFromFileObj } from './getPosterImageFromFileObj';
Expand All @@ -61,3 +60,4 @@ export { default as getRelativeElementPosition } from './getRelativeElementPosit
export { default as isCTABlock } from './isCTABlock';
export { default as useMoveBlockToPage } from './useMoveBlockToPage';
export { default as useIsBlockAllowedOnPage } from './useIsBlockAllowedOnPage';
export { default as useDisplayPasteError } from './useDisplayPasteError';

This file was deleted.

33 changes: 33 additions & 0 deletions assets/src/stories-editor/helpers/useDisplayPasteError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* WordPress dependencies
*/
import { getBlockType } from '@wordpress/blocks';
import { __, sprintf } from '@wordpress/i18n';
import { useDispatch } from '@wordpress/data';

/**
* A hook to display a paste error message.
*
* @return {Function} Returns a function to display a paste error message.
*/
const useDisplayPasteError = () => {
const { createErrorNotice } = useDispatch( 'core/notices' );

return ( name ) => {
const blockType = getBlockType( name );
const removeMessage = sprintf(
// translators: %s: Type of block (i.e. Text, Image etc)
__( 'Unable to paste %s block.', 'amp' ),
blockType.title
);
createErrorNotice(
removeMessage,
{
type: 'snackbar',
isDismissible: true,
}
);
};
};

export default useDisplayPasteError;

0 comments on commit b3149bc

Please sign in to comment.