@wordpress/block-editor 8.5.3 → 8.5.4

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.
Files changed (46) hide show
  1. package/build/components/block-content-overlay/index.js +4 -13
  2. package/build/components/block-content-overlay/index.js.map +1 -1
  3. package/build/components/block-lock/modal.js +4 -34
  4. package/build/components/block-lock/modal.js.map +1 -1
  5. package/build/components/block-lock/toolbar.js +1 -2
  6. package/build/components/block-lock/toolbar.js.map +1 -1
  7. package/build/components/block-lock/use-block-lock.js +1 -4
  8. package/build/components/block-lock/use-block-lock.js.map +1 -1
  9. package/build/components/inserter/index.js +21 -7
  10. package/build/components/inserter/index.js.map +1 -1
  11. package/build/components/inserter/quick-inserter.js +4 -5
  12. package/build/components/inserter/quick-inserter.js.map +1 -1
  13. package/build/components/writing-flow/use-click-selection.js +1 -3
  14. package/build/components/writing-flow/use-click-selection.js.map +1 -1
  15. package/build/components/writing-flow/use-selection-observer.js +44 -9
  16. package/build/components/writing-flow/use-selection-observer.js.map +1 -1
  17. package/build/store/selectors.js +0 -24
  18. package/build/store/selectors.js.map +1 -1
  19. package/build-module/components/block-content-overlay/index.js +4 -13
  20. package/build-module/components/block-content-overlay/index.js.map +1 -1
  21. package/build-module/components/block-lock/modal.js +5 -34
  22. package/build-module/components/block-lock/modal.js.map +1 -1
  23. package/build-module/components/block-lock/toolbar.js +1 -2
  24. package/build-module/components/block-lock/toolbar.js.map +1 -1
  25. package/build-module/components/block-lock/use-block-lock.js +1 -4
  26. package/build-module/components/block-lock/use-block-lock.js.map +1 -1
  27. package/build-module/components/inserter/index.js +21 -7
  28. package/build-module/components/inserter/index.js.map +1 -1
  29. package/build-module/components/inserter/quick-inserter.js +4 -5
  30. package/build-module/components/inserter/quick-inserter.js.map +1 -1
  31. package/build-module/components/writing-flow/use-click-selection.js +1 -3
  32. package/build-module/components/writing-flow/use-click-selection.js.map +1 -1
  33. package/build-module/components/writing-flow/use-selection-observer.js +44 -9
  34. package/build-module/components/writing-flow/use-selection-observer.js.map +1 -1
  35. package/build-module/store/selectors.js +0 -22
  36. package/build-module/store/selectors.js.map +1 -1
  37. package/package.json +4 -4
  38. package/src/components/block-content-overlay/index.js +2 -19
  39. package/src/components/block-lock/modal.js +3 -42
  40. package/src/components/block-lock/toolbar.js +2 -2
  41. package/src/components/block-lock/use-block-lock.js +1 -4
  42. package/src/components/inserter/index.js +20 -0
  43. package/src/components/inserter/quick-inserter.js +3 -11
  44. package/src/components/writing-flow/use-click-selection.js +1 -4
  45. package/src/components/writing-flow/use-selection-observer.js +51 -13
  46. package/src/store/selectors.js +0 -20
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/block-editor",
3
- "version": "8.5.3",
3
+ "version": "8.5.4",
4
4
  "description": "Generic block editor.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -37,7 +37,7 @@
37
37
  "@wordpress/api-fetch": "^6.3.1",
38
38
  "@wordpress/blob": "^3.6.1",
39
39
  "@wordpress/blocks": "^11.5.3",
40
- "@wordpress/components": "^19.8.2",
40
+ "@wordpress/components": "^19.8.3",
41
41
  "@wordpress/compose": "^5.4.1",
42
42
  "@wordpress/data": "^6.6.1",
43
43
  "@wordpress/date": "^4.6.1",
@@ -52,7 +52,7 @@
52
52
  "@wordpress/keyboard-shortcuts": "^3.4.1",
53
53
  "@wordpress/keycodes": "^3.6.1",
54
54
  "@wordpress/notices": "^3.6.1",
55
- "@wordpress/rich-text": "^5.4.1",
55
+ "@wordpress/rich-text": "^5.4.2",
56
56
  "@wordpress/shortcode": "^3.6.1",
57
57
  "@wordpress/style-engine": "^0.5.1",
58
58
  "@wordpress/token-list": "^2.6.1",
@@ -77,5 +77,5 @@
77
77
  "publishConfig": {
78
78
  "access": "public"
79
79
  },
80
- "gitHead": "37e930b93fbba88fa024a91eb527a90f855c97f3"
80
+ "gitHead": "1fdd4758150247d6b690051aed18fa27c15f3a32"
81
81
  }
@@ -25,7 +25,6 @@ export default function BlockContentOverlay( {
25
25
  const [ isHovered, setIsHovered ] = useState( false );
26
26
 
27
27
  const {
28
- canEdit,
29
28
  isParentSelected,
30
29
  hasChildSelected,
31
30
  isDraggingBlocks,
@@ -37,10 +36,8 @@ export default function BlockContentOverlay( {
37
36
  hasSelectedInnerBlock,
38
37
  isDraggingBlocks: _isDraggingBlocks,
39
38
  isBlockHighlighted,
40
- canEditBlock,
41
39
  } = select( blockEditorStore );
42
40
  return {
43
- canEdit: canEditBlock( clientId ),
44
41
  isParentSelected: isBlockSelected( clientId ),
45
42
  hasChildSelected: hasSelectedInnerBlock( clientId, true ),
46
43
  isDraggingBlocks: _isDraggingBlocks(),
@@ -62,12 +59,6 @@ export default function BlockContentOverlay( {
62
59
  );
63
60
 
64
61
  useEffect( () => {
65
- // The overlay is always active when editing is locked.
66
- if ( ! canEdit ) {
67
- setIsOverlayActive( true );
68
- return;
69
- }
70
-
71
62
  // Reenable when blocks are not in use.
72
63
  if ( ! isParentSelected && ! hasChildSelected && ! isOverlayActive ) {
73
64
  setIsOverlayActive( true );
@@ -84,13 +75,7 @@ export default function BlockContentOverlay( {
84
75
  if ( hasChildSelected && isOverlayActive ) {
85
76
  setIsOverlayActive( false );
86
77
  }
87
- }, [
88
- isParentSelected,
89
- hasChildSelected,
90
- isOverlayActive,
91
- isHovered,
92
- canEdit,
93
- ] );
78
+ }, [ isParentSelected, hasChildSelected, isOverlayActive, isHovered ] );
94
79
 
95
80
  // Disabled because the overlay div doesn't actually have a role or functionality
96
81
  // as far as the a11y is concerned. We're just catching the first click so that
@@ -103,9 +88,7 @@ export default function BlockContentOverlay( {
103
88
  onMouseEnter={ () => setIsHovered( true ) }
104
89
  onMouseLeave={ () => setIsHovered( false ) }
105
90
  onMouseUp={
106
- isOverlayActive && canEdit
107
- ? () => setIsOverlayActive( false )
108
- : undefined
91
+ isOverlayActive ? () => setIsOverlayActive( false ) : undefined
109
92
  }
110
93
  >
111
94
  { wrapperProps?.children }
@@ -13,8 +13,7 @@ import {
13
13
  } from '@wordpress/components';
14
14
  import { lock as lockIcon, unlock as unlockIcon } from '@wordpress/icons';
15
15
  import { useInstanceId } from '@wordpress/compose';
16
- import { useDispatch, useSelect } from '@wordpress/data';
17
- import { isReusableBlock, getBlockType } from '@wordpress/blocks';
16
+ import { useDispatch } from '@wordpress/data';
18
17
 
19
18
  /**
20
19
  * Internal dependencies
@@ -25,18 +24,7 @@ import { store as blockEditorStore } from '../../store';
25
24
 
26
25
  export default function BlockLockModal( { clientId, onClose } ) {
27
26
  const [ lock, setLock ] = useState( { move: false, remove: false } );
28
- const { canEdit, canMove, canRemove } = useBlockLock( clientId );
29
- const { isReusable } = useSelect(
30
- ( select ) => {
31
- const { getBlockName } = select( blockEditorStore );
32
- const blockName = getBlockName( clientId );
33
-
34
- return {
35
- isReusable: isReusableBlock( getBlockType( blockName ) ),
36
- };
37
- },
38
- [ clientId ]
39
- );
27
+ const { canMove, canRemove } = useBlockLock( clientId );
40
28
  const { updateBlockAttributes } = useDispatch( blockEditorStore );
41
29
  const blockInformation = useBlockDisplayInformation( clientId );
42
30
  const instanceId = useInstanceId(
@@ -48,9 +36,8 @@ export default function BlockLockModal( { clientId, onClose } ) {
48
36
  setLock( {
49
37
  move: ! canMove,
50
38
  remove: ! canRemove,
51
- ...( isReusable ? { edit: ! canEdit } : {} ),
52
39
  } );
53
- }, [ canEdit, canMove, canRemove, isReusable ] );
40
+ }, [ canMove, canRemove ] );
54
41
 
55
42
  const isAllChecked = Object.values( lock ).every( Boolean );
56
43
  const isMixed = Object.values( lock ).some( Boolean ) && ! isAllChecked;
@@ -94,36 +81,10 @@ export default function BlockLockModal( { clientId, onClose } ) {
94
81
  setLock( {
95
82
  move: newValue,
96
83
  remove: newValue,
97
- ...( isReusable ? { edit: newValue } : {} ),
98
84
  } )
99
85
  }
100
86
  />
101
87
  <ul className="block-editor-block-lock-modal__checklist">
102
- { isReusable && (
103
- <li className="block-editor-block-lock-modal__checklist-item">
104
- <CheckboxControl
105
- label={
106
- <>
107
- { __( 'Restrict editing' ) }
108
- <Icon
109
- icon={
110
- lock.edit
111
- ? lockIcon
112
- : unlockIcon
113
- }
114
- />
115
- </>
116
- }
117
- checked={ !! lock.edit }
118
- onChange={ ( edit ) =>
119
- setLock( ( prevLock ) => ( {
120
- ...prevLock,
121
- edit,
122
- } ) )
123
- }
124
- />
125
- </li>
126
- ) }
127
88
  <li className="block-editor-block-lock-modal__checklist-item">
128
89
  <CheckboxControl
129
90
  label={
@@ -15,7 +15,7 @@ import useBlockDisplayInformation from '../use-block-display-information';
15
15
 
16
16
  export default function BlockLockToolbar( { clientId } ) {
17
17
  const blockInformation = useBlockDisplayInformation( clientId );
18
- const { canEdit, canMove, canRemove, canLock } = useBlockLock( clientId );
18
+ const { canMove, canRemove, canLock } = useBlockLock( clientId );
19
19
 
20
20
  const [ isModalOpen, toggleModal ] = useReducer(
21
21
  ( isActive ) => ! isActive,
@@ -26,7 +26,7 @@ export default function BlockLockToolbar( { clientId } ) {
26
26
  return null;
27
27
  }
28
28
 
29
- if ( canEdit && canMove && canRemove ) {
29
+ if ( canMove && canRemove ) {
30
30
  return null;
31
31
  }
32
32
 
@@ -19,7 +19,6 @@ export default function useBlockLock( clientId ) {
19
19
  return useSelect(
20
20
  ( select ) => {
21
21
  const {
22
- canEditBlock,
23
22
  canMoveBlock,
24
23
  canRemoveBlock,
25
24
  canLockBlockType,
@@ -28,16 +27,14 @@ export default function useBlockLock( clientId ) {
28
27
  } = select( blockEditorStore );
29
28
  const rootClientId = getBlockRootClientId( clientId );
30
29
 
31
- const canEdit = canEditBlock( clientId );
32
30
  const canMove = canMoveBlock( clientId, rootClientId );
33
31
  const canRemove = canRemoveBlock( clientId, rootClientId );
34
32
 
35
33
  return {
36
- canEdit,
37
34
  canMove,
38
35
  canRemove,
39
36
  canLock: canLockBlockType( getBlockName( clientId ) ),
40
- isLocked: ! canEdit || ! canMove || ! canRemove,
37
+ isLocked: ! canMove || ! canRemove,
41
38
  };
42
39
  },
43
40
  [ clientId ]
@@ -30,6 +30,7 @@ const defaultRenderToggle = ( {
30
30
  blockTitle,
31
31
  hasSingleBlockType,
32
32
  toggleProps = {},
33
+ prioritizePatterns,
33
34
  } ) => {
34
35
  let label;
35
36
  if ( hasSingleBlockType ) {
@@ -38,6 +39,8 @@ const defaultRenderToggle = ( {
38
39
  _x( 'Add %s', 'directly add the only allowed block' ),
39
40
  blockTitle
40
41
  );
42
+ } else if ( prioritizePatterns ) {
43
+ label = __( 'Add pattern' );
41
44
  } else {
42
45
  label = _x( 'Add block', 'Generic label for block inserter button' );
43
46
  }
@@ -106,6 +109,7 @@ class Inserter extends Component {
106
109
  toggleProps,
107
110
  hasItems,
108
111
  renderToggle = defaultRenderToggle,
112
+ prioritizePatterns,
109
113
  } = this.props;
110
114
 
111
115
  return renderToggle( {
@@ -116,6 +120,7 @@ class Inserter extends Component {
116
120
  hasSingleBlockType,
117
121
  directInsertBlock,
118
122
  toggleProps,
123
+ prioritizePatterns,
119
124
  } );
120
125
  }
121
126
 
@@ -138,6 +143,7 @@ class Inserter extends Component {
138
143
  // This prop is experimental to give some time for the quick inserter to mature
139
144
  // Feel free to make them stable after a few releases.
140
145
  __experimentalIsQuick: isQuick,
146
+ prioritizePatterns,
141
147
  } = this.props;
142
148
 
143
149
  if ( isQuick ) {
@@ -149,6 +155,7 @@ class Inserter extends Component {
149
155
  rootClientId={ rootClientId }
150
156
  clientId={ clientId }
151
157
  isAppender={ isAppender }
158
+ prioritizePatterns={ prioritizePatterns }
152
159
  />
153
160
  );
154
161
  }
@@ -206,7 +213,11 @@ export default compose( [
206
213
  hasInserterItems,
207
214
  __experimentalGetAllowedBlocks,
208
215
  __experimentalGetDirectInsertBlock,
216
+ getBlockIndex,
217
+ getBlockCount,
218
+ getSettings,
209
219
  } = select( blockEditorStore );
220
+
210
221
  const { getBlockVariations } = select( blocksStore );
211
222
 
212
223
  rootClientId =
@@ -218,6 +229,10 @@ export default compose( [
218
229
  rootClientId
219
230
  );
220
231
 
232
+ const index = getBlockIndex( clientId );
233
+ const blockCount = getBlockCount();
234
+ const settings = getSettings();
235
+
221
236
  const hasSingleBlockType =
222
237
  size( allowedBlocks ) === 1 &&
223
238
  size(
@@ -236,6 +251,11 @@ export default compose( [
236
251
  allowedBlockType,
237
252
  directInsertBlock,
238
253
  rootClientId,
254
+ prioritizePatterns:
255
+ settings.__experimentalPreferPatternsOnRoot &&
256
+ ! rootClientId &&
257
+ index > 0 &&
258
+ ( index < blockCount || blockCount === 0 ),
239
259
  };
240
260
  } ),
241
261
  withDispatch( ( dispatch, ownProps, { select } ) => {
@@ -30,6 +30,7 @@ export default function QuickInserter( {
30
30
  rootClientId,
31
31
  clientId,
32
32
  isAppender,
33
+ prioritizePatterns,
33
34
  } ) {
34
35
  const [ filterValue, setFilterValue ] = useState( '' );
35
36
  const [ destinationRootClientId, onInsertBlocks ] = useInsertionPoint( {
@@ -48,11 +49,7 @@ export default function QuickInserter( {
48
49
  destinationRootClientId
49
50
  );
50
51
 
51
- const {
52
- setInserterIsOpened,
53
- insertionIndex,
54
- prioritizePatterns,
55
- } = useSelect(
52
+ const { setInserterIsOpened, insertionIndex } = useSelect(
56
53
  ( select ) => {
57
54
  const { getSettings, getBlockIndex, getBlockCount } = select(
58
55
  blockEditorStore
@@ -63,15 +60,10 @@ export default function QuickInserter( {
63
60
 
64
61
  return {
65
62
  setInserterIsOpened: settings.__experimentalSetIsInserterOpened,
66
- prioritizePatterns:
67
- settings.__experimentalPreferPatternsOnRoot &&
68
- ! rootClientId &&
69
- index > 0 &&
70
- ( index < blockCount || blockCount === 0 ),
71
63
  insertionIndex: index === -1 ? blockCount : index,
72
64
  };
73
65
  },
74
- [ clientId, rootClientId ]
66
+ [ clientId ]
75
67
  );
76
68
 
77
69
  const showPatterns =
@@ -11,10 +11,9 @@ import { store as blockEditorStore } from '../../store';
11
11
  import { getBlockClientId } from '../../utils/dom';
12
12
 
13
13
  export default function useClickSelection() {
14
- const { multiSelect, selectBlock } = useDispatch( blockEditorStore );
14
+ const { selectBlock } = useDispatch( blockEditorStore );
15
15
  const {
16
16
  isSelectionEnabled,
17
- getBlockParents,
18
17
  getBlockSelectionStart,
19
18
  hasMultiSelection,
20
19
  } = useSelect( blockEditorStore );
@@ -54,10 +53,8 @@ export default function useClickSelection() {
54
53
  };
55
54
  },
56
55
  [
57
- multiSelect,
58
56
  selectBlock,
59
57
  isSelectionEnabled,
60
- getBlockParents,
61
58
  getBlockSelectionStart,
62
59
  hasMultiSelection,
63
60
  ]
@@ -76,43 +76,81 @@ export default function useSelectionObserver() {
76
76
  const { multiSelect, selectBlock, selectionChange } = useDispatch(
77
77
  blockEditorStore
78
78
  );
79
- const { getBlockParents } = useSelect( blockEditorStore );
79
+ const { getBlockParents, getBlockSelectionStart } = useSelect(
80
+ blockEditorStore
81
+ );
80
82
  return useRefEffect(
81
83
  ( node ) => {
82
84
  const { ownerDocument } = node;
83
85
  const { defaultView } = ownerDocument;
84
86
 
85
- function onSelectionChange() {
87
+ function onSelectionChange( event ) {
86
88
  const selection = defaultView.getSelection();
87
-
88
89
  // If no selection is found, end multi selection and disable the
89
90
  // contentEditable wrapper.
90
- if ( ! selection.rangeCount || selection.isCollapsed ) {
91
+ if ( ! selection.rangeCount ) {
92
+ setContentEditableWrapper( node, false );
93
+ return;
94
+ }
95
+ // If selection is collapsed and we haven't used `shift+click`,
96
+ // end multi selection and disable the contentEditable wrapper.
97
+ // We have to check about `shift+click` case because elements
98
+ // that don't support text selection might be involved, and we might
99
+ // update the clientIds to multi-select blocks.
100
+ // For now we check if the event is a `mouse` event.
101
+ const isClickShift = event.shiftKey && event.type === 'mouseup';
102
+ if ( selection.isCollapsed && ! isClickShift ) {
91
103
  setContentEditableWrapper( node, false );
92
104
  return;
93
105
  }
94
106
 
95
- const clientId = getBlockClientId(
107
+ let startClientId = getBlockClientId(
96
108
  extractSelectionStartNode( selection )
97
109
  );
98
- const endClientId = getBlockClientId(
110
+ let endClientId = getBlockClientId(
99
111
  extractSelectionEndNode( selection )
100
112
  );
113
+ // If the selection has changed and we had pressed `shift+click`,
114
+ // we need to check if in an element that doesn't support
115
+ // text selection has been clicked.
116
+ if ( isClickShift ) {
117
+ const selectedClientId = getBlockSelectionStart();
118
+ const clickedClientId = getBlockClientId( event.target );
119
+ // `endClientId` is not defined if we end the selection by clicking a non-selectable block.
120
+ // We need to check if there was already a selection with a non-selectable focusNode.
121
+ const focusNodeIsNonSelectable =
122
+ clickedClientId !== endClientId;
123
+ if (
124
+ ( startClientId === endClientId &&
125
+ selection.isCollapsed ) ||
126
+ ! endClientId ||
127
+ focusNodeIsNonSelectable
128
+ ) {
129
+ endClientId = clickedClientId;
130
+ }
131
+ // Handle the case when we have a non-selectable block
132
+ // selected and click another one.
133
+ if ( startClientId !== selectedClientId ) {
134
+ startClientId = selectedClientId;
135
+ }
136
+ }
101
137
 
102
- // If the selection did not involve a block, return early.
103
- if ( clientId === undefined && endClientId === undefined ) {
138
+ // If the selection did not involve a block, return.
139
+ if (
140
+ startClientId === undefined &&
141
+ endClientId === undefined
142
+ ) {
104
143
  setContentEditableWrapper( node, false );
105
144
  return;
106
145
  }
107
146
 
108
- const isSingularSelection = clientId === endClientId;
109
-
147
+ const isSingularSelection = startClientId === endClientId;
110
148
  if ( isSingularSelection ) {
111
- selectBlock( clientId );
149
+ selectBlock( startClientId );
112
150
  } else {
113
151
  const startPath = [
114
- ...getBlockParents( clientId ),
115
- clientId,
152
+ ...getBlockParents( startClientId ),
153
+ startClientId,
116
154
  ];
117
155
  const endPath = [
118
156
  ...getBlockParents( endClientId ),
@@ -1695,26 +1695,6 @@ export function canMoveBlocks( state, clientIds, rootClientId = null ) {
1695
1695
  );
1696
1696
  }
1697
1697
 
1698
- /**
1699
- * Determines if the given block is allowed to be edited.
1700
- *
1701
- * @param {Object} state Editor state.
1702
- * @param {string} clientId The block client Id.
1703
- *
1704
- * @return {boolean} Whether the given block is allowed to be edited.
1705
- */
1706
- export function canEditBlock( state, clientId ) {
1707
- const attributes = getBlockAttributes( state, clientId );
1708
- if ( attributes === null ) {
1709
- return true;
1710
- }
1711
-
1712
- const { lock } = attributes;
1713
-
1714
- // When the edit is true, we cannot edit the block.
1715
- return ! lock?.edit;
1716
- }
1717
-
1718
1698
  /**
1719
1699
  * Determines if the given block type can be locked/unlocked by a user.
1720
1700
  *