-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Expand file tree
/
Copy pathprivate-selectors.js
More file actions
137 lines (130 loc) · 4.18 KB
/
private-selectors.js
File metadata and controls
137 lines (130 loc) · 4.18 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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/**
* 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,
getBlockOrder,
} 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 = createSelector(
( state, clientId = '' ) => {
if ( state.blockEditingModes.has( clientId ) ) {
return state.blockEditingModes.get( clientId );
}
if ( ! clientId ) {
return 'default';
}
const rootClientId = getBlockRootClientId( state, clientId );
const templateLock = getTemplateLock( state, rootClientId );
if ( templateLock === 'contentOnly' ) {
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
);
return isContent ? 'contentOnly' : 'disabled';
}
const parentMode = getBlockEditingMode( state, rootClientId );
return parentMode === 'contentOnly' ? 'default' : parentMode;
},
( state ) => [
state.blockEditingModes,
state.blocks.parents,
state.settings.templateLock,
state.blockListSettings,
]
);
/**
* Returns true if the block with the given client ID and all of its descendants
* have an editing mode of 'disabled', or false otherwise.
*
* @param {Object} state Global application state.
* @param {string} clientId The block client ID.
*
* @return {boolean} Whether the block and its descendants are disabled.
*/
export const isBlockSubtreeDisabled = createSelector(
( state, clientId ) => {
const isChildSubtreeDisabled = ( childClientId ) => {
const mode = state.blockEditingModes.get( childClientId );
return (
( mode === undefined || mode === 'disabled' ) &&
getBlockOrder( state, childClientId ).every(
isChildSubtreeDisabled
)
);
};
return (
getBlockEditingMode( state, clientId ) === 'disabled' &&
getBlockOrder( state, clientId ).every( isChildSubtreeDisabled )
);
},
( state ) => [ state.blockEditingModes, state.blocks.parents ]
);