diff --git a/packages/e2e-tests/specs/editor/plugins/custom-taxonomies.test.js b/packages/e2e-tests/specs/editor/plugins/custom-taxonomies.test.js deleted file mode 100644 index 42c476f9cf12a4..00000000000000 --- a/packages/e2e-tests/specs/editor/plugins/custom-taxonomies.test.js +++ /dev/null @@ -1,61 +0,0 @@ -/** - * WordPress dependencies - */ -import { - activatePlugin, - createNewPost, - deactivatePlugin, - findSidebarPanelWithTitle, - openDocumentSettingsSidebar, -} from '@wordpress/e2e-test-utils'; - -describe( 'Custom Taxonomies labels are used', () => { - beforeAll( async () => { - await activatePlugin( 'gutenberg-test-custom-taxonomies' ); - } ); - - beforeEach( async () => { - await createNewPost(); - } ); - - afterAll( async () => { - await deactivatePlugin( 'gutenberg-test-custom-taxonomies' ); - } ); - - it( 'Ensures the custom taxonomy labels are respected', async () => { - // Open the Setting sidebar. - await openDocumentSettingsSidebar(); - - const openButton = await findSidebarPanelWithTitle( 'Model' ); - expect( openButton ).not.toBeFalsy(); - - // Get the classes from the panel. - const buttonClassName = await ( - await openButton.getProperty( 'className' ) - ).jsonValue(); - - // Open the panel if needed. - if ( -1 === buttonClassName.indexOf( 'is-opened' ) ) { - await openButton.click(); - } - - // Check the add new button. - const labelNew = await page.$x( - "//label[@class='components-form-token-field__label' and contains(text(), 'Add New Model')]" - ); - expect( labelNew ).not.toBeFalsy(); - - // Fill with one entry. - await page.type( - 'input.components-form-token-field__input', - 'Model 1' - ); - await page.keyboard.press( 'Enter' ); - - // Check the "Remove Model" - const value = await page.$x( - "//div[@class='components-form-token-field__input-container']//span//button[@aria-label='Remove Model']" - ); - expect( value ).not.toBeFalsy(); - } ); -} ); diff --git a/packages/edit-site/src/components/block-editor/back-button.js b/packages/edit-site/src/components/block-editor/back-button.js index 4723adc3f0a7aa..b7c281031f15b9 100644 --- a/packages/edit-site/src/components/block-editor/back-button.js +++ b/packages/edit-site/src/components/block-editor/back-button.js @@ -19,7 +19,9 @@ function BackButton() { const isTemplatePart = location.params.postType === 'wp_template_part'; const previousTemplateId = location.state?.fromTemplateId; - if ( ! isTemplatePart || ! previousTemplateId ) { + const isFocusMode = isTemplatePart; + + if ( ! isFocusMode || ! previousTemplateId ) { return null; } diff --git a/packages/edit-site/src/components/block-editor/constants.js b/packages/edit-site/src/components/block-editor/constants.js new file mode 100644 index 00000000000000..5985167c1e7d39 --- /dev/null +++ b/packages/edit-site/src/components/block-editor/constants.js @@ -0,0 +1 @@ +export const FOCUSABLE_ENTITIES = [ 'wp_template_part' ]; diff --git a/packages/edit-site/src/components/block-editor/index.js b/packages/edit-site/src/components/block-editor/index.js index 9184913e5840ff..08a316028ba80b 100644 --- a/packages/edit-site/src/components/block-editor/index.js +++ b/packages/edit-site/src/components/block-editor/index.js @@ -1,228 +1,49 @@ /** * External dependencies */ -import classnames from 'classnames'; /** * WordPress dependencies */ -import { useSelect, useDispatch } from '@wordpress/data'; -import { useMemo, useRef } from '@wordpress/element'; -import { useEntityBlockEditor, store as coreStore } from '@wordpress/core-data'; -import { - BlockList, - BlockInspector, - BlockTools, - __unstableUseClipboardHandler as useClipboardHandler, - __unstableUseTypingObserver as useTypingObserver, - BlockEditorKeyboardShortcuts, - store as blockEditorStore, - privateApis as blockEditorPrivateApis, -} from '@wordpress/block-editor'; -import { - useMergeRefs, - useViewportMatch, - useResizeObserver, -} from '@wordpress/compose'; +import { useSelect } from '@wordpress/data'; +import { BlockInspector } from '@wordpress/block-editor'; + import { ReusableBlocksMenuItems } from '@wordpress/reusable-blocks'; /** * Internal dependencies */ -import inserterMediaCategories from './inserter-media-categories'; + import TemplatePartConverter from '../template-part-converter'; import { SidebarInspectorFill } from '../sidebar-edit-mode'; import { store as editSiteStore } from '../../store'; -import BackButton from './back-button'; -import ResizableEditor from './resizable-editor'; -import EditorCanvas from './editor-canvas'; import { unlock } from '../../lock-unlock'; -import EditorCanvasContainer from '../editor-canvas-container'; -import { - DisableNonPageContentBlocks, - usePageContentFocusNotifications, -} from '../page-content-focus'; - -const { ExperimentalBlockEditorProvider } = unlock( blockEditorPrivateApis ); - -const LAYOUT = { - type: 'default', - // At the root level of the site editor, no alignments should be allowed. - alignments: [], -}; +import { DisableNonPageContentBlocks } from '../page-content-focus'; +import SiteEditorCanvas from './site-editor-canvas'; +import DefaultBlockEditorProvider from './providers/default-block-editor-provider'; export default function BlockEditor() { - const { setIsInserterOpened } = useDispatch( editSiteStore ); - const { storedSettings, templateType, canvasMode, hasPageContentFocus } = - useSelect( - ( select ) => { - const { - getSettings, - getEditedPostType, - getCanvasMode, - hasPageContentFocus: _hasPageContentFocus, - } = unlock( select( editSiteStore ) ); - - return { - storedSettings: getSettings( setIsInserterOpened ), - templateType: getEditedPostType(), - canvasMode: getCanvasMode(), - hasPageContentFocus: _hasPageContentFocus(), - }; - }, - [ setIsInserterOpened ] + const { hasPageContentFocus } = useSelect( ( select ) => { + const { hasPageContentFocus: _hasPageContentFocus } = unlock( + select( editSiteStore ) ); - const settingsBlockPatterns = - storedSettings.__experimentalAdditionalBlockPatterns ?? // WP 6.0 - storedSettings.__experimentalBlockPatterns; // WP 5.9 - const settingsBlockPatternCategories = - storedSettings.__experimentalAdditionalBlockPatternCategories ?? // WP 6.0 - storedSettings.__experimentalBlockPatternCategories; // WP 5.9 - - const { restBlockPatterns, restBlockPatternCategories } = useSelect( - ( select ) => ( { - restBlockPatterns: select( coreStore ).getBlockPatterns(), - restBlockPatternCategories: - select( coreStore ).getBlockPatternCategories(), - } ), - [] - ); - - const blockPatterns = useMemo( - () => - [ - ...( settingsBlockPatterns || [] ), - ...( restBlockPatterns || [] ), - ] - .filter( - ( x, index, arr ) => - index === arr.findIndex( ( y ) => x.name === y.name ) - ) - .filter( ( { postTypes } ) => { - return ( - ! postTypes || - ( Array.isArray( postTypes ) && - postTypes.includes( templateType ) ) - ); - } ), - [ settingsBlockPatterns, restBlockPatterns, templateType ] - ); - - const blockPatternCategories = useMemo( - () => - [ - ...( settingsBlockPatternCategories || [] ), - ...( restBlockPatternCategories || [] ), - ].filter( - ( x, index, arr ) => - index === arr.findIndex( ( y ) => x.name === y.name ) - ), - [ settingsBlockPatternCategories, restBlockPatternCategories ] - ); - - const settings = useMemo( () => { - const { - __experimentalAdditionalBlockPatterns, - __experimentalAdditionalBlockPatternCategories, - ...restStoredSettings - } = storedSettings; - return { - ...restStoredSettings, - inserterMediaCategories, - __experimentalBlockPatterns: blockPatterns, - __experimentalBlockPatternCategories: blockPatternCategories, + hasPageContentFocus: _hasPageContentFocus(), }; - }, [ storedSettings, blockPatterns, blockPatternCategories ] ); - - const [ blocks, onInput, onChange ] = useEntityBlockEditor( - 'postType', - templateType - ); - - const contentRef = useRef(); - const mergedRefs = useMergeRefs( [ - contentRef, - useClipboardHandler(), - useTypingObserver(), - usePageContentFocusNotifications(), - ] ); - const isMobileViewport = useViewportMatch( 'small', '<' ); - const { clearSelectedBlock } = useDispatch( blockEditorStore ); - const [ resizeObserver, sizes ] = useResizeObserver(); - - const isTemplatePart = templateType === 'wp_template_part'; - - const hasBlocks = blocks.length !== 0; - const enableResizing = - isTemplatePart && - canvasMode !== 'view' && - // Disable resizing in mobile viewport. - ! isMobileViewport; - const isViewMode = canvasMode === 'view'; - const showBlockAppender = - ( isTemplatePart && hasBlocks ) || isViewMode ? false : undefined; + }, [] ); return ( - + { hasPageContentFocus && } - - { ( [ editorCanvasView ] ) => - editorCanvasView ? ( -
- { editorCanvasView } -
- ) : ( - { - // Clear selected block when clicking on the gray background. - if ( event.target === event.currentTarget ) { - clearSelectedBlock(); - } - } } - > - - - - - { resizeObserver } - - - - - ) - } -
+ + + -
+ ); } diff --git a/packages/edit-site/src/components/block-editor/providers/default-block-editor-provider.js b/packages/edit-site/src/components/block-editor/providers/default-block-editor-provider.js new file mode 100644 index 00000000000000..2ee0ae467f8d65 --- /dev/null +++ b/packages/edit-site/src/components/block-editor/providers/default-block-editor-provider.js @@ -0,0 +1,44 @@ +/** + * WordPress dependencies + */ +import { useEntityBlockEditor } from '@wordpress/core-data'; +import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; +import { useSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import { store as editSiteStore } from '../../../store'; +import { unlock } from '../../../lock-unlock'; +import useSiteEditorSettings from '../use-site-editor-settings'; + +const { ExperimentalBlockEditorProvider } = unlock( blockEditorPrivateApis ); + +export default function DefaultBlockEditorProvider( { children } ) { + const settings = useSiteEditorSettings(); + + const { templateType } = useSelect( ( select ) => { + const { getEditedPostType } = unlock( select( editSiteStore ) ); + + return { + templateType: getEditedPostType(), + }; + }, [] ); + + const [ blocks, onInput, onChange ] = useEntityBlockEditor( + 'postType', + templateType + ); + + return ( + + { children } + + ); +} diff --git a/packages/edit-site/src/components/block-editor/site-editor-canvas.js b/packages/edit-site/src/components/block-editor/site-editor-canvas.js new file mode 100644 index 00000000000000..204ff85443fb80 --- /dev/null +++ b/packages/edit-site/src/components/block-editor/site-editor-canvas.js @@ -0,0 +1,136 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; +/** + * WordPress dependencies + */ +import { useSelect, useDispatch } from '@wordpress/data'; +import { useRef } from '@wordpress/element'; +import { + BlockList, + BlockTools, + __unstableUseClipboardHandler as useClipboardHandler, + __unstableUseTypingObserver as useTypingObserver, + BlockEditorKeyboardShortcuts, + store as blockEditorStore, +} from '@wordpress/block-editor'; +import { + useMergeRefs, + useViewportMatch, + useResizeObserver, +} from '@wordpress/compose'; +/** + * Internal dependencies + */ +import BackButton from './back-button'; +import ResizableEditor from './resizable-editor'; +import EditorCanvas from './editor-canvas'; +import EditorCanvasContainer from '../editor-canvas-container'; +import { usePageContentFocusNotifications } from '../page-content-focus'; +import useSiteEditorSettings from './use-site-editor-settings'; +import { store as editSiteStore } from '../../store'; +import { FOCUSABLE_ENTITIES } from './constants'; +import { unlock } from '../../lock-unlock'; + +const LAYOUT = { + type: 'default', + // At the root level of the site editor, no alignments should be allowed. + alignments: [], +}; + +export default function SiteEditorCanvas() { + const { clearSelectedBlock } = useDispatch( blockEditorStore ); + + const { isFocusMode, isViewMode } = useSelect( ( select ) => { + const { getEditedPostType, getCanvasMode } = unlock( + select( editSiteStore ) + ); + + const _templateType = getEditedPostType(); + + return { + isFocusMode: FOCUSABLE_ENTITIES.includes( _templateType ), + isViewMode: getCanvasMode() === 'view', + }; + }, [] ); + + const [ resizeObserver, sizes ] = useResizeObserver(); + + const settings = useSiteEditorSettings(); + + const { hasBlocks } = useSelect( ( select ) => { + const { getBlockCount } = select( blockEditorStore ); + + const blocks = getBlockCount(); + + return { + hasBlocks: !! blocks, + }; + }, [] ); + + const isMobileViewport = useViewportMatch( 'small', '<' ); + const enableResizing = + isFocusMode && + ! isViewMode && + // Disable resizing in mobile viewport. + ! isMobileViewport; + + const contentRef = useRef(); + const mergedRefs = useMergeRefs( [ + contentRef, + useClipboardHandler(), + useTypingObserver(), + usePageContentFocusNotifications(), + ] ); + + // Hide the appender when in view mode (i.e. not editing). + const showBlockAppender = hasBlocks || isViewMode ? false : undefined; + + return ( + + { ( [ editorCanvasView ] ) => + editorCanvasView ? ( +
+ { editorCanvasView } +
+ ) : ( + { + // Clear selected block when clicking on the gray background. + if ( event.target === event.currentTarget ) { + clearSelectedBlock(); + } + } } + > + + + + + { resizeObserver } + + + + + ) + } +
+ ); +} diff --git a/packages/edit-site/src/components/block-editor/use-site-editor-settings.js b/packages/edit-site/src/components/block-editor/use-site-editor-settings.js new file mode 100644 index 00000000000000..4ce186ad9d6bb5 --- /dev/null +++ b/packages/edit-site/src/components/block-editor/use-site-editor-settings.js @@ -0,0 +1,83 @@ +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; +import { useMemo } from '@wordpress/element'; +import { store as coreStore } from '@wordpress/core-data'; +/** + * Internal dependencies + */ +import { store as editSiteStore } from '../../store'; +import { unlock } from '../../lock-unlock'; +import inserterMediaCategories from './inserter-media-categories'; + +export default function useSiteEditorSettings( templateType ) { + const { storedSettings } = useSelect( ( select ) => { + const { getSettings } = unlock( select( editSiteStore ) ); + + return { + storedSettings: getSettings(), + }; + }, [] ); + + const settingsBlockPatterns = + storedSettings.__experimentalAdditionalBlockPatterns ?? // WP 6.0 + storedSettings.__experimentalBlockPatterns; // WP 5.9 + const settingsBlockPatternCategories = + storedSettings.__experimentalAdditionalBlockPatternCategories ?? // WP 6.0 + storedSettings.__experimentalBlockPatternCategories; // WP 5.9 + + const { restBlockPatterns, restBlockPatternCategories } = useSelect( + ( select ) => ( { + restBlockPatterns: select( coreStore ).getBlockPatterns(), + restBlockPatternCategories: + select( coreStore ).getBlockPatternCategories(), + } ), + [] + ); + const blockPatterns = useMemo( + () => + [ + ...( settingsBlockPatterns || [] ), + ...( restBlockPatterns || [] ), + ] + .filter( + ( x, index, arr ) => + index === arr.findIndex( ( y ) => x.name === y.name ) + ) + .filter( ( { postTypes } ) => { + return ( + ! postTypes || + ( Array.isArray( postTypes ) && + postTypes.includes( templateType ) ) + ); + } ), + [ settingsBlockPatterns, restBlockPatterns, templateType ] + ); + + const blockPatternCategories = useMemo( + () => + [ + ...( settingsBlockPatternCategories || [] ), + ...( restBlockPatternCategories || [] ), + ].filter( + ( x, index, arr ) => + index === arr.findIndex( ( y ) => x.name === y.name ) + ), + [ settingsBlockPatternCategories, restBlockPatternCategories ] + ); + return useMemo( () => { + const { + __experimentalAdditionalBlockPatterns, + __experimentalAdditionalBlockPatternCategories, + ...restStoredSettings + } = storedSettings; + + return { + ...restStoredSettings, + inserterMediaCategories, + __experimentalBlockPatterns: blockPatterns, + __experimentalBlockPatternCategories: blockPatternCategories, + }; + }, [ storedSettings, blockPatterns, blockPatternCategories ] ); +} diff --git a/test/e2e/specs/editor/plugins/custom-taxonomies.spec.js b/test/e2e/specs/editor/plugins/custom-taxonomies.spec.js new file mode 100644 index 00000000000000..241832513f1ec4 --- /dev/null +++ b/test/e2e/specs/editor/plugins/custom-taxonomies.spec.js @@ -0,0 +1,47 @@ +/** + * WordPress dependencies + */ +const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); + +test.describe( 'Block context', () => { + test.beforeAll( async ( { requestUtils } ) => { + await requestUtils.activatePlugin( 'gutenberg-test-custom-taxonomies' ); + } ); + + test.beforeEach( async ( { admin } ) => { + await admin.createNewPost(); + } ); + test.afterAll( async ( { requestUtils } ) => { + await requestUtils.deactivatePlugin( + 'gutenberg-test-custom-taxonomies' + ); + } ); + + test( 'Ensures the custom taxonomy labels are respected', async ( { + editor, + page, + } ) => { + await editor.openDocumentSettingsSidebar(); + + // Verify Model + const openButton = page.locator( "role=button[name='Model'i]" ); + expect( openButton ).not.toBeFalsy(); + + // Open Model + await openButton.click(); + + // Check the add new button. + const labelNew = page.locator( + "role=StaticText[name='ADD NEW MODEL'i]" + ); + expect( labelNew ).not.toBeFalsy(); + + // Fill with one entry. + await page.type( "role=combobox[name='ADD NEW MODEL'i]", 'Model 1' ); + await page.keyboard.press( 'Enter' ); + + // Check the "Remove Model" + const value = page.locator( "role=button[name='Remove Model'i]" ); + expect( value ).not.toBeFalsy(); + } ); +} );