From ee9b5d37b8f22a0c1070f37e3b0605a610f9f1e0 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Mon, 11 Sep 2023 19:16:22 +0200 Subject: [PATCH 1/9] Use `UnsupportedBlockDetails` in unsupported blocks --- .../src/components/index.native.js | 1 + .../block-library/src/missing/edit.native.js | 131 +++--------------- .../src/missing/style.native.scss | 67 --------- 3 files changed, 20 insertions(+), 179 deletions(-) diff --git a/packages/block-editor/src/components/index.native.js b/packages/block-editor/src/components/index.native.js index 1f675daaa8ca1..a89fdb9d6ac63 100644 --- a/packages/block-editor/src/components/index.native.js +++ b/packages/block-editor/src/components/index.native.js @@ -67,6 +67,7 @@ export { export { default as Warning } from './warning'; export { default as ContrastChecker } from './contrast-checker'; export { default as useMultipleOriginColorsAndGradients } from './colors-gradients/use-multiple-origin-colors-and-gradients'; +export { default as UnsupportedBlockDetails } from './unsupported-block-details'; export { BottomSheetSettings, diff --git a/packages/block-library/src/missing/edit.native.js b/packages/block-library/src/missing/edit.native.js index cf590dc0181c4..080f6c1db09f3 100644 --- a/packages/block-library/src/missing/edit.native.js +++ b/packages/block-library/src/missing/edit.native.js @@ -11,12 +11,7 @@ import { /** * WordPress dependencies */ -import { - requestUnsupportedBlockFallback, - sendActionButtonPressedAction, - actionButtons, -} from '@wordpress/react-native-bridge'; -import { BottomSheet, Icon, TextControl } from '@wordpress/components'; +import { Icon } from '@wordpress/components'; import { compose, withPreferredColorScheme } from '@wordpress/compose'; import { coreBlocks } from '@wordpress/block-library'; import { normalizeIconObject } from '@wordpress/blocks'; @@ -25,7 +20,10 @@ import { __, _x, sprintf } from '@wordpress/i18n'; import { help, plugins } from '@wordpress/icons'; import { withSelect, withDispatch } from '@wordpress/data'; import { applyFilters } from '@wordpress/hooks'; -import { store as blockEditorStore } from '@wordpress/block-editor'; +import { + UnsupportedBlockDetails, + store as blockEditorStore, +} from '@wordpress/block-editor'; /** * Internal dependencies @@ -121,122 +119,31 @@ export class UnsupportedBlockEdit extends Component { } renderSheet( blockTitle, blockName ) { - const { - getStylesFromColorScheme, - attributes, - clientId, - isUnsupportedBlockEditorSupported, - canEnableUnsupportedBlockEditor, - isEditableInUnsupportedBlockEditor, - } = this.props; - const infoTextStyle = getStylesFromColorScheme( - styles.infoText, - styles.infoTextDark - ); - const infoTitleStyle = getStylesFromColorScheme( - styles.infoTitle, - styles.infoTitleDark - ); - const infoDescriptionStyle = getStylesFromColorScheme( - styles.infoDescription, - styles.infoDescriptionDark - ); - const infoSheetIconStyle = getStylesFromColorScheme( - styles.infoSheetIcon, - styles.infoSheetIconDark - ); - + const { clientId } = this.props; + const { showHelp } = this.state; /* translators: Missing block alert title. %s: The localized block name */ const titleFormat = __( "'%s' is not fully-supported" ); - const infoTitle = sprintf( titleFormat, blockTitle ); - const missingBlockDetail = applyFilters( + const title = sprintf( titleFormat, blockTitle ); + const description = applyFilters( 'native.missing_block_detail', __( 'We are working hard to add more blocks with each release.' ), blockName ); - const missingBlockActionButton = applyFilters( + const actionButtonLabel = applyFilters( 'native.missing_block_action_button', __( 'Edit using web editor' ) ); - const actionButtonStyle = getStylesFromColorScheme( - styles.actionButton, - styles.actionButtonDark - ); - return ( - { - if ( this.state.sendFallbackMessage ) { - // On iOS, onModalHide is called when the controller is still part of the hierarchy. - // A small delay will ensure that the controller has already been removed. - this.timeout = setTimeout( () => { - // For the Classic block, the content is kept in the `content` attribute. - const content = - blockName === 'core/freeform' - ? attributes.content - : attributes.originalContent; - requestUnsupportedBlockFallback( - content, - clientId, - blockName, - blockTitle - ); - }, 100 ); - this.setState( { sendFallbackMessage: false } ); - } else if ( this.state.sendButtonPressMessage ) { - this.timeout = setTimeout( () => { - sendActionButtonPressedAction( - actionButtons.missingBlockAlertActionButton - ); - }, 100 ); - this.setState( { sendButtonPressMessage: false } ); - } - } } - > - - - - { infoTitle } - - { isEditableInUnsupportedBlockEditor && - missingBlockDetail && ( - - { missingBlockDetail } - - ) } - - { ( isUnsupportedBlockEditorSupported || - canEnableUnsupportedBlockEditor ) && - isEditableInUnsupportedBlockEditor && ( - <> - - - - ) } - + ); } diff --git a/packages/block-library/src/missing/style.native.scss b/packages/block-library/src/missing/style.native.scss index 9a56f82f7e3f0..5d83c67f78b81 100644 --- a/packages/block-library/src/missing/style.native.scss +++ b/packages/block-library/src/missing/style.native.scss @@ -1,13 +1,3 @@ -/** @format */ -.content { - padding-top: 8; - padding-bottom: 0; - padding-left: 24; - padding-right: 24; - align-items: center; - justify-content: space-evenly; -} - .helpIconContainer { position: absolute; top: 0; @@ -20,12 +10,6 @@ align-items: flex-end; } -.infoContainer { - flex-direction: column; - align-items: center; - justify-content: flex-end; -} - .infoIcon { size: 36; height: 36; @@ -38,49 +22,6 @@ color: $dark-tertiary; } -.infoSheetIcon { - size: 36; - height: 36; - padding-top: 8; - padding-bottom: 8; - color: $gray; -} - -.infoSheetIconDark { - color: $gray-20; -} - -.infoText { - text-align: center; - color: $gray-dark; -} - -.infoTextDark { - color: $white; -} - -.infoTitle { - padding-top: 8; - padding-bottom: 12; - font-size: 20; - font-weight: bold; - color: $gray-dark; -} - -.infoTitleDark { - color: $white; -} - -.infoDescription { - padding-bottom: 24; - font-size: 16; - color: $gray-darken-20; -} - -.infoDescriptionDark { - color: $gray-20; -} - .unsupportedBlock { height: 142; background-color: #e0e0e0; // $light-dim @@ -136,11 +77,3 @@ .unsupportedBlockSubtitleDark { color: $gray-20; } - -.actionButton { - color: $blue-50; -} - -.actionButtonDark { - color: $blue-30; -} From 589cf7822114f2f69a9d0e26333eac266c42fa79 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Fri, 6 Oct 2023 16:08:59 +0200 Subject: [PATCH 2/9] Fix missing outline in Classic block --- .../src/components/block-list/block-outline.native.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-list/block-outline.native.js b/packages/block-editor/src/components/block-list/block-outline.native.js index 83c6a58bac365..76f0f8cb94794 100644 --- a/packages/block-editor/src/components/block-list/block-outline.native.js +++ b/packages/block-editor/src/components/block-list/block-outline.native.js @@ -13,7 +13,7 @@ import { usePreferredColorSchemeStyle } from '@wordpress/compose'; */ import styles from './block.scss'; -const TEXT_BLOCKS_WITH_OUTLINE = [ 'core/missing' ]; +const TEXT_BLOCKS_WITH_OUTLINE = [ 'core/missing', 'core/freeform' ]; function BlockOutline( { blockCategory, From 2e7218d9ed9a5664ceeaaa9bcf50e9942be86a1e Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Fri, 6 Oct 2023 18:33:09 +0200 Subject: [PATCH 3/9] Add missing mock style used `UnsupportedBlockDetails` component --- test/native/__mocks__/styleMock.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/native/__mocks__/styleMock.js b/test/native/__mocks__/styleMock.js index 8b682ef005e49..55942d977ad00 100644 --- a/test/native/__mocks__/styleMock.js +++ b/test/native/__mocks__/styleMock.js @@ -208,4 +208,7 @@ module.exports = { marginLeft: 16, minWidth: 32, }, + 'unsupported-block-details__icon': { + color: 'gray', + }, }; From e26563271aa88d6b3607c691c5b378990d7daf5b Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Fri, 6 Oct 2023 18:33:52 +0200 Subject: [PATCH 4/9] Mock RN bridge elements related to UBE --- test/native/setup.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/native/setup.js b/test/native/setup.js index 60b42dc25d2fe..00fb95070d84d 100644 --- a/test/native/setup.js +++ b/test/native/setup.js @@ -129,6 +129,10 @@ jest.mock( '@wordpress/react-native-bridge', () => { generateHapticFeedback: jest.fn(), toggleUndoButton: jest.fn(), toggleRedoButton: jest.fn(), + sendActionButtonPressedAction: jest.fn(), + actionButtons: { + missingBlockAlertActionButton: 'missing_block_alert_action_button', + }, }; } ); From 1d95282eb4ab1a3c926aaa590a5f1382dbcba606 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Fri, 6 Oct 2023 18:35:41 +0200 Subject: [PATCH 5/9] Expand Missing block integration tests --- .../missing/test/edit-integration.native.js | 188 +++++++++++++----- 1 file changed, 139 insertions(+), 49 deletions(-) diff --git a/packages/block-library/src/missing/test/edit-integration.native.js b/packages/block-library/src/missing/test/edit-integration.native.js index 4e1a4779572f2..5f5871104e15e 100644 --- a/packages/block-library/src/missing/test/edit-integration.native.js +++ b/packages/block-library/src/missing/test/edit-integration.native.js @@ -1,81 +1,171 @@ /** * External dependencies */ -import { initializeEditor, fireEvent, within } from 'test/helpers'; +import { + fireEvent, + getBlock, + initializeEditor, + screen, + setupCoreBlocks, + withFakeTimers, + within, +} from 'test/helpers'; +import { Platform } from 'react-native'; /** * WordPress dependencies */ -import { getBlockTypes, unregisterBlockType } from '@wordpress/blocks'; +import { unregisterBlockType } from '@wordpress/blocks'; import { setLocaleData } from '@wordpress/i18n'; +import { requestUnsupportedBlockFallback } from '@wordpress/react-native-bridge'; + +// Override modal mock to prevent unmounting it when is not visible. +// This is required to be able to trigger onClose and onDismiss events when +// the modal is dismissed. +jest.mock( 'react-native-modal', () => { + const mockComponent = require( 'react-native/jest/mockComponent' ); + return mockComponent( 'react-native-modal' ); +} ); -/** - * Internal dependencies - */ -import { registerCoreBlocks } from '../..'; +const TABLE_BLOCK_HTML = ` +
12
34
+`; +const MODAL_DISMISS_EVENT = Platform.OS === 'ios' ? 'onDismiss' : 'onModalHide'; -beforeAll( () => { - // Mock translations. - setLocaleData( { - 'block title\u0004Table': [ 'Tabla' ], - "'%s' is not fully-supported": [ '«%s» no es totalmente compatible' ], - } ); +setupCoreBlocks(); - // Register all core blocks. - registerCoreBlocks(); +beforeAll( () => { + // For the purpose of this test suite we consider Reusable blocks/Patterns as unsupported. + // For this reason we unregister it to force it to be rendered as an unsupported block. + unregisterBlockType( 'core/block' ); } ); -afterAll( () => { - // Clean up translations. - setLocaleData( {} ); +describe( 'Unsupported block', () => { + describe( 'localized elements', () => { + beforeEach( () => { + // Mock translations. + setLocaleData( { + 'block title\u0004Table': [ 'Tabla' ], + "'%s' is not fully-supported": [ + '«%s» no es totalmente compatible', + ], + } ); + } ); + + afterEach( () => { + // Clean up translations. + setLocaleData( {} ); + } ); + + it( 'requests translated block title in block placeholder', async () => { + await initializeEditor( { + initialHtml: TABLE_BLOCK_HTML, + } ); + + const [ missingBlock ] = await screen.findAllByLabelText( + /Unsupported Block\. Row 1/ + ); + + const translatedTableTitle = + within( missingBlock ).getByText( 'Tabla' ); + + expect( translatedTableTitle ).toBeDefined(); + } ); + + it( 'requests translated block title in bottom sheet', async () => { + await initializeEditor( { + initialHtml: TABLE_BLOCK_HTML, + } ); + + const [ missingBlock ] = await screen.findAllByLabelText( + /Unsupported Block\. Row 1/ + ); + + fireEvent.press( missingBlock ); - // Clean up registered blocks. - getBlockTypes().forEach( ( block ) => { - unregisterBlockType( block.name ); + const [ helpButton ] = + await screen.findAllByLabelText( 'Help button' ); + + fireEvent.press( helpButton ); + + const bottomSheetTitle = await screen.findByText( + '«Tabla» no es totalmente compatible' + ); + + expect( bottomSheetTitle ).toBeDefined(); + } ); } ); -} ); -describe( 'Unsupported block', () => { - it( 'requests translated block title in block placeholder', async () => { - const initialHtml = ` -
12
34
- `; - const screen = await initializeEditor( { - initialHtml, + it( 'show edit block option when UBE is available', async () => { + await initializeEditor( { + initialHtml: TABLE_BLOCK_HTML, + capabilities: { + unsupportedBlockEditor: true, + canEnableUnsupportedBlockEditor: true, + }, } ); - const [ missingBlock ] = await screen.findAllByLabelText( - /Unsupported Block\. Row 1/ - ); + const missingBlock = getBlock( screen, 'Unsupported' ); + fireEvent.press( missingBlock ); + + // Tap the block to open the unsupported block details + fireEvent.press( within( missingBlock ).getByText( 'Unsupported' ) ); - const translatedTableTitle = - within( missingBlock ).getByText( 'Tabla' ); + const actionButton = screen.getByText( 'Edit using web editor' ); + expect( actionButton ).toBeVisible(); - expect( translatedTableTitle ).toBeDefined(); + // UBE is requested after the modal hides and a timeout is ran + await withFakeTimers( async () => { + fireEvent.press( actionButton ); + fireEvent( + screen.getByTestId( 'bottom-sheet' ), + MODAL_DISMISS_EVENT + ); + jest.runOnlyPendingTimers(); + } ); + expect( requestUnsupportedBlockFallback ).toHaveBeenCalled(); } ); - it( 'requests translated block title in bottom sheet', async () => { - const initialHtml = ` -
12
34
- `; - const screen = await initializeEditor( { - initialHtml, + it( 'does not show edit block option when UBE is not available', async () => { + await initializeEditor( { + initialHtml: TABLE_BLOCK_HTML, + capabilities: { + unsupportedBlockEditor: false, + canEnableUnsupportedBlockEditor: false, + }, } ); - const [ missingBlock ] = await screen.findAllByLabelText( - /Unsupported Block\. Row 1/ + const missingBlock = getBlock( screen, 'Unsupported' ); + fireEvent.press( missingBlock ); + + // Tap the block to open the unsupported block details + fireEvent.press( within( missingBlock ).getByText( 'Unsupported' ) ); + + const actionButton = await screen.queryByText( + 'Edit using web editor' ); + expect( actionButton ).toBeNull(); + } ); - fireEvent.press( missingBlock ); + it( 'does not show edit block option when block is incompatible with UBE', async () => { + await initializeEditor( { + // Reusable blocks/Patterns is the only block type unsupported in UBE. + initialHtml: '', + capabilities: { + unsupportedBlockEditor: true, + canEnableUnsupportedBlockEditor: true, + }, + } ); - const [ helpButton ] = await screen.findAllByLabelText( 'Help button' ); + const missingBlock = getBlock( screen, 'Unsupported' ); + fireEvent.press( missingBlock ); - fireEvent.press( helpButton ); + // Tap the block to open the unsupported block details + fireEvent.press( within( missingBlock ).getByText( 'Unsupported' ) ); - const bottomSheetTitle = await screen.findByText( - '«Tabla» no es totalmente compatible' + const actionButton = await screen.queryByText( + 'Edit using web editor' ); - - expect( bottomSheetTitle ).toBeDefined(); + expect( actionButton ).toBeNull(); } ); } ); From 236b6b9ce27a5546f2e65768dc5ee111ce029f77 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Fri, 6 Oct 2023 18:36:17 +0200 Subject: [PATCH 6/9] Remove Missing block unit tests related to UBE These tests have been superseded by integration tests. --- .../src/missing/test/edit.native.js | 41 ------------------- 1 file changed, 41 deletions(-) diff --git a/packages/block-library/src/missing/test/edit.native.js b/packages/block-library/src/missing/test/edit.native.js index 5905a98cd8890..47d0da572b7c8 100644 --- a/packages/block-library/src/missing/test/edit.native.js +++ b/packages/block-library/src/missing/test/edit.native.js @@ -63,47 +63,6 @@ describe( 'Missing block', () => { "' is not fully-supported" ); } ); - - describe( 'Unsupported block editor (UBE)', () => { - beforeEach( () => { - // By default we set the web editor as available. - storeConfig.selectors.getSettings.mockReturnValue( { - capabilities: { unsupportedBlockEditor: true }, - } ); - } ); - - it( 'renders edit action if UBE is available', () => { - const testInstance = getTestComponentWithContent(); - const bottomSheet = - testInstance.UNSAFE_getByType( BottomSheet ); - const bottomSheetCells = bottomSheet.props.children[ 1 ]; - expect( bottomSheetCells ).toBeTruthy(); - expect( bottomSheetCells.props.children.length ).toBe( 2 ); - expect( bottomSheetCells.props.children[ 0 ].props.label ).toBe( - 'Edit using web editor' - ); - } ); - - it( 'does not render edit action if UBE is not available', () => { - storeConfig.selectors.getSettings.mockReturnValue( { - capabilities: { unsupportedBlockEditor: false }, - } ); - - const testInstance = getTestComponentWithContent(); - const bottomSheet = - testInstance.UNSAFE_getByType( BottomSheet ); - expect( bottomSheet.props.children[ 1 ] ).toBeFalsy(); - } ); - - it( 'does not render edit action if the block is incompatible with UBE', () => { - const testInstance = getTestComponentWithContent( { - originalName: 'core/block', - } ); - const bottomSheet = - testInstance.UNSAFE_getByType( BottomSheet ); - expect( bottomSheet.props.children[ 1 ] ).toBeFalsy(); - } ); - } ); } ); it( 'renders admin plugins icon', () => { From 404518fa4c0aa8dc3eedf40afd4c7602461dce6a Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Fri, 6 Oct 2023 18:57:34 +0200 Subject: [PATCH 7/9] Update UBE test descriptions and comments --- .../src/missing/test/edit-integration.native.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/block-library/src/missing/test/edit-integration.native.js b/packages/block-library/src/missing/test/edit-integration.native.js index 5f5871104e15e..5c033b655fcbd 100644 --- a/packages/block-library/src/missing/test/edit-integration.native.js +++ b/packages/block-library/src/missing/test/edit-integration.native.js @@ -96,7 +96,7 @@ describe( 'Unsupported block', () => { } ); } ); - it( 'show edit block option when UBE is available', async () => { + it( 'requests web editor when UBE is available', async () => { await initializeEditor( { initialHtml: TABLE_BLOCK_HTML, capabilities: { @@ -114,7 +114,7 @@ describe( 'Unsupported block', () => { const actionButton = screen.getByText( 'Edit using web editor' ); expect( actionButton ).toBeVisible(); - // UBE is requested after the modal hides and a timeout is ran + // UBE is requested after the modal hides and running a timeout await withFakeTimers( async () => { fireEvent.press( actionButton ); fireEvent( @@ -126,7 +126,7 @@ describe( 'Unsupported block', () => { expect( requestUnsupportedBlockFallback ).toHaveBeenCalled(); } ); - it( 'does not show edit block option when UBE is not available', async () => { + it( 'does not show web editor option when UBE is not available', async () => { await initializeEditor( { initialHtml: TABLE_BLOCK_HTML, capabilities: { @@ -147,9 +147,9 @@ describe( 'Unsupported block', () => { expect( actionButton ).toBeNull(); } ); - it( 'does not show edit block option when block is incompatible with UBE', async () => { + it( 'does not show web editor option when block is incompatible with UBE', async () => { await initializeEditor( { - // Reusable blocks/Patterns is the only block type unsupported in UBE. + // Reusable blocks/Patterns is a block type unsupported by UBE initialHtml: '', capabilities: { unsupportedBlockEditor: true, From 9628202f1942b6b18aea8401a750c14bc5ddf5c3 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Mon, 9 Oct 2023 13:12:00 +0200 Subject: [PATCH 8/9] Use default action label of `UnsupportedBlockDetails` compoment --- packages/block-library/src/missing/edit.native.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/block-library/src/missing/edit.native.js b/packages/block-library/src/missing/edit.native.js index 080f6c1db09f3..8aa4738aeea85 100644 --- a/packages/block-library/src/missing/edit.native.js +++ b/packages/block-library/src/missing/edit.native.js @@ -129,10 +129,6 @@ export class UnsupportedBlockEdit extends Component { __( 'We are working hard to add more blocks with each release.' ), blockName ); - const actionButtonLabel = applyFilters( - 'native.missing_block_action_button', - __( 'Edit using web editor' ) - ); return ( ); } From 93f452832ba03d94debec9d479e1f79279524a96 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Mon, 9 Oct 2023 13:55:30 +0200 Subject: [PATCH 9/9] Update Missing block integration tests --- .../src/missing/test/edit-integration.native.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/block-library/src/missing/test/edit-integration.native.js b/packages/block-library/src/missing/test/edit-integration.native.js index 5c033b655fcbd..04b0bce688c3d 100644 --- a/packages/block-library/src/missing/test/edit-integration.native.js +++ b/packages/block-library/src/missing/test/edit-integration.native.js @@ -62,9 +62,7 @@ describe( 'Unsupported block', () => { initialHtml: TABLE_BLOCK_HTML, } ); - const [ missingBlock ] = await screen.findAllByLabelText( - /Unsupported Block\. Row 1/ - ); + const missingBlock = getBlock( screen, 'Unsupported' ); const translatedTableTitle = within( missingBlock ).getByText( 'Tabla' ); @@ -77,9 +75,7 @@ describe( 'Unsupported block', () => { initialHtml: TABLE_BLOCK_HTML, } ); - const [ missingBlock ] = await screen.findAllByLabelText( - /Unsupported Block\. Row 1/ - ); + const missingBlock = getBlock( screen, 'Unsupported' ); fireEvent.press( missingBlock );