diff --git a/docs/reference-guides/data/data-core-edit-post.md b/docs/reference-guides/data/data-core-edit-post.md index 7834d1ee1b88b..0401734597d24 100644 --- a/docs/reference-guides/data/data-core-edit-post.md +++ b/docs/reference-guides/data/data-core-edit-post.md @@ -476,6 +476,8 @@ _Parameters_ ### switchEditorMode +> **Deprecated** + Triggers an action used to switch editor mode. _Parameters_ @@ -484,6 +486,8 @@ _Parameters_ ### toggleDistractionFree +> **Deprecated** + Action that toggles Distraction free mode. Distraction free mode expects there are no sidebars, as due to the z-index values set, you can't close sidebars. ### toggleEditorPanelEnabled diff --git a/docs/reference-guides/data/data-core-edit-site.md b/docs/reference-guides/data/data-core-edit-site.md index 636ccab4f3c6d..a2bc9ea1bfb96 100644 --- a/docs/reference-guides/data/data-core-edit-site.md +++ b/docs/reference-guides/data/data-core-edit-site.md @@ -395,10 +395,18 @@ _Returns_ ### switchEditorMode -Undocumented declaration. +> **Deprecated** + +Triggers an action used to switch editor mode. + +_Parameters_ + +- _mode_ `string`: The editor mode. ### toggleDistractionFree +> **Deprecated** + Action that toggles Distraction free mode. Distraction free mode expects there are no sidebars, as due to the z-index values set, you can't close sidebars. ### toggleFeature diff --git a/docs/reference-guides/data/data-core-editor.md b/docs/reference-guides/data/data-core-editor.md index 7208302204164..2c4185d3a998f 100644 --- a/docs/reference-guides/data/data-core-editor.md +++ b/docs/reference-guides/data/data-core-editor.md @@ -353,6 +353,18 @@ _Returns_ - `Array`: Block list. +### getEditorMode + +Returns the current editing mode. + +_Parameters_ + +- _state_ `Object`: Global application state. + +_Returns_ + +- `string`: Editing mode. + ### getEditorSelection Returns the current selection. @@ -1467,6 +1479,14 @@ _Related_ - stopTyping in core/block-editor store. +### switchEditorMode + +Triggers an action used to switch editor mode. + +_Parameters_ + +- _mode_ `string`: The editor mode. + ### synchronizeTemplate _Related_ @@ -1479,6 +1499,10 @@ _Related_ - toggleBlockMode in core/block-editor store. +### toggleDistractionFree + +Action that toggles Distraction free mode. Distraction free mode expects there are no sidebars, as due to the z-index values set, you can't close sidebars. + ### toggleEditorPanelEnabled Returns an action object used to enable or disable a panel in the editor. diff --git a/packages/edit-post/src/components/header/index.js b/packages/edit-post/src/components/header/index.js index b573ac43fe5fa..b7e42d0217eef 100644 --- a/packages/edit-post/src/components/header/index.js +++ b/packages/edit-post/src/components/header/index.js @@ -69,7 +69,7 @@ function Header( { setEntitiesSavedStatesCallback, initialPost } ) { hasHistory, } = useSelect( ( select ) => { const { get: getPreference } = select( preferencesStore ); - const { getEditorMode } = select( editPostStore ); + const { getEditorMode } = select( editorStore ); return { isTextEditor: getEditorMode() === 'text', diff --git a/packages/edit-post/src/components/header/mode-switcher/index.js b/packages/edit-post/src/components/header/mode-switcher/index.js index 1ca01a4b024f8..5336245ae2f3a 100644 --- a/packages/edit-post/src/components/header/mode-switcher/index.js +++ b/packages/edit-post/src/components/header/mode-switcher/index.js @@ -7,11 +7,6 @@ import { useSelect, useDispatch } from '@wordpress/data'; import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts'; import { store as editorStore } from '@wordpress/editor'; -/** - * Internal dependencies - */ -import { store as editPostStore } from '../../../store'; - /** * Set of available mode options. * @@ -41,11 +36,11 @@ function ModeSwitcher() { isCodeEditingEnabled: select( editorStore ).getEditorSettings() .codeEditingEnabled, - mode: select( editPostStore ).getEditorMode(), + mode: select( editorStore ).getEditorMode(), } ), [] ); - const { switchEditorMode } = useDispatch( editPostStore ); + const { switchEditorMode } = useDispatch( editorStore ); let selectedMode = mode; if ( ! isRichEditingEnabled && mode === 'visual' ) { diff --git a/packages/edit-post/src/components/header/writing-menu/index.js b/packages/edit-post/src/components/header/writing-menu/index.js index 54ad4104dccf1..9c369c4717e9f 100644 --- a/packages/edit-post/src/components/header/writing-menu/index.js +++ b/packages/edit-post/src/components/header/writing-menu/index.js @@ -10,15 +10,11 @@ import { PreferenceToggleMenuItem, store as preferencesStore, } from '@wordpress/preferences'; - -/** - * Internal dependencies - */ -import { store as postEditorStore } from '../../../store'; +import { store as editorStore } from '@wordpress/editor'; function WritingMenu() { const { set: setPreference } = useDispatch( preferencesStore ); - const { toggleDistractionFree } = useDispatch( postEditorStore ); + const { toggleDistractionFree } = useDispatch( editorStore ); const turnOffDistractionFree = () => { setPreference( 'core', 'distractionFree', false ); diff --git a/packages/edit-post/src/components/keyboard-shortcuts/index.js b/packages/edit-post/src/components/keyboard-shortcuts/index.js index 0bdcd5613599a..27d6ea57e4d67 100644 --- a/packages/edit-post/src/components/keyboard-shortcuts/index.js +++ b/packages/edit-post/src/components/keyboard-shortcuts/index.js @@ -29,7 +29,6 @@ function KeyboardShortcuts() { openGeneralSidebar, closeGeneralSidebar, toggleFeature, - toggleDistractionFree, } = useDispatch( editPostStore ); const { registerShortcut } = useDispatch( keyboardShortcutsStore ); const { replaceBlocks } = useDispatch( blockEditorStore ); @@ -39,6 +38,7 @@ function KeyboardShortcuts() { getBlockAttributes, getBlockSelectionStart, } = useSelect( blockEditorStore ); + const { toggleDistractionFree } = useDispatch( editorStore ); const handleTextLevelShortcut = ( event, level ) => { event.preventDefault(); diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index 9dd7314357e04..ad1e1ffa50f32 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -180,7 +180,7 @@ function Layout( { initialPost } ) { select( editPostStore ).isFeatureActive( 'fullscreenMode' ), isInserterOpened: select( editorStore ).isInserterOpened(), isListViewOpened: select( editorStore ).isListViewOpened(), - mode: select( editPostStore ).getEditorMode(), + mode: select( editorStore ).getEditorMode(), isRichEditingEnabled: editorSettings.richEditingEnabled, hasActiveMetaboxes: select( editPostStore ).hasMetaBoxes(), previousShortcut: select( @@ -310,7 +310,8 @@ function Layout( { initialPost } ) { editorNotices={ } secondarySidebar={ secondarySidebar() } sidebar={ - ( ! isMobileViewport || sidebarIsOpened ) && ( + ( ( isMobileViewport && sidebarIsOpened ) || + ( ! isMobileViewport && ! isDistractionFree ) ) && ( <> { ! isMobileViewport && ! sidebarIsOpened && (
diff --git a/packages/edit-post/src/components/layout/index.native.js b/packages/edit-post/src/components/layout/index.native.js index 6821aa754eea7..a3943f3059787 100644 --- a/packages/edit-post/src/components/layout/index.native.js +++ b/packages/edit-post/src/components/layout/index.native.js @@ -36,7 +36,6 @@ import styles from './style.scss'; import headerToolbarStyles from '../header/header-toolbar/style.scss'; import Header from '../header'; import VisualEditor from '../visual-editor'; -import { store as editPostStore } from '../../store'; class Layout extends Component { constructor() { @@ -192,9 +191,8 @@ class Layout extends Component { export default compose( [ withSelect( ( select ) => { - const { __unstableIsEditorReady: isEditorReady } = + const { __unstableIsEditorReady: isEditorReady, getEditorMode } = select( editorStore ); - const { getEditorMode } = select( editPostStore ); const { getSettings } = select( blockEditorStore ); const globalStyles = getSettings()?.__experimentalGlobalStylesBaseStyles?.color; diff --git a/packages/edit-post/src/components/text-editor/index.js b/packages/edit-post/src/components/text-editor/index.js index 871273c4a9e83..af3818e177885 100644 --- a/packages/edit-post/src/components/text-editor/index.js +++ b/packages/edit-post/src/components/text-editor/index.js @@ -21,7 +21,7 @@ export default function TextEditor() { const isRichEditingEnabled = useSelect( ( select ) => { return select( editorStore ).getEditorSettings().richEditingEnabled; }, [] ); - const { switchEditorMode } = useDispatch( editPostStore ); + const { switchEditorMode } = useDispatch( editorStore ); const { isWelcomeGuideVisible } = useSelect( ( select ) => { const { isFeatureActive } = select( editPostStore ); diff --git a/packages/edit-post/src/editor.native.js b/packages/edit-post/src/editor.native.js index 1e49673540e37..6a3bcc0d0355b 100644 --- a/packages/edit-post/src/editor.native.js +++ b/packages/edit-post/src/editor.native.js @@ -9,7 +9,7 @@ import { GestureHandlerRootView } from 'react-native-gesture-handler'; * WordPress dependencies */ import { Component } from '@wordpress/element'; -import { EditorProvider } from '@wordpress/editor'; +import { EditorProvider, store as editorStore } from '@wordpress/editor'; import { parse, serialize } from '@wordpress/blocks'; import { withDispatch, withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; @@ -24,7 +24,6 @@ import { store as coreStore } from '@wordpress/core-data'; * Internal dependencies */ import Layout from './components/layout'; -import { store as editPostStore } from './store'; class Editor extends Component { constructor( props ) { @@ -154,14 +153,14 @@ class Editor extends Component { export default compose( [ withSelect( ( select ) => { - const { getEditorMode } = select( editPostStore ); + const { getEditorMode } = select( editorStore ); return { mode: getEditorMode(), }; } ), withDispatch( ( dispatch ) => { - const { switchEditorMode } = dispatch( editPostStore ); + const { switchEditorMode } = dispatch( editorStore ); const { editEntityRecord } = dispatch( coreStore ); return { switchEditorMode, diff --git a/packages/edit-post/src/hooks/commands/use-common-commands.js b/packages/edit-post/src/hooks/commands/use-common-commands.js index c12a5e1d5c611..eb478f53a8c63 100644 --- a/packages/edit-post/src/hooks/commands/use-common-commands.js +++ b/packages/edit-post/src/hooks/commands/use-common-commands.js @@ -4,14 +4,11 @@ import { useSelect, useDispatch } from '@wordpress/data'; import { __, isRTL } from '@wordpress/i18n'; import { - code, drawerLeft, drawerRight, blockDefault, keyboard, fullscreen, - listView, - external, formatListBullets, } from '@wordpress/icons'; import { useCommand } from '@wordpress/commands'; @@ -28,48 +25,26 @@ import { PREFERENCES_MODAL_NAME } from '../../components/preferences-modal'; import { store as editPostStore } from '../../store'; export default function useCommonCommands() { - const { - openGeneralSidebar, - closeGeneralSidebar, - switchEditorMode, - toggleDistractionFree, - } = useDispatch( editPostStore ); + const { openGeneralSidebar, closeGeneralSidebar } = + useDispatch( editPostStore ); const { openModal } = useDispatch( interfaceStore ); - const { - editorMode, - activeSidebar, - isListViewOpen, - isFullscreen, - isPublishSidebarEnabled, - showBlockBreadcrumbs, - isDistractionFree, - isTopToolbar, - isFocusMode, - } = useSelect( ( select ) => { - const { get } = select( preferencesStore ); - const { getEditorMode } = select( editPostStore ); - const { isListViewOpened } = select( editorStore ); - - return { - activeSidebar: select( interfaceStore ).getActiveComplementaryArea( - editPostStore.name - ), - editorMode: getEditorMode(), - isListViewOpen: isListViewOpened(), - isPublishSidebarEnabled: - select( editorStore ).isPublishSidebarEnabled(), - showBlockBreadcrumbs: get( 'core', 'showBlockBreadcrumbs' ), - isDistractionFree: get( 'core', 'distractionFree' ), - isFocusMode: get( 'core', 'focusMode' ), - isTopToolbar: get( 'core', 'fixedToolbar' ), - isFullscreen: get( 'core/edit-post', 'fullscreenMode' ), - }; - }, [] ); + const { activeSidebar, isFullscreen, isPublishSidebarEnabled } = useSelect( + ( select ) => { + const { get } = select( preferencesStore ); + + return { + activeSidebar: select( + interfaceStore + ).getActiveComplementaryArea( editPostStore.name ), + isPublishSidebarEnabled: + select( editorStore ).isPublishSidebarEnabled(), + isFullscreen: get( 'core/edit-post', 'fullscreenMode' ), + }; + }, + [] + ); const { toggle } = useDispatch( preferencesStore ); const { createInfoNotice } = useDispatch( noticesStore ); - const { __unstableSaveForPreview, setIsListViewOpened } = - useDispatch( editorStore ); - const { getCurrentPostId } = useSelect( editorStore ); useCommand( { name: 'core/open-settings-sidebar', @@ -99,41 +74,6 @@ export default function useCommonCommands() { }, } ); - useCommand( { - name: 'core/toggle-distraction-free', - label: isDistractionFree - ? __( 'Exit Distraction Free' ) - : __( 'Enter Distraction Free ' ), - callback: ( { close } ) => { - toggleDistractionFree(); - close(); - }, - } ); - - useCommand( { - name: 'core/toggle-spotlight-mode', - label: __( 'Toggle spotlight' ), - callback: ( { close } ) => { - toggle( 'core', 'focusMode' ); - close(); - createInfoNotice( - isFocusMode ? __( 'Spotlight off.' ) : __( 'Spotlight on.' ), - { - id: 'core/edit-post/toggle-spotlight-mode/notice', - type: 'snackbar', - actions: [ - { - label: __( 'Undo' ), - onClick: () => { - toggle( 'core', 'focusMode' ); - }, - }, - ], - } - ); - }, - } ); - useCommand( { name: 'core/toggle-fullscreen-mode', label: isFullscreen @@ -161,67 +101,6 @@ export default function useCommonCommands() { }, } ); - useCommand( { - name: 'core/toggle-list-view', - label: isListViewOpen - ? __( 'Close List View' ) - : __( 'Open List View' ), - icon: listView, - callback: ( { close } ) => { - setIsListViewOpened( ! isListViewOpen ); - close(); - createInfoNotice( - isListViewOpen ? __( 'List View off.' ) : __( 'List View on.' ), - { - id: 'core/edit-post/toggle-list-view/notice', - type: 'snackbar', - } - ); - }, - } ); - - useCommand( { - name: 'core/toggle-top-toolbar', - label: __( 'Toggle top toolbar' ), - callback: ( { close } ) => { - toggle( 'core', 'fixedToolbar' ); - if ( isDistractionFree ) { - toggleDistractionFree(); - } - close(); - createInfoNotice( - isTopToolbar - ? __( 'Top toolbar off.' ) - : __( 'Top toolbar on.' ), - { - id: 'core/edit-post/toggle-top-toolbar/notice', - type: 'snackbar', - actions: [ - { - label: __( 'Undo' ), - onClick: () => { - toggle( 'core', 'fixedToolbar' ); - }, - }, - ], - } - ); - }, - } ); - - useCommand( { - name: 'core/toggle-code-editor', - label: - editorMode === 'visual' - ? __( 'Open code editor' ) - : __( 'Exit code editor' ), - icon: code, - callback: ( { close } ) => { - switchEditorMode( editorMode === 'visual' ? 'text' : 'visual' ); - close(); - }, - } ); - useCommand( { name: 'core/open-preferences', label: __( 'Editor preferences' ), @@ -239,26 +118,6 @@ export default function useCommonCommands() { }, } ); - useCommand( { - name: 'core/toggle-breadcrumbs', - label: showBlockBreadcrumbs - ? __( 'Hide block breadcrumbs' ) - : __( 'Show block breadcrumbs' ), - callback: ( { close } ) => { - toggle( 'core', 'showBlockBreadcrumbs' ); - close(); - createInfoNotice( - showBlockBreadcrumbs - ? __( 'Breadcrumbs hidden.' ) - : __( 'Breadcrumbs visible.' ), - { - id: 'core/edit-post/toggle-breadcrumbs/notice', - type: 'snackbar', - } - ); - }, - } ); - useCommand( { name: 'core/toggle-publish-sidebar', label: isPublishSidebarEnabled @@ -279,16 +138,4 @@ export default function useCommonCommands() { ); }, } ); - - useCommand( { - name: 'core/preview-link', - label: __( 'Preview in a new tab' ), - icon: external, - callback: async ( { close } ) => { - close(); - const postId = getCurrentPostId(); - const link = await __unstableSaveForPreview(); - window.open( link, `wp-preview-${ postId }` ); - }, - } ); } diff --git a/packages/edit-post/src/store/actions.js b/packages/edit-post/src/store/actions.js index b18a7d1ba9aef..5c5430787cad3 100644 --- a/packages/edit-post/src/store/actions.js +++ b/packages/edit-post/src/store/actions.js @@ -1,13 +1,9 @@ /** * WordPress dependencies */ -import { __ } from '@wordpress/i18n'; import apiFetch from '@wordpress/api-fetch'; import { store as interfaceStore } from '@wordpress/interface'; import { store as preferencesStore } from '@wordpress/preferences'; -import { speak } from '@wordpress/a11y'; -import { store as noticesStore } from '@wordpress/notices'; -import { store as blockEditorStore } from '@wordpress/block-editor'; import { store as editorStore } from '@wordpress/editor'; import deprecated from '@wordpress/deprecated'; import { addFilter } from '@wordpress/hooks'; @@ -26,13 +22,7 @@ import { unlock } from '../lock-unlock'; */ export const openGeneralSidebar = ( name ) => - ( { dispatch, registry } ) => { - const isDistractionFree = registry - .select( preferencesStore ) - .get( 'core', 'distractionFree' ); - if ( isDistractionFree ) { - dispatch.toggleDistractionFree(); - } + ( { registry } ) => { registry .dispatch( interfaceStore ) .enableComplementaryArea( editPostStore.name, name ); @@ -190,30 +180,18 @@ export const toggleFeature = /** * Triggers an action used to switch editor mode. * + * @deprecated + * * @param {string} mode The editor mode. */ export const switchEditorMode = ( mode ) => - ( { dispatch, registry } ) => { - registry.dispatch( preferencesStore ).set( 'core', 'editorMode', mode ); - - // Unselect blocks when we switch to the code editor. - if ( mode !== 'visual' ) { - registry.dispatch( blockEditorStore ).clearSelectedBlock(); - } - - if ( - mode === 'text' && - registry.select( preferencesStore ).get( 'core', 'distractionFree' ) - ) { - dispatch.toggleDistractionFree(); - } - - const message = - mode === 'visual' - ? __( 'Visual editor selected' ) - : __( 'Code editor selected' ); - speak( message, 'assertive' ); + ( { registry } ) => { + deprecated( "dispatch( 'core/edit-post' ).switchEditorMode", { + since: '6.6', + alternative: "dispatch( 'core/editor').switchEditorMode", + } ); + registry.dispatch( editorStore ).switchEditorMode( mode ); }; /** @@ -503,64 +481,15 @@ export const initializeMetaBoxes = * Action that toggles Distraction free mode. * Distraction free mode expects there are no sidebars, as due to the * z-index values set, you can't close sidebars. + * + * @deprecated */ export const toggleDistractionFree = () => - ( { dispatch, registry } ) => { - const isDistractionFree = registry - .select( preferencesStore ) - .get( 'core', 'distractionFree' ); - if ( isDistractionFree ) { - registry - .dispatch( preferencesStore ) - .set( 'core', 'fixedToolbar', false ); - } - if ( ! isDistractionFree ) { - registry.batch( () => { - registry - .dispatch( preferencesStore ) - .set( 'core', 'fixedToolbar', true ); - registry.dispatch( editorStore ).setIsInserterOpened( false ); - registry.dispatch( editorStore ).setIsListViewOpened( false ); - dispatch.closeGeneralSidebar(); - } ); - } - registry.batch( () => { - registry - .dispatch( preferencesStore ) - .set( 'core', 'distractionFree', ! isDistractionFree ); - registry - .dispatch( noticesStore ) - .createInfoNotice( - isDistractionFree - ? __( 'Distraction free off.' ) - : __( 'Distraction free on.' ), - { - id: 'core/edit-post/distraction-free-mode/notice', - type: 'snackbar', - actions: [ - { - label: __( 'Undo' ), - onClick: () => { - registry.batch( () => { - registry - .dispatch( preferencesStore ) - .set( - 'core', - 'fixedToolbar', - isDistractionFree ? true : false - ); - registry - .dispatch( preferencesStore ) - .toggle( - 'core', - 'distractionFree' - ); - } ); - }, - }, - ], - } - ); + ( { registry } ) => { + deprecated( "dispatch( 'core/edit-post' ).toggleDistractionFree", { + since: '6.6', + alternative: "dispatch( 'core/editor').toggleDistractionFree", } ); + registry.dispatch( editorStore ).toggleDistractionFree(); }; diff --git a/packages/edit-post/src/store/test/actions.js b/packages/edit-post/src/store/test/actions.js index 04c010630e50d..cb872d30ee3e2 100644 --- a/packages/edit-post/src/store/test/actions.js +++ b/packages/edit-post/src/store/test/actions.js @@ -53,18 +53,6 @@ describe( 'actions', () => { ).toBeNull(); } ); - it( 'openGeneralSidebar - should turn off distraction free mode when opening a general sidebar', () => { - registry - .dispatch( preferencesStore ) - .set( 'core', 'distractionFree', true ); - registry - .dispatch( editPostStore ) - .openGeneralSidebar( 'edit-post/block' ); - expect( - registry.select( preferencesStore ).get( 'core', 'distractionFree' ) - ).toBe( false ); - } ); - it( 'toggleFeature', () => { registry.dispatch( editPostStore ).toggleFeature( 'welcomeGuide' ); expect( @@ -81,52 +69,6 @@ describe( 'actions', () => { ).toBe( false ); } ); - describe( 'switchEditorMode', () => { - it( 'to visual', () => { - // Switch to text first, since the default is visual. - registry.dispatch( editPostStore ).switchEditorMode( 'text' ); - expect( registry.select( editPostStore ).getEditorMode() ).toEqual( - 'text' - ); - registry.dispatch( editPostStore ).switchEditorMode( 'visual' ); - expect( registry.select( editPostStore ).getEditorMode() ).toEqual( - 'visual' - ); - } ); - - it( 'to text', () => { - // It defaults to visual. - expect( registry.select( editPostStore ).getEditorMode() ).toEqual( - 'visual' - ); - // Add a selected client id and make sure it's there. - const clientId = 'clientId_1'; - registry.dispatch( blockEditorStore ).selectionChange( clientId ); - expect( - registry.select( blockEditorStore ).getSelectedBlockClientId() - ).toEqual( clientId ); - - registry.dispatch( editPostStore ).switchEditorMode( 'text' ); - expect( - registry.select( blockEditorStore ).getSelectedBlockClientId() - ).toBeNull(); - expect( registry.select( editPostStore ).getEditorMode() ).toEqual( - 'text' - ); - } ); - it( 'should turn off distraction free mode when switching to code editor', () => { - registry - .dispatch( preferencesStore ) - .set( 'core', 'distractionFree', true ); - registry.dispatch( editPostStore ).switchEditorMode( 'text' ); - expect( - registry - .select( preferencesStore ) - .get( 'core', 'distractionFree' ) - ).toBe( false ); - } ); - } ); - it( 'togglePinnedPluginItem', () => { registry.dispatch( editPostStore ).togglePinnedPluginItem( 'rigatoni' ); // Sidebars are pinned by default. @@ -199,40 +141,4 @@ describe( 'actions', () => { ).toEqual( expectedB ); } ); } ); - - describe( 'toggleDistractionFree', () => { - it( 'should properly update settings to prevent layout corruption when enabling distraction free mode', () => { - // Enable everything that shouldn't be enabled in distraction free mode. - registry - .dispatch( preferencesStore ) - .set( 'core', 'fixedToolbar', true ); - registry.dispatch( editorStore ).setIsListViewOpened( true ); - registry - .dispatch( editPostStore ) - .openGeneralSidebar( 'edit-post/block' ); - // Initial state is falsy. - registry.dispatch( editPostStore ).toggleDistractionFree(); - expect( - registry - .select( preferencesStore ) - .get( 'core', 'fixedToolbar' ) - ).toBe( true ); - expect( registry.select( editorStore ).isListViewOpened() ).toBe( - false - ); - expect( registry.select( editorStore ).isInserterOpened() ).toBe( - false - ); - expect( - registry - .select( interfaceStore ) - .getActiveComplementaryArea( editPostStore.name ) - ).toBeNull(); - expect( - registry - .select( preferencesStore ) - .get( 'core', 'distractionFree' ) - ).toBe( true ); - } ); - } ); } ); 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 index 0c7dbe8ec3d04..fe3105af2dd55 100644 --- 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 @@ -162,6 +162,7 @@ export function useSpecificEditorSettings() { // I wonder if they should be set in the post editor too __experimentalArchiveTitleTypeLabel: archiveLabels.archiveTypeLabel, __experimentalArchiveTitleNameLabel: archiveLabels.archiveNameLabel, + __unstableIsPreviewMode: canvasMode === 'view', }; }, [ settings, diff --git a/packages/edit-site/src/components/code-editor/index.js b/packages/edit-site/src/components/code-editor/index.js index 1fb4a5b7cd6bf..a02ab71810628 100644 --- a/packages/edit-site/src/components/code-editor/index.js +++ b/packages/edit-site/src/components/code-editor/index.js @@ -14,6 +14,7 @@ import { __ } from '@wordpress/i18n'; import { Button, VisuallyHidden } from '@wordpress/components'; import { useMemo } from '@wordpress/element'; import { useInstanceId } from '@wordpress/compose'; +import { store as editorStore } from '@wordpress/editor'; /** * Internal dependencies @@ -52,7 +53,7 @@ export default function CodeEditor() { return content; }, [ content, blocks ] ); - const { switchEditorMode } = useDispatch( editSiteStore ); + const { switchEditorMode } = useDispatch( editorStore ); return (
diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index 9c95755db2803..4a7d73a11db57 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -115,14 +115,18 @@ export default function Editor( { isLoading } ) { postTypeLabel, } = useSelect( ( select ) => { const { get } = select( preferencesStore ); - const { getEditedPostContext, getEditorMode, getCanvasMode } = unlock( + const { getEditedPostContext, getCanvasMode } = unlock( select( editSiteStore ) ); const { __unstableGetEditorMode } = select( blockEditorStore ); const { getActiveComplementaryArea } = select( interfaceStore ); const { getEntityRecord } = select( coreDataStore ); - const { isInserterOpened, isListViewOpened, getPostTypeLabel } = - select( editorStore ); + const { + isInserterOpened, + isListViewOpened, + getPostTypeLabel, + getEditorMode, + } = select( editorStore ); const _context = getEditedPostContext(); // The currently selected entity to display. @@ -264,10 +268,9 @@ export default function Editor( { isLoading } ) { } sidebar={ isEditMode && - isRightSidebarOpen && ( - <> - - + isRightSidebarOpen && + ! isDistractionFree && ( + ) } footer={ diff --git a/packages/edit-site/src/components/header-edit-mode/document-tools/index.js b/packages/edit-site/src/components/header-edit-mode/document-tools/index.js index 41a4d89f4077c..cd7720a1a34f9 100644 --- a/packages/edit-site/src/components/header-edit-mode/document-tools/index.js +++ b/packages/edit-site/src/components/header-edit-mode/document-tools/index.js @@ -15,7 +15,6 @@ import { /** * Internal dependencies */ -import { store as editSiteStore } from '../../../store'; import { unlock } from '../../../lock-unlock'; const { DocumentTools: EditorDocumentTools } = unlock( editorPrivateApis ); @@ -26,7 +25,7 @@ export default function DocumentTools( { isDistractionFree, } ) { const { isVisualMode } = useSelect( ( select ) => { - const { getEditorMode } = select( editSiteStore ); + const { getEditorMode } = select( editorStore ); return { isVisualMode: getEditorMode() === 'visual', diff --git a/packages/edit-site/src/components/header-edit-mode/mode-switcher/index.js b/packages/edit-site/src/components/header-edit-mode/mode-switcher/index.js index 2c27444f669c0..261bcb852b15f 100644 --- a/packages/edit-site/src/components/header-edit-mode/mode-switcher/index.js +++ b/packages/edit-site/src/components/header-edit-mode/mode-switcher/index.js @@ -5,11 +5,7 @@ import { __ } from '@wordpress/i18n'; import { MenuItemsChoice, MenuGroup } from '@wordpress/components'; import { useSelect, useDispatch } from '@wordpress/data'; import { store as keyboardShortcutsStore } from '@wordpress/keyboard-shortcuts'; - -/** - * Internal dependencies - */ -import { store as editSiteStore } from '../../../store'; +import { store as editorStore } from '@wordpress/editor'; /** * Set of available mode options. @@ -33,11 +29,11 @@ function ModeSwitcher() { shortcut: select( keyboardShortcutsStore ).getShortcutRepresentation( 'core/edit-site/toggle-mode' ), - mode: select( editSiteStore ).getEditorMode(), + mode: select( editorStore ).getEditorMode(), } ), [] ); - const { switchEditorMode } = useDispatch( editSiteStore ); + const { switchEditorMode } = useDispatch( editorStore ); const choices = MODES.map( ( choice ) => { if ( choice.value !== mode ) { diff --git a/packages/edit-site/src/components/header-edit-mode/more-menu/index.js b/packages/edit-site/src/components/header-edit-mode/more-menu/index.js index 6f87e62bd750f..8cafbb519bb1f 100644 --- a/packages/edit-site/src/components/header-edit-mode/more-menu/index.js +++ b/packages/edit-site/src/components/header-edit-mode/more-menu/index.js @@ -16,6 +16,7 @@ import { store as preferencesStore, } from '@wordpress/preferences'; import { store as coreStore } from '@wordpress/core-data'; +import { store as editorStore } from '@wordpress/editor'; /** * Internal dependencies @@ -33,7 +34,6 @@ import SiteExport from './site-export'; import WelcomeGuideMenuItem from './welcome-guide-menu-item'; import CopyContentMenuItem from './copy-content-menu-item'; import ModeSwitcher from '../mode-switcher'; -import { store as editSiteStore } from '../../../store'; export default function MoreMenu( { showIconLabels } ) { const { openModal } = useDispatch( interfaceStore ); @@ -42,7 +42,7 @@ export default function MoreMenu( { showIconLabels } ) { return select( coreStore ).getCurrentTheme().is_block_theme; }, [] ); - const { toggleDistractionFree } = useDispatch( editSiteStore ); + const { toggleDistractionFree } = useDispatch( editorStore ); const turnOffDistractionFree = () => { setPreference( 'core', 'distractionFree', false ); diff --git a/packages/edit-site/src/components/keyboard-shortcuts/edit-mode.js b/packages/edit-site/src/components/keyboard-shortcuts/edit-mode.js index 07e017349a0c6..436a7218f5543 100644 --- a/packages/edit-site/src/components/keyboard-shortcuts/edit-mode.js +++ b/packages/edit-site/src/components/keyboard-shortcuts/edit-mode.js @@ -6,6 +6,7 @@ import { useDispatch, useSelect } from '@wordpress/data'; import { store as blockEditorStore } from '@wordpress/block-editor'; import { store as interfaceStore } from '@wordpress/interface'; import { createBlock } from '@wordpress/blocks'; +import { store as editorStore } from '@wordpress/editor'; /** * Internal dependencies @@ -15,7 +16,7 @@ import { SIDEBAR_BLOCK } from '../sidebar-edit-mode/constants'; import { STORE_NAME } from '../../store/constants'; function KeyboardShortcutsEditMode() { - const { getEditorMode } = useSelect( editSiteStore ); + const { getEditorMode } = useSelect( editorStore ); const isBlockInspectorOpen = useSelect( ( select ) => select( interfaceStore ).getActiveComplementaryArea( @@ -24,7 +25,7 @@ function KeyboardShortcutsEditMode() { [] ); const { switchEditorMode, toggleDistractionFree } = - useDispatch( editSiteStore ); + useDispatch( editorStore ); const { enableComplementaryArea, disableComplementaryArea } = useDispatch( interfaceStore ); const { replaceBlocks } = useDispatch( blockEditorStore ); diff --git a/packages/edit-site/src/components/sidebar-edit-mode/global-styles-sidebar.js b/packages/edit-site/src/components/sidebar-edit-mode/global-styles-sidebar.js index 14d1d10691c25..5cc0baa489ec7 100644 --- a/packages/edit-site/src/components/sidebar-edit-mode/global-styles-sidebar.js +++ b/packages/edit-site/src/components/sidebar-edit-mode/global-styles-sidebar.js @@ -41,7 +41,7 @@ export default function GlobalStylesSidebar() { ); const canvasContainerView = getEditorCanvasContainerView(); const _isVisualEditorMode = - 'visual' === select( editSiteStore ).getEditorMode(); + 'visual' === select( editorStore ).getEditorMode(); const _isEditCanvasMode = 'edit' === getCanvasMode(); const _showListViewByDefault = select( preferencesStore ).get( 'core', diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js index 9840098e338bd..a064e9f587853 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js @@ -10,6 +10,7 @@ import { useViewportMatch } from '@wordpress/compose'; import { BlockEditorProvider } from '@wordpress/block-editor'; import { useCallback } from '@wordpress/element'; import { store as editorStore } from '@wordpress/editor'; +import { store as preferencesStore } from '@wordpress/preferences'; /** * Internal dependencies @@ -115,13 +116,15 @@ export default function SidebarNavigationScreenGlobalStyles() { }, [] ); + const { set: setPreference } = useDispatch( preferencesStore ); const openGlobalStyles = useCallback( async () => { return Promise.all( [ + setPreference( 'core', 'distractionFree', false ), setCanvasMode( 'edit' ), openGeneralSidebar( 'edit-site/global-styles' ), ] ); - }, [ setCanvasMode, openGeneralSidebar ] ); + }, [ setCanvasMode, openGeneralSidebar, setPreference ] ); const openStyleBook = useCallback( async () => { await openGlobalStyles(); diff --git a/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js b/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js index 2eb873f84f181..2974a8948358a 100644 --- a/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js +++ b/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js @@ -13,17 +13,13 @@ import { drawerLeft, drawerRight, blockDefault, - code, keyboard, - listView, symbol, } from '@wordpress/icons'; import { useCommandLoader } from '@wordpress/commands'; import { decodeEntities } from '@wordpress/html-entities'; import { privateApis as routerPrivateApis } from '@wordpress/router'; -import { store as preferencesStore } from '@wordpress/preferences'; import { store as interfaceStore } from '@wordpress/interface'; -import { store as noticesStore } from '@wordpress/notices'; import { store as editorStore } from '@wordpress/editor'; /** @@ -103,37 +99,6 @@ function usePageContentFocusCommands() { return { isLoading: false, commands }; } -function useEditorModeCommands() { - const { switchEditorMode } = useDispatch( editSiteStore ); - const { canvasMode, editorMode } = useSelect( - ( select ) => ( { - canvasMode: unlock( select( editSiteStore ) ).getCanvasMode(), - editorMode: select( editSiteStore ).getEditorMode(), - } ), - [] - ); - - if ( canvasMode !== 'edit' || editorMode !== 'text' ) { - return { isLoading: false, commands: [] }; - } - - const commands = []; - - if ( editorMode === 'text' ) { - commands.push( { - name: 'core/exit-code-editor', - label: __( 'Exit code editor' ), - icon: code, - callback: ( { close } ) => { - switchEditorMode( 'visual' ); - close(); - }, - } ); - } - - return { isLoading: false, commands }; -} - function useManipulateDocumentCommands() { const { isLoaded, record: template } = useEditedEntityRecord(); const { removeTemplate, revertTemplate } = useDispatch( editSiteStore ); @@ -214,42 +179,17 @@ function useManipulateDocumentCommands() { } function useEditUICommands() { - const { - openGeneralSidebar, - closeGeneralSidebar, - toggleDistractionFree, - setIsListViewOpened, - switchEditorMode, - } = useDispatch( editSiteStore ); - const { - canvasMode, - editorMode, - activeSidebar, - showBlockBreadcrumbs, - isListViewOpen, - isDistractionFree, - isTopToolbar, - isFocusMode, - } = useSelect( ( select ) => { - const { get } = select( preferencesStore ); - const { getEditorMode } = select( editSiteStore ); - const { isListViewOpened } = select( editorStore ); + const { openGeneralSidebar, closeGeneralSidebar } = + useDispatch( editSiteStore ); + const { canvasMode, activeSidebar } = useSelect( ( select ) => { return { canvasMode: unlock( select( editSiteStore ) ).getCanvasMode(), - editorMode: getEditorMode(), activeSidebar: select( interfaceStore ).getActiveComplementaryArea( editSiteStore.name ), - showBlockBreadcrumbs: get( 'core', 'showBlockBreadcrumbs' ), - isListViewOpen: isListViewOpened(), - isDistractionFree: get( 'core', 'distractionFree' ), - isFocusMode: get( 'core', 'focusMode' ), - isTopToolbar: get( 'core', 'fixedToolbar' ), }; }, [] ); const { openModal } = useDispatch( interfaceStore ); - const { toggle } = useDispatch( preferencesStore ); - const { createInfoNotice } = useDispatch( noticesStore ); if ( canvasMode !== 'edit' ) { return { isLoading: false, commands: [] }; @@ -285,82 +225,6 @@ function useEditUICommands() { }, } ); - commands.push( { - name: 'core/toggle-spotlight-mode', - label: __( 'Toggle spotlight' ), - callback: ( { close } ) => { - toggle( 'core', 'focusMode' ); - close(); - createInfoNotice( - isFocusMode ? __( 'Spotlight off.' ) : __( 'Spotlight on.' ), - { - id: 'core/edit-site/toggle-spotlight-mode/notice', - type: 'snackbar', - actions: [ - { - label: __( 'Undo' ), - onClick: () => { - toggle( 'core', 'focusMode' ); - }, - }, - ], - } - ); - }, - } ); - - commands.push( { - name: 'core/toggle-distraction-free', - label: isDistractionFree - ? __( 'Exit Distraction Free' ) - : __( 'Enter Distraction Free ' ), - callback: ( { close } ) => { - toggleDistractionFree(); - close(); - }, - } ); - - commands.push( { - name: 'core/toggle-top-toolbar', - label: __( 'Toggle top toolbar' ), - callback: ( { close } ) => { - toggle( 'core', 'fixedToolbar' ); - if ( isDistractionFree ) { - toggleDistractionFree(); - } - close(); - createInfoNotice( - isTopToolbar - ? __( 'Top toolbar off.' ) - : __( 'Top toolbar on.' ), - { - id: 'core/edit-site/toggle-top-toolbar/notice', - type: 'snackbar', - actions: [ - { - label: __( 'Undo' ), - onClick: () => { - toggle( 'core', 'fixedToolbar' ); - }, - }, - ], - } - ); - }, - } ); - - if ( editorMode === 'visual' ) { - commands.push( { - name: 'core/toggle-code-editor', - label: __( 'Open code editor' ), - icon: code, - callback: ( { close } ) => { - switchEditorMode( 'text' ); - close(); - }, - } ); - } - commands.push( { name: 'core/open-preferences', label: __( 'Editor preferences' ), @@ -378,45 +242,6 @@ function useEditUICommands() { }, } ); - commands.push( { - name: 'core/toggle-breadcrumbs', - label: showBlockBreadcrumbs - ? __( 'Hide block breadcrumbs' ) - : __( 'Show block breadcrumbs' ), - callback: ( { close } ) => { - toggle( 'core', 'showBlockBreadcrumbs' ); - close(); - createInfoNotice( - showBlockBreadcrumbs - ? __( 'Breadcrumbs hidden.' ) - : __( 'Breadcrumbs visible.' ), - { - id: 'core/edit-site/toggle-breadcrumbs/notice', - type: 'snackbar', - } - ); - }, - } ); - - commands.push( { - name: 'core/toggle-list-view', - label: isListViewOpen - ? __( 'Close List View' ) - : __( 'Open List View' ), - icon: listView, - callback: ( { close } ) => { - setIsListViewOpened( ! isListViewOpen ); - close(); - createInfoNotice( - isListViewOpen ? __( 'List View off.' ) : __( 'List View on.' ), - { - id: 'core/edit-site/toggle-list-view/notice', - type: 'snackbar', - } - ); - }, - } ); - return { isLoading: false, commands, @@ -458,12 +283,6 @@ function usePatternCommands() { } export function useEditModeCommands() { - useCommandLoader( { - name: 'core/exit-code-editor', - hook: useEditorModeCommands, - context: 'site-editor-edit', - } ); - useCommandLoader( { name: 'core/edit-site/page-content-focus', hook: usePageContentFocusCommands, diff --git a/packages/edit-site/src/store/actions.js b/packages/edit-site/src/store/actions.js index 388d7cc0a413e..6aefab6ea0ff2 100644 --- a/packages/edit-site/src/store/actions.js +++ b/packages/edit-site/src/store/actions.js @@ -11,7 +11,6 @@ import { store as coreStore } from '@wordpress/core-data'; import { store as interfaceStore } from '@wordpress/interface'; import { store as blockEditorStore } from '@wordpress/block-editor'; import { store as editorStore } from '@wordpress/editor'; -import { speak } from '@wordpress/a11y'; import { store as preferencesStore } from '@wordpress/preferences'; /** @@ -477,13 +476,7 @@ export const revertTemplate = */ export const openGeneralSidebar = ( name ) => - ( { dispatch, registry } ) => { - const isDistractionFree = registry - .select( preferencesStore ) - .get( 'core', 'distractionFree' ); - if ( isDistractionFree ) { - dispatch.toggleDistractionFree(); - } + ( { registry } ) => { registry .dispatch( interfaceStore ) .enableComplementaryArea( editSiteStoreName, name ); @@ -500,29 +493,21 @@ export const closeGeneralSidebar = .disableComplementaryArea( editSiteStoreName ); }; +/** + * Triggers an action used to switch editor mode. + * + * @deprecated + * + * @param {string} mode The editor mode. + */ export const switchEditorMode = ( mode ) => - ( { dispatch, registry } ) => { - registry - .dispatch( 'core/preferences' ) - .set( 'core', 'editorMode', mode ); - - // Unselect blocks when we switch to a non visual mode. - if ( mode !== 'visual' ) { - registry.dispatch( blockEditorStore ).clearSelectedBlock(); - } - - if ( mode === 'visual' ) { - speak( __( 'Visual editor selected' ), 'assertive' ); - } else if ( mode === 'text' ) { - const isDistractionFree = registry - .select( preferencesStore ) - .get( 'core', 'distractionFree' ); - if ( isDistractionFree ) { - dispatch.toggleDistractionFree(); - } - speak( __( 'Code editor selected' ), 'assertive' ); - } + ( { registry } ) => { + deprecated( "dispatch( 'core/edit-site' ).switchEditorMode", { + since: '6.6', + alternative: "dispatch( 'core/editor').switchEditorMode", + } ); + registry.dispatch( editorStore ).switchEditorMode( mode ); }; /** @@ -552,64 +537,15 @@ export const setHasPageContentFocus = * Action that toggles Distraction free mode. * Distraction free mode expects there are no sidebars, as due to the * z-index values set, you can't close sidebars. + * + * @deprecated */ export const toggleDistractionFree = () => - ( { dispatch, registry } ) => { - const isDistractionFree = registry - .select( preferencesStore ) - .get( 'core', 'distractionFree' ); - if ( isDistractionFree ) { - registry - .dispatch( preferencesStore ) - .set( 'core', 'fixedToolbar', false ); - } - if ( ! isDistractionFree ) { - registry.batch( () => { - registry - .dispatch( preferencesStore ) - .set( 'core', 'fixedToolbar', true ); - registry.dispatch( editorStore ).setIsInserterOpened( false ); - registry.dispatch( editorStore ).setIsListViewOpened( false ); - dispatch.closeGeneralSidebar(); - } ); - } - registry.batch( () => { - registry - .dispatch( preferencesStore ) - .set( 'core', 'distractionFree', ! isDistractionFree ); - registry - .dispatch( noticesStore ) - .createInfoNotice( - isDistractionFree - ? __( 'Distraction free off.' ) - : __( 'Distraction free on.' ), - { - id: 'core/edit-site/distraction-free-mode/notice', - type: 'snackbar', - actions: [ - { - label: __( 'Undo' ), - onClick: () => { - registry.batch( () => { - registry - .dispatch( preferencesStore ) - .set( - 'core', - 'fixedToolbar', - isDistractionFree ? true : false - ); - registry - .dispatch( preferencesStore ) - .toggle( - 'core', - 'distractionFree' - ); - } ); - }, - }, - ], - } - ); + ( { registry } ) => { + deprecated( "dispatch( 'core/edit-site' ).toggleDistractionFree", { + since: '6.6', + alternative: "dispatch( 'core/editor').toggleDistractionFree", } ); + registry.dispatch( editorStore ).toggleDistractionFree(); }; diff --git a/packages/edit-site/src/store/test/actions.js b/packages/edit-site/src/store/test/actions.js index b3612b9a801cc..05dd239d19c69 100644 --- a/packages/edit-site/src/store/test/actions.js +++ b/packages/edit-site/src/store/test/actions.js @@ -75,79 +75,4 @@ describe( 'actions', () => { expect( select.getEditedPostType() ).toBe( 'wp_template_part' ); } ); } ); - - describe( 'openGeneralSidebar', () => { - it( 'should turn off distraction free mode when opening a general sidebar', () => { - const registry = createRegistryWithStores(); - registry - .dispatch( preferencesStore ) - .set( 'core', 'distractionFree', true ); - registry - .dispatch( editSiteStore ) - .openGeneralSidebar( 'edit-site/global-styles' ); - expect( - registry - .select( preferencesStore ) - .get( 'core', 'distractionFree' ) - ).toBe( false ); - } ); - } ); - - describe( 'switchEditorMode', () => { - it( 'should turn off distraction free mode when switching to code editor', () => { - const registry = createRegistryWithStores(); - registry - .dispatch( preferencesStore ) - .set( 'core', 'distractionFree', true ); - registry.dispatch( editSiteStore ).switchEditorMode( 'visual' ); - expect( - registry - .select( preferencesStore ) - .get( 'core', 'distractionFree' ) - ).toBe( true ); - registry.dispatch( editSiteStore ).switchEditorMode( 'text' ); - expect( - registry - .select( preferencesStore ) - .get( 'core', 'distractionFree' ) - ).toBe( false ); - } ); - } ); - - describe( 'toggleDistractionFree', () => { - it( 'should properly update settings to prevent layout corruption when enabling distraction free mode', () => { - const registry = createRegistryWithStores(); - // Enable everything that shouldn't be enabled in distraction free mode. - registry - .dispatch( preferencesStore ) - .set( 'core', 'fixedToolbar', true ); - registry.dispatch( editorStore ).setIsListViewOpened( true ); - registry - .dispatch( editSiteStore ) - .openGeneralSidebar( 'edit-site/global-styles' ); - // Initial state is falsy. - registry.dispatch( editSiteStore ).toggleDistractionFree(); - expect( - registry - .select( preferencesStore ) - .get( 'core', 'fixedToolbar' ) - ).toBe( true ); - expect( registry.select( editorStore ).isListViewOpened() ).toBe( - false - ); - expect( registry.select( editorStore ).isInserterOpened() ).toBe( - false - ); - expect( - registry - .select( interfaceStore ) - .getActiveComplementaryArea( editSiteStore.name ) - ).toBeNull(); - expect( - registry - .select( preferencesStore ) - .get( 'core', 'distractionFree' ) - ).toBe( true ); - } ); - } ); } ); diff --git a/packages/editor/src/components/commands/index.js b/packages/editor/src/components/commands/index.js new file mode 100644 index 0000000000000..eb97e8d10b93a --- /dev/null +++ b/packages/editor/src/components/commands/index.js @@ -0,0 +1,202 @@ +/** + * WordPress dependencies + */ +import { useSelect, useDispatch } from '@wordpress/data'; +import { __ } from '@wordpress/i18n'; +import { code, listView, external } from '@wordpress/icons'; +import { useCommandLoader } from '@wordpress/commands'; +import { store as preferencesStore } from '@wordpress/preferences'; +import { store as noticesStore } from '@wordpress/notices'; +import { store as blockEditorStore } from '@wordpress/block-editor'; +import { store as coreStore } from '@wordpress/core-data'; + +/** + * Internal dependencies + */ +import { store as editorStore } from '../../store'; + +function useEditorCommandLoader() { + const { + editorMode, + isListViewOpen, + showBlockBreadcrumbs, + isDistractionFree, + isTopToolbar, + isFocusMode, + isPreviewMode, + isViewable, + } = useSelect( ( select ) => { + const { get } = select( preferencesStore ); + const { isListViewOpened, getCurrentPostType } = select( editorStore ); + const { getSettings } = select( blockEditorStore ); + const { getPostType } = select( coreStore ); + + return { + editorMode: get( 'core', 'editorMode' ) ?? 'visual', + isListViewOpen: isListViewOpened(), + showBlockBreadcrumbs: get( 'core', 'showBlockBreadcrumbs' ), + isDistractionFree: get( 'core', 'distractionFree' ), + isFocusMode: get( 'core', 'focusMode' ), + isTopToolbar: get( 'core', 'fixedToolbar' ), + isPreviewMode: getSettings().__unstableIsPreviewMode, + isViewable: getPostType( getCurrentPostType() )?.viewable ?? false, + }; + }, [] ); + const { toggle } = useDispatch( preferencesStore ); + const { createInfoNotice } = useDispatch( noticesStore ); + const { + __unstableSaveForPreview, + setIsListViewOpened, + switchEditorMode, + toggleDistractionFree, + } = useDispatch( editorStore ); + const { getCurrentPostId } = useSelect( editorStore ); + + if ( isPreviewMode ) { + return { commands: [], isLoading: false }; + } + + const commands = []; + + commands.push( { + name: 'core/toggle-distraction-free', + label: isDistractionFree + ? __( 'Exit Distraction Free' ) + : __( 'Enter Distraction Free ' ), + callback: ( { close } ) => { + toggleDistractionFree(); + close(); + }, + } ); + + commands.push( { + name: 'core/toggle-spotlight-mode', + label: __( 'Toggle spotlight' ), + callback: ( { close } ) => { + toggle( 'core', 'focusMode' ); + close(); + createInfoNotice( + isFocusMode ? __( 'Spotlight off.' ) : __( 'Spotlight on.' ), + { + id: 'core/editor/toggle-spotlight-mode/notice', + type: 'snackbar', + actions: [ + { + label: __( 'Undo' ), + onClick: () => { + toggle( 'core', 'focusMode' ); + }, + }, + ], + } + ); + }, + } ); + + commands.push( { + name: 'core/toggle-list-view', + label: isListViewOpen + ? __( 'Close List View' ) + : __( 'Open List View' ), + icon: listView, + callback: ( { close } ) => { + setIsListViewOpened( ! isListViewOpen ); + close(); + createInfoNotice( + isListViewOpen ? __( 'List View off.' ) : __( 'List View on.' ), + { + id: 'core/editor/toggle-list-view/notice', + type: 'snackbar', + } + ); + }, + } ); + + commands.push( { + name: 'core/toggle-top-toolbar', + label: __( 'Toggle top toolbar' ), + callback: ( { close } ) => { + toggle( 'core', 'fixedToolbar' ); + if ( isDistractionFree ) { + toggleDistractionFree(); + } + close(); + createInfoNotice( + isTopToolbar + ? __( 'Top toolbar off.' ) + : __( 'Top toolbar on.' ), + { + id: 'core/editor/toggle-top-toolbar/notice', + type: 'snackbar', + actions: [ + { + label: __( 'Undo' ), + onClick: () => { + toggle( 'core', 'fixedToolbar' ); + }, + }, + ], + } + ); + }, + } ); + + commands.push( { + name: 'core/toggle-code-editor', + label: + editorMode === 'visual' + ? __( 'Open code editor' ) + : __( 'Exit code editor' ), + icon: code, + callback: ( { close } ) => { + switchEditorMode( editorMode === 'visual' ? 'text' : 'visual' ); + close(); + }, + } ); + + commands.push( { + name: 'core/toggle-breadcrumbs', + label: showBlockBreadcrumbs + ? __( 'Hide block breadcrumbs' ) + : __( 'Show block breadcrumbs' ), + callback: ( { close } ) => { + toggle( 'core', 'showBlockBreadcrumbs' ); + close(); + createInfoNotice( + showBlockBreadcrumbs + ? __( 'Breadcrumbs hidden.' ) + : __( 'Breadcrumbs visible.' ), + { + id: 'core/editor/toggle-breadcrumbs/notice', + type: 'snackbar', + } + ); + }, + } ); + + if ( isViewable ) { + commands.push( { + name: 'core/preview-link', + label: __( 'Preview in a new tab' ), + icon: external, + callback: async ( { close } ) => { + close(); + const postId = getCurrentPostId(); + const link = await __unstableSaveForPreview(); + window.open( link, `wp-preview-${ postId }` ); + }, + } ); + } + + return { + commands, + isLoading: false, + }; +} + +export default function useCommands() { + useCommandLoader( { + name: 'core/editor/edit-ui', + hook: useEditorCommandLoader, + } ); +} diff --git a/packages/editor/src/components/commands/index.native.js b/packages/editor/src/components/commands/index.native.js new file mode 100644 index 0000000000000..23e48951a0329 --- /dev/null +++ b/packages/editor/src/components/commands/index.native.js @@ -0,0 +1,2 @@ +// Commands are disabled in the mobile native version. +export default function useCommands() {} diff --git a/packages/editor/src/components/provider/index.js b/packages/editor/src/components/provider/index.js index 9f0d25e157635..323b231b56219 100644 --- a/packages/editor/src/components/provider/index.js +++ b/packages/editor/src/components/provider/index.js @@ -24,6 +24,7 @@ import { unlock } from '../../lock-unlock'; import DisableNonPageContentBlocks from './disable-non-page-content-blocks'; import NavigationBlockEditingMode from './navigation-block-editing-mode'; import { useHideBlocksFromInserter } from './use-hide-bocks-from-inserter'; +import useCommands from '../commands'; const { ExperimentalBlockEditorProvider } = unlock( blockEditorPrivateApis ); const { PatternsMenuItems } = unlock( editPatternsPrivateApis ); @@ -232,6 +233,9 @@ export const ExperimentalEditorProvider = withRegistryProvider( useHideBlocksFromInserter( post.type ); + // Register the editor commands. + useCommands(); + if ( ! isReady ) { return null; } diff --git a/packages/editor/src/components/provider/index.native.js b/packages/editor/src/components/provider/index.native.js index 17a7a55bfedd4..fe0b5fcf9f10b 100644 --- a/packages/editor/src/components/provider/index.native.js +++ b/packages/editor/src/components/provider/index.native.js @@ -59,8 +59,6 @@ const postTypeEntities = [ import { EditorHelpTopics, store as editorStore } from '@wordpress/editor'; import { store as noticesStore } from '@wordpress/notices'; import { store as coreStore } from '@wordpress/core-data'; -// eslint-disable-next-line no-restricted-imports -import { store as editPostStore } from '@wordpress/edit-post'; /** * Internal dependencies @@ -392,8 +390,8 @@ const ComposedNativeProvider = compose( [ getEditedPostAttribute, getEditedPostContent, getEditorSettings, + getEditorMode, } = select( editorStore ); - const { getEditorMode } = select( editPostStore ); const { getBlockIndex, getSelectedBlockClientId, getGlobalBlockCount } = select( blockEditorStore ); @@ -417,15 +415,18 @@ const ComposedNativeProvider = compose( [ }; } ), withDispatch( ( dispatch ) => { - const { editPost, resetEditorBlocks, updateEditorSettings } = - dispatch( editorStore ); + const { + editPost, + resetEditorBlocks, + updateEditorSettings, + switchEditorMode, + } = dispatch( editorStore ); const { clearSelectedBlock, updateSettings, insertBlock, replaceBlock, } = dispatch( blockEditorStore ); - const { switchEditorMode } = dispatch( editPostStore ); const { addEntities, receiveEntityRecords } = dispatch( coreStore ); const { createSuccessNotice, createErrorNotice } = dispatch( noticesStore ); diff --git a/packages/editor/src/store/actions.js b/packages/editor/src/store/actions.js index 4c0f1078fde65..33119aa2e75e6 100644 --- a/packages/editor/src/store/actions.js +++ b/packages/editor/src/store/actions.js @@ -1,6 +1,7 @@ /** * WordPress dependencies */ +import { speak } from '@wordpress/a11y'; import apiFetch from '@wordpress/api-fetch'; import deprecated from '@wordpress/deprecated'; import { @@ -13,6 +14,7 @@ import { store as coreStore } from '@wordpress/core-data'; import { store as blockEditorStore } from '@wordpress/block-editor'; import { applyFilters } from '@wordpress/hooks'; import { store as preferencesStore } from '@wordpress/preferences'; +import { __ } from '@wordpress/i18n'; /** * Internal dependencies @@ -725,6 +727,99 @@ export function setIsListViewOpened( isOpen ) { }; } +/** + * Action that toggles Distraction free mode. + * Distraction free mode expects there are no sidebars, as due to the + * z-index values set, you can't close sidebars. + */ +export const toggleDistractionFree = + () => + ( { dispatch, registry } ) => { + const isDistractionFree = registry + .select( preferencesStore ) + .get( 'core', 'distractionFree' ); + if ( isDistractionFree ) { + registry + .dispatch( preferencesStore ) + .set( 'core', 'fixedToolbar', false ); + } + if ( ! isDistractionFree ) { + registry.batch( () => { + registry + .dispatch( preferencesStore ) + .set( 'core', 'fixedToolbar', true ); + dispatch.setIsInserterOpened( false ); + dispatch.setIsListViewOpened( false ); + } ); + } + registry.batch( () => { + registry + .dispatch( preferencesStore ) + .set( 'core', 'distractionFree', ! isDistractionFree ); + registry + .dispatch( noticesStore ) + .createInfoNotice( + isDistractionFree + ? __( 'Distraction free off.' ) + : __( 'Distraction free on.' ), + { + id: 'core/editor/distraction-free-mode/notice', + type: 'snackbar', + actions: [ + { + label: __( 'Undo' ), + onClick: () => { + registry.batch( () => { + registry + .dispatch( preferencesStore ) + .set( + 'core', + 'fixedToolbar', + isDistractionFree ? true : false + ); + registry + .dispatch( preferencesStore ) + .toggle( + 'core', + 'distractionFree' + ); + } ); + }, + }, + ], + } + ); + } ); + }; + +/** + * Triggers an action used to switch editor mode. + * + * @param {string} mode The editor mode. + */ +export const switchEditorMode = + ( mode ) => + ( { dispatch, registry } ) => { + registry.dispatch( preferencesStore ).set( 'core', 'editorMode', mode ); + + // Unselect blocks when we switch to a non visual mode. + if ( mode !== 'visual' ) { + registry.dispatch( blockEditorStore ).clearSelectedBlock(); + } + + if ( mode === 'visual' ) { + speak( __( 'Visual editor selected' ), 'assertive' ); + } else if ( mode === 'text' ) { + const isDistractionFree = registry + .select( preferencesStore ) + .get( 'core', 'distractionFree' ); + if ( isDistractionFree ) { + dispatch.toggleDistractionFree(); + } + speak( __( 'Code editor selected' ), 'assertive' ); + } + }; + /** * Backward compatibility */ diff --git a/packages/editor/src/store/selectors.js b/packages/editor/src/store/selectors.js index f7bf1f58bba39..985bd9a7eb2f0 100644 --- a/packages/editor/src/store/selectors.js +++ b/packages/editor/src/store/selectors.js @@ -1313,6 +1313,18 @@ export function isInserterOpened( state ) { return !! state.blockInserterPanel; } +/** + * Returns the current editing mode. + * + * @param {Object} state Global application state. + * + * @return {string} Editing mode. + */ +export const getEditorMode = createRegistrySelector( + ( select ) => () => + select( preferencesStore ).get( 'core', 'editorMode' ) ?? 'visual' +); + /* * Backward compatibility */ diff --git a/packages/editor/src/store/test/actions.js b/packages/editor/src/store/test/actions.js index b977e92baf8c1..a2e683cc23cc9 100644 --- a/packages/editor/src/store/test/actions.js +++ b/packages/editor/src/store/test/actions.js @@ -488,4 +488,86 @@ describe( 'Editor actions', () => { ).toBe( false ); } ); } ); + + describe( 'switchEditorMode', () => { + let registry; + + beforeEach( () => { + registry = createRegistryWithStores(); + } ); + + it( 'to visual', () => { + // Switch to text first, since the default is visual. + registry.dispatch( editorStore ).switchEditorMode( 'text' ); + expect( registry.select( editorStore ).getEditorMode() ).toEqual( + 'text' + ); + registry.dispatch( editorStore ).switchEditorMode( 'visual' ); + expect( registry.select( editorStore ).getEditorMode() ).toEqual( + 'visual' + ); + } ); + + it( 'to text', () => { + // It defaults to visual. + expect( registry.select( editorStore ).getEditorMode() ).toEqual( + 'visual' + ); + // Add a selected client id and make sure it's there. + const clientId = 'clientId_1'; + registry.dispatch( blockEditorStore ).selectionChange( clientId ); + expect( + registry.select( blockEditorStore ).getSelectedBlockClientId() + ).toEqual( clientId ); + + registry.dispatch( editorStore ).switchEditorMode( 'text' ); + expect( + registry.select( blockEditorStore ).getSelectedBlockClientId() + ).toBeNull(); + expect( registry.select( editorStore ).getEditorMode() ).toEqual( + 'text' + ); + } ); + it( 'should turn off distraction free mode when switching to code editor', () => { + registry + .dispatch( preferencesStore ) + .set( 'core', 'distractionFree', true ); + registry.dispatch( editorStore ).switchEditorMode( 'text' ); + expect( + registry + .select( preferencesStore ) + .get( 'core', 'distractionFree' ) + ).toBe( false ); + } ); + } ); + + describe( 'toggleDistractionFree', () => { + it( 'should properly update settings to prevent layout corruption when enabling distraction free mode', () => { + const registry = createRegistryWithStores(); + + // Enable everything that shouldn't be enabled in distraction free mode. + registry + .dispatch( preferencesStore ) + .set( 'core', 'fixedToolbar', true ); + registry.dispatch( editorStore ).setIsListViewOpened( true ); + // Initial state is falsy. + registry.dispatch( editorStore ).toggleDistractionFree(); + expect( + registry + .select( preferencesStore ) + .get( 'core', 'fixedToolbar' ) + ).toBe( true ); + expect( registry.select( editorStore ).isListViewOpened() ).toBe( + false + ); + expect( registry.select( editorStore ).isInserterOpened() ).toBe( + false + ); + expect( + registry + .select( preferencesStore ) + .get( 'core', 'distractionFree' ) + ).toBe( true ); + } ); + } ); } );