@wordpress/block-editor 14.3.1 → 14.3.3
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 +2 -2
- package/build/components/block-heading-level-dropdown/index.js +3 -1
- package/build/components/block-heading-level-dropdown/index.js.map +1 -1
- package/build/components/block-list/block.js +27 -4
- package/build/components/block-list/block.js.map +1 -1
- package/build/components/block-list/use-block-props/use-focus-first-element.js +0 -1
- package/build/components/block-list/use-block-props/use-focus-first-element.js.map +1 -1
- package/build/components/block-list/use-block-props/use-zoom-out-mode-exit.js +9 -4
- package/build/components/block-list/use-block-props/use-zoom-out-mode-exit.js.map +1 -1
- package/build/components/block-list/zoom-out-separator.js +18 -1
- package/build/components/block-list/zoom-out-separator.js.map +1 -1
- package/build/components/block-switcher/utils.js +1 -1
- package/build/components/block-switcher/utils.js.map +1 -1
- package/build/components/block-tools/zoom-out-toolbar.js +5 -2
- package/build/components/block-tools/zoom-out-toolbar.js.map +1 -1
- package/build/components/block-variation-transforms/index.js +12 -6
- package/build/components/block-variation-transforms/index.js.map +1 -1
- package/build/components/rich-text/event-listeners/paste-handler.js +2 -13
- package/build/components/rich-text/event-listeners/paste-handler.js.map +1 -1
- package/build/components/rich-text/index.js +34 -20
- package/build/components/rich-text/index.js.map +1 -1
- package/build/components/tool-selector/index.js +2 -1
- package/build/components/tool-selector/index.js.map +1 -1
- package/build/components/writing-flow/index.js +1 -2
- package/build/components/writing-flow/index.js.map +1 -1
- package/build/components/writing-flow/use-arrow-nav.js +1 -4
- package/build/components/writing-flow/use-arrow-nav.js.map +1 -1
- package/build/components/writing-flow/use-input.js +1 -31
- package/build/components/writing-flow/use-input.js.map +1 -1
- package/build/components/writing-flow/use-select-all.js +1 -14
- package/build/components/writing-flow/use-select-all.js.map +1 -1
- package/build/components/writing-flow/use-selection-observer.js +2 -6
- package/build/components/writing-flow/use-selection-observer.js.map +1 -1
- package/build/components/writing-flow/utils.js +0 -27
- package/build/components/writing-flow/utils.js.map +1 -1
- package/build/hooks/layout.js +12 -8
- package/build/hooks/layout.js.map +1 -1
- package/build/hooks/use-bindings-attributes.js +22 -28
- package/build/hooks/use-bindings-attributes.js.map +1 -1
- package/build/hooks/use-zoom-out.js +20 -23
- package/build/hooks/use-zoom-out.js.map +1 -1
- package/build/store/private-actions.js +25 -0
- package/build/store/private-actions.js.map +1 -1
- package/build/store/private-selectors.js +22 -0
- package/build/store/private-selectors.js.map +1 -1
- package/build/store/reducer.js +21 -1
- package/build/store/reducer.js.map +1 -1
- package/build/store/selectors.js +12 -5
- package/build/store/selectors.js.map +1 -1
- package/build-module/components/block-heading-level-dropdown/index.js +3 -1
- package/build-module/components/block-heading-level-dropdown/index.js.map +1 -1
- package/build-module/components/block-list/block.js +28 -7
- package/build-module/components/block-list/block.js.map +1 -1
- package/build-module/components/block-list/use-block-props/use-focus-first-element.js +0 -1
- package/build-module/components/block-list/use-block-props/use-focus-first-element.js.map +1 -1
- package/build-module/components/block-list/use-block-props/use-zoom-out-mode-exit.js +9 -4
- package/build-module/components/block-list/use-block-props/use-zoom-out-mode-exit.js.map +1 -1
- package/build-module/components/block-list/zoom-out-separator.js +18 -1
- package/build-module/components/block-list/zoom-out-separator.js.map +1 -1
- package/build-module/components/block-switcher/utils.js +1 -1
- package/build-module/components/block-switcher/utils.js.map +1 -1
- package/build-module/components/block-tools/zoom-out-toolbar.js +5 -2
- package/build-module/components/block-tools/zoom-out-toolbar.js.map +1 -1
- package/build-module/components/block-variation-transforms/index.js +12 -6
- package/build-module/components/block-variation-transforms/index.js.map +1 -1
- package/build-module/components/rich-text/event-listeners/paste-handler.js +2 -13
- package/build-module/components/rich-text/event-listeners/paste-handler.js.map +1 -1
- package/build-module/components/rich-text/index.js +34 -20
- package/build-module/components/rich-text/index.js.map +1 -1
- package/build-module/components/tool-selector/index.js +2 -1
- package/build-module/components/tool-selector/index.js.map +1 -1
- package/build-module/components/writing-flow/index.js +1 -2
- package/build-module/components/writing-flow/index.js.map +1 -1
- package/build-module/components/writing-flow/use-arrow-nav.js +1 -4
- package/build-module/components/writing-flow/use-arrow-nav.js.map +1 -1
- package/build-module/components/writing-flow/use-input.js +1 -31
- package/build-module/components/writing-flow/use-input.js.map +1 -1
- package/build-module/components/writing-flow/use-select-all.js +1 -14
- package/build-module/components/writing-flow/use-select-all.js.map +1 -1
- package/build-module/components/writing-flow/use-selection-observer.js +2 -6
- package/build-module/components/writing-flow/use-selection-observer.js.map +1 -1
- package/build-module/components/writing-flow/utils.js +0 -26
- package/build-module/components/writing-flow/utils.js.map +1 -1
- package/build-module/hooks/layout.js +13 -9
- package/build-module/hooks/layout.js.map +1 -1
- package/build-module/hooks/use-bindings-attributes.js +22 -28
- package/build-module/hooks/use-bindings-attributes.js.map +1 -1
- package/build-module/hooks/use-zoom-out.js +20 -23
- package/build-module/hooks/use-zoom-out.js.map +1 -1
- package/build-module/store/private-actions.js +23 -0
- package/build-module/store/private-actions.js.map +1 -1
- package/build-module/store/private-selectors.js +20 -0
- package/build-module/store/private-selectors.js.map +1 -1
- package/build-module/store/reducer.js +20 -1
- package/build-module/store/reducer.js.map +1 -1
- package/build-module/store/selectors.js +12 -5
- package/build-module/store/selectors.js.map +1 -1
- package/build-style/content-rtl.css +10 -0
- package/build-style/content.css +10 -0
- package/build-style/style-rtl.css +4 -0
- package/build-style/style.css +4 -0
- package/package.json +20 -20
- package/src/components/block-heading-level-dropdown/index.js +7 -1
- package/src/components/block-list/block.js +47 -11
- package/src/components/block-list/content.scss +12 -0
- package/src/components/block-list/use-block-props/use-focus-first-element.js +0 -1
- package/src/components/block-list/use-block-props/use-zoom-out-mode-exit.js +7 -3
- package/src/components/block-list/zoom-out-separator.js +14 -1
- package/src/components/block-switcher/test/use-transformed.patterns.js +3 -3
- package/src/components/block-switcher/test/utils.js +3 -3
- package/src/components/block-switcher/utils.js +1 -1
- package/src/components/block-toolbar/style.scss +7 -0
- package/src/components/block-tools/zoom-out-toolbar.js +5 -2
- package/src/components/block-variation-transforms/index.js +13 -4
- package/src/components/rich-text/event-listeners/paste-handler.js +2 -7
- package/src/components/rich-text/index.js +36 -23
- package/src/components/tool-selector/index.js +4 -1
- package/src/components/writing-flow/index.js +0 -2
- package/src/components/writing-flow/use-arrow-nav.js +2 -9
- package/src/components/writing-flow/use-input.js +1 -36
- package/src/components/writing-flow/use-select-all.js +1 -18
- package/src/components/writing-flow/use-selection-observer.js +3 -14
- package/src/components/writing-flow/utils.js +0 -30
- package/src/hooks/layout.js +17 -12
- package/src/hooks/use-bindings-attributes.js +26 -32
- package/src/hooks/use-zoom-out.js +21 -27
- package/src/store/private-actions.js +23 -0
- package/src/store/private-selectors.js +20 -0
- package/src/store/reducer.js +20 -0
- package/src/store/selectors.js +13 -8
- package/src/store/test/private-selectors.js +2 -2
- package/src/store/test/selectors.js +10 -6
- package/build/components/writing-flow/use-event-redirect.js +0 -66
- package/build/components/writing-flow/use-event-redirect.js.map +0 -1
- package/build-module/components/writing-flow/use-event-redirect.js +0 -60
- package/build-module/components/writing-flow/use-event-redirect.js.map +0 -1
- package/src/components/writing-flow/use-event-redirect.js +0 -72
|
@@ -19,7 +19,6 @@ import { useRefEffect } from '@wordpress/compose';
|
|
|
19
19
|
*/
|
|
20
20
|
import { getBlockClientId, isInSameBlock } from '../../utils/dom';
|
|
21
21
|
import { store as blockEditorStore } from '../../store';
|
|
22
|
-
import { getSelectionRoot } from './utils';
|
|
23
22
|
|
|
24
23
|
/**
|
|
25
24
|
* Returns true if the element should consider edge navigation upon a keyboard
|
|
@@ -191,7 +190,8 @@ export default function useArrowNav() {
|
|
|
191
190
|
return;
|
|
192
191
|
}
|
|
193
192
|
|
|
194
|
-
const { keyCode, shiftKey, ctrlKey, altKey, metaKey } =
|
|
193
|
+
const { keyCode, target, shiftKey, ctrlKey, altKey, metaKey } =
|
|
194
|
+
event;
|
|
195
195
|
const isUp = keyCode === UP;
|
|
196
196
|
const isDown = keyCode === DOWN;
|
|
197
197
|
const isLeft = keyCode === LEFT;
|
|
@@ -233,11 +233,6 @@ export default function useArrowNav() {
|
|
|
233
233
|
return;
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
-
const target =
|
|
237
|
-
ownerDocument.activeElement === node
|
|
238
|
-
? getSelectionRoot( ownerDocument )
|
|
239
|
-
: event.target;
|
|
240
|
-
|
|
241
236
|
// Abort if our current target is not a candidate for navigation
|
|
242
237
|
// (e.g. preserve native input behaviors).
|
|
243
238
|
if ( ! isNavigationCandidate( target, keyCode, hasModifier ) ) {
|
|
@@ -279,7 +274,6 @@ export default function useArrowNav() {
|
|
|
279
274
|
( altKey ? isHorizontalEdge( target, isReverseDir ) : true ) &&
|
|
280
275
|
! keepCaretInsideBlock
|
|
281
276
|
) {
|
|
282
|
-
node.contentEditable = false;
|
|
283
277
|
const closestTabbable = getClosestTabbable(
|
|
284
278
|
target,
|
|
285
279
|
isReverse,
|
|
@@ -303,7 +297,6 @@ export default function useArrowNav() {
|
|
|
303
297
|
isHorizontalEdge( target, isReverseDir ) &&
|
|
304
298
|
! keepCaretInsideBlock
|
|
305
299
|
) {
|
|
306
|
-
node.contentEditable = false;
|
|
307
300
|
const closestTabbable = getClosestTabbable(
|
|
308
301
|
target,
|
|
309
302
|
isReverseDir,
|
|
@@ -16,7 +16,6 @@ import {
|
|
|
16
16
|
* Internal dependencies
|
|
17
17
|
*/
|
|
18
18
|
import { store as blockEditorStore } from '../../store';
|
|
19
|
-
import { getSelectionRoot } from './utils';
|
|
20
19
|
|
|
21
20
|
/**
|
|
22
21
|
* Handles input for selections across blocks.
|
|
@@ -50,24 +49,7 @@ export default function useInput() {
|
|
|
50
49
|
// DOM. This will cause React errors (and the DOM should only be
|
|
51
50
|
// altered in a controlled fashion).
|
|
52
51
|
if ( node.contentEditable === 'true' ) {
|
|
53
|
-
|
|
54
|
-
const range = selection.rangeCount
|
|
55
|
-
? selection.getRangeAt( 0 )
|
|
56
|
-
: null;
|
|
57
|
-
const root = getSelectionRoot( node.ownerDocument );
|
|
58
|
-
|
|
59
|
-
// If selection is contained within a nested editable, allow
|
|
60
|
-
// input. We need to ensure that selection is maintained.
|
|
61
|
-
if ( root ) {
|
|
62
|
-
node.contentEditable = false;
|
|
63
|
-
root.focus();
|
|
64
|
-
selection.removeAllRanges();
|
|
65
|
-
if ( range ) {
|
|
66
|
-
selection.addRange( range );
|
|
67
|
-
}
|
|
68
|
-
} else {
|
|
69
|
-
event.preventDefault();
|
|
70
|
-
}
|
|
52
|
+
event.preventDefault();
|
|
71
53
|
}
|
|
72
54
|
}
|
|
73
55
|
|
|
@@ -77,23 +59,6 @@ export default function useInput() {
|
|
|
77
59
|
}
|
|
78
60
|
|
|
79
61
|
if ( ! hasMultiSelection() ) {
|
|
80
|
-
const { ownerDocument } = node;
|
|
81
|
-
if ( node === ownerDocument.activeElement ) {
|
|
82
|
-
if ( event.key === 'End' || event.key === 'Home' ) {
|
|
83
|
-
const selectionRoot = getSelectionRoot( ownerDocument );
|
|
84
|
-
const selection =
|
|
85
|
-
ownerDocument.defaultView.getSelection();
|
|
86
|
-
selection.selectAllChildren( selectionRoot );
|
|
87
|
-
const method =
|
|
88
|
-
event.key === 'End'
|
|
89
|
-
? 'collapseToEnd'
|
|
90
|
-
: 'collapseToStart';
|
|
91
|
-
selection[ method ]();
|
|
92
|
-
event.preventDefault();
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
62
|
if ( event.keyCode === ENTER ) {
|
|
98
63
|
if ( event.shiftKey || __unstableIsFullySelected() ) {
|
|
99
64
|
return;
|
|
@@ -10,7 +10,6 @@ import { useRefEffect } from '@wordpress/compose';
|
|
|
10
10
|
* Internal dependencies
|
|
11
11
|
*/
|
|
12
12
|
import { store as blockEditorStore } from '../../store';
|
|
13
|
-
import { getSelectionRoot } from './utils';
|
|
14
13
|
|
|
15
14
|
export default function useSelectAll() {
|
|
16
15
|
const { getBlockOrder, getSelectedBlockClientIds, getBlockRootClientId } =
|
|
@@ -24,27 +23,12 @@ export default function useSelectAll() {
|
|
|
24
23
|
return;
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
const selectionRoot = getSelectionRoot( node.ownerDocument );
|
|
28
26
|
const selectedClientIds = getSelectedBlockClientIds();
|
|
29
27
|
|
|
30
|
-
// Abort if there is selection, but it is not within a block.
|
|
31
|
-
if ( selectionRoot && ! selectedClientIds.length ) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
28
|
if (
|
|
36
|
-
selectionRoot &&
|
|
37
29
|
selectedClientIds.length < 2 &&
|
|
38
|
-
! isEntirelySelected(
|
|
30
|
+
! isEntirelySelected( event.target )
|
|
39
31
|
) {
|
|
40
|
-
if ( node === node.ownerDocument.activeElement ) {
|
|
41
|
-
event.preventDefault();
|
|
42
|
-
node.ownerDocument.defaultView
|
|
43
|
-
.getSelection()
|
|
44
|
-
.selectAllChildren( selectionRoot );
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
32
|
return;
|
|
49
33
|
}
|
|
50
34
|
|
|
@@ -61,7 +45,6 @@ export default function useSelectAll() {
|
|
|
61
45
|
node.ownerDocument.defaultView
|
|
62
46
|
.getSelection()
|
|
63
47
|
.removeAllRanges();
|
|
64
|
-
node.contentEditable = 'false';
|
|
65
48
|
selectBlock( rootClientId );
|
|
66
49
|
}
|
|
67
50
|
return;
|
|
@@ -107,12 +107,8 @@ function getRichTextElement( node ) {
|
|
|
107
107
|
export default function useSelectionObserver() {
|
|
108
108
|
const { multiSelect, selectBlock, selectionChange } =
|
|
109
109
|
useDispatch( blockEditorStore );
|
|
110
|
-
const {
|
|
111
|
-
|
|
112
|
-
getBlockSelectionStart,
|
|
113
|
-
isMultiSelecting,
|
|
114
|
-
getSelectedBlockClientId,
|
|
115
|
-
} = useSelect( blockEditorStore );
|
|
110
|
+
const { getBlockParents, getBlockSelectionStart, isMultiSelecting } =
|
|
111
|
+
useSelect( blockEditorStore );
|
|
116
112
|
return useRefEffect(
|
|
117
113
|
( node ) => {
|
|
118
114
|
const { ownerDocument } = node;
|
|
@@ -195,17 +191,10 @@ export default function useSelectionObserver() {
|
|
|
195
191
|
return;
|
|
196
192
|
}
|
|
197
193
|
|
|
198
|
-
setContentEditableWrapper(
|
|
199
|
-
node,
|
|
200
|
-
!! ( startClientId && endClientId )
|
|
201
|
-
);
|
|
202
|
-
|
|
203
194
|
const isSingularSelection = startClientId === endClientId;
|
|
204
195
|
if ( isSingularSelection ) {
|
|
205
196
|
if ( ! isMultiSelecting() ) {
|
|
206
|
-
|
|
207
|
-
selectBlock( startClientId );
|
|
208
|
-
}
|
|
197
|
+
selectBlock( startClientId );
|
|
209
198
|
} else {
|
|
210
199
|
multiSelect( startClientId, startClientId );
|
|
211
200
|
}
|
|
@@ -116,33 +116,3 @@ function toPlainText( html ) {
|
|
|
116
116
|
// Merge any consecutive line breaks
|
|
117
117
|
return plainText.replace( /\n\n+/g, '\n\n' );
|
|
118
118
|
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Gets the current content editable root element based on the selection.
|
|
122
|
-
* @param {Document} ownerDocument
|
|
123
|
-
* @return {Element|undefined} The content editable root element.
|
|
124
|
-
*/
|
|
125
|
-
export function getSelectionRoot( ownerDocument ) {
|
|
126
|
-
const { defaultView } = ownerDocument;
|
|
127
|
-
const { anchorNode, focusNode } = defaultView.getSelection();
|
|
128
|
-
|
|
129
|
-
if ( ! anchorNode || ! focusNode ) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const anchorElement = (
|
|
134
|
-
anchorNode.nodeType === anchorNode.ELEMENT_NODE
|
|
135
|
-
? anchorNode
|
|
136
|
-
: anchorNode.parentElement
|
|
137
|
-
).closest( '[contenteditable]' );
|
|
138
|
-
|
|
139
|
-
if ( ! anchorElement ) {
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if ( ! anchorElement.contains( focusNode ) ) {
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return anchorElement;
|
|
148
|
-
}
|
package/src/hooks/layout.js
CHANGED
|
@@ -11,8 +11,8 @@ import { addFilter } from '@wordpress/hooks';
|
|
|
11
11
|
import { getBlockSupport, hasBlockSupport } from '@wordpress/blocks';
|
|
12
12
|
import { useSelect } from '@wordpress/data';
|
|
13
13
|
import {
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
__experimentalToggleGroupControl as ToggleGroupControl,
|
|
15
|
+
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
|
|
16
16
|
ToggleControl,
|
|
17
17
|
PanelBody,
|
|
18
18
|
privateApis as componentsPrivateApis,
|
|
@@ -315,21 +315,26 @@ export default {
|
|
|
315
315
|
|
|
316
316
|
function LayoutTypeSwitcher( { type, onChange } ) {
|
|
317
317
|
return (
|
|
318
|
-
<
|
|
318
|
+
<ToggleGroupControl
|
|
319
|
+
__next40pxDefaultSize
|
|
320
|
+
isBlock
|
|
321
|
+
label={ __( 'Layout type' ) }
|
|
322
|
+
__nextHasNoMarginBottom
|
|
323
|
+
hideLabelFromVision
|
|
324
|
+
isAdaptiveWidth
|
|
325
|
+
value={ type }
|
|
326
|
+
onChange={ onChange }
|
|
327
|
+
>
|
|
319
328
|
{ getLayoutTypes().map( ( { name, label } ) => {
|
|
320
329
|
return (
|
|
321
|
-
<
|
|
322
|
-
// TODO: Switch to `true` (40px size) if possible
|
|
323
|
-
__next40pxDefaultSize={ false }
|
|
330
|
+
<ToggleGroupControlOption
|
|
324
331
|
key={ name }
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
{ label }
|
|
329
|
-
</Button>
|
|
332
|
+
value={ name }
|
|
333
|
+
label={ label }
|
|
334
|
+
/>
|
|
330
335
|
);
|
|
331
336
|
} ) }
|
|
332
|
-
</
|
|
337
|
+
</ToggleGroupControl>
|
|
333
338
|
);
|
|
334
339
|
}
|
|
335
340
|
|
|
@@ -103,11 +103,7 @@ export const withBlockBindingSupport = createHigherOrderComponent(
|
|
|
103
103
|
const sources = useSelect( ( select ) =>
|
|
104
104
|
unlock( select( blocksStore ) ).getAllBlockBindingsSources()
|
|
105
105
|
);
|
|
106
|
-
const { name, clientId } = props;
|
|
107
|
-
const hasParentPattern = !! props.context[ 'pattern/overrides' ];
|
|
108
|
-
const hasPatternOverridesDefaultBinding =
|
|
109
|
-
props.attributes.metadata?.bindings?.[ DEFAULT_ATTRIBUTE ]
|
|
110
|
-
?.source === 'core/pattern-overrides';
|
|
106
|
+
const { name, clientId, context, setAttributes } = props;
|
|
111
107
|
const blockBindings = useMemo(
|
|
112
108
|
() =>
|
|
113
109
|
replacePatternOverrideDefaultBindings(
|
|
@@ -121,6 +117,7 @@ export const withBlockBindingSupport = createHigherOrderComponent(
|
|
|
121
117
|
// used purposely here to ensure `boundAttributes` is updated whenever
|
|
122
118
|
// there are attribute updates.
|
|
123
119
|
// `source.getValues` may also call a selector via `registry.select`.
|
|
120
|
+
const updatedContext = {};
|
|
124
121
|
const boundAttributes = useSelect( () => {
|
|
125
122
|
if ( ! blockBindings ) {
|
|
126
123
|
return;
|
|
@@ -139,6 +136,11 @@ export const withBlockBindingSupport = createHigherOrderComponent(
|
|
|
139
136
|
continue;
|
|
140
137
|
}
|
|
141
138
|
|
|
139
|
+
// Populate context.
|
|
140
|
+
for ( const key of source.usesContext || [] ) {
|
|
141
|
+
updatedContext[ key ] = blockContext[ key ];
|
|
142
|
+
}
|
|
143
|
+
|
|
142
144
|
blockBindingsBySource.set( source, {
|
|
143
145
|
...blockBindingsBySource.get( source ),
|
|
144
146
|
[ attributeName ]: {
|
|
@@ -149,27 +151,17 @@ export const withBlockBindingSupport = createHigherOrderComponent(
|
|
|
149
151
|
|
|
150
152
|
if ( blockBindingsBySource.size ) {
|
|
151
153
|
for ( const [ source, bindings ] of blockBindingsBySource ) {
|
|
152
|
-
// Populate context.
|
|
153
|
-
const context = {};
|
|
154
|
-
|
|
155
|
-
if ( source.usesContext?.length ) {
|
|
156
|
-
for ( const key of source.usesContext ) {
|
|
157
|
-
context[ key ] = blockContext[ key ];
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
154
|
// Get values in batch if the source supports it.
|
|
162
155
|
let values = {};
|
|
163
156
|
if ( ! source.getValues ) {
|
|
164
157
|
Object.keys( bindings ).forEach( ( attr ) => {
|
|
165
|
-
// Default to the
|
|
166
|
-
values[ attr ] =
|
|
167
|
-
bindings[ attr ].args?.key || source.label;
|
|
158
|
+
// Default to the the source label when `getValues` doesn't exist.
|
|
159
|
+
values[ attr ] = source.label;
|
|
168
160
|
} );
|
|
169
161
|
} else {
|
|
170
162
|
values = source.getValues( {
|
|
171
163
|
registry,
|
|
172
|
-
context,
|
|
164
|
+
context: updatedContext,
|
|
173
165
|
clientId,
|
|
174
166
|
bindings,
|
|
175
167
|
} );
|
|
@@ -191,9 +183,19 @@ export const withBlockBindingSupport = createHigherOrderComponent(
|
|
|
191
183
|
}
|
|
192
184
|
|
|
193
185
|
return attributes;
|
|
194
|
-
}, [
|
|
195
|
-
|
|
196
|
-
|
|
186
|
+
}, [
|
|
187
|
+
blockBindings,
|
|
188
|
+
name,
|
|
189
|
+
clientId,
|
|
190
|
+
updatedContext,
|
|
191
|
+
registry,
|
|
192
|
+
sources,
|
|
193
|
+
] );
|
|
194
|
+
|
|
195
|
+
const hasParentPattern = !! updatedContext[ 'pattern/overrides' ];
|
|
196
|
+
const hasPatternOverridesDefaultBinding =
|
|
197
|
+
props.attributes.metadata?.bindings?.[ DEFAULT_ATTRIBUTE ]
|
|
198
|
+
?.source === 'core/pattern-overrides';
|
|
197
199
|
|
|
198
200
|
const _setAttributes = useCallback(
|
|
199
201
|
( nextAttributes ) => {
|
|
@@ -237,18 +239,9 @@ export const withBlockBindingSupport = createHigherOrderComponent(
|
|
|
237
239
|
source,
|
|
238
240
|
bindings,
|
|
239
241
|
] of blockBindingsBySource ) {
|
|
240
|
-
// Populate context.
|
|
241
|
-
const context = {};
|
|
242
|
-
|
|
243
|
-
if ( source.usesContext?.length ) {
|
|
244
|
-
for ( const key of source.usesContext ) {
|
|
245
|
-
context[ key ] = blockContext[ key ];
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
242
|
source.setValues( {
|
|
250
243
|
registry,
|
|
251
|
-
context,
|
|
244
|
+
context: updatedContext,
|
|
252
245
|
clientId,
|
|
253
246
|
bindings,
|
|
254
247
|
} );
|
|
@@ -278,7 +271,7 @@ export const withBlockBindingSupport = createHigherOrderComponent(
|
|
|
278
271
|
blockBindings,
|
|
279
272
|
name,
|
|
280
273
|
clientId,
|
|
281
|
-
|
|
274
|
+
updatedContext,
|
|
282
275
|
setAttributes,
|
|
283
276
|
sources,
|
|
284
277
|
hasPatternOverridesDefaultBinding,
|
|
@@ -292,6 +285,7 @@ export const withBlockBindingSupport = createHigherOrderComponent(
|
|
|
292
285
|
{ ...props }
|
|
293
286
|
attributes={ { ...props.attributes, ...boundAttributes } }
|
|
294
287
|
setAttributes={ _setAttributes }
|
|
288
|
+
context={ { ...context, ...updatedContext } }
|
|
295
289
|
/>
|
|
296
290
|
</>
|
|
297
291
|
);
|
|
@@ -8,46 +8,40 @@ import { useEffect, useRef } from '@wordpress/element';
|
|
|
8
8
|
* Internal dependencies
|
|
9
9
|
*/
|
|
10
10
|
import { store as blockEditorStore } from '../store';
|
|
11
|
+
import { unlock } from '../lock-unlock';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
|
-
* A hook used to set the
|
|
14
|
+
* A hook used to set the zoomed out view, invoking the hook sets the mode.
|
|
14
15
|
*
|
|
15
|
-
* @param {boolean} zoomOut If we should
|
|
16
|
+
* @param {boolean} zoomOut If we should zoom out or not.
|
|
16
17
|
*/
|
|
17
18
|
export function useZoomOut( zoomOut = true ) {
|
|
18
|
-
const {
|
|
19
|
-
const {
|
|
19
|
+
const { setZoomLevel } = unlock( useDispatch( blockEditorStore ) );
|
|
20
|
+
const { isZoomOut } = unlock( useSelect( blockEditorStore ) );
|
|
20
21
|
|
|
21
|
-
const
|
|
22
|
-
const mode = __unstableGetEditorMode();
|
|
22
|
+
const originalIsZoomOutRef = useRef( null );
|
|
23
23
|
|
|
24
24
|
useEffect( () => {
|
|
25
25
|
// Only set this on mount so we know what to return to when we unmount.
|
|
26
|
-
if ( !
|
|
27
|
-
|
|
26
|
+
if ( ! originalIsZoomOutRef.current ) {
|
|
27
|
+
originalIsZoomOutRef.current = isZoomOut();
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
__unstableGetEditorMode() === 'zoom-out' &&
|
|
34
|
-
__unstableGetEditorMode() !== originalEditingModeRef.current
|
|
35
|
-
) {
|
|
36
|
-
__unstableSetEditorMode( originalEditingModeRef.current );
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
}, [] );
|
|
40
|
-
|
|
41
|
-
// The effect opens the zoom-out view if we want it open and it's not currently in zoom-out mode.
|
|
42
|
-
useEffect( () => {
|
|
43
|
-
if ( zoomOut && mode !== 'zoom-out' ) {
|
|
44
|
-
__unstableSetEditorMode( 'zoom-out' );
|
|
30
|
+
// The effect opens the zoom-out view if we want it open and the canvas is not currently zoomed-out.
|
|
31
|
+
if ( zoomOut && isZoomOut() === false ) {
|
|
32
|
+
setZoomLevel( 50 );
|
|
45
33
|
} else if (
|
|
46
34
|
! zoomOut &&
|
|
47
|
-
|
|
48
|
-
|
|
35
|
+
isZoomOut() &&
|
|
36
|
+
originalIsZoomOutRef.current !== isZoomOut()
|
|
49
37
|
) {
|
|
50
|
-
|
|
38
|
+
setZoomLevel( originalIsZoomOutRef.current ? 50 : 100 );
|
|
51
39
|
}
|
|
52
|
-
|
|
40
|
+
|
|
41
|
+
return () => {
|
|
42
|
+
if ( isZoomOut() && isZoomOut() !== originalIsZoomOutRef.current ) {
|
|
43
|
+
setZoomLevel( originalIsZoomOutRef.current ? 50 : 100 );
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}, [ isZoomOut, setZoomLevel, zoomOut ] );
|
|
53
47
|
}
|
|
@@ -383,3 +383,26 @@ export const modifyContentLockBlock =
|
|
|
383
383
|
focusModeToRevert
|
|
384
384
|
);
|
|
385
385
|
};
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Sets the zoom level.
|
|
389
|
+
*
|
|
390
|
+
* @param {number} zoom the new zoom level
|
|
391
|
+
* @return {Object} Action object.
|
|
392
|
+
*/
|
|
393
|
+
export function setZoomLevel( zoom = 100 ) {
|
|
394
|
+
return {
|
|
395
|
+
type: 'SET_ZOOM_LEVEL',
|
|
396
|
+
zoom,
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Resets the Zoom state.
|
|
402
|
+
* @return {Object} Action object.
|
|
403
|
+
*/
|
|
404
|
+
export function resetZoomLevel() {
|
|
405
|
+
return {
|
|
406
|
+
type: 'RESET_ZOOM_LEVEL',
|
|
407
|
+
};
|
|
408
|
+
}
|
|
@@ -560,3 +560,23 @@ export function isZoomOutMode( state ) {
|
|
|
560
560
|
export function getSectionRootClientId( state ) {
|
|
561
561
|
return state.settings?.[ sectionRootClientIdKey ];
|
|
562
562
|
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Returns the zoom out state.
|
|
566
|
+
*
|
|
567
|
+
* @param {Object} state Global application state.
|
|
568
|
+
* @return {boolean} The zoom out state.
|
|
569
|
+
*/
|
|
570
|
+
export function getZoomLevel( state ) {
|
|
571
|
+
return state.zoomLevel;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Returns whether the editor is considered zoomed out.
|
|
576
|
+
*
|
|
577
|
+
* @param {Object} state Global application state.
|
|
578
|
+
* @return {boolean} Whether the editor is zoomed.
|
|
579
|
+
*/
|
|
580
|
+
export function isZoomOut( state ) {
|
|
581
|
+
return getZoomLevel( state ) < 100;
|
|
582
|
+
}
|
package/src/store/reducer.js
CHANGED
|
@@ -2085,6 +2085,25 @@ export function hoveredBlockClientId( state = false, action ) {
|
|
|
2085
2085
|
return state;
|
|
2086
2086
|
}
|
|
2087
2087
|
|
|
2088
|
+
/**
|
|
2089
|
+
* Reducer setting zoom out state.
|
|
2090
|
+
*
|
|
2091
|
+
* @param {boolean} state Current state.
|
|
2092
|
+
* @param {Object} action Dispatched action.
|
|
2093
|
+
*
|
|
2094
|
+
* @return {boolean} Updated state.
|
|
2095
|
+
*/
|
|
2096
|
+
export function zoomLevel( state = 100, action ) {
|
|
2097
|
+
switch ( action.type ) {
|
|
2098
|
+
case 'SET_ZOOM_LEVEL':
|
|
2099
|
+
return action.zoom;
|
|
2100
|
+
case 'RESET_ZOOM_LEVEL':
|
|
2101
|
+
return 100;
|
|
2102
|
+
}
|
|
2103
|
+
|
|
2104
|
+
return state;
|
|
2105
|
+
}
|
|
2106
|
+
|
|
2088
2107
|
const combinedReducers = combineReducers( {
|
|
2089
2108
|
blocks,
|
|
2090
2109
|
isDragging,
|
|
@@ -2118,6 +2137,7 @@ const combinedReducers = combineReducers( {
|
|
|
2118
2137
|
openedBlockSettingsMenu,
|
|
2119
2138
|
registeredInserterMediaCategories,
|
|
2120
2139
|
hoveredBlockClientId,
|
|
2140
|
+
zoomLevel,
|
|
2121
2141
|
} );
|
|
2122
2142
|
|
|
2123
2143
|
function withAutomaticChangeReset( reducer ) {
|
package/src/store/selectors.js
CHANGED
|
@@ -2467,7 +2467,7 @@ export const __experimentalGetPatternsByBlockTypes = createRegistrySelector(
|
|
|
2467
2467
|
* Determines the items that appear in the available pattern transforms list.
|
|
2468
2468
|
*
|
|
2469
2469
|
* For now we only handle blocks without InnerBlocks and take into account
|
|
2470
|
-
* the `
|
|
2470
|
+
* the `role` property of blocks' attributes for the transformation.
|
|
2471
2471
|
*
|
|
2472
2472
|
* We return the first set of possible eligible block patterns,
|
|
2473
2473
|
* by checking the `blockTypes` property. We still have to recurse through
|
|
@@ -2489,7 +2489,7 @@ export const __experimentalGetPatternTransformItems = createRegistrySelector(
|
|
|
2489
2489
|
}
|
|
2490
2490
|
/**
|
|
2491
2491
|
* For now we only handle blocks without InnerBlocks and take into account
|
|
2492
|
-
* the `
|
|
2492
|
+
* the `role` property of blocks' attributes for the transformation.
|
|
2493
2493
|
* Note that the blocks have been retrieved through `getBlock`, which doesn't
|
|
2494
2494
|
* return the inner blocks of an inner block controller, so we still need
|
|
2495
2495
|
* to check for this case too.
|
|
@@ -2926,6 +2926,7 @@ export const getBlockEditingMode = createRegistrySelector(
|
|
|
2926
2926
|
if ( clientId === null ) {
|
|
2927
2927
|
clientId = '';
|
|
2928
2928
|
}
|
|
2929
|
+
|
|
2929
2930
|
// In zoom-out mode, override the behavior set by
|
|
2930
2931
|
// __unstableSetBlockEditingMode to only allow editing the top-level
|
|
2931
2932
|
// sections.
|
|
@@ -2943,9 +2944,13 @@ export const getBlockEditingMode = createRegistrySelector(
|
|
|
2943
2944
|
state,
|
|
2944
2945
|
sectionRootClientId
|
|
2945
2946
|
);
|
|
2946
|
-
|
|
2947
|
-
|
|
2947
|
+
|
|
2948
|
+
// Sections are always contentOnly.
|
|
2949
|
+
if ( sectionsClientIds?.includes( clientId ) ) {
|
|
2950
|
+
return 'contentOnly';
|
|
2948
2951
|
}
|
|
2952
|
+
|
|
2953
|
+
return 'disabled';
|
|
2949
2954
|
}
|
|
2950
2955
|
|
|
2951
2956
|
const blockEditingMode = state.blockEditingModes.get( clientId );
|
|
@@ -2959,10 +2964,10 @@ export const getBlockEditingMode = createRegistrySelector(
|
|
|
2959
2964
|
const templateLock = getTemplateLock( state, rootClientId );
|
|
2960
2965
|
if ( templateLock === 'contentOnly' ) {
|
|
2961
2966
|
const name = getBlockName( state, clientId );
|
|
2962
|
-
const
|
|
2963
|
-
select( blocksStore )
|
|
2964
|
-
|
|
2965
|
-
|
|
2967
|
+
const { hasContentRoleAttribute } = unlock(
|
|
2968
|
+
select( blocksStore )
|
|
2969
|
+
);
|
|
2970
|
+
const isContent = hasContentRoleAttribute( name );
|
|
2966
2971
|
return isContent ? 'contentOnly' : 'disabled';
|
|
2967
2972
|
}
|
|
2968
2973
|
const parentMode = getBlockEditingMode( state, rootClientId );
|
|
@@ -124,10 +124,10 @@ describe( 'private selectors', () => {
|
|
|
124
124
|
blockEditingModes: new Map( [] ),
|
|
125
125
|
};
|
|
126
126
|
|
|
127
|
-
const
|
|
127
|
+
const hasContentRoleAttribute = jest.fn( () => false );
|
|
128
128
|
getBlockEditingMode.registry = {
|
|
129
129
|
select: jest.fn( () => ( {
|
|
130
|
-
|
|
130
|
+
hasContentRoleAttribute,
|
|
131
131
|
} ) ),
|
|
132
132
|
};
|
|
133
133
|
|
|
@@ -15,6 +15,7 @@ import { select, dispatch } from '@wordpress/data';
|
|
|
15
15
|
*/
|
|
16
16
|
import * as selectors from '../selectors';
|
|
17
17
|
import { store } from '../';
|
|
18
|
+
import { lock } from '../../lock-unlock';
|
|
18
19
|
|
|
19
20
|
const {
|
|
20
21
|
getBlockName,
|
|
@@ -4372,11 +4373,14 @@ describe( 'getBlockEditingMode', () => {
|
|
|
4372
4373
|
blockEditingModes: new Map( [] ),
|
|
4373
4374
|
};
|
|
4374
4375
|
|
|
4375
|
-
const
|
|
4376
|
+
const hasContentRoleAttribute = jest.fn( () => false );
|
|
4377
|
+
|
|
4378
|
+
const fauxPrivateAPIs = {};
|
|
4379
|
+
|
|
4380
|
+
lock( fauxPrivateAPIs, { hasContentRoleAttribute } );
|
|
4381
|
+
|
|
4376
4382
|
getBlockEditingMode.registry = {
|
|
4377
|
-
select: jest.fn( () =>
|
|
4378
|
-
__experimentalHasContentRoleAttribute,
|
|
4379
|
-
} ) ),
|
|
4383
|
+
select: jest.fn( () => fauxPrivateAPIs ),
|
|
4380
4384
|
};
|
|
4381
4385
|
|
|
4382
4386
|
it( 'should return default by default', () => {
|
|
@@ -4480,7 +4484,7 @@ describe( 'getBlockEditingMode', () => {
|
|
|
4480
4484
|
},
|
|
4481
4485
|
},
|
|
4482
4486
|
};
|
|
4483
|
-
|
|
4487
|
+
hasContentRoleAttribute.mockReturnValueOnce( false );
|
|
4484
4488
|
expect(
|
|
4485
4489
|
getBlockEditingMode( state, 'b3247f75-fd94-4fef-97f9-5bfd162cc416' )
|
|
4486
4490
|
).toBe( 'disabled' );
|
|
@@ -4496,7 +4500,7 @@ describe( 'getBlockEditingMode', () => {
|
|
|
4496
4500
|
},
|
|
4497
4501
|
},
|
|
4498
4502
|
};
|
|
4499
|
-
|
|
4503
|
+
hasContentRoleAttribute.mockReturnValueOnce( true );
|
|
4500
4504
|
expect(
|
|
4501
4505
|
getBlockEditingMode( state, 'b3247f75-fd94-4fef-97f9-5bfd162cc416' )
|
|
4502
4506
|
).toBe( 'contentOnly' );
|