@wordpress/block-editor 14.8.0 → 14.8.1-next.cd6172eb0.0

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 (249) hide show
  1. package/build/autocompleters/block.js +2 -4
  2. package/build/autocompleters/block.js.map +1 -1
  3. package/build/autocompleters/link.js +2 -4
  4. package/build/autocompleters/link.js.map +1 -1
  5. package/build/components/block-canvas/index.js +3 -6
  6. package/build/components/block-canvas/index.js.map +1 -1
  7. package/build/components/block-list/block.js +6 -5
  8. package/build/components/block-list/block.js.map +1 -1
  9. package/build/components/block-list/index.js +0 -1
  10. package/build/components/block-list/index.js.map +1 -1
  11. package/build/components/block-list/use-block-props/index.js +7 -2
  12. package/build/components/block-list/use-block-props/index.js.map +1 -1
  13. package/build/components/block-list/use-block-props/use-firefox-draggable-compatibility.js +34 -0
  14. package/build/components/block-list/use-block-props/use-firefox-draggable-compatibility.js.map +1 -0
  15. package/build/components/block-list/use-block-props/use-selected-block-event-handlers.js +98 -5
  16. package/build/components/block-list/use-block-props/use-selected-block-event-handlers.js.map +1 -1
  17. package/build/components/block-patterns-list/index.js +13 -4
  18. package/build/components/block-patterns-list/index.js.map +1 -1
  19. package/build/components/block-popover/inbetween.js +4 -0
  20. package/build/components/block-popover/inbetween.js.map +1 -1
  21. package/build/components/block-settings-menu/block-settings-dropdown.js +7 -4
  22. package/build/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  23. package/build/components/block-settings-menu-controls/index.js +1 -1
  24. package/build/components/block-settings-menu-controls/index.js.map +1 -1
  25. package/build/components/block-switcher/index.js +12 -22
  26. package/build/components/block-switcher/index.js.map +1 -1
  27. package/build/components/block-switcher/use-transformed-patterns.js +0 -1
  28. package/build/components/block-switcher/use-transformed-patterns.js.map +1 -1
  29. package/build/components/block-switcher/utils.js +0 -1
  30. package/build/components/block-switcher/utils.js.map +1 -1
  31. package/build/components/block-toolbar/index.js +7 -6
  32. package/build/components/block-toolbar/index.js.map +1 -1
  33. package/build/components/block-variation-transforms/index.js +0 -1
  34. package/build/components/block-variation-transforms/index.js.map +1 -1
  35. package/build/components/date-format-picker/index.js +0 -1
  36. package/build/components/date-format-picker/index.js.map +1 -1
  37. package/build/components/font-appearance-control/index.js +1 -0
  38. package/build/components/font-appearance-control/index.js.map +1 -1
  39. package/build/components/font-family/index.js +10 -0
  40. package/build/components/font-family/index.js.map +1 -1
  41. package/build/components/global-styles/dimensions-panel.js +17 -16
  42. package/build/components/global-styles/dimensions-panel.js.map +1 -1
  43. package/build/components/global-styles/get-global-styles-changes.js +0 -1
  44. package/build/components/global-styles/get-global-styles-changes.js.map +1 -1
  45. package/build/components/iframe/use-scale-canvas.js +68 -47
  46. package/build/components/iframe/use-scale-canvas.js.map +1 -1
  47. package/build/components/inserter/block-patterns-tab/index.js +0 -10
  48. package/build/components/inserter/block-patterns-tab/index.js.map +1 -1
  49. package/build/components/inserter/menu.js +2 -1
  50. package/build/components/inserter/menu.js.map +1 -1
  51. package/build/components/inserter-draggable-blocks/index.js +19 -10
  52. package/build/components/inserter-draggable-blocks/index.js.map +1 -1
  53. package/build/components/letter-spacing-control/index.js +10 -0
  54. package/build/components/letter-spacing-control/index.js.map +1 -1
  55. package/build/components/line-height-control/index.js +1 -0
  56. package/build/components/line-height-control/index.js.map +1 -1
  57. package/build/components/media-placeholder/index.js +18 -18
  58. package/build/components/media-placeholder/index.js.map +1 -1
  59. package/build/components/observe-typing/index.js +0 -1
  60. package/build/components/observe-typing/index.js.map +1 -1
  61. package/build/components/recursion-provider/index.js +0 -1
  62. package/build/components/recursion-provider/index.js.map +1 -1
  63. package/build/components/rich-text/index.js +5 -1
  64. package/build/components/rich-text/index.js.map +1 -1
  65. package/build/components/rich-text/native/use-format-types.js +0 -1
  66. package/build/components/rich-text/native/use-format-types.js.map +1 -1
  67. package/build/components/rich-text/use-format-types.js +0 -1
  68. package/build/components/rich-text/use-format-types.js.map +1 -1
  69. package/build/components/spacing-sizes-control/utils.js +0 -1
  70. package/build/components/spacing-sizes-control/utils.js.map +1 -1
  71. package/build/components/typewriter/index.js +0 -1
  72. package/build/components/typewriter/index.js.map +1 -1
  73. package/build/components/use-block-drop-zone/index.js +11 -2
  74. package/build/components/use-block-drop-zone/index.js.map +1 -1
  75. package/build/components/use-moving-animation/index.js +15 -2
  76. package/build/components/use-moving-animation/index.js.map +1 -1
  77. package/build/components/use-resize-canvas/index.js +1 -1
  78. package/build/components/use-resize-canvas/index.js.map +1 -1
  79. package/build/components/writing-flow/use-drag-selection.js +11 -0
  80. package/build/components/writing-flow/use-drag-selection.js.map +1 -1
  81. package/build/components/writing-flow/use-tab-nav.js +6 -2
  82. package/build/components/writing-flow/use-tab-nav.js.map +1 -1
  83. package/build/hooks/block-bindings.js +4 -3
  84. package/build/hooks/block-bindings.js.map +1 -1
  85. package/build/hooks/gap.js +1 -1
  86. package/build/hooks/gap.js.map +1 -1
  87. package/build/hooks/generated-class-name.js +0 -1
  88. package/build/hooks/generated-class-name.js.map +1 -1
  89. package/build/store/private-selectors.js +1 -7
  90. package/build/store/private-selectors.js.map +1 -1
  91. package/build/store/reducer.js +478 -2
  92. package/build/store/reducer.js.map +1 -1
  93. package/build/store/selectors.js +12 -55
  94. package/build/store/selectors.js.map +1 -1
  95. package/build/utils/object.js +0 -1
  96. package/build/utils/object.js.map +1 -1
  97. package/build-module/autocompleters/block.js +2 -4
  98. package/build-module/autocompleters/block.js.map +1 -1
  99. package/build-module/autocompleters/link.js +2 -4
  100. package/build-module/autocompleters/link.js.map +1 -1
  101. package/build-module/components/block-canvas/index.js +3 -6
  102. package/build-module/components/block-canvas/index.js.map +1 -1
  103. package/build-module/components/block-list/block.js +8 -7
  104. package/build-module/components/block-list/block.js.map +1 -1
  105. package/build-module/components/block-list/index.js +0 -1
  106. package/build-module/components/block-list/index.js.map +1 -1
  107. package/build-module/components/block-list/use-block-props/index.js +7 -2
  108. package/build-module/components/block-list/use-block-props/index.js.map +1 -1
  109. package/build-module/components/block-list/use-block-props/use-firefox-draggable-compatibility.js +28 -0
  110. package/build-module/components/block-list/use-block-props/use-firefox-draggable-compatibility.js.map +1 -0
  111. package/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.js +97 -5
  112. package/build-module/components/block-list/use-block-props/use-selected-block-event-handlers.js.map +1 -1
  113. package/build-module/components/block-patterns-list/index.js +13 -4
  114. package/build-module/components/block-patterns-list/index.js.map +1 -1
  115. package/build-module/components/block-popover/inbetween.js +4 -0
  116. package/build-module/components/block-popover/inbetween.js.map +1 -1
  117. package/build-module/components/block-settings-menu/block-settings-dropdown.js +7 -4
  118. package/build-module/components/block-settings-menu/block-settings-dropdown.js.map +1 -1
  119. package/build-module/components/block-settings-menu-controls/index.js +1 -1
  120. package/build-module/components/block-settings-menu-controls/index.js.map +1 -1
  121. package/build-module/components/block-switcher/index.js +13 -23
  122. package/build-module/components/block-switcher/index.js.map +1 -1
  123. package/build-module/components/block-switcher/use-transformed-patterns.js +0 -1
  124. package/build-module/components/block-switcher/use-transformed-patterns.js.map +1 -1
  125. package/build-module/components/block-switcher/utils.js +0 -1
  126. package/build-module/components/block-switcher/utils.js.map +1 -1
  127. package/build-module/components/block-toolbar/index.js +7 -6
  128. package/build-module/components/block-toolbar/index.js.map +1 -1
  129. package/build-module/components/block-variation-transforms/index.js +0 -1
  130. package/build-module/components/block-variation-transforms/index.js.map +1 -1
  131. package/build-module/components/date-format-picker/index.js +0 -1
  132. package/build-module/components/date-format-picker/index.js.map +1 -1
  133. package/build-module/components/font-appearance-control/index.js +1 -0
  134. package/build-module/components/font-appearance-control/index.js.map +1 -1
  135. package/build-module/components/font-family/index.js +10 -0
  136. package/build-module/components/font-family/index.js.map +1 -1
  137. package/build-module/components/global-styles/dimensions-panel.js +17 -16
  138. package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
  139. package/build-module/components/global-styles/get-global-styles-changes.js +0 -1
  140. package/build-module/components/global-styles/get-global-styles-changes.js.map +1 -1
  141. package/build-module/components/iframe/use-scale-canvas.js +68 -47
  142. package/build-module/components/iframe/use-scale-canvas.js.map +1 -1
  143. package/build-module/components/inserter/block-patterns-tab/index.js +1 -11
  144. package/build-module/components/inserter/block-patterns-tab/index.js.map +1 -1
  145. package/build-module/components/inserter/menu.js +2 -1
  146. package/build-module/components/inserter/menu.js.map +1 -1
  147. package/build-module/components/inserter-draggable-blocks/index.js +20 -11
  148. package/build-module/components/inserter-draggable-blocks/index.js.map +1 -1
  149. package/build-module/components/letter-spacing-control/index.js +9 -0
  150. package/build-module/components/letter-spacing-control/index.js.map +1 -1
  151. package/build-module/components/line-height-control/index.js +1 -0
  152. package/build-module/components/line-height-control/index.js.map +1 -1
  153. package/build-module/components/media-placeholder/index.js +18 -18
  154. package/build-module/components/media-placeholder/index.js.map +1 -1
  155. package/build-module/components/observe-typing/index.js +0 -1
  156. package/build-module/components/observe-typing/index.js.map +1 -1
  157. package/build-module/components/recursion-provider/index.js +0 -1
  158. package/build-module/components/recursion-provider/index.js.map +1 -1
  159. package/build-module/components/rich-text/index.js +5 -1
  160. package/build-module/components/rich-text/index.js.map +1 -1
  161. package/build-module/components/rich-text/native/use-format-types.js +0 -1
  162. package/build-module/components/rich-text/native/use-format-types.js.map +1 -1
  163. package/build-module/components/rich-text/use-format-types.js +0 -1
  164. package/build-module/components/rich-text/use-format-types.js.map +1 -1
  165. package/build-module/components/spacing-sizes-control/utils.js +0 -1
  166. package/build-module/components/spacing-sizes-control/utils.js.map +1 -1
  167. package/build-module/components/typewriter/index.js +0 -1
  168. package/build-module/components/typewriter/index.js.map +1 -1
  169. package/build-module/components/use-block-drop-zone/index.js +11 -2
  170. package/build-module/components/use-block-drop-zone/index.js.map +1 -1
  171. package/build-module/components/use-moving-animation/index.js +15 -2
  172. package/build-module/components/use-moving-animation/index.js.map +1 -1
  173. package/build-module/components/use-resize-canvas/index.js +1 -1
  174. package/build-module/components/use-resize-canvas/index.js.map +1 -1
  175. package/build-module/components/writing-flow/use-drag-selection.js +11 -0
  176. package/build-module/components/writing-flow/use-drag-selection.js.map +1 -1
  177. package/build-module/components/writing-flow/use-tab-nav.js +6 -2
  178. package/build-module/components/writing-flow/use-tab-nav.js.map +1 -1
  179. package/build-module/hooks/block-bindings.js +4 -3
  180. package/build-module/hooks/block-bindings.js.map +1 -1
  181. package/build-module/hooks/gap.js +1 -1
  182. package/build-module/hooks/gap.js.map +1 -1
  183. package/build-module/hooks/generated-class-name.js +0 -1
  184. package/build-module/hooks/generated-class-name.js.map +1 -1
  185. package/build-module/store/private-selectors.js +1 -6
  186. package/build-module/store/private-selectors.js.map +1 -1
  187. package/build-module/store/reducer.js +479 -3
  188. package/build-module/store/reducer.js.map +1 -1
  189. package/build-module/store/selectors.js +12 -55
  190. package/build-module/store/selectors.js.map +1 -1
  191. package/build-module/utils/object.js +0 -1
  192. package/build-module/utils/object.js.map +1 -1
  193. package/build-style/content-rtl.css +17 -4
  194. package/build-style/content.css +17 -4
  195. package/build-style/style-rtl.css +21 -16
  196. package/build-style/style.css +21 -16
  197. package/package.json +32 -32
  198. package/src/autocompleters/block.js +2 -4
  199. package/src/autocompleters/link.js +2 -4
  200. package/src/components/alignment-control/stories/aliginment-toolbar.story.js +47 -0
  201. package/src/components/alignment-control/stories/index.story.js +51 -0
  202. package/src/components/alignment-control/test/__snapshots__/index.js.snap +5 -5
  203. package/src/components/block-alignment-control/test/__snapshots__/index.js.snap +4 -4
  204. package/src/components/block-canvas/index.js +3 -5
  205. package/src/components/block-draggable/content.scss +11 -5
  206. package/src/components/block-list/block.js +7 -13
  207. package/src/components/block-list/content.scss +6 -0
  208. package/src/components/block-list/use-block-props/index.js +7 -0
  209. package/src/components/block-list/use-block-props/use-firefox-draggable-compatibility.js +25 -0
  210. package/src/components/block-list/use-block-props/use-selected-block-event-handlers.js +112 -8
  211. package/src/components/block-patterns-list/index.js +12 -1
  212. package/src/components/block-patterns-list/style.scss +16 -5
  213. package/src/components/block-popover/inbetween.js +4 -0
  214. package/src/components/block-settings-menu/block-settings-dropdown.js +6 -1
  215. package/src/components/block-settings-menu-controls/index.js +2 -1
  216. package/src/components/block-switcher/index.js +19 -21
  217. package/src/components/block-switcher/style.scss +0 -9
  218. package/src/components/block-title/test/index.js +2 -0
  219. package/src/components/block-toolbar/index.js +8 -6
  220. package/src/components/block-tools/style.scss +5 -0
  221. package/src/components/block-vertical-alignment-control/test/__snapshots__/index.js.snap +3 -3
  222. package/src/components/font-appearance-control/index.js +1 -0
  223. package/src/components/font-family/index.js +10 -0
  224. package/src/components/font-family/style.scss +5 -0
  225. package/src/components/global-styles/dimensions-panel.js +16 -16
  226. package/src/components/iframe/content.scss +6 -1
  227. package/src/components/iframe/use-scale-canvas.js +103 -81
  228. package/src/components/inserter/block-patterns-tab/index.js +1 -17
  229. package/src/components/inserter/menu.js +8 -1
  230. package/src/components/inserter-draggable-blocks/index.js +19 -29
  231. package/src/components/letter-spacing-control/README.md +2 -1
  232. package/src/components/letter-spacing-control/index.js +17 -0
  233. package/src/components/line-height-control/index.js +1 -0
  234. package/src/components/media-placeholder/index.js +25 -28
  235. package/src/components/rich-text/index.js +5 -0
  236. package/src/components/use-block-drop-zone/index.js +18 -1
  237. package/src/components/use-moving-animation/index.js +15 -0
  238. package/src/components/use-resize-canvas/index.js +1 -1
  239. package/src/components/writing-flow/use-drag-selection.js +11 -0
  240. package/src/components/writing-flow/use-tab-nav.js +9 -6
  241. package/src/hooks/block-bindings.js +8 -4
  242. package/src/hooks/gap.js +1 -1
  243. package/src/store/private-selectors.js +2 -17
  244. package/src/store/reducer.js +639 -2
  245. package/src/store/selectors.js +19 -69
  246. package/src/store/test/private-selectors.js +1 -0
  247. package/src/store/test/reducer.js +849 -0
  248. package/src/store/test/selectors.js +4 -110
  249. package/src/style.scss +1 -0
@@ -10,7 +10,10 @@ import {
10
10
  registerBlockType,
11
11
  unregisterBlockType,
12
12
  createBlock,
13
+ privateApis,
13
14
  } from '@wordpress/blocks';
15
+ import { combineReducers, select } from '@wordpress/data';
16
+ import { store as preferencesStore } from '@wordpress/preferences';
14
17
 
15
18
  /**
16
19
  * Internal dependencies
@@ -38,8 +41,30 @@ import {
38
41
  blockEditingModes,
39
42
  openedBlockSettingsMenu,
40
43
  expandedBlock,
44
+ zoomLevel,
45
+ withDerivedBlockEditingModes,
41
46
  } from '../reducer';
42
47
 
48
+ import { unlock } from '../../lock-unlock';
49
+ import { sectionRootClientIdKey } from '.././private-keys';
50
+
51
+ const { isContentBlock } = unlock( privateApis );
52
+
53
+ jest.mock( '@wordpress/data/src/select', () => {
54
+ const actualSelect = jest.requireActual( '@wordpress/data/src/select' );
55
+
56
+ return {
57
+ select: jest.fn( ( ...args ) => actualSelect.select( ...args ) ),
58
+ };
59
+ } );
60
+
61
+ jest.mock( '@wordpress/blocks/src/api/utils', () => {
62
+ return {
63
+ ...jest.requireActual( '@wordpress/blocks/src/api/utils' ),
64
+ isContentBlock: jest.fn(),
65
+ };
66
+ } );
67
+
43
68
  const noop = () => {};
44
69
 
45
70
  describe( 'state', () => {
@@ -3544,4 +3569,828 @@ describe( 'state', () => {
3544
3569
  expect( state ).toBe( null );
3545
3570
  } );
3546
3571
  } );
3572
+
3573
+ describe( 'withDerivedBlockEditingModes', () => {
3574
+ const testReducer = withDerivedBlockEditingModes(
3575
+ combineReducers( {
3576
+ blocks,
3577
+ settings,
3578
+ zoomLevel,
3579
+ } )
3580
+ );
3581
+
3582
+ function dispatchActions( actions, reducer, initialState = {} ) {
3583
+ return actions.reduce( ( _state, action ) => {
3584
+ return reducer( _state, action );
3585
+ }, initialState );
3586
+ }
3587
+
3588
+ beforeEach( () => {
3589
+ isContentBlock.mockImplementation(
3590
+ ( blockName ) => blockName === 'core/paragraph'
3591
+ );
3592
+ } );
3593
+
3594
+ afterAll( () => {
3595
+ isContentBlock.mockRestore();
3596
+ } );
3597
+
3598
+ describe( 'edit mode', () => {
3599
+ let initialState;
3600
+ beforeAll( () => {
3601
+ select.mockImplementation( ( storeName ) => {
3602
+ if ( storeName === preferencesStore ) {
3603
+ return {
3604
+ get: jest.fn( () => 'edit' ),
3605
+ };
3606
+ }
3607
+ return select( storeName );
3608
+ } );
3609
+
3610
+ initialState = dispatchActions(
3611
+ [
3612
+ {
3613
+ type: 'UPDATE_SETTINGS',
3614
+ settings: {
3615
+ [ sectionRootClientIdKey ]: '',
3616
+ },
3617
+ },
3618
+ {
3619
+ type: 'RESET_BLOCKS',
3620
+ blocks: [
3621
+ {
3622
+ name: 'core/group',
3623
+ clientId: 'group-1',
3624
+ attributes: {},
3625
+ innerBlocks: [
3626
+ {
3627
+ name: 'core/paragraph',
3628
+ clientId: 'paragraph-1',
3629
+ attributes: {},
3630
+ innerBlocks: [],
3631
+ },
3632
+ {
3633
+ name: 'core/group',
3634
+ clientId: 'group-2',
3635
+ attributes: {},
3636
+ innerBlocks: [
3637
+ {
3638
+ name: 'core/paragraph',
3639
+ clientId: 'paragraph-2',
3640
+ attributes: {},
3641
+ innerBlocks: [],
3642
+ },
3643
+ ],
3644
+ },
3645
+ ],
3646
+ },
3647
+ ],
3648
+ },
3649
+ ],
3650
+ testReducer
3651
+ );
3652
+ } );
3653
+
3654
+ afterAll( () => {
3655
+ select.mockRestore();
3656
+ } );
3657
+
3658
+ it( 'returns no block editing modes when zoomed out / navigation mode are not active and there are no synced patterns', () => {
3659
+ expect( initialState.derivedBlockEditingModes ).toEqual(
3660
+ new Map()
3661
+ );
3662
+ } );
3663
+ } );
3664
+
3665
+ describe( 'synced patterns', () => {
3666
+ let initialState;
3667
+ beforeAll( () => {
3668
+ select.mockImplementation( ( storeName ) => {
3669
+ if ( storeName === preferencesStore ) {
3670
+ return {
3671
+ get: jest.fn( () => 'edit' ),
3672
+ };
3673
+ }
3674
+ return select( storeName );
3675
+ } );
3676
+
3677
+ // Simulates how the editor typically inserts controlled blocks,
3678
+ // - first the pattern is inserted with no inner blocks.
3679
+ // - next the pattern is marked as a controlled block.
3680
+ // - finally, once the inner blocks of the pattern are received, they're inserted.
3681
+ // This process is repeated for the two patterns in this test.
3682
+ initialState = dispatchActions(
3683
+ [
3684
+ {
3685
+ type: 'UPDATE_SETTINGS',
3686
+ settings: {
3687
+ [ sectionRootClientIdKey ]: '',
3688
+ },
3689
+ },
3690
+ {
3691
+ type: 'RESET_BLOCKS',
3692
+ blocks: [
3693
+ {
3694
+ name: 'core/group',
3695
+ clientId: 'group-1',
3696
+ attributes: {},
3697
+ innerBlocks: [
3698
+ {
3699
+ name: 'core/paragraph',
3700
+ clientId: 'paragraph-1',
3701
+ attributes: {},
3702
+ innerBlocks: [],
3703
+ },
3704
+ {
3705
+ name: 'core/group',
3706
+ clientId: 'group-2',
3707
+ attributes: {},
3708
+ innerBlocks: [
3709
+ {
3710
+ name: 'core/paragraph',
3711
+ clientId: 'paragraph-2',
3712
+ attributes: {},
3713
+ innerBlocks: [],
3714
+ },
3715
+ ],
3716
+ },
3717
+ ],
3718
+ },
3719
+ ],
3720
+ },
3721
+ {
3722
+ type: 'INSERT_BLOCKS',
3723
+ rootClientId: '',
3724
+ blocks: [
3725
+ {
3726
+ name: 'core/block',
3727
+ clientId: 'root-pattern',
3728
+ attributes: {},
3729
+ innerBlocks: [],
3730
+ },
3731
+ ],
3732
+ },
3733
+ {
3734
+ type: 'SET_HAS_CONTROLLED_INNER_BLOCKS',
3735
+ clientId: 'root-pattern',
3736
+ hasControlledInnerBlocks: true,
3737
+ },
3738
+ {
3739
+ type: 'REPLACE_INNER_BLOCKS',
3740
+ rootClientId: 'root-pattern',
3741
+ blocks: [
3742
+ {
3743
+ name: 'core/block',
3744
+ clientId: 'nested-pattern',
3745
+ attributes: {},
3746
+ innerBlocks: [],
3747
+ },
3748
+ {
3749
+ name: 'core/paragraph',
3750
+ clientId: 'pattern-paragraph',
3751
+ attributes: {},
3752
+ innerBlocks: [],
3753
+ },
3754
+ {
3755
+ name: 'core/group',
3756
+ clientId: 'pattern-group',
3757
+ attributes: {},
3758
+ innerBlocks: [
3759
+ {
3760
+ name: 'core/paragraph',
3761
+ clientId:
3762
+ 'pattern-paragraph-with-overrides',
3763
+ attributes: {
3764
+ metadata: {
3765
+ bindings: {
3766
+ __default:
3767
+ 'core/pattern-overrides',
3768
+ },
3769
+ },
3770
+ },
3771
+ innerBlocks: [],
3772
+ },
3773
+ ],
3774
+ },
3775
+ ],
3776
+ },
3777
+ {
3778
+ type: 'SET_HAS_CONTROLLED_INNER_BLOCKS',
3779
+ clientId: 'nested-pattern',
3780
+ hasControlledInnerBlocks: true,
3781
+ },
3782
+ {
3783
+ type: 'REPLACE_INNER_BLOCKS',
3784
+ rootClientId: 'nested-pattern',
3785
+ blocks: [
3786
+ {
3787
+ name: 'core/paragraph',
3788
+ clientId: 'nested-paragraph',
3789
+ attributes: {},
3790
+ innerBlocks: [],
3791
+ },
3792
+ {
3793
+ name: 'core/group',
3794
+ clientId: 'nested-group',
3795
+ attributes: {},
3796
+ innerBlocks: [
3797
+ {
3798
+ name: 'core/paragraph',
3799
+ clientId:
3800
+ 'nested-paragraph-with-overrides',
3801
+ attributes: {
3802
+ metadata: {
3803
+ bindings: {
3804
+ __default:
3805
+ 'core/pattern-overrides',
3806
+ },
3807
+ },
3808
+ },
3809
+ innerBlocks: [],
3810
+ },
3811
+ ],
3812
+ },
3813
+ ],
3814
+ },
3815
+ ],
3816
+ testReducer,
3817
+ initialState
3818
+ );
3819
+ } );
3820
+
3821
+ afterAll( () => {
3822
+ select.mockRestore();
3823
+ } );
3824
+
3825
+ it( 'returns the expected block editing modes for synced patterns', () => {
3826
+ // Only the parent pattern and its own children that have bindings
3827
+ // are in contentOnly mode. All other blocks are disabled.
3828
+ expect( initialState.derivedBlockEditingModes ).toEqual(
3829
+ new Map(
3830
+ Object.entries( {
3831
+ 'pattern-paragraph': 'disabled',
3832
+ 'pattern-group': 'disabled',
3833
+ 'pattern-paragraph-with-overrides': 'contentOnly',
3834
+ 'nested-pattern': 'disabled',
3835
+ 'nested-paragraph': 'disabled',
3836
+ 'nested-group': 'disabled',
3837
+ 'nested-paragraph-with-overrides': 'disabled',
3838
+ } )
3839
+ )
3840
+ );
3841
+ } );
3842
+
3843
+ it( 'removes block editing modes when synced patterns are removed', () => {
3844
+ const { derivedBlockEditingModes } = dispatchActions(
3845
+ [
3846
+ {
3847
+ type: 'REMOVE_BLOCKS',
3848
+ clientIds: [ 'root-pattern' ],
3849
+ },
3850
+ ],
3851
+ testReducer,
3852
+ initialState
3853
+ );
3854
+
3855
+ expect( derivedBlockEditingModes ).toEqual( new Map() );
3856
+ } );
3857
+
3858
+ it( 'returns the expected block editing modes for synced patterns when switching to navigation mode', () => {
3859
+ select.mockImplementation( ( storeName ) => {
3860
+ if ( storeName === preferencesStore ) {
3861
+ return {
3862
+ get: jest.fn( () => 'navigation' ),
3863
+ };
3864
+ }
3865
+ return select( storeName );
3866
+ } );
3867
+
3868
+ const {
3869
+ derivedBlockEditingModes,
3870
+ derivedNavModeBlockEditingModes,
3871
+ } = dispatchActions(
3872
+ [
3873
+ {
3874
+ type: 'SET_EDITOR_MODE',
3875
+ mode: 'navigation',
3876
+ },
3877
+ ],
3878
+ testReducer,
3879
+ initialState
3880
+ );
3881
+
3882
+ expect( derivedBlockEditingModes ).toEqual(
3883
+ new Map(
3884
+ Object.entries( {
3885
+ 'pattern-paragraph': 'disabled',
3886
+ 'pattern-group': 'disabled',
3887
+ 'pattern-paragraph-with-overrides': 'contentOnly', // Pattern child with bindings.
3888
+ 'nested-pattern': 'disabled',
3889
+ 'nested-paragraph': 'disabled',
3890
+ 'nested-group': 'disabled',
3891
+ 'nested-paragraph-with-overrides': 'disabled',
3892
+ } )
3893
+ )
3894
+ );
3895
+
3896
+ expect( derivedNavModeBlockEditingModes ).toEqual(
3897
+ new Map(
3898
+ Object.entries( {
3899
+ '': 'contentOnly', // Section root.
3900
+ 'group-1': 'contentOnly', // Section.
3901
+ 'paragraph-1': 'contentOnly', // Content block in section.
3902
+ 'group-2': 'disabled',
3903
+ 'paragraph-2': 'contentOnly', // Content block in section.
3904
+ 'root-pattern': 'contentOnly', // Section.
3905
+ 'pattern-paragraph': 'disabled',
3906
+ 'pattern-group': 'disabled',
3907
+ 'pattern-paragraph-with-overrides': 'contentOnly', // Pattern child with bindings.
3908
+ 'nested-pattern': 'disabled',
3909
+ 'nested-paragraph': 'disabled',
3910
+ 'nested-group': 'disabled',
3911
+ 'nested-paragraph-with-overrides': 'disabled',
3912
+ } )
3913
+ )
3914
+ );
3915
+
3916
+ select.mockImplementation( ( storeName ) => {
3917
+ if ( storeName === preferencesStore ) {
3918
+ return {
3919
+ get: jest.fn( () => 'edit' ),
3920
+ };
3921
+ }
3922
+ return select( storeName );
3923
+ } );
3924
+ } );
3925
+
3926
+ it( 'returns the expected block editing modes for synced patterns when switching to zoomed out mode', () => {
3927
+ const { derivedBlockEditingModes } = dispatchActions(
3928
+ [
3929
+ {
3930
+ type: 'SET_ZOOM_LEVEL',
3931
+ zoom: 'auto-scaled',
3932
+ },
3933
+ ],
3934
+ testReducer,
3935
+ initialState
3936
+ );
3937
+
3938
+ expect( derivedBlockEditingModes ).toEqual(
3939
+ new Map(
3940
+ Object.entries( {
3941
+ '': 'contentOnly', // Section root.
3942
+ 'group-1': 'contentOnly', // Section.
3943
+ 'paragraph-1': 'disabled',
3944
+ 'group-2': 'disabled',
3945
+ 'paragraph-2': 'disabled',
3946
+ 'root-pattern': 'contentOnly', // Pattern and section.
3947
+ 'pattern-paragraph': 'disabled',
3948
+ 'pattern-group': 'disabled',
3949
+ 'pattern-paragraph-with-overrides': 'disabled',
3950
+ 'nested-pattern': 'disabled',
3951
+ 'nested-paragraph': 'disabled',
3952
+ 'nested-group': 'disabled',
3953
+ 'nested-paragraph-with-overrides': 'disabled',
3954
+ } )
3955
+ )
3956
+ );
3957
+ } );
3958
+ } );
3959
+
3960
+ describe( 'navigation mode', () => {
3961
+ let initialState;
3962
+
3963
+ beforeAll( () => {
3964
+ select.mockImplementation( ( storeName ) => {
3965
+ if ( storeName === preferencesStore ) {
3966
+ return {
3967
+ get: jest.fn( () => 'navigation' ),
3968
+ };
3969
+ }
3970
+ return select( storeName );
3971
+ } );
3972
+
3973
+ initialState = dispatchActions(
3974
+ [
3975
+ {
3976
+ type: 'UPDATE_SETTINGS',
3977
+ settings: {
3978
+ [ sectionRootClientIdKey ]: '',
3979
+ },
3980
+ },
3981
+ {
3982
+ type: 'RESET_BLOCKS',
3983
+ blocks: [
3984
+ {
3985
+ name: 'core/group',
3986
+ clientId: 'group-1',
3987
+ attributes: {},
3988
+ innerBlocks: [
3989
+ {
3990
+ name: 'core/paragraph',
3991
+ clientId: 'paragraph-1',
3992
+ attributes: {},
3993
+ innerBlocks: [],
3994
+ },
3995
+ {
3996
+ name: 'core/group',
3997
+ clientId: 'group-2',
3998
+ attributes: {},
3999
+ innerBlocks: [
4000
+ {
4001
+ name: 'core/paragraph',
4002
+ clientId: 'paragraph-2',
4003
+ attributes: {},
4004
+ innerBlocks: [],
4005
+ },
4006
+ ],
4007
+ },
4008
+ ],
4009
+ },
4010
+ ],
4011
+ },
4012
+ ],
4013
+ testReducer
4014
+ );
4015
+ } );
4016
+
4017
+ afterAll( () => {
4018
+ select.mockRestore();
4019
+ } );
4020
+
4021
+ it( 'returns the expected block editing modes', () => {
4022
+ expect( initialState.derivedNavModeBlockEditingModes ).toEqual(
4023
+ new Map(
4024
+ Object.entries( {
4025
+ '': 'contentOnly', // Section root.
4026
+ 'group-1': 'contentOnly', // Section block.
4027
+ 'paragraph-1': 'contentOnly', // Content block in section.
4028
+ 'group-2': 'disabled', // Non-content block in section.
4029
+ 'paragraph-2': 'contentOnly', // Content block in section.
4030
+ } )
4031
+ )
4032
+ );
4033
+ } );
4034
+
4035
+ it( 'removes block editing modes when blocks are removed', () => {
4036
+ const { derivedNavModeBlockEditingModes } = dispatchActions(
4037
+ [
4038
+ {
4039
+ type: 'REMOVE_BLOCKS',
4040
+ clientIds: [ 'group-2' ],
4041
+ },
4042
+ ],
4043
+ testReducer,
4044
+ initialState
4045
+ );
4046
+
4047
+ expect( derivedNavModeBlockEditingModes ).toEqual(
4048
+ new Map(
4049
+ Object.entries( {
4050
+ '': 'contentOnly',
4051
+ 'group-1': 'contentOnly',
4052
+ 'paragraph-1': 'contentOnly',
4053
+ } )
4054
+ )
4055
+ );
4056
+ } );
4057
+
4058
+ it( 'updates block editing modes when new blocks are inserted', () => {
4059
+ const { derivedNavModeBlockEditingModes } = dispatchActions(
4060
+ [
4061
+ {
4062
+ type: 'INSERT_BLOCKS',
4063
+ rootClientId: '',
4064
+ blocks: [
4065
+ {
4066
+ name: 'core/group',
4067
+ clientId: 'group-3',
4068
+ attributes: {},
4069
+ innerBlocks: [
4070
+ {
4071
+ name: 'core/paragraph',
4072
+ clientId: 'paragraph-3',
4073
+ attributes: {},
4074
+ innerBlocks: [],
4075
+ },
4076
+ {
4077
+ name: 'core/group',
4078
+ clientId: 'group-4',
4079
+ attributes: {},
4080
+ innerBlocks: [],
4081
+ },
4082
+ ],
4083
+ },
4084
+ ],
4085
+ },
4086
+ ],
4087
+ testReducer,
4088
+ initialState
4089
+ );
4090
+
4091
+ expect( derivedNavModeBlockEditingModes ).toEqual(
4092
+ new Map(
4093
+ Object.entries( {
4094
+ '': 'contentOnly', // Section root.
4095
+ 'group-1': 'contentOnly', // Section block.
4096
+ 'paragraph-1': 'contentOnly', // Content block in section.
4097
+ 'group-2': 'disabled', // Non-content block in section.
4098
+ 'paragraph-2': 'contentOnly', // Content block in section.
4099
+ 'group-3': 'contentOnly', // New section block.
4100
+ 'paragraph-3': 'contentOnly', // New content block in section.
4101
+ 'group-4': 'disabled', // Non-content block in section.
4102
+ } )
4103
+ )
4104
+ );
4105
+ } );
4106
+
4107
+ it( 'updates block editing modes when blocks are moved to a new position', () => {
4108
+ const { derivedNavModeBlockEditingModes } = dispatchActions(
4109
+ [
4110
+ {
4111
+ type: 'MOVE_BLOCKS_TO_POSITION',
4112
+ clientIds: [ 'group-2' ],
4113
+ fromRootClientId: 'group-1',
4114
+ toRootClientId: '',
4115
+ },
4116
+ ],
4117
+ testReducer,
4118
+ initialState
4119
+ );
4120
+ expect( derivedNavModeBlockEditingModes ).toEqual(
4121
+ new Map(
4122
+ Object.entries( {
4123
+ '': 'contentOnly', // Section root.
4124
+ 'group-1': 'contentOnly', // Section block.
4125
+ 'paragraph-1': 'contentOnly', // Content block in section.
4126
+ 'group-2': 'contentOnly', // New section block.
4127
+ 'paragraph-2': 'contentOnly', // Still a content block in a section.
4128
+ } )
4129
+ )
4130
+ );
4131
+ } );
4132
+
4133
+ it( 'handles changes to the section root', () => {
4134
+ const { derivedNavModeBlockEditingModes } = dispatchActions(
4135
+ [
4136
+ {
4137
+ type: 'UPDATE_SETTINGS',
4138
+ settings: {
4139
+ [ sectionRootClientIdKey ]: 'group-1',
4140
+ },
4141
+ },
4142
+ ],
4143
+ testReducer,
4144
+ initialState
4145
+ );
4146
+
4147
+ expect( derivedNavModeBlockEditingModes ).toEqual(
4148
+ new Map(
4149
+ Object.entries( {
4150
+ '': 'disabled',
4151
+ 'group-1': 'contentOnly',
4152
+ 'paragraph-1': 'contentOnly',
4153
+ 'group-2': 'contentOnly',
4154
+ 'paragraph-2': 'contentOnly',
4155
+ } )
4156
+ )
4157
+ );
4158
+ } );
4159
+ } );
4160
+
4161
+ describe( 'zoom out mode', () => {
4162
+ let initialState;
4163
+
4164
+ beforeAll( () => {
4165
+ initialState = dispatchActions(
4166
+ [
4167
+ {
4168
+ type: 'UPDATE_SETTINGS',
4169
+ settings: {
4170
+ [ sectionRootClientIdKey ]: '',
4171
+ },
4172
+ },
4173
+ {
4174
+ type: 'SET_ZOOM_LEVEL',
4175
+ zoom: 'auto-scaled',
4176
+ },
4177
+ {
4178
+ type: 'RESET_BLOCKS',
4179
+ blocks: [
4180
+ {
4181
+ name: 'core/group',
4182
+ clientId: 'group-1',
4183
+ attributes: {},
4184
+ innerBlocks: [
4185
+ {
4186
+ name: 'core/paragraph',
4187
+ clientId: 'paragraph-1',
4188
+ attributes: {},
4189
+ innerBlocks: [],
4190
+ },
4191
+ {
4192
+ name: 'core/group',
4193
+ clientId: 'group-2',
4194
+ attributes: {},
4195
+ innerBlocks: [
4196
+ {
4197
+ name: 'core/paragraph',
4198
+ clientId: 'paragraph-2',
4199
+ attributes: {},
4200
+ innerBlocks: [],
4201
+ },
4202
+ ],
4203
+ },
4204
+ ],
4205
+ },
4206
+ ],
4207
+ },
4208
+ ],
4209
+ testReducer
4210
+ );
4211
+ } );
4212
+
4213
+ it( 'returns the expected block editing modes', () => {
4214
+ expect( initialState.derivedBlockEditingModes ).toEqual(
4215
+ new Map(
4216
+ Object.entries( {
4217
+ '': 'contentOnly', // Section root.
4218
+ 'group-1': 'contentOnly', // Section block.
4219
+ 'paragraph-1': 'disabled',
4220
+ 'group-2': 'disabled',
4221
+ 'paragraph-2': 'disabled',
4222
+ } )
4223
+ )
4224
+ );
4225
+ } );
4226
+
4227
+ it( 'overrides navigation mode', () => {
4228
+ select.mockImplementation( ( storeName ) => {
4229
+ if ( storeName === preferencesStore ) {
4230
+ return {
4231
+ get: jest.fn( () => 'navigation' ),
4232
+ };
4233
+ }
4234
+ return select( storeName );
4235
+ } );
4236
+
4237
+ const { derivedBlockEditingModes } = dispatchActions(
4238
+ [
4239
+ {
4240
+ type: 'SET_EDITOR_MODE',
4241
+ mode: 'navigation',
4242
+ },
4243
+ ],
4244
+ testReducer,
4245
+ initialState
4246
+ );
4247
+
4248
+ expect( derivedBlockEditingModes ).toEqual(
4249
+ new Map(
4250
+ Object.entries( {
4251
+ '': 'contentOnly', // Section root.
4252
+ 'group-1': 'contentOnly', // Section block.
4253
+ 'paragraph-1': 'disabled',
4254
+ 'group-2': 'disabled',
4255
+ 'paragraph-2': 'disabled',
4256
+ } )
4257
+ )
4258
+ );
4259
+
4260
+ select.mockImplementation( ( storeName ) => {
4261
+ if ( storeName === preferencesStore ) {
4262
+ return {
4263
+ get: jest.fn( () => 'edit' ),
4264
+ };
4265
+ }
4266
+ return select( storeName );
4267
+ } );
4268
+ } );
4269
+
4270
+ it( 'removes block editing modes when blocks are removed', () => {
4271
+ const { derivedBlockEditingModes } = dispatchActions(
4272
+ [
4273
+ {
4274
+ type: 'REMOVE_BLOCKS',
4275
+ clientIds: [ 'group-2' ],
4276
+ },
4277
+ ],
4278
+ testReducer,
4279
+ initialState
4280
+ );
4281
+
4282
+ expect( derivedBlockEditingModes ).toEqual(
4283
+ new Map(
4284
+ Object.entries( {
4285
+ '': 'contentOnly',
4286
+ 'group-1': 'contentOnly',
4287
+ 'paragraph-1': 'disabled',
4288
+ } )
4289
+ )
4290
+ );
4291
+ } );
4292
+
4293
+ it( 'updates block editing modes when new blocks are inserted', () => {
4294
+ const { derivedBlockEditingModes } = dispatchActions(
4295
+ [
4296
+ {
4297
+ type: 'INSERT_BLOCKS',
4298
+ rootClientId: '',
4299
+ blocks: [
4300
+ {
4301
+ name: 'core/group',
4302
+ clientId: 'group-3',
4303
+ attributes: {},
4304
+ innerBlocks: [
4305
+ {
4306
+ name: 'core/paragraph',
4307
+ clientId: 'paragraph-3',
4308
+ attributes: {},
4309
+ innerBlocks: [],
4310
+ },
4311
+ {
4312
+ name: 'core/group',
4313
+ clientId: 'group-4',
4314
+ attributes: {},
4315
+ innerBlocks: [],
4316
+ },
4317
+ ],
4318
+ },
4319
+ ],
4320
+ },
4321
+ ],
4322
+ testReducer,
4323
+ initialState
4324
+ );
4325
+
4326
+ expect( derivedBlockEditingModes ).toEqual(
4327
+ new Map(
4328
+ Object.entries( {
4329
+ '': 'contentOnly', // Section root.
4330
+ 'group-1': 'contentOnly', // Section block.
4331
+ 'paragraph-1': 'disabled',
4332
+ 'group-2': 'disabled',
4333
+ 'paragraph-2': 'disabled',
4334
+ 'group-3': 'contentOnly', // New section block.
4335
+ 'paragraph-3': 'disabled',
4336
+ 'group-4': 'disabled',
4337
+ } )
4338
+ )
4339
+ );
4340
+ } );
4341
+
4342
+ it( 'updates block editing modes when blocks are moved to a new position', () => {
4343
+ const { derivedBlockEditingModes } = dispatchActions(
4344
+ [
4345
+ {
4346
+ type: 'MOVE_BLOCKS_TO_POSITION',
4347
+ clientIds: [ 'group-2' ],
4348
+ fromRootClientId: 'group-1',
4349
+ toRootClientId: '',
4350
+ },
4351
+ ],
4352
+ testReducer,
4353
+ initialState
4354
+ );
4355
+ expect( derivedBlockEditingModes ).toEqual(
4356
+ new Map(
4357
+ Object.entries( {
4358
+ '': 'contentOnly', // Section root.
4359
+ 'group-1': 'contentOnly', // Section block.
4360
+ 'paragraph-1': 'disabled',
4361
+ 'group-2': 'contentOnly', // New section block.
4362
+ 'paragraph-2': 'disabled',
4363
+ } )
4364
+ )
4365
+ );
4366
+ } );
4367
+
4368
+ it( 'handles changes to the section root', () => {
4369
+ const { derivedBlockEditingModes } = dispatchActions(
4370
+ [
4371
+ {
4372
+ type: 'UPDATE_SETTINGS',
4373
+ settings: {
4374
+ [ sectionRootClientIdKey ]: 'group-1',
4375
+ },
4376
+ },
4377
+ ],
4378
+ testReducer,
4379
+ initialState
4380
+ );
4381
+
4382
+ expect( derivedBlockEditingModes ).toEqual(
4383
+ new Map(
4384
+ Object.entries( {
4385
+ '': 'disabled',
4386
+ 'group-1': 'contentOnly', // New section root.
4387
+ 'paragraph-1': 'contentOnly', // Section block.
4388
+ 'group-2': 'contentOnly', // Section block.
4389
+ 'paragraph-2': 'disabled',
4390
+ } )
4391
+ )
4392
+ );
4393
+ } );
4394
+ } );
4395
+ } );
3547
4396
  } );