@wordpress/edit-post
Version:
Edit Post module for WordPress.
379 lines (350 loc) • 10.1 kB
JavaScript
/**
* External dependencies
*/
import createSelector from 'rememo';
import { get, includes, some, flatten, values } from 'lodash';
/**
* WordPress dependencies
*/
import { createRegistrySelector } from '@wordpress/data';
import { store as interfaceStore } from '@wordpress/interface';
import { store as coreStore } from '@wordpress/core-data';
import { store as editorStore } from '@wordpress/editor';
/**
* Returns the current editing mode.
*
* @param {Object} state Global application state.
*
* @return {string} Editing mode.
*/
export function getEditorMode( state ) {
return getPreference( state, 'editorMode', 'visual' );
}
/**
* Returns true if the editor sidebar is opened.
*
* @param {Object} state Global application state
*
* @return {boolean} Whether the editor sidebar is opened.
*/
export const isEditorSidebarOpened = createRegistrySelector(
( select ) => () => {
const activeGeneralSidebar = select(
interfaceStore
).getActiveComplementaryArea( 'core/edit-post' );
return includes(
[ 'edit-post/document', 'edit-post/block' ],
activeGeneralSidebar
);
}
);
/**
* Returns true if the plugin sidebar is opened.
*
* @param {Object} state Global application state
* @return {boolean} Whether the plugin sidebar is opened.
*/
export const isPluginSidebarOpened = createRegistrySelector(
( select ) => () => {
const activeGeneralSidebar = select(
interfaceStore
).getActiveComplementaryArea( 'core/edit-post' );
return (
!! activeGeneralSidebar &&
! includes(
[ 'edit-post/document', 'edit-post/block' ],
activeGeneralSidebar
)
);
}
);
/**
* Returns the current active general sidebar name, or null if there is no
* general sidebar active. The active general sidebar is a unique name to
* identify either an editor or plugin sidebar.
*
* Examples:
*
* - `edit-post/document`
* - `my-plugin/insert-image-sidebar`
*
* @param {Object} state Global application state.
*
* @return {?string} Active general sidebar name.
*/
export const getActiveGeneralSidebarName = createRegistrySelector(
( select ) => () => {
return select( interfaceStore ).getActiveComplementaryArea(
'core/edit-post'
);
}
);
/**
* Returns the preferences (these preferences are persisted locally).
*
* @param {Object} state Global application state.
*
* @return {Object} Preferences Object.
*/
export function getPreferences( state ) {
return state.preferences;
}
/**
*
* @param {Object} state Global application state.
* @param {string} preferenceKey Preference Key.
* @param {*} defaultValue Default Value.
*
* @return {*} Preference Value.
*/
export function getPreference( state, preferenceKey, defaultValue ) {
const preferences = getPreferences( state );
const value = preferences[ preferenceKey ];
return value === undefined ? defaultValue : value;
}
/**
* Returns true if the publish sidebar is opened.
*
* @param {Object} state Global application state
*
* @return {boolean} Whether the publish sidebar is open.
*/
export function isPublishSidebarOpened( state ) {
return state.publishSidebarActive;
}
/**
* Returns true if the given panel was programmatically removed, or false otherwise.
* All panels are not removed by default.
*
* @param {Object} state Global application state.
* @param {string} panelName A string that identifies the panel.
*
* @return {boolean} Whether or not the panel is removed.
*/
export function isEditorPanelRemoved( state, panelName ) {
return includes( state.removedPanels, panelName );
}
/**
* Returns true if the given panel is enabled, or false otherwise. Panels are
* enabled by default.
*
* @param {Object} state Global application state.
* @param {string} panelName A string that identifies the panel.
*
* @return {boolean} Whether or not the panel is enabled.
*/
export function isEditorPanelEnabled( state, panelName ) {
const panels = getPreference( state, 'panels' );
return (
! isEditorPanelRemoved( state, panelName ) &&
get( panels, [ panelName, 'enabled' ], true )
);
}
/**
* Returns true if the given panel is open, or false otherwise. Panels are
* closed by default.
*
* @param {Object} state Global application state.
* @param {string} panelName A string that identifies the panel.
*
* @return {boolean} Whether or not the panel is open.
*/
export function isEditorPanelOpened( state, panelName ) {
const panels = getPreference( state, 'panels' );
return (
get( panels, [ panelName ] ) === true ||
get( panels, [ panelName, 'opened' ] ) === true
);
}
/**
* Returns true if a modal is active, or false otherwise.
*
* @param {Object} state Global application state.
* @param {string} modalName A string that uniquely identifies the modal.
*
* @return {boolean} Whether the modal is active.
*/
export function isModalActive( state, modalName ) {
return state.activeModal === modalName;
}
/**
* Returns whether the given feature is enabled or not.
*
* @param {Object} state Global application state.
* @param {string} feature Feature slug.
*
* @return {boolean} Is active.
*/
export function isFeatureActive( state, feature ) {
return get( state.preferences.features, [ feature ], false );
}
/**
* Returns true if the plugin item is pinned to the header.
* When the value is not set it defaults to true.
*
* @param {Object} state Global application state.
* @param {string} pluginName Plugin item name.
*
* @return {boolean} Whether the plugin item is pinned.
*/
export const isPluginItemPinned = createRegistrySelector(
( select ) => ( pluginName ) => {
return select( interfaceStore ).isItemPinned(
'core/edit-post',
pluginName
);
}
);
/**
* Returns an array of active meta box locations.
*
* @param {Object} state Post editor state.
*
* @return {string[]} Active meta box locations.
*/
export const getActiveMetaBoxLocations = createSelector(
( state ) => {
return Object.keys( state.metaBoxes.locations ).filter( ( location ) =>
isMetaBoxLocationActive( state, location )
);
},
( state ) => [ state.metaBoxes.locations ]
);
/**
* Returns true if a metabox location is active and visible
*
* @param {Object} state Post editor state.
* @param {string} location Meta box location to test.
*
* @return {boolean} Whether the meta box location is active and visible.
*/
export function isMetaBoxLocationVisible( state, location ) {
return (
isMetaBoxLocationActive( state, location ) &&
some( getMetaBoxesPerLocation( state, location ), ( { id } ) => {
return isEditorPanelEnabled( state, `meta-box-${ id }` );
} )
);
}
/**
* Returns true if there is an active meta box in the given location, or false
* otherwise.
*
* @param {Object} state Post editor state.
* @param {string} location Meta box location to test.
*
* @return {boolean} Whether the meta box location is active.
*/
export function isMetaBoxLocationActive( state, location ) {
const metaBoxes = getMetaBoxesPerLocation( state, location );
return !! metaBoxes && metaBoxes.length !== 0;
}
/**
* Returns the list of all the available meta boxes for a given location.
*
* @param {Object} state Global application state.
* @param {string} location Meta box location to test.
*
* @return {?Array} List of meta boxes.
*/
export function getMetaBoxesPerLocation( state, location ) {
return state.metaBoxes.locations[ location ];
}
/**
* Returns the list of all the available meta boxes.
*
* @param {Object} state Global application state.
*
* @return {Array} List of meta boxes.
*/
export const getAllMetaBoxes = createSelector(
( state ) => {
return flatten( values( state.metaBoxes.locations ) );
},
( state ) => [ state.metaBoxes.locations ]
);
/**
* Returns true if the post is using Meta Boxes
*
* @param {Object} state Global application state
*
* @return {boolean} Whether there are metaboxes or not.
*/
export function hasMetaBoxes( state ) {
return getActiveMetaBoxLocations( state ).length > 0;
}
/**
* Returns true if the Meta Boxes are being saved.
*
* @param {Object} state Global application state.
*
* @return {boolean} Whether the metaboxes are being saved.
*/
export function isSavingMetaBoxes( state ) {
return state.metaBoxes.isSaving;
}
/**
* Returns the current editing canvas device type.
*
* @param {Object} state Global application state.
*
* @return {string} Device type.
*/
export function __experimentalGetPreviewDeviceType( state ) {
return state.deviceType;
}
/**
* Returns true if the inserter is opened.
*
* @param {Object} state Global application state.
*
* @return {boolean} Whether the inserter is opened.
*/
export function isInserterOpened( state ) {
return !! state.blockInserterPanel;
}
/**
* Get the insertion point for the inserter.
*
* @param {Object} state Global application state.
*
* @return {Object} The root client ID and index to insert at.
*/
export function __experimentalGetInsertionPoint( state ) {
const { rootClientId, insertionIndex } = state.blockInserterPanel;
return { rootClientId, insertionIndex };
}
/**
* Returns true if the template editing mode is enabled.
*
* @param {Object} state Global application state.
*
* @return {boolean} Whether we're editing the template.
*/
export function isEditingTemplate( state ) {
return state.isEditingTemplate;
}
/**
* Retrieves the template of the currently edited post.
*
* @return {Object?} Post Template.
*/
export const getEditedPostTemplate = createRegistrySelector(
( select ) => () => {
const currentTemplate = select( editorStore ).getEditedPostAttribute(
'template'
);
if ( currentTemplate ) {
return select( coreStore )
.getEntityRecords( 'postType', 'wp_template' )
?.find( ( template ) => template.slug === currentTemplate );
}
const post = select( editorStore ).getCurrentPost();
if ( post.link && post.status !== 'auto-draft' ) {
return select( coreStore ).__experimentalGetTemplateForLink(
post.link
);
}
return null;
}
);