From 666cbe8169cc93f04bbbed55c629a0722c08e4de Mon Sep 17 00:00:00 2001 From: illusaen Date: Wed, 7 Apr 2021 08:16:17 -0500 Subject: [PATCH] Transform Blocks (#28453) * WC: WIP: Adding transform block ability with no filters. Also refactored options picker for block settings to have options in one object for better filtering and separated out props to the three different types. * Moving getPossibleBLockTransformations to block menu so that we can tell if there are no valid transformation options and if so, not pop up transform option. * Adding filter hook to modify transform.isMatch for each registered block depending on if they are allowed to transform. * Separating out transform logic into transforms.native.js. Adding all block transformation categories in. * Removing extraneous transforms.native.js file. Adding a fix for transforming group -> column block that resulted in crash. * Adding ' blocks' to end of transformations which split one block into multiple. Co-authored-by: Wendy Chen --- .../src/components/block-list/index.native.js | 2 +- .../block-actions-menu.native.js | 276 ++++++++++-------- .../block-transformations-menu.native.js | 91 ++++++ .../src/audio/transforms.native.js | 12 + .../src/buttons/transforms.native.js | 12 + .../src/code/transforms.native.js | 12 + .../block-library/src/column/edit.native.js | 4 + .../src/columns/transforms.native.js | 12 + .../src/cover/transforms.native.js | 12 + .../src/embed/transforms.native.js | 12 + .../src/file/transforms.native.js | 12 + .../src/gallery/transforms.native.js | 12 + .../src/heading/transforms.native.js | 12 + .../src/html/transforms.native.js | 11 + .../src/image/transforms.native.js | 12 + packages/block-library/src/index.native.js | 24 ++ .../src/list/transforms.native.js | 12 + .../src/media-text/transforms.native.js | 12 + .../src/more/transforms.native.js | 12 + .../src/nextpage/transforms.native.js | 12 + .../src/paragraph/transforms.native.js | 12 + .../src/preformatted/transforms.native.js | 12 + .../src/pullquote/transforms.native.js | 12 + .../src/quote/transforms.native.js | 12 + .../src/separator/transforms.native.js | 12 + .../src/shortcode/transforms.native.js | 12 + .../src/table/transforms.native.js | 11 + .../src/text-columns/transforms.native.js | 12 + .../src/transformationCategories.native.js | 46 +++ .../src/verse/transforms.native.js | 12 + .../src/video/transforms.native.js | 12 + packages/blocks/src/api/factory.js | 33 ++- 32 files changed, 646 insertions(+), 128 deletions(-) create mode 100644 packages/block-editor/src/components/block-switcher/block-transformations-menu.native.js create mode 100644 packages/block-library/src/audio/transforms.native.js create mode 100644 packages/block-library/src/buttons/transforms.native.js create mode 100644 packages/block-library/src/code/transforms.native.js create mode 100644 packages/block-library/src/columns/transforms.native.js create mode 100644 packages/block-library/src/cover/transforms.native.js create mode 100644 packages/block-library/src/embed/transforms.native.js create mode 100644 packages/block-library/src/file/transforms.native.js create mode 100644 packages/block-library/src/gallery/transforms.native.js create mode 100644 packages/block-library/src/heading/transforms.native.js create mode 100644 packages/block-library/src/html/transforms.native.js create mode 100644 packages/block-library/src/image/transforms.native.js create mode 100644 packages/block-library/src/list/transforms.native.js create mode 100644 packages/block-library/src/media-text/transforms.native.js create mode 100644 packages/block-library/src/more/transforms.native.js create mode 100644 packages/block-library/src/nextpage/transforms.native.js create mode 100644 packages/block-library/src/paragraph/transforms.native.js create mode 100644 packages/block-library/src/preformatted/transforms.native.js create mode 100644 packages/block-library/src/pullquote/transforms.native.js create mode 100644 packages/block-library/src/quote/transforms.native.js create mode 100644 packages/block-library/src/separator/transforms.native.js create mode 100644 packages/block-library/src/shortcode/transforms.native.js create mode 100644 packages/block-library/src/table/transforms.native.js create mode 100644 packages/block-library/src/text-columns/transforms.native.js create mode 100644 packages/block-library/src/transformationCategories.native.js create mode 100644 packages/block-library/src/verse/transforms.native.js create mode 100644 packages/block-library/src/video/transforms.native.js diff --git a/packages/block-editor/src/components/block-list/index.native.js b/packages/block-editor/src/components/block-list/index.native.js index 9ca43f790e5b82..c60163cf9a3bee 100644 --- a/packages/block-editor/src/components/block-list/index.native.js +++ b/packages/block-editor/src/components/block-list/index.native.js @@ -60,7 +60,7 @@ export class BlockList extends Component { renderFooterAppender: this.props.renderFooterAppender, renderAppender: this.props.renderAppender, onDeleteBlock: this.props.onDeleteBlock, - contentStyle: this.props.contentstyle, + contentStyle: this.props.contentStyle, }; this.renderItem = this.renderItem.bind( this ); this.renderBlockListFooter = this.renderBlockListFooter.bind( this ); diff --git a/packages/block-editor/src/components/block-mobile-toolbar/block-actions-menu.native.js b/packages/block-editor/src/components/block-mobile-toolbar/block-actions-menu.native.js index 735abb833e4fee..a5cc68adaf85e3 100644 --- a/packages/block-editor/src/components/block-mobile-toolbar/block-actions-menu.native.js +++ b/packages/block-editor/src/components/block-mobile-toolbar/block-actions-menu.native.js @@ -31,31 +31,37 @@ import { store as noticesStore } from '@wordpress/notices'; */ import { getMoversSetup } from '../block-mover/mover-description'; import { store as blockEditorStore } from '../../store'; +import BlockTransformationsMenu from '../block-switcher/block-transformations-menu'; const BlockActionsMenu = ( { - onDelete, - isStackedHorizontally, - wrapBlockSettings, - wrapBlockMover, - openGeneralSidebar, - onMoveDown, - onMoveUp, - isFirst, - isLast, + // Select blockTitle, - isEmptyDefaultBlock, - anchorNodeRef, + canInsertBlockType, getBlocksByClientId, + isEmptyDefaultBlock, + isFirst, + isLast, + rootClientId, selectedBlockClientId, + selectedBlockPossibleTransformations, + // Dispatch createSuccessNotice, duplicateBlock, - removeBlocks, + onMoveDown, + onMoveUp, + openGeneralSidebar, pasteBlock, - canInsertBlockType, - rootClientId, + removeBlocks, + // Passed in + anchorNodeRef, + isStackedHorizontally, + onDelete, + wrapBlockMover, + wrapBlockSettings, } ) => { const [ clipboard, setCurrentClipboard ] = useState( getClipboard() ); - const pickerRef = useRef(); + const blockActionsMenuPickerRef = useRef(); + const blockTransformationMenuPickerRef = useRef(); const moversOptions = { keys: [ 'icon', 'actionTitle' ] }; const clipboardBlock = clipboard && rawHandler( { HTML: clipboard } )[ 0 ]; const isPasteEnabled = @@ -69,134 +75,137 @@ const BlockActionsMenu = ( { }, } = getMoversSetup( isStackedHorizontally, moversOptions ); - const deleteOption = { - id: 'deleteOption', - label: __( 'Remove block' ), - value: 'deleteOption', - separated: true, - disabled: isEmptyDefaultBlock, - }; - - const settingsOption = { - id: 'settingsOption', - label: __( 'Block settings' ), - value: 'settingsOption', - }; - - const backwardButtonOption = { - id: 'backwardButtonOption', - label: backwardButtonTitle, - value: 'backwardButtonOption', - disabled: isFirst, - }; - - const forwardButtonOption = { - id: 'forwardButtonOption', - label: forwardButtonTitle, - value: 'forwardButtonOption', - disabled: isLast, - }; - - const copyButtonOption = { - id: 'copyButtonOption', - label: __( 'Copy block' ), - value: 'copyButtonOption', - }; - - const cutButtonOption = { - id: 'cutButtonOption', - label: __( 'Cut block' ), - value: 'cutButtonOption', - }; - - const pasteButtonOption = { - id: 'pasteButtonOption', - label: __( 'Paste block after' ), - value: 'pasteButtonOption', - }; - - const duplicateButtonOption = { - id: 'duplicateButtonOption', - label: __( 'Duplicate block' ), - value: 'duplicateButtonOption', - }; - - const options = compact( [ - wrapBlockMover && backwardButtonOption, - wrapBlockMover && forwardButtonOption, - wrapBlockSettings && settingsOption, - copyButtonOption, - cutButtonOption, - isPasteEnabled && pasteButtonOption, - duplicateButtonOption, - deleteOption, - ] ); - - function onPasteBlock() { - if ( ! clipboard ) { - return; - } - - pasteBlock( rawHandler( { HTML: clipboard } )[ 0 ] ); - } - - function onPickerSelect( value ) { - switch ( value ) { - case deleteOption.value: + const allOptions = { + settings: { + id: 'settingsOption', + label: __( 'Block settings' ), + value: 'settingsOption', + onSelect: openGeneralSidebar, + }, + backwardButton: { + id: 'backwardButtonOption', + label: backwardButtonTitle, + value: 'backwardButtonOption', + disabled: isFirst, + onSelect: onMoveUp, + }, + forwardButton: { + id: 'forwardButtonOption', + label: forwardButtonTitle, + value: 'forwardButtonOption', + disabled: isLast, + onSelect: onMoveDown, + }, + delete: { + id: 'deleteOption', + label: __( 'Remove block' ), + value: 'deleteOption', + separated: true, + disabled: isEmptyDefaultBlock, + onSelect: () => { onDelete(); createSuccessNotice( // translators: displayed right after the block is removed. __( 'Block removed' ) ); - break; - case settingsOption.value: - openGeneralSidebar(); - break; - case forwardButtonOption.value: - onMoveDown(); - break; - case backwardButtonOption.value: - onMoveUp(); - break; - case copyButtonOption.value: - const copyBlock = getBlocksByClientId( selectedBlockClientId ); - const serializedBlock = serialize( copyBlock ); + }, + }, + transformButton: { + id: 'transformButtonOption', + label: __( 'Transform block…' ), + value: 'transformButtonOption', + onSelect: () => { + if ( blockTransformationMenuPickerRef.current ) { + blockTransformationMenuPickerRef.current.presentPicker(); + } + }, + }, + copyButton: { + id: 'copyButtonOption', + label: __( 'Copy block' ), + value: 'copyButtonOption', + onSelect: () => { + const serializedBlock = serialize( + getBlocksByClientId( selectedBlockClientId ) + ); setCurrentClipboard( serializedBlock ); setClipboard( serializedBlock ); createSuccessNotice( // translators: displayed right after the block is copied. __( 'Block copied' ) ); - break; - case cutButtonOption.value: - const cutBlock = getBlocksByClientId( selectedBlockClientId ); - setClipboard( serialize( cutBlock ) ); + }, + }, + cutButton: { + id: 'cutButtonOption', + label: __( 'Cut block' ), + value: 'cutButtonOption', + onSelect: () => { + setClipboard( + serialize( getBlocksByClientId( selectedBlockClientId ) ) + ); removeBlocks( selectedBlockClientId ); createSuccessNotice( // translators: displayed right after the block is cut. __( 'Block cut' ) ); - break; - case pasteButtonOption.value: + }, + }, + pasteButton: { + id: 'pasteButtonOption', + label: __( 'Paste block after' ), + value: 'pasteButtonOption', + onSelect: () => { onPasteBlock(); createSuccessNotice( // translators: displayed right after the block is pasted. __( 'Block pasted' ) ); - break; - case duplicateButtonOption.value: + }, + }, + duplicateButton: { + id: 'duplicateButtonOption', + label: __( 'Duplicate block' ), + value: 'duplicateButtonOption', + onSelect: () => { duplicateBlock(); createSuccessNotice( // translators: displayed right after the block is duplicated. __( 'Block duplicated' ) ); - break; + }, + }, + }; + + const options = compact( [ + wrapBlockMover && allOptions.backwardButton, + wrapBlockMover && allOptions.forwardButton, + wrapBlockSettings && allOptions.settings, + selectedBlockPossibleTransformations.length && + allOptions.transformButton, + allOptions.copyButton, + allOptions.cutButton, + isPasteEnabled && allOptions.pasteButton, + allOptions.duplicateButton, + allOptions.delete, + ] ); + + function onPasteBlock() { + if ( ! clipboard ) { + return; } + + pasteBlock( rawHandler( { HTML: clipboard } )[ 0 ] ); + } + + function onPickerSelect( value ) { + const selectedItem = options.find( ( item ) => item.value === value ); + selectedItem.onSelect(); } function onPickerPresent() { - if ( pickerRef.current ) { - pickerRef.current.presentPicker(); + if ( blockActionsMenuPickerRef.current ) { + blockActionsMenuPickerRef.current.presentPicker(); } } @@ -223,7 +232,7 @@ const BlockActionsMenu = ( { } } /> + ); }; @@ -245,6 +262,7 @@ export default compose( getBlockRootClientId, getBlockOrder, getBlockName, + getBlockTransformItems, getBlock, getBlocksByClientId, getSelectedBlockClientIds, @@ -271,16 +289,24 @@ export default compose( const isEmptyDefaultBlock = isExactlyOneBlock && isDefaultBlock && isEmptyContent; + const selectedBlockClientId = getSelectedBlockClientIds(); + const selectedBlock = getBlocksByClientId( selectedBlockClientId ); + const selectedBlockPossibleTransformations = getBlockTransformItems( + selectedBlock, + rootClientId + ); + return { + blockTitle, + canInsertBlockType, + currentIndex: firstIndex, + getBlocksByClientId, + isEmptyDefaultBlock, isFirst: firstIndex === 0, isLast: lastIndex === blockOrder.length - 1, rootClientId, - blockTitle, - isEmptyDefaultBlock, - getBlocksByClientId, - selectedBlockClientId: getSelectedBlockClientIds(), - currentIndex: firstIndex, - canInsertBlockType, + selectedBlockClientId, + selectedBlockPossibleTransformations, }; } ), withDispatch( @@ -300,15 +326,14 @@ export default compose( const { createSuccessNotice } = dispatch( noticesStore ); return { - onMoveDown: partial( moveBlocksDown, clientIds, rootClientId ), - onMoveUp: partial( moveBlocksUp, clientIds, rootClientId ), - openGeneralSidebar: () => - openGeneralSidebar( 'edit-post/block' ), createSuccessNotice, duplicateBlock() { return duplicateBlocks( clientIds ); }, - removeBlocks, + onMoveDown: partial( moveBlocksDown, clientIds, rootClientId ), + onMoveUp: partial( moveBlocksUp, clientIds, rootClientId ), + openGeneralSidebar: () => + openGeneralSidebar( 'edit-post/block' ), pasteBlock: ( clipboardBlock ) => { const canReplaceBlock = isUnmodifiedDefaultBlock( getBlock( getBlockSelectionEnd() ) @@ -330,6 +355,7 @@ export default compose( replaceBlocks( clientIds, clipboardBlock ); } }, + removeBlocks, }; } ), diff --git a/packages/block-editor/src/components/block-switcher/block-transformations-menu.native.js b/packages/block-editor/src/components/block-switcher/block-transformations-menu.native.js new file mode 100644 index 00000000000000..ce2822d0c6dbc9 --- /dev/null +++ b/packages/block-editor/src/components/block-switcher/block-transformations-menu.native.js @@ -0,0 +1,91 @@ +/** + * External dependencies + */ +import { findNodeHandle, Platform } from 'react-native'; + +/** + * WordPress dependencies + */ +import { __, sprintf } from '@wordpress/i18n'; +import { switchToBlockType } from '@wordpress/blocks'; +import { Picker } from '@wordpress/components'; +import { useDispatch } from '@wordpress/data'; +import { store as noticesStore } from '@wordpress/notices'; + +/** + * Internal dependencies + */ +import { store as blockEditorStore } from '../../store'; + +const BlockTransformationsMenu = ( { + anchorNodeRef, + blockTitle, + pickerRef, + possibleTransformations, + selectedBlock, + selectedBlockClientId, +} ) => { + const { replaceBlocks } = useDispatch( blockEditorStore ); + const { createSuccessNotice } = useDispatch( noticesStore ); + + const pickerOptions = () => { + const selectedBlockName = + ( selectedBlock.length && selectedBlock[ 0 ].name ) || ''; + const blocksThatSplitWhenTransformed = { + 'core/list': [ 'core/paragraph', 'core/heading' ], + 'core/quote': [ 'core/paragraph' ], + 'core/pullquote': [ 'core/paragraph' ], + }; + + return possibleTransformations.map( ( item ) => { + const label = + selectedBlockName.length && + blocksThatSplitWhenTransformed[ selectedBlockName ] && + blocksThatSplitWhenTransformed[ selectedBlockName ].includes( + item.id + ) + ? `${ item.title } blocks` + : item.title; + return { + label, + value: item.id, + }; + } ); + }; + + const getAnchor = () => + anchorNodeRef ? findNodeHandle( anchorNodeRef ) : undefined; + + function onPickerSelect( value ) { + replaceBlocks( + selectedBlockClientId, + switchToBlockType( selectedBlock, value ) + ); + + const selectedItem = pickerOptions().find( + ( item ) => item.value === value + ); + const successNotice = sprintf( + /* translators: 1: From block title, e.g. Paragraph. 2: To block title, e.g. Header. */ + __( '%1$s transformed to %2$s' ), + blockTitle, + selectedItem.label + ); + createSuccessNotice( successNotice ); + } + + return ( + + ); +}; + +export default BlockTransformationsMenu; diff --git a/packages/block-library/src/audio/transforms.native.js b/packages/block-library/src/audio/transforms.native.js new file mode 100644 index 00000000000000..839cdfe3c93810 --- /dev/null +++ b/packages/block-library/src/audio/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.media, +}; + +export default transforms; diff --git a/packages/block-library/src/buttons/transforms.native.js b/packages/block-library/src/buttons/transforms.native.js new file mode 100644 index 00000000000000..0816b765fee290 --- /dev/null +++ b/packages/block-library/src/buttons/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.other, +}; + +export default transforms; diff --git a/packages/block-library/src/code/transforms.native.js b/packages/block-library/src/code/transforms.native.js new file mode 100644 index 00000000000000..21b6405a15030a --- /dev/null +++ b/packages/block-library/src/code/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.richText, +}; + +export default transforms; diff --git a/packages/block-library/src/column/edit.native.js b/packages/block-library/src/column/edit.native.js index 2532629f91616f..bb3bbe045eec43 100644 --- a/packages/block-library/src/column/edit.native.js +++ b/packages/block-library/src/column/edit.native.js @@ -52,6 +52,10 @@ function ColumnEdit( { clientId, blockWidth, } ) { + if ( ! contentStyle ) { + contentStyle = { [ clientId ]: {} }; + } + const { verticalAlignment, width } = attributes; const { valueUnit = '%' } = getValueAndUnit( width ) || {}; diff --git a/packages/block-library/src/columns/transforms.native.js b/packages/block-library/src/columns/transforms.native.js new file mode 100644 index 00000000000000..032a3464258944 --- /dev/null +++ b/packages/block-library/src/columns/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.grouped, +}; + +export default transforms; diff --git a/packages/block-library/src/cover/transforms.native.js b/packages/block-library/src/cover/transforms.native.js new file mode 100644 index 00000000000000..839cdfe3c93810 --- /dev/null +++ b/packages/block-library/src/cover/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.media, +}; + +export default transforms; diff --git a/packages/block-library/src/embed/transforms.native.js b/packages/block-library/src/embed/transforms.native.js new file mode 100644 index 00000000000000..839cdfe3c93810 --- /dev/null +++ b/packages/block-library/src/embed/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.media, +}; + +export default transforms; diff --git a/packages/block-library/src/file/transforms.native.js b/packages/block-library/src/file/transforms.native.js new file mode 100644 index 00000000000000..839cdfe3c93810 --- /dev/null +++ b/packages/block-library/src/file/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.media, +}; + +export default transforms; diff --git a/packages/block-library/src/gallery/transforms.native.js b/packages/block-library/src/gallery/transforms.native.js new file mode 100644 index 00000000000000..839cdfe3c93810 --- /dev/null +++ b/packages/block-library/src/gallery/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.media, +}; + +export default transforms; diff --git a/packages/block-library/src/heading/transforms.native.js b/packages/block-library/src/heading/transforms.native.js new file mode 100644 index 00000000000000..21b6405a15030a --- /dev/null +++ b/packages/block-library/src/heading/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.richText, +}; + +export default transforms; diff --git a/packages/block-library/src/html/transforms.native.js b/packages/block-library/src/html/transforms.native.js new file mode 100644 index 00000000000000..9e7c243a6d8cd5 --- /dev/null +++ b/packages/block-library/src/html/transforms.native.js @@ -0,0 +1,11 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: [], +}; + +export default transforms; diff --git a/packages/block-library/src/image/transforms.native.js b/packages/block-library/src/image/transforms.native.js new file mode 100644 index 00000000000000..839cdfe3c93810 --- /dev/null +++ b/packages/block-library/src/image/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.media, +}; + +export default transforms; diff --git a/packages/block-library/src/index.native.js b/packages/block-library/src/index.native.js index d7d9b1e4bbf646..c16a19709ea15b 100644 --- a/packages/block-library/src/index.native.js +++ b/packages/block-library/src/index.native.js @@ -63,6 +63,8 @@ import * as buttons from './buttons'; import * as socialLink from './social-link'; import * as socialLinks from './social-links'; +import { transformationCategory } from './transformationCategories'; + export const coreBlocks = [ // Common blocks are grouped at the top to prioritize their display // in various contexts — like the inserter and auto-complete components. @@ -180,6 +182,28 @@ addFilter( } ); +addFilter( + 'blocks.registerBlockType', + 'core/react-native-editor', + ( settings, name ) => { + if ( ! settings.transforms ) { + return settings; + } + + if ( ! settings.transforms.supportedMobileTransforms ) { + return { + ...settings, + transforms: { + ...settings.transforms, + supportedMobileTransforms: transformationCategory( name ), + }, + }; + } + + return settings; + } +); + /** * Function to register core blocks provided by the block editor. * diff --git a/packages/block-library/src/list/transforms.native.js b/packages/block-library/src/list/transforms.native.js new file mode 100644 index 00000000000000..21b6405a15030a --- /dev/null +++ b/packages/block-library/src/list/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.richText, +}; + +export default transforms; diff --git a/packages/block-library/src/media-text/transforms.native.js b/packages/block-library/src/media-text/transforms.native.js new file mode 100644 index 00000000000000..839cdfe3c93810 --- /dev/null +++ b/packages/block-library/src/media-text/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.media, +}; + +export default transforms; diff --git a/packages/block-library/src/more/transforms.native.js b/packages/block-library/src/more/transforms.native.js new file mode 100644 index 00000000000000..0816b765fee290 --- /dev/null +++ b/packages/block-library/src/more/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.other, +}; + +export default transforms; diff --git a/packages/block-library/src/nextpage/transforms.native.js b/packages/block-library/src/nextpage/transforms.native.js new file mode 100644 index 00000000000000..0816b765fee290 --- /dev/null +++ b/packages/block-library/src/nextpage/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.other, +}; + +export default transforms; diff --git a/packages/block-library/src/paragraph/transforms.native.js b/packages/block-library/src/paragraph/transforms.native.js new file mode 100644 index 00000000000000..21b6405a15030a --- /dev/null +++ b/packages/block-library/src/paragraph/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.richText, +}; + +export default transforms; diff --git a/packages/block-library/src/preformatted/transforms.native.js b/packages/block-library/src/preformatted/transforms.native.js new file mode 100644 index 00000000000000..21b6405a15030a --- /dev/null +++ b/packages/block-library/src/preformatted/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.richText, +}; + +export default transforms; diff --git a/packages/block-library/src/pullquote/transforms.native.js b/packages/block-library/src/pullquote/transforms.native.js new file mode 100644 index 00000000000000..21b6405a15030a --- /dev/null +++ b/packages/block-library/src/pullquote/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.richText, +}; + +export default transforms; diff --git a/packages/block-library/src/quote/transforms.native.js b/packages/block-library/src/quote/transforms.native.js new file mode 100644 index 00000000000000..21b6405a15030a --- /dev/null +++ b/packages/block-library/src/quote/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.richText, +}; + +export default transforms; diff --git a/packages/block-library/src/separator/transforms.native.js b/packages/block-library/src/separator/transforms.native.js new file mode 100644 index 00000000000000..0816b765fee290 --- /dev/null +++ b/packages/block-library/src/separator/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.other, +}; + +export default transforms; diff --git a/packages/block-library/src/shortcode/transforms.native.js b/packages/block-library/src/shortcode/transforms.native.js new file mode 100644 index 00000000000000..21b6405a15030a --- /dev/null +++ b/packages/block-library/src/shortcode/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.richText, +}; + +export default transforms; diff --git a/packages/block-library/src/table/transforms.native.js b/packages/block-library/src/table/transforms.native.js new file mode 100644 index 00000000000000..9e7c243a6d8cd5 --- /dev/null +++ b/packages/block-library/src/table/transforms.native.js @@ -0,0 +1,11 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: [], +}; + +export default transforms; diff --git a/packages/block-library/src/text-columns/transforms.native.js b/packages/block-library/src/text-columns/transforms.native.js new file mode 100644 index 00000000000000..032a3464258944 --- /dev/null +++ b/packages/block-library/src/text-columns/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.grouped, +}; + +export default transforms; diff --git a/packages/block-library/src/transformationCategories.native.js b/packages/block-library/src/transformationCategories.native.js new file mode 100644 index 00000000000000..9fa4c09cc9bb1a --- /dev/null +++ b/packages/block-library/src/transformationCategories.native.js @@ -0,0 +1,46 @@ +const transformationCategories = { + richText: [ + 'core/paragraph', + 'core/heading', + 'core/list', + 'core/quote', + 'core/pullquote', + 'core/preformatted', + 'core/verse', + 'core/shortcode', + 'core/code', + ], + media: [ + 'core/image', + 'core/video', + 'core/gallery', + 'core/cover', + 'core/file', + 'core/audio', + 'core/media-text', + 'core/embed', + ], + grouped: [ 'core/columns', 'core/group', 'core/text-columns' ], + other: [ + 'core/more', + 'core/nextpage', + 'core/separator', + 'core/spacer', + 'core/latest-posts', + 'core/buttons', + ], +}; + +export const transformationCategory = ( blockName ) => { + const found = Object.entries( + transformationCategories + ).find( ( [ , value ] ) => value.includes( blockName ) ); + if ( ! found ) { + return []; + } + + const group = found[ 0 ]; + return transformationCategories[ group ]; +}; + +export default transformationCategories; diff --git a/packages/block-library/src/verse/transforms.native.js b/packages/block-library/src/verse/transforms.native.js new file mode 100644 index 00000000000000..21b6405a15030a --- /dev/null +++ b/packages/block-library/src/verse/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.richText, +}; + +export default transforms; diff --git a/packages/block-library/src/video/transforms.native.js b/packages/block-library/src/video/transforms.native.js new file mode 100644 index 00000000000000..839cdfe3c93810 --- /dev/null +++ b/packages/block-library/src/video/transforms.native.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import webTransforms from './transforms.js'; +import transformationCategories from '../transformationCategories'; + +const transforms = { + ...webTransforms, + supportedMobileTransforms: transformationCategories.media, +}; + +export default transforms; diff --git a/packages/blocks/src/api/factory.js b/packages/blocks/src/api/factory.js index 2432597a7ca3ee..5831cfff3e86ef 100644 --- a/packages/blocks/src/api/factory.js +++ b/packages/blocks/src/api/factory.js @@ -229,6 +229,14 @@ const isPossibleTransformForSource = ( transform, direction, blocks ) => { } } + if ( + transform.usingMobileTransformations && + isWildcardBlockTransform( transform ) && + ! isContainerGroupBlock( sourceBlock.name ) + ) { + return false; + } + return true; }; @@ -252,7 +260,6 @@ const getBlockTypesForPossibleFromTransforms = ( blocks ) => { allBlockTypes, ( blockType ) => { const fromTransforms = getBlockTransforms( 'from', blockType.name ); - return !! findTransform( fromTransforms, ( transform ) => { return isPossibleTransformForSource( transform, @@ -412,10 +419,32 @@ export function getBlockTransforms( direction, blockTypeOrName ) { return []; } + const usingMobileTransformations = + transforms.supportedMobileTransforms && + Array.isArray( transforms.supportedMobileTransforms ); + const filteredTransforms = usingMobileTransformations + ? filter( transforms[ direction ], ( t ) => { + if ( ! t.blocks || ! t.blocks.length ) { + return false; + } + + if ( isWildcardBlockTransform( t ) ) { + return true; + } + + return every( t.blocks, ( transformBlockName ) => + transforms.supportedMobileTransforms.includes( + transformBlockName + ) + ); + } ) + : transforms[ direction ]; + // Map transforms to normal form. - return transforms[ direction ].map( ( transform ) => ( { + return filteredTransforms.map( ( transform ) => ( { ...transform, blockName, + usingMobileTransformations, } ) ); }