@wordpress/block-editor 12.3.7 → 12.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -4
- package/build/components/block-removal-warning-modal/index.js +15 -25
- package/build/components/block-removal-warning-modal/index.js.map +1 -1
- package/build/components/colors-gradients/control.js +4 -2
- package/build/components/colors-gradients/control.js.map +1 -1
- package/build/components/global-styles/dimensions-panel.js +13 -2
- package/build/components/global-styles/dimensions-panel.js.map +1 -1
- package/build/components/iframe/index.js +16 -3
- package/build/components/iframe/index.js.map +1 -1
- package/build/components/iframe/use-compatibility-styles.js +5 -0
- package/build/components/iframe/use-compatibility-styles.js.map +1 -1
- package/build/components/index.js +1 -10
- package/build/components/index.js.map +1 -1
- package/build/components/inserter/reusable-block-rename-hint.js +22 -2
- package/build/components/inserter/reusable-block-rename-hint.js.map +1 -1
- package/build/components/rich-text/get-rich-text-values.js +7 -1
- package/build/components/rich-text/get-rich-text-values.js.map +1 -1
- package/build/components/spacing-sizes-control/hooks/use-spacing-sizes.js +1 -1
- package/build/components/spacing-sizes-control/hooks/use-spacing-sizes.js.map +1 -1
- package/build/components/spacing-sizes-control/input-controls/axial.js +6 -2
- package/build/components/spacing-sizes-control/input-controls/axial.js.map +1 -1
- package/build/components/spacing-sizes-control/input-controls/separated.js +5 -1
- package/build/components/spacing-sizes-control/input-controls/separated.js.map +1 -1
- package/build/components/spacing-sizes-control/input-controls/single.js +5 -1
- package/build/components/spacing-sizes-control/input-controls/single.js.map +1 -1
- package/build/components/spacing-sizes-control/utils.js +1 -1
- package/build/components/spacing-sizes-control/utils.js.map +1 -1
- package/build/private-apis.js +5 -1
- package/build/private-apis.js.map +1 -1
- package/build/store/index.js +10 -1
- package/build/store/index.js.map +1 -1
- package/build/store/private-actions.js +36 -36
- package/build/store/private-actions.js.map +1 -1
- package/build/store/private-selectors.js +3 -3
- package/build/store/private-selectors.js.map +1 -1
- package/build/store/reducer.js +16 -8
- package/build/store/reducer.js.map +1 -1
- package/build-module/components/block-removal-warning-modal/index.js +16 -23
- package/build-module/components/block-removal-warning-modal/index.js.map +1 -1
- package/build-module/components/colors-gradients/control.js +3 -2
- package/build-module/components/colors-gradients/control.js.map +1 -1
- package/build-module/components/global-styles/dimensions-panel.js +13 -2
- package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
- package/build-module/components/iframe/index.js +16 -3
- package/build-module/components/iframe/index.js.map +1 -1
- package/build-module/components/iframe/use-compatibility-styles.js +5 -0
- package/build-module/components/iframe/use-compatibility-styles.js.map +1 -1
- package/build-module/components/index.js +0 -5
- package/build-module/components/index.js.map +1 -1
- package/build-module/components/inserter/reusable-block-rename-hint.js +21 -2
- package/build-module/components/inserter/reusable-block-rename-hint.js.map +1 -1
- package/build-module/components/rich-text/get-rich-text-values.js +7 -1
- package/build-module/components/rich-text/get-rich-text-values.js.map +1 -1
- package/build-module/components/spacing-sizes-control/hooks/use-spacing-sizes.js +1 -1
- package/build-module/components/spacing-sizes-control/hooks/use-spacing-sizes.js.map +1 -1
- package/build-module/components/spacing-sizes-control/input-controls/axial.js +7 -3
- package/build-module/components/spacing-sizes-control/input-controls/axial.js.map +1 -1
- package/build-module/components/spacing-sizes-control/input-controls/separated.js +6 -2
- package/build-module/components/spacing-sizes-control/input-controls/separated.js.map +1 -1
- package/build-module/components/spacing-sizes-control/input-controls/single.js +6 -2
- package/build-module/components/spacing-sizes-control/input-controls/single.js.map +1 -1
- package/build-module/components/spacing-sizes-control/utils.js +1 -1
- package/build-module/components/spacing-sizes-control/utils.js.map +1 -1
- package/build-module/private-apis.js +4 -1
- package/build-module/private-apis.js.map +1 -1
- package/build-module/store/index.js +10 -1
- package/build-module/store/index.js.map +1 -1
- package/build-module/store/private-actions.js +35 -32
- package/build-module/store/private-actions.js.map +1 -1
- package/build-module/store/private-selectors.js +2 -2
- package/build-module/store/private-selectors.js.map +1 -1
- package/build-module/store/reducer.js +16 -8
- package/build-module/store/reducer.js.map +1 -1
- package/package.json +10 -10
- package/src/components/block-removal-warning-modal/index.js +13 -27
- package/src/components/colors-gradients/control.js +3 -2
- package/src/components/global-styles/dimensions-panel.js +8 -2
- package/src/components/iframe/index.js +15 -10
- package/src/components/iframe/use-compatibility-styles.js +5 -0
- package/src/components/index.js +0 -5
- package/src/components/inserter/reusable-block-rename-hint.js +17 -0
- package/src/components/rich-text/get-rich-text-values.js +11 -1
- package/src/components/spacing-sizes-control/hooks/use-spacing-sizes.js +1 -1
- package/src/components/spacing-sizes-control/input-controls/axial.js +17 -2
- package/src/components/spacing-sizes-control/input-controls/separated.js +17 -2
- package/src/components/spacing-sizes-control/input-controls/single.js +12 -2
- package/src/components/spacing-sizes-control/utils.js +1 -1
- package/src/private-apis.js +6 -0
- package/src/store/index.js +10 -0
- package/src/store/private-actions.js +33 -36
- package/src/store/private-selectors.js +2 -2
- package/src/store/reducer.js +16 -8
- package/src/store/test/actions.js +3 -0
|
@@ -16,38 +16,26 @@ import { __ } from '@wordpress/i18n';
|
|
|
16
16
|
import { store as blockEditorStore } from '../../store';
|
|
17
17
|
import { unlock } from '../../lock-unlock';
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
// important blocks. For example, in the site editor, the Query Loop block is
|
|
21
|
-
// deemed important. In such cases, we'll ask the user for confirmation that
|
|
22
|
-
// they intended to remove such block(s).
|
|
23
|
-
//
|
|
24
|
-
// @see https://github.com/WordPress/gutenberg/pull/51145
|
|
25
|
-
export const blockTypePromptMessages = {
|
|
26
|
-
'core/query': __( 'Query Loop displays a list of posts or pages.' ),
|
|
27
|
-
'core/post-content': __(
|
|
28
|
-
'Post Content displays the content of a post or page.'
|
|
29
|
-
),
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export function BlockRemovalWarningModal() {
|
|
19
|
+
export function BlockRemovalWarningModal( { rules } ) {
|
|
33
20
|
const { clientIds, selectPrevious, blockNamesForPrompt } = useSelect(
|
|
34
21
|
( select ) =>
|
|
35
22
|
unlock( select( blockEditorStore ) ).getRemovalPromptData()
|
|
36
23
|
);
|
|
37
24
|
|
|
38
25
|
const {
|
|
39
|
-
|
|
40
|
-
|
|
26
|
+
clearBlockRemovalPrompt,
|
|
27
|
+
setBlockRemovalRules,
|
|
41
28
|
privateRemoveBlocks,
|
|
42
29
|
} = unlock( useDispatch( blockEditorStore ) );
|
|
43
30
|
|
|
44
|
-
//
|
|
31
|
+
// Load block removal rules, simultaneously signalling that the block
|
|
32
|
+
// removal prompt is in place.
|
|
45
33
|
useEffect( () => {
|
|
46
|
-
|
|
34
|
+
setBlockRemovalRules( rules );
|
|
47
35
|
return () => {
|
|
48
|
-
|
|
36
|
+
setBlockRemovalRules();
|
|
49
37
|
};
|
|
50
|
-
}, [
|
|
38
|
+
}, [ rules, setBlockRemovalRules ] );
|
|
51
39
|
|
|
52
40
|
if ( ! blockNamesForPrompt ) {
|
|
53
41
|
return;
|
|
@@ -55,25 +43,23 @@ export function BlockRemovalWarningModal() {
|
|
|
55
43
|
|
|
56
44
|
const onConfirmRemoval = () => {
|
|
57
45
|
privateRemoveBlocks( clientIds, selectPrevious, /* force */ true );
|
|
58
|
-
|
|
46
|
+
clearBlockRemovalPrompt();
|
|
59
47
|
};
|
|
60
48
|
|
|
61
49
|
return (
|
|
62
50
|
<Modal
|
|
63
51
|
title={ __( 'Are you sure?' ) }
|
|
64
|
-
onRequestClose={
|
|
52
|
+
onRequestClose={ clearBlockRemovalPrompt }
|
|
65
53
|
style={ {
|
|
66
54
|
maxWidth: '40rem',
|
|
67
55
|
} }
|
|
68
56
|
>
|
|
69
57
|
{ blockNamesForPrompt.length === 1 ? (
|
|
70
|
-
<p>{
|
|
58
|
+
<p>{ rules[ blockNamesForPrompt[ 0 ] ] }</p>
|
|
71
59
|
) : (
|
|
72
60
|
<ul style={ { listStyleType: 'disc', paddingLeft: '1rem' } }>
|
|
73
61
|
{ blockNamesForPrompt.map( ( name ) => (
|
|
74
|
-
<li key={ name }>
|
|
75
|
-
{ blockTypePromptMessages[ name ] }
|
|
76
|
-
</li>
|
|
62
|
+
<li key={ name }>{ rules[ name ] }</li>
|
|
77
63
|
) ) }
|
|
78
64
|
</ul>
|
|
79
65
|
) }
|
|
@@ -83,7 +69,7 @@ export function BlockRemovalWarningModal() {
|
|
|
83
69
|
: __( 'Removing this block is not advised.' ) }
|
|
84
70
|
</p>
|
|
85
71
|
<HStack justify="right">
|
|
86
|
-
<Button variant="tertiary" onClick={
|
|
72
|
+
<Button variant="tertiary" onClick={ clearBlockRemovalPrompt }>
|
|
87
73
|
{ __( 'Cancel' ) }
|
|
88
74
|
</Button>
|
|
89
75
|
<Button variant="primary" onClick={ onConfirmRemoval }>
|
|
@@ -6,6 +6,7 @@ import classnames from 'classnames';
|
|
|
6
6
|
/**
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
|
+
import { __ } from '@wordpress/i18n';
|
|
9
10
|
import {
|
|
10
11
|
BaseControl,
|
|
11
12
|
__experimentalVStack as VStack,
|
|
@@ -28,12 +29,12 @@ const colorsAndGradientKeys = [
|
|
|
28
29
|
|
|
29
30
|
const TAB_COLOR = {
|
|
30
31
|
name: 'color',
|
|
31
|
-
title: 'Solid',
|
|
32
|
+
title: __( 'Solid' ),
|
|
32
33
|
value: 'color',
|
|
33
34
|
};
|
|
34
35
|
const TAB_GRADIENT = {
|
|
35
36
|
name: 'gradient',
|
|
36
|
-
title: 'Gradient',
|
|
37
|
+
title: __( 'Gradient' ),
|
|
37
38
|
value: 'gradient',
|
|
38
39
|
};
|
|
39
40
|
|
|
@@ -207,18 +207,24 @@ export default function DimensionsPanel( {
|
|
|
207
207
|
// in global styles but not in block inspector.
|
|
208
208
|
includeLayoutControls = false,
|
|
209
209
|
} ) {
|
|
210
|
+
const { dimensions, spacing } = settings;
|
|
211
|
+
|
|
210
212
|
const decodeValue = ( rawValue ) => {
|
|
211
213
|
if ( rawValue && typeof rawValue === 'object' ) {
|
|
212
214
|
return Object.keys( rawValue ).reduce( ( acc, key ) => {
|
|
213
215
|
acc[ key ] = getValueFromVariable(
|
|
214
|
-
{ settings },
|
|
216
|
+
{ settings: { dimensions, spacing } },
|
|
215
217
|
'',
|
|
216
218
|
rawValue[ key ]
|
|
217
219
|
);
|
|
218
220
|
return acc;
|
|
219
221
|
}, {} );
|
|
220
222
|
}
|
|
221
|
-
return getValueFromVariable(
|
|
223
|
+
return getValueFromVariable(
|
|
224
|
+
{ settings: { dimensions, spacing } },
|
|
225
|
+
'',
|
|
226
|
+
rawValue
|
|
227
|
+
);
|
|
222
228
|
};
|
|
223
229
|
|
|
224
230
|
const showSpacingPresetsControl = useHasSpacingPresets( settings );
|
|
@@ -88,11 +88,14 @@ function Iframe( {
|
|
|
88
88
|
forwardedRef: ref,
|
|
89
89
|
...props
|
|
90
90
|
} ) {
|
|
91
|
-
const {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
91
|
+
const { resolvedAssets, isPreviewMode } = useSelect( ( select ) => {
|
|
92
|
+
const settings = select( blockEditorStore ).getSettings();
|
|
93
|
+
return {
|
|
94
|
+
resolvedAssets: settings.__unstableResolvedAssets,
|
|
95
|
+
isPreviewMode: settings.__unstableIsPreviewMode,
|
|
96
|
+
};
|
|
97
|
+
}, [] );
|
|
98
|
+
const { styles = '', scripts = '' } = resolvedAssets;
|
|
96
99
|
const [ iframeDocument, setIframeDocument ] = useState();
|
|
97
100
|
const [ bodyClasses, setBodyClasses ] = useState( [] );
|
|
98
101
|
const compatStyles = useCompatibilityStyles();
|
|
@@ -140,11 +143,13 @@ function Iframe( {
|
|
|
140
143
|
compatStyle.cloneNode( true )
|
|
141
144
|
);
|
|
142
145
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
if ( ! isPreviewMode ) {
|
|
147
|
+
// eslint-disable-next-line no-console
|
|
148
|
+
console.warn(
|
|
149
|
+
`${ compatStyle.id } was added to the iframe incorrectly. Please use block.json or enqueue_block_assets to add styles to the iframe.`,
|
|
150
|
+
compatStyle
|
|
151
|
+
);
|
|
152
|
+
}
|
|
148
153
|
}
|
|
149
154
|
|
|
150
155
|
iFrameDocument.addEventListener(
|
|
@@ -45,6 +45,11 @@ export function useCompatibilityStyles() {
|
|
|
45
45
|
return accumulator;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
// Don't try to add styles without ID. Styles enqueued via the WP dependency system will always have IDs.
|
|
49
|
+
if ( ! ownerNode.id ) {
|
|
50
|
+
return accumulator;
|
|
51
|
+
}
|
|
52
|
+
|
|
48
53
|
function matchFromRules( _cssRules ) {
|
|
49
54
|
return Array.from( _cssRules ).find(
|
|
50
55
|
( {
|
package/src/components/index.js
CHANGED
|
@@ -164,8 +164,3 @@ export { default as __experimentalInspectorPopoverHeader } from './inspector-pop
|
|
|
164
164
|
|
|
165
165
|
export { default as BlockEditorProvider } from './provider';
|
|
166
166
|
export { default as useSetting } from './use-setting';
|
|
167
|
-
|
|
168
|
-
/*
|
|
169
|
-
* The following rename hint component can be removed in 6.4.
|
|
170
|
-
*/
|
|
171
|
-
export { default as ReusableBlocksRenameHint } from './inserter/reusable-block-rename-hint';
|
|
@@ -10,7 +10,24 @@ import { close } from '@wordpress/icons';
|
|
|
10
10
|
import { store as preferencesStore } from '@wordpress/preferences';
|
|
11
11
|
|
|
12
12
|
const PREFERENCE_NAME = 'isResuableBlocksrRenameHintVisible';
|
|
13
|
+
/*
|
|
14
|
+
* This hook was added in 6.3 to help users with the transition from Reusable blocks to Patterns.
|
|
15
|
+
* It is only exported for use in the reusable-blocks package as well as block-editor.
|
|
16
|
+
* It will be removed in 6.4. and should not be used in any new code.
|
|
17
|
+
*/
|
|
18
|
+
export function useReusableBlocksRenameHint() {
|
|
19
|
+
return useSelect(
|
|
20
|
+
( select ) =>
|
|
21
|
+
select( preferencesStore ).get( 'core', PREFERENCE_NAME ) ?? true,
|
|
22
|
+
[]
|
|
23
|
+
);
|
|
24
|
+
}
|
|
13
25
|
|
|
26
|
+
/*
|
|
27
|
+
* This component was added in 6.3 to help users with the transition from Reusable blocks to Patterns.
|
|
28
|
+
* It is only exported for use in the reusable-blocks package as well as block-editor.
|
|
29
|
+
* It will be removed in 6.4. and should not be used in any new code.
|
|
30
|
+
*/
|
|
14
31
|
export default function ReusableBlocksRenameHint() {
|
|
15
32
|
const isReusableBlocksRenameHint = useSelect(
|
|
16
33
|
( select ) =>
|
|
@@ -78,10 +78,20 @@ function addValuesForElements( children, ...args ) {
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
function _getSaveElement( name, attributes, innerBlocks ) {
|
|
82
|
+
return getSaveElement(
|
|
83
|
+
name,
|
|
84
|
+
attributes,
|
|
85
|
+
innerBlocks.map( ( block ) =>
|
|
86
|
+
_getSaveElement( block.name, block.attributes, block.innerBlocks )
|
|
87
|
+
)
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
81
91
|
function addValuesForBlocks( values, blocks ) {
|
|
82
92
|
for ( let i = 0; i < blocks.length; i++ ) {
|
|
83
93
|
const { name, attributes, innerBlocks } = blocks[ i ];
|
|
84
|
-
const saveElement =
|
|
94
|
+
const saveElement = _getSaveElement( name, attributes, innerBlocks );
|
|
85
95
|
addValuesForElement( saveElement, values, innerBlocks );
|
|
86
96
|
}
|
|
87
97
|
}
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
* Internal dependencies
|
|
3
3
|
*/
|
|
4
4
|
import SpacingInputControl from './spacing-input-control';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
LABELS,
|
|
7
|
+
ICONS,
|
|
8
|
+
getPresetValueFromCustomValue,
|
|
9
|
+
hasAxisSupport,
|
|
10
|
+
} from '../utils';
|
|
6
11
|
|
|
7
12
|
const groupedSides = [ 'vertical', 'horizontal' ];
|
|
8
13
|
|
|
@@ -20,7 +25,17 @@ export default function AxialInputControls( {
|
|
|
20
25
|
if ( ! onChange ) {
|
|
21
26
|
return;
|
|
22
27
|
}
|
|
23
|
-
|
|
28
|
+
|
|
29
|
+
// Encode the existing value into the preset value if the passed in value matches the value of one of the spacingSizes.
|
|
30
|
+
const nextValues = {
|
|
31
|
+
...Object.keys( values ).reduce( ( acc, key ) => {
|
|
32
|
+
acc[ key ] = getPresetValueFromCustomValue(
|
|
33
|
+
values[ key ],
|
|
34
|
+
spacingSizes
|
|
35
|
+
);
|
|
36
|
+
return acc;
|
|
37
|
+
}, {} ),
|
|
38
|
+
};
|
|
24
39
|
|
|
25
40
|
if ( side === 'vertical' ) {
|
|
26
41
|
nextValues.top = next;
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
* Internal dependencies
|
|
3
3
|
*/
|
|
4
4
|
import SpacingInputControl from './spacing-input-control';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
ALL_SIDES,
|
|
7
|
+
LABELS,
|
|
8
|
+
ICONS,
|
|
9
|
+
getPresetValueFromCustomValue,
|
|
10
|
+
} from '../utils';
|
|
6
11
|
|
|
7
12
|
export default function SeparatedInputControls( {
|
|
8
13
|
minimumCustomValue,
|
|
@@ -20,7 +25,17 @@ export default function SeparatedInputControls( {
|
|
|
20
25
|
: ALL_SIDES;
|
|
21
26
|
|
|
22
27
|
const createHandleOnChange = ( side ) => ( next ) => {
|
|
23
|
-
|
|
28
|
+
// Encode the existing value into the preset value if the passed in value matches the value of one of the spacingSizes.
|
|
29
|
+
const nextValues = {
|
|
30
|
+
...Object.keys( values ).reduce( ( acc, key ) => {
|
|
31
|
+
acc[ key ] = getPresetValueFromCustomValue(
|
|
32
|
+
values[ key ],
|
|
33
|
+
spacingSizes
|
|
34
|
+
);
|
|
35
|
+
return acc;
|
|
36
|
+
}, {} ),
|
|
37
|
+
};
|
|
38
|
+
|
|
24
39
|
nextValues[ side ] = next;
|
|
25
40
|
|
|
26
41
|
onChange( nextValues );
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Internal dependencies
|
|
3
3
|
*/
|
|
4
4
|
import SpacingInputControl from './spacing-input-control';
|
|
5
|
-
import { LABELS } from '../utils';
|
|
5
|
+
import { LABELS, getPresetValueFromCustomValue } from '../utils';
|
|
6
6
|
|
|
7
7
|
export default function SingleInputControl( {
|
|
8
8
|
minimumCustomValue,
|
|
@@ -16,7 +16,17 @@ export default function SingleInputControl( {
|
|
|
16
16
|
values,
|
|
17
17
|
} ) {
|
|
18
18
|
const createHandleOnChange = ( currentSide ) => ( next ) => {
|
|
19
|
-
|
|
19
|
+
// Encode the existing value into the preset value if the passed in value matches the value of one of the spacingSizes.
|
|
20
|
+
const nextValues = {
|
|
21
|
+
...Object.keys( values ).reduce( ( acc, key ) => {
|
|
22
|
+
acc[ key ] = getPresetValueFromCustomValue(
|
|
23
|
+
values[ key ],
|
|
24
|
+
spacingSizes
|
|
25
|
+
);
|
|
26
|
+
return acc;
|
|
27
|
+
}, {} ),
|
|
28
|
+
};
|
|
29
|
+
|
|
20
30
|
nextValues[ currentSide ] = next;
|
|
21
31
|
|
|
22
32
|
onChange( nextValues );
|
|
@@ -102,7 +102,7 @@ export function getCustomValueFromPreset( value, spacingSizes ) {
|
|
|
102
102
|
*/
|
|
103
103
|
export function getPresetValueFromCustomValue( value, spacingSizes ) {
|
|
104
104
|
// Return value as-is if it is already a preset;
|
|
105
|
-
if ( isValueSpacingPreset( value ) ) {
|
|
105
|
+
if ( isValueSpacingPreset( value ) || value === '0' ) {
|
|
106
106
|
return value;
|
|
107
107
|
}
|
|
108
108
|
|
package/src/private-apis.js
CHANGED
|
@@ -18,6 +18,10 @@ import { BlockRemovalWarningModal } from './components/block-removal-warning-mod
|
|
|
18
18
|
import { useLayoutClasses, useLayoutStyles } from './hooks';
|
|
19
19
|
import DimensionsTool from './components/dimensions-tool';
|
|
20
20
|
import ResolutionTool from './components/resolution-tool';
|
|
21
|
+
import {
|
|
22
|
+
default as ReusableBlocksRenameHint,
|
|
23
|
+
useReusableBlocksRenameHint,
|
|
24
|
+
} from './components/inserter/reusable-block-rename-hint';
|
|
21
25
|
|
|
22
26
|
/**
|
|
23
27
|
* Private @wordpress/block-editor APIs.
|
|
@@ -41,4 +45,6 @@ lock( privateApis, {
|
|
|
41
45
|
useLayoutStyles,
|
|
42
46
|
DimensionsTool,
|
|
43
47
|
ResolutionTool,
|
|
48
|
+
ReusableBlocksRenameHint,
|
|
49
|
+
useReusableBlocksRenameHint,
|
|
44
50
|
} );
|
package/src/store/index.js
CHANGED
|
@@ -43,3 +43,13 @@ const registeredStore = registerStore( STORE_NAME, {
|
|
|
43
43
|
} );
|
|
44
44
|
unlock( registeredStore ).registerPrivateActions( privateActions );
|
|
45
45
|
unlock( registeredStore ).registerPrivateSelectors( privateSelectors );
|
|
46
|
+
|
|
47
|
+
// TODO: Remove once we switch to the `register` function (see above).
|
|
48
|
+
//
|
|
49
|
+
// Until then, private functions also need to be attached to the original
|
|
50
|
+
// `store` descriptor in order to avoid unit tests failing, which could happen
|
|
51
|
+
// when tests create new registries in which they register stores.
|
|
52
|
+
//
|
|
53
|
+
// @see https://github.com/WordPress/gutenberg/pull/51145#discussion_r1239999590
|
|
54
|
+
unlock( store ).registerPrivateActions( privateActions );
|
|
55
|
+
unlock( store ).registerPrivateSelectors( privateSelectors );
|
|
@@ -3,11 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { Platform } from '@wordpress/element';
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
* Internal dependencies
|
|
8
|
-
*/
|
|
9
|
-
import { blockTypePromptMessages } from '../components/block-removal-warning-modal';
|
|
10
|
-
|
|
11
6
|
const castArray = ( maybeArray ) =>
|
|
12
7
|
Array.isArray( maybeArray ) ? maybeArray : [ maybeArray ];
|
|
13
8
|
|
|
@@ -155,35 +150,22 @@ export const privateRemoveBlocks =
|
|
|
155
150
|
// confirmation that they intended to remove such block(s). However,
|
|
156
151
|
// the editor instance is responsible for presenting those confirmation
|
|
157
152
|
// prompts to the user. Any instance opting into removal prompts must
|
|
158
|
-
// register using `
|
|
153
|
+
// register using `setBlockRemovalRules()`.
|
|
159
154
|
//
|
|
160
155
|
// @see https://github.com/WordPress/gutenberg/pull/51145
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
// FIXME: Without this existence check, the unit tests for
|
|
164
|
-
// `__experimentalDeleteReusableBlock` in
|
|
165
|
-
// `packages/reusable-blocks/src/store/test/actions.js` fail due to
|
|
166
|
-
// the fact that the `registry` object passed to the thunk actions
|
|
167
|
-
// doesn't include this private action. This needs to be
|
|
168
|
-
// investigated to understand whether it's a real smell or if it's
|
|
169
|
-
// because not all store code has been updated to accommodate
|
|
170
|
-
// private selectors.
|
|
171
|
-
select.isRemovalPromptSupported &&
|
|
172
|
-
select.isRemovalPromptSupported()
|
|
173
|
-
) {
|
|
156
|
+
const rules = ! forceRemove && select.getBlockRemovalRules();
|
|
157
|
+
if ( rules ) {
|
|
174
158
|
const blockNamesForPrompt = new Set();
|
|
175
159
|
|
|
176
160
|
// Given a list of client IDs of blocks that the user intended to
|
|
177
161
|
// remove, perform a tree search (BFS) to find all block names
|
|
178
162
|
// corresponding to "important" blocks, i.e. blocks that require a
|
|
179
163
|
// removal prompt.
|
|
180
|
-
//
|
|
181
|
-
// @see blockTypePromptMessages
|
|
182
164
|
const queue = [ ...clientIds ];
|
|
183
165
|
while ( queue.length ) {
|
|
184
166
|
const clientId = queue.shift();
|
|
185
167
|
const blockName = select.getBlockName( clientId );
|
|
186
|
-
if (
|
|
168
|
+
if ( rules[ blockName ] ) {
|
|
187
169
|
blockNamesForPrompt.add( blockName );
|
|
188
170
|
}
|
|
189
171
|
const innerBlocks = select.getBlockOrder( clientId );
|
|
@@ -194,7 +176,7 @@ export const privateRemoveBlocks =
|
|
|
194
176
|
// skip any other steps (thus postponing actual removal).
|
|
195
177
|
if ( blockNamesForPrompt.size ) {
|
|
196
178
|
dispatch(
|
|
197
|
-
|
|
179
|
+
displayBlockRemovalPrompt(
|
|
198
180
|
clientIds,
|
|
199
181
|
selectPrevious,
|
|
200
182
|
Array.from( blockNamesForPrompt )
|
|
@@ -246,7 +228,7 @@ export const ensureDefaultBlock =
|
|
|
246
228
|
* Returns an action object used in signalling that a block removal prompt must
|
|
247
229
|
* be displayed.
|
|
248
230
|
*
|
|
249
|
-
* Contrast with `
|
|
231
|
+
* Contrast with `setBlockRemovalRules`.
|
|
250
232
|
*
|
|
251
233
|
* @param {string|string[]} clientIds Client IDs of blocks to remove.
|
|
252
234
|
* @param {boolean} selectPrevious True if the previous block
|
|
@@ -254,16 +236,19 @@ export const ensureDefaultBlock =
|
|
|
254
236
|
* (if no previous block exists)
|
|
255
237
|
* should be selected
|
|
256
238
|
* when a block is removed.
|
|
257
|
-
* @param {string[]} blockNamesForPrompt Names of blocks
|
|
239
|
+
* @param {string[]} blockNamesForPrompt Names of the blocks that
|
|
240
|
+
* triggered the need for
|
|
241
|
+
* confirmation before removal.
|
|
242
|
+
*
|
|
258
243
|
* @return {Object} Action object.
|
|
259
244
|
*/
|
|
260
|
-
|
|
245
|
+
function displayBlockRemovalPrompt(
|
|
261
246
|
clientIds,
|
|
262
247
|
selectPrevious,
|
|
263
248
|
blockNamesForPrompt
|
|
264
249
|
) {
|
|
265
250
|
return {
|
|
266
|
-
type: '
|
|
251
|
+
type: 'DISPLAY_BLOCK_REMOVAL_PROMPT',
|
|
267
252
|
clientIds,
|
|
268
253
|
selectPrevious,
|
|
269
254
|
blockNamesForPrompt,
|
|
@@ -277,24 +262,36 @@ export function displayRemovalPrompt(
|
|
|
277
262
|
*
|
|
278
263
|
* @return {Object} Action object.
|
|
279
264
|
*/
|
|
280
|
-
export function
|
|
265
|
+
export function clearBlockRemovalPrompt() {
|
|
281
266
|
return {
|
|
282
|
-
type: '
|
|
267
|
+
type: 'CLEAR_BLOCK_REMOVAL_PROMPT',
|
|
283
268
|
};
|
|
284
269
|
}
|
|
285
270
|
|
|
286
271
|
/**
|
|
287
|
-
* Returns an action object used
|
|
288
|
-
*
|
|
272
|
+
* Returns an action object used to set up any rules that a block editor may
|
|
273
|
+
* provide in order to prevent a user from accidentally removing certain
|
|
274
|
+
* blocks. These rules are then used to display a confirmation prompt to the
|
|
275
|
+
* user. For instance, in the Site Editor, the Query Loop block is important
|
|
276
|
+
* enough to warrant such confirmation.
|
|
277
|
+
*
|
|
278
|
+
* IMPORTANT: Registering rules implicitly signals to the `privateRemoveBlocks`
|
|
279
|
+
* action that the editor will be responsible for displaying block removal
|
|
280
|
+
* prompts and confirming deletions. This action is meant to be used by
|
|
281
|
+
* component `BlockRemovalWarningModal` only.
|
|
282
|
+
*
|
|
283
|
+
* The data is a record whose keys are block types (e.g. 'core/query') and
|
|
284
|
+
* whose values are the explanation to be shown to users (e.g. 'Query Loop
|
|
285
|
+
* displays a list of posts or pages.').
|
|
289
286
|
*
|
|
290
|
-
* Contrast with `
|
|
287
|
+
* Contrast with `displayBlockRemovalPrompt`.
|
|
291
288
|
*
|
|
292
|
-
* @param {
|
|
289
|
+
* @param {Record<string,string>|false} rules Block removal rules.
|
|
293
290
|
* @return {Object} Action object.
|
|
294
291
|
*/
|
|
295
|
-
export function
|
|
292
|
+
export function setBlockRemovalRules( rules = false ) {
|
|
296
293
|
return {
|
|
297
|
-
type: '
|
|
298
|
-
|
|
294
|
+
type: 'SET_BLOCK_REMOVAL_RULES',
|
|
295
|
+
rules,
|
|
299
296
|
};
|
|
300
297
|
}
|
|
@@ -202,6 +202,6 @@ export function getRemovalPromptData( state ) {
|
|
|
202
202
|
*
|
|
203
203
|
* @return {boolean} Whether removal prompt exists.
|
|
204
204
|
*/
|
|
205
|
-
export function
|
|
206
|
-
return state.
|
|
205
|
+
export function getBlockRemovalRules( state ) {
|
|
206
|
+
return state.blockRemovalRules;
|
|
207
207
|
}
|
package/src/store/reducer.js
CHANGED
|
@@ -1480,14 +1480,14 @@ export function isSelectionEnabled( state = true, action ) {
|
|
|
1480
1480
|
*/
|
|
1481
1481
|
function removalPromptData( state = false, action ) {
|
|
1482
1482
|
switch ( action.type ) {
|
|
1483
|
-
case '
|
|
1483
|
+
case 'DISPLAY_BLOCK_REMOVAL_PROMPT':
|
|
1484
1484
|
const { clientIds, selectPrevious, blockNamesForPrompt } = action;
|
|
1485
1485
|
return {
|
|
1486
1486
|
clientIds,
|
|
1487
1487
|
selectPrevious,
|
|
1488
1488
|
blockNamesForPrompt,
|
|
1489
1489
|
};
|
|
1490
|
-
case '
|
|
1490
|
+
case 'CLEAR_BLOCK_REMOVAL_PROMPT':
|
|
1491
1491
|
return false;
|
|
1492
1492
|
}
|
|
1493
1493
|
|
|
@@ -1495,17 +1495,25 @@ function removalPromptData( state = false, action ) {
|
|
|
1495
1495
|
}
|
|
1496
1496
|
|
|
1497
1497
|
/**
|
|
1498
|
-
* Reducer
|
|
1498
|
+
* Reducer returning any rules that a block editor may provide in order to
|
|
1499
|
+
* prevent a user from accidentally removing certain blocks. These rules are
|
|
1500
|
+
* then used to display a confirmation prompt to the user. For instance, in the
|
|
1501
|
+
* Site Editor, the Query Loop block is important enough to warrant such
|
|
1502
|
+
* confirmation.
|
|
1503
|
+
*
|
|
1504
|
+
* The data is a record whose keys are block types (e.g. 'core/query') and
|
|
1505
|
+
* whose values are the explanation to be shown to users (e.g. 'Query Loop
|
|
1506
|
+
* displays a list of posts or pages.').
|
|
1499
1507
|
*
|
|
1500
1508
|
* @param {boolean} state Current state.
|
|
1501
1509
|
* @param {Object} action Dispatched action.
|
|
1502
1510
|
*
|
|
1503
|
-
* @return {
|
|
1511
|
+
* @return {Record<string,string>} Updated state.
|
|
1504
1512
|
*/
|
|
1505
|
-
function
|
|
1513
|
+
function blockRemovalRules( state = false, action ) {
|
|
1506
1514
|
switch ( action.type ) {
|
|
1507
|
-
case '
|
|
1508
|
-
return action.
|
|
1515
|
+
case 'SET_BLOCK_REMOVAL_RULES':
|
|
1516
|
+
return action.rules;
|
|
1509
1517
|
}
|
|
1510
1518
|
|
|
1511
1519
|
return state;
|
|
@@ -1924,7 +1932,7 @@ const combinedReducers = combineReducers( {
|
|
|
1924
1932
|
blockVisibility,
|
|
1925
1933
|
blockEditingModes,
|
|
1926
1934
|
removalPromptData,
|
|
1927
|
-
|
|
1935
|
+
blockRemovalRules,
|
|
1928
1936
|
} );
|
|
1929
1937
|
|
|
1930
1938
|
function withAutomaticChangeReset( reducer ) {
|
|
@@ -617,6 +617,7 @@ describe( 'actions', () => {
|
|
|
617
617
|
const select = {
|
|
618
618
|
getBlockRootClientId: () => undefined,
|
|
619
619
|
canRemoveBlocks: () => true,
|
|
620
|
+
getBlockRemovalRules: () => false,
|
|
620
621
|
};
|
|
621
622
|
const dispatch = Object.assign( jest.fn(), {
|
|
622
623
|
selectPreviousBlock: jest.fn(),
|
|
@@ -727,6 +728,7 @@ describe( 'actions', () => {
|
|
|
727
728
|
const select = {
|
|
728
729
|
getBlockRootClientId: () => null,
|
|
729
730
|
canRemoveBlocks: () => true,
|
|
731
|
+
getBlockRemovalRules: () => false,
|
|
730
732
|
};
|
|
731
733
|
const dispatch = Object.assign( jest.fn(), {
|
|
732
734
|
selectPreviousBlock: jest.fn(),
|
|
@@ -751,6 +753,7 @@ describe( 'actions', () => {
|
|
|
751
753
|
const select = {
|
|
752
754
|
getBlockRootClientId: () => null,
|
|
753
755
|
canRemoveBlocks: () => true,
|
|
756
|
+
getBlockRemovalRules: () => false,
|
|
754
757
|
};
|
|
755
758
|
const dispatch = Object.assign( jest.fn(), {
|
|
756
759
|
selectPreviousBlock: jest.fn(),
|