-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Expand file tree
/
Copy pathprivate-selectors.js
More file actions
113 lines (106 loc) · 3.45 KB
/
private-selectors.js
File metadata and controls
113 lines (106 loc) · 3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
* External dependencies
*/
import createSelector from 'rememo';
/**
* WordPress dependencies
*/
import { select } from '@wordpress/data';
import { store as blocksStore } from '@wordpress/blocks';
/**
* Internal dependencies
*/
import {
getBlockRootClientId,
getTemplateLock,
getBlockName,
} from './selectors';
/**
* Returns true if the block interface is hidden, or false otherwise.
*
* @param {Object} state Global application state.
*
* @return {boolean} Whether the block toolbar is hidden.
*/
export function isBlockInterfaceHidden( state ) {
return state.isBlockInterfaceHidden;
}
/**
* Gets the client ids of the last inserted blocks.
*
* @param {Object} state Global application state.
* @return {Array|undefined} Client Ids of the last inserted block(s).
*/
export function getLastInsertedBlocksClientIds( state ) {
return state?.lastBlockInserted?.clientIds;
}
/**
* @typedef {import('../components/block-editing-mode').BlockEditingMode} BlockEditingMode
*/
/**
* Returns the block editing mode for a given block.
*
* The mode can be one of three options:
*
* - `'disabled'`: Prevents editing the block entirely, i.e. it cannot be
* selected.
* - `'contentOnly'`: Hides all non-content UI, e.g. auxiliary controls in the
* toolbar, the block movers, block settings.
* - `'default'`: Allows editing the block as normal.
*
* Blocks can set a mode using the `useBlockEditingMode` hook.
*
* The mode is inherited by all of the block's inner blocks, unless they have
* their own mode.
*
* A template lock can also set a mode. If the template lock is `'contentOnly'`,
* the block's mode is overridden to `'contentOnly'` if the block has a content
* role attribute, or `'disabled'` otherwise.
*
* @see useBlockEditingMode
*
* @param {Object} state Global application state.
* @param {string} clientId The block client ID, or `''` for the root container.
*
* @return {BlockEditingMode} The block editing mode. One of `'disabled'`,
* `'contentOnly'`, or `'default'`.
*/
export const getBlockEditingMode = ( state, clientId = '' ) => {
const explicitEditingMode = getExplicitBlockEditingMode( state, clientId );
const rootClientId = getBlockRootClientId( state, clientId );
const templateLock = getTemplateLock( state, rootClientId );
const name = getBlockName( state, clientId );
// TODO: Terrible hack! We're calling the global select() function here
// instead of using createRegistrySelector(). The problem with using
// createRegistrySelector() is that then the public block-editor selectors
// (e.g. canInsertBlockTypeUnmemoized) can't call this private block-editor
// selector due to a bug in @wordpress/data. See
// https://github.com/WordPress/gutenberg/pull/50985.
const isContent =
select( blocksStore ).__experimentalHasContentRoleAttribute( name );
if (
explicitEditingMode === 'disabled' ||
( templateLock === 'contentOnly' && ! isContent )
) {
return 'disabled';
}
if (
explicitEditingMode === 'contentOnly' ||
( templateLock === 'contentOnly' && isContent )
) {
return 'contentOnly';
}
return 'default';
};
const getExplicitBlockEditingMode = createSelector(
( state, clientId = '' ) => {
while (
! state.blockEditingModes.has( clientId ) &&
state.blocks.parents.has( clientId )
) {
clientId = state.blocks.parents.get( clientId );
}
return state.blockEditingModes.get( clientId ) ?? 'default';
},
( state ) => [ state.blockEditingModes, state.blocks.parents ]
);