@wordpress/block-editor 15.13.2-next.v.202602271551.0 → 15.13.2

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 (195) hide show
  1. package/build/components/block-bindings/attribute-control.cjs +5 -2
  2. package/build/components/block-bindings/attribute-control.cjs.map +2 -2
  3. package/build/components/block-inspector/edit-contents.cjs +5 -4
  4. package/build/components/block-inspector/edit-contents.cjs.map +2 -2
  5. package/build/components/block-list/block-html.cjs +6 -2
  6. package/build/components/block-list/block-html.cjs.map +2 -2
  7. package/build/components/block-list/block.cjs +9 -1
  8. package/build/components/block-list/block.cjs.map +2 -2
  9. package/build/components/block-list/use-block-props/index.cjs +10 -1
  10. package/build/components/block-list/use-block-props/index.cjs.map +2 -2
  11. package/build/components/block-quick-navigation/index.cjs +1 -6
  12. package/build/components/block-quick-navigation/index.cjs.map +3 -3
  13. package/build/components/block-settings-menu/block-settings-dropdown.cjs +4 -47
  14. package/build/components/block-settings-menu/block-settings-dropdown.cjs.map +2 -2
  15. package/build/components/block-settings-menu-controls/index.cjs +1 -0
  16. package/build/components/block-settings-menu-controls/index.cjs.map +2 -2
  17. package/build/components/block-styles/index.cjs +7 -1
  18. package/build/components/block-styles/index.cjs.map +3 -3
  19. package/build/components/block-styles/menu-items.cjs +16 -10
  20. package/build/components/block-styles/menu-items.cjs.map +3 -3
  21. package/build/components/block-switcher/block-styles-menu.cjs +2 -50
  22. package/build/components/block-switcher/block-styles-menu.cjs.map +3 -3
  23. package/build/components/block-toolbar/block-toolbar-icon.cjs +1 -1
  24. package/build/components/block-toolbar/block-toolbar-icon.cjs.map +2 -2
  25. package/build/components/block-toolbar/index.cjs +8 -4
  26. package/build/components/block-toolbar/index.cjs.map +2 -2
  27. package/build/components/block-tools/index.cjs +4 -3
  28. package/build/components/block-tools/index.cjs.map +2 -2
  29. package/build/components/block-variation-transforms/index.cjs +11 -5
  30. package/build/components/block-variation-transforms/index.cjs.map +2 -2
  31. package/build/components/block-visibility/modal.cjs +2 -2
  32. package/build/components/block-visibility/modal.cjs.map +2 -2
  33. package/build/components/block-visibility/use-block-visibility.cjs +4 -3
  34. package/build/components/block-visibility/use-block-visibility.cjs.map +2 -2
  35. package/build/components/block-visibility/viewport-visibility-info.cjs +6 -1
  36. package/build/components/block-visibility/viewport-visibility-info.cjs.map +2 -2
  37. package/build/components/dimensions-tool/scale-tool.cjs +2 -2
  38. package/build/components/dimensions-tool/scale-tool.cjs.map +2 -2
  39. package/build/components/grid/grid-visualizer.cjs +0 -3
  40. package/build/components/grid/grid-visualizer.cjs.map +2 -2
  41. package/build/components/iframe/index.cjs +1 -3
  42. package/build/components/iframe/index.cjs.map +2 -2
  43. package/build/components/iframe/use-scale-canvas.cjs +0 -1
  44. package/build/components/iframe/use-scale-canvas.cjs.map +2 -2
  45. package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.cjs +8 -4
  46. package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.cjs.map +2 -2
  47. package/build/components/link-picker/link-preview.cjs +2 -1
  48. package/build/components/link-picker/link-preview.cjs.map +3 -3
  49. package/build/components/list-view/block.cjs +1 -2
  50. package/build/components/list-view/block.cjs.map +2 -2
  51. package/build/components/provider/index.cjs +23 -7
  52. package/build/components/provider/index.cjs.map +2 -2
  53. package/build/components/provider/use-media-upload-settings.cjs +1 -0
  54. package/build/components/provider/use-media-upload-settings.cjs.map +2 -2
  55. package/build/components/writing-flow/use-arrow-nav.cjs +1 -1
  56. package/build/components/writing-flow/use-arrow-nav.cjs.map +2 -2
  57. package/build/hooks/auto-inspector-controls.cjs +26 -2
  58. package/build/hooks/auto-inspector-controls.cjs.map +3 -3
  59. package/build/hooks/cross-origin-isolation.cjs +9 -75
  60. package/build/hooks/cross-origin-isolation.cjs.map +2 -2
  61. package/build/hooks/custom-css.cjs +26 -0
  62. package/build/hooks/custom-css.cjs.map +3 -3
  63. package/build/private-apis.cjs +1 -0
  64. package/build/private-apis.cjs.map +2 -2
  65. package/build/store/actions.cjs +0 -8
  66. package/build/store/actions.cjs.map +2 -2
  67. package/build/store/private-keys.cjs +3 -0
  68. package/build/store/private-keys.cjs.map +2 -2
  69. package/build/store/private-selectors.cjs +4 -3
  70. package/build/store/private-selectors.cjs.map +2 -2
  71. package/build/store/reducer.cjs +65 -59
  72. package/build/store/reducer.cjs.map +2 -2
  73. package/build/store/selectors.cjs +16 -14
  74. package/build/store/selectors.cjs.map +2 -2
  75. package/build-module/components/block-bindings/attribute-control.mjs +5 -2
  76. package/build-module/components/block-bindings/attribute-control.mjs.map +2 -2
  77. package/build-module/components/block-inspector/edit-contents.mjs +5 -4
  78. package/build-module/components/block-inspector/edit-contents.mjs.map +2 -2
  79. package/build-module/components/block-list/block-html.mjs +7 -3
  80. package/build-module/components/block-list/block-html.mjs.map +2 -2
  81. package/build-module/components/block-list/block.mjs +10 -2
  82. package/build-module/components/block-list/block.mjs.map +2 -2
  83. package/build-module/components/block-list/use-block-props/index.mjs +11 -2
  84. package/build-module/components/block-list/use-block-props/index.mjs.map +2 -2
  85. package/build-module/components/block-quick-navigation/index.mjs +1 -6
  86. package/build-module/components/block-quick-navigation/index.mjs.map +2 -2
  87. package/build-module/components/block-settings-menu/block-settings-dropdown.mjs +5 -48
  88. package/build-module/components/block-settings-menu/block-settings-dropdown.mjs.map +2 -2
  89. package/build-module/components/block-settings-menu-controls/index.mjs +1 -0
  90. package/build-module/components/block-settings-menu-controls/index.mjs.map +2 -2
  91. package/build-module/components/block-styles/index.mjs +7 -1
  92. package/build-module/components/block-styles/index.mjs.map +2 -2
  93. package/build-module/components/block-styles/menu-items.mjs +6 -10
  94. package/build-module/components/block-styles/menu-items.mjs.map +2 -2
  95. package/build-module/components/block-switcher/block-styles-menu.mjs +3 -51
  96. package/build-module/components/block-switcher/block-styles-menu.mjs.map +2 -2
  97. package/build-module/components/block-toolbar/block-toolbar-icon.mjs +1 -1
  98. package/build-module/components/block-toolbar/block-toolbar-icon.mjs.map +2 -2
  99. package/build-module/components/block-toolbar/index.mjs +8 -4
  100. package/build-module/components/block-toolbar/index.mjs.map +2 -2
  101. package/build-module/components/block-tools/index.mjs +4 -3
  102. package/build-module/components/block-tools/index.mjs.map +2 -2
  103. package/build-module/components/block-variation-transforms/index.mjs +11 -5
  104. package/build-module/components/block-variation-transforms/index.mjs.map +2 -2
  105. package/build-module/components/block-visibility/modal.mjs +2 -2
  106. package/build-module/components/block-visibility/modal.mjs.map +2 -2
  107. package/build-module/components/block-visibility/use-block-visibility.mjs +4 -3
  108. package/build-module/components/block-visibility/use-block-visibility.mjs.map +2 -2
  109. package/build-module/components/block-visibility/viewport-visibility-info.mjs +6 -1
  110. package/build-module/components/block-visibility/viewport-visibility-info.mjs.map +2 -2
  111. package/build-module/components/dimensions-tool/scale-tool.mjs +2 -2
  112. package/build-module/components/dimensions-tool/scale-tool.mjs.map +2 -2
  113. package/build-module/components/grid/grid-visualizer.mjs +0 -3
  114. package/build-module/components/grid/grid-visualizer.mjs.map +2 -2
  115. package/build-module/components/iframe/index.mjs +2 -9
  116. package/build-module/components/iframe/index.mjs.map +2 -2
  117. package/build-module/components/iframe/use-scale-canvas.mjs +0 -1
  118. package/build-module/components/iframe/use-scale-canvas.mjs.map +2 -2
  119. package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.mjs +8 -4
  120. package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.mjs.map +2 -2
  121. package/build-module/components/link-picker/link-preview.mjs +2 -1
  122. package/build-module/components/link-picker/link-preview.mjs.map +2 -2
  123. package/build-module/components/list-view/block.mjs +1 -2
  124. package/build-module/components/list-view/block.mjs.map +2 -2
  125. package/build-module/components/provider/index.mjs +23 -7
  126. package/build-module/components/provider/index.mjs.map +2 -2
  127. package/build-module/components/provider/use-media-upload-settings.mjs +1 -0
  128. package/build-module/components/provider/use-media-upload-settings.mjs.map +2 -2
  129. package/build-module/components/writing-flow/use-arrow-nav.mjs +1 -1
  130. package/build-module/components/writing-flow/use-arrow-nav.mjs.map +2 -2
  131. package/build-module/hooks/auto-inspector-controls.mjs +28 -4
  132. package/build-module/hooks/auto-inspector-controls.mjs.map +2 -2
  133. package/build-module/hooks/cross-origin-isolation.mjs +9 -75
  134. package/build-module/hooks/cross-origin-isolation.mjs.map +2 -2
  135. package/build-module/hooks/custom-css.mjs +28 -2
  136. package/build-module/hooks/custom-css.mjs.map +2 -2
  137. package/build-module/private-apis.mjs +3 -1
  138. package/build-module/private-apis.mjs.map +2 -2
  139. package/build-module/store/actions.mjs +0 -8
  140. package/build-module/store/actions.mjs.map +2 -2
  141. package/build-module/store/private-keys.mjs +2 -0
  142. package/build-module/store/private-keys.mjs.map +2 -2
  143. package/build-module/store/private-selectors.mjs +4 -3
  144. package/build-module/store/private-selectors.mjs.map +2 -2
  145. package/build-module/store/reducer.mjs +65 -58
  146. package/build-module/store/reducer.mjs.map +2 -2
  147. package/build-module/store/selectors.mjs +16 -14
  148. package/build-module/store/selectors.mjs.map +2 -2
  149. package/build-style/content-rtl.css +25 -1
  150. package/build-style/content.css +25 -2
  151. package/build-style/style-rtl.css +3 -0
  152. package/build-style/style.css +3 -0
  153. package/package.json +39 -39
  154. package/src/components/block-bindings/attribute-control.js +8 -3
  155. package/src/components/block-inspector/edit-contents.js +5 -3
  156. package/src/components/block-list/block-html.js +13 -3
  157. package/src/components/block-list/block.js +10 -1
  158. package/src/components/block-list/content.scss +35 -4
  159. package/src/components/block-list/use-block-props/index.js +11 -1
  160. package/src/components/block-quick-navigation/index.js +1 -6
  161. package/src/components/block-settings-menu/block-settings-dropdown.js +2 -46
  162. package/src/components/block-settings-menu-controls/index.js +1 -0
  163. package/src/components/block-styles/index.js +7 -1
  164. package/src/components/block-styles/menu-items.js +11 -10
  165. package/src/components/block-switcher/block-styles-menu.js +1 -47
  166. package/src/components/block-toolbar/block-toolbar-icon.js +6 -1
  167. package/src/components/block-toolbar/index.js +7 -2
  168. package/src/components/block-tools/index.js +11 -4
  169. package/src/components/block-tools/style.scss +5 -0
  170. package/src/components/block-variation-transforms/index.js +41 -36
  171. package/src/components/block-visibility/use-block-visibility.js +4 -2
  172. package/src/components/block-visibility/viewport-visibility-info.js +8 -1
  173. package/src/components/dimensions-tool/scale-tool.js +2 -2
  174. package/src/components/grid/grid-visualizer.js +0 -3
  175. package/src/components/iframe/index.js +2 -12
  176. package/src/components/iframe/use-scale-canvas.js +0 -1
  177. package/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js +9 -5
  178. package/src/components/link-picker/link-preview.js +2 -1
  179. package/src/components/list-view/block.js +0 -5
  180. package/src/components/provider/index.js +49 -6
  181. package/src/components/provider/use-media-upload-settings.js +1 -0
  182. package/src/components/writing-flow/use-arrow-nav.js +9 -2
  183. package/src/hooks/auto-inspector-controls.js +31 -4
  184. package/src/hooks/cross-origin-isolation.js +10 -109
  185. package/src/hooks/custom-css.js +36 -2
  186. package/src/hooks/test/cross-origin-isolation.js +15 -42
  187. package/src/private-apis.js +2 -0
  188. package/src/store/actions.js +0 -8
  189. package/src/store/private-keys.js +1 -0
  190. package/src/store/private-selectors.js +6 -3
  191. package/src/store/reducer.js +96 -77
  192. package/src/store/selectors.js +59 -22
  193. package/src/store/test/private-selectors.js +67 -34
  194. package/src/store/test/reducer.js +436 -57
  195. package/src/store/test/selectors.js +611 -53
@@ -37,14 +37,13 @@ import {
37
37
  settings,
38
38
  lastBlockAttributesChange,
39
39
  lastBlockInserted,
40
- blockEditingModes,
41
40
  expandedBlock,
42
41
  zoomLevel,
43
42
  editedContentOnlySection,
44
43
  withDerivedBlockEditingModes,
45
44
  viewportModalClientIds,
46
45
  } from '../reducer';
47
-
46
+ import { getBlockOrder, getBlocks } from '../selectors';
48
47
  import { unlock } from '../../lock-unlock';
49
48
  import { sectionRootClientIdKey, isIsolatedEditorKey } from '.././private-keys';
50
49
 
@@ -287,6 +286,7 @@ describe( 'state', () => {
287
286
  } )
288
287
  ),
289
288
  controlledInnerBlocks: {},
289
+ blockEditingModes: new Map(),
290
290
  } );
291
291
 
292
292
  const newChildBlock = createBlock( 'core/test-child-block', {
@@ -345,6 +345,7 @@ describe( 'state', () => {
345
345
  } )
346
346
  ),
347
347
  controlledInnerBlocks: {},
348
+ blockEditingModes: new Map(),
348
349
  } );
349
350
  expect( state.tree.get( 'chicken' ) ).not.toBe(
350
351
  existingState.tree.get( 'chicken' )
@@ -387,6 +388,7 @@ describe( 'state', () => {
387
388
  } )
388
389
  ),
389
390
  controlledInnerBlocks: {},
391
+ blockEditingModes: new Map(),
390
392
  } );
391
393
 
392
394
  const newChildBlock = createBlock( 'core/test-child-block', {
@@ -445,6 +447,7 @@ describe( 'state', () => {
445
447
  } )
446
448
  ),
447
449
  controlledInnerBlocks: {},
450
+ blockEditingModes: new Map(),
448
451
  } );
449
452
  expect( state.tree.get( 'chicken' ) ).not.toBe(
450
453
  existingState.tree.get( 'chicken' )
@@ -516,6 +519,7 @@ describe( 'state', () => {
516
519
  ),
517
520
  tree: new Map(),
518
521
  controlledInnerBlocks: {},
522
+ blockEditingModes: new Map(),
519
523
  } );
520
524
 
521
525
  const newChildBlock1 = createBlock( 'core/test-child-block', {
@@ -610,6 +614,7 @@ describe( 'state', () => {
610
614
  } )
611
615
  ),
612
616
  controlledInnerBlocks: {},
617
+ blockEditingModes: new Map(),
613
618
  } );
614
619
 
615
620
  expect( state.tree.get( '' ).innerBlocks[ 0 ] ).toBe(
@@ -685,6 +690,7 @@ describe( 'state', () => {
685
690
  } )
686
691
  ),
687
692
  controlledInnerBlocks: {},
693
+ blockEditingModes: new Map(),
688
694
  } );
689
695
 
690
696
  const newChildBlock = createBlock( 'core/test-block' );
@@ -737,6 +743,7 @@ describe( 'state', () => {
737
743
  } )
738
744
  ),
739
745
  controlledInnerBlocks: {},
746
+ blockEditingModes: new Map(),
740
747
  } );
741
748
 
742
749
  // The block object of the parent should be updated.
@@ -758,6 +765,7 @@ describe( 'state', () => {
758
765
  isIgnoredChange: false,
759
766
  tree: new Map(),
760
767
  controlledInnerBlocks: {},
768
+ blockEditingModes: new Map(),
761
769
  } );
762
770
  } );
763
771
 
@@ -1841,43 +1849,6 @@ describe( 'state', () => {
1841
1849
  ] );
1842
1850
  } );
1843
1851
 
1844
- it( 'should not remove last block when fromRootClientId is incorrect', () => {
1845
- const original = blocks( undefined, {
1846
- type: 'RESET_BLOCKS',
1847
- blocks: [
1848
- {
1849
- clientId: 'chicken',
1850
- name: 'core/test-block',
1851
- attributes: {},
1852
- innerBlocks: [],
1853
- },
1854
- {
1855
- clientId: 'ribs',
1856
- name: 'core/test-block',
1857
- attributes: {},
1858
- innerBlocks: [
1859
- {
1860
- clientId: 'nested',
1861
- name: 'core/test-block',
1862
- attributes: {},
1863
- innerBlocks: [],
1864
- },
1865
- ],
1866
- },
1867
- ],
1868
- } );
1869
- const state = blocks( original, {
1870
- type: 'MOVE_BLOCKS_TO_POSITION',
1871
- clientIds: [ 'nested' ],
1872
- fromRootClientId: '',
1873
- toRootClientId: '',
1874
- index: 0,
1875
- } );
1876
-
1877
- // The state should be unchnaged - no blocks moved or removed.
1878
- expect( state.order.get( '' ) ).toEqual( [ 'chicken', 'ribs' ] );
1879
- } );
1880
-
1881
1852
  describe( 'blocks', () => {
1882
1853
  describe( 'byClientId', () => {
1883
1854
  it( 'should ignore updates to non-existent block', () => {
@@ -2478,6 +2449,203 @@ describe( 'state', () => {
2478
2449
  expect( state.controlledInnerBlocks.chicken ).toBe( true );
2479
2450
  } );
2480
2451
 
2452
+ it( 'should preserve controlledInnerBlocks blocks across RESET_BLOCKS', () => {
2453
+ const original = blocks( undefined, {
2454
+ type: 'RESET_BLOCKS',
2455
+ blocks: [
2456
+ {
2457
+ clientId: 'chicken',
2458
+ name: 'core/test-block',
2459
+ attributes: {},
2460
+ innerBlocks: [],
2461
+ },
2462
+ ],
2463
+ } );
2464
+ const withControlled = blocks( original, {
2465
+ type: 'SET_HAS_CONTROLLED_INNER_BLOCKS',
2466
+ clientId: 'chicken',
2467
+ hasControlledInnerBlocks: true,
2468
+ } );
2469
+
2470
+ const withControlledContent = blocks( withControlled, {
2471
+ type: 'REPLACE_INNER_BLOCKS',
2472
+ rootClientId: 'chicken',
2473
+ blocks: [
2474
+ {
2475
+ clientId: 'content',
2476
+ innerBlocks: [
2477
+ {
2478
+ clientId: 'content-inner',
2479
+ innerBlocks: [],
2480
+ },
2481
+ ],
2482
+ },
2483
+ ],
2484
+ } );
2485
+
2486
+ expect(
2487
+ getBlocks(
2488
+ { blocks: withControlledContent },
2489
+ 'chicken'
2490
+ ).map( ( b ) => b.clientId )
2491
+ ).toEqual( [ 'content' ] );
2492
+ expect(
2493
+ getBlocks(
2494
+ { blocks: withControlledContent },
2495
+ 'content'
2496
+ ).map( ( b ) => b.clientId )
2497
+ ).toEqual( [ 'content-inner' ] );
2498
+
2499
+ const state = blocks( withControlledContent, {
2500
+ type: 'RESET_BLOCKS',
2501
+ blocks: [
2502
+ {
2503
+ clientId: 'chicken',
2504
+ name: 'core/test-block',
2505
+ attributes: {},
2506
+ innerBlocks: [],
2507
+ },
2508
+ ],
2509
+ } );
2510
+
2511
+ expect( state.controlledInnerBlocks.chicken ).toBe( true );
2512
+ expect(
2513
+ getBlocks( { blocks: state }, 'chicken' ).map(
2514
+ ( b ) => b.clientId
2515
+ )
2516
+ ).toEqual( [ 'content' ] );
2517
+ expect(
2518
+ getBlocks( { blocks: state }, 'content' ).map(
2519
+ ( b ) => b.clientId
2520
+ )
2521
+ ).toEqual( [ 'content-inner' ] );
2522
+ } );
2523
+
2524
+ it( 'should forget controlledInnerBlocks during full RESET_BLOCKS', () => {
2525
+ const templateBlock = {
2526
+ clientId: 'template',
2527
+ name: 'core/post-content',
2528
+ attributes: {},
2529
+ innerBlocks: [],
2530
+ };
2531
+ const contentBlock = {
2532
+ clientId: 'content',
2533
+ name: 'core/paragraph',
2534
+ attributes: {},
2535
+ innerBlocks: [],
2536
+ };
2537
+
2538
+ let state = blocks( undefined, {
2539
+ type: 'RESET_BLOCKS',
2540
+ blocks: [ templateBlock ],
2541
+ } );
2542
+
2543
+ state = blocks( state, {
2544
+ type: 'SET_HAS_CONTROLLED_INNER_BLOCKS',
2545
+ clientId: 'template',
2546
+ hasControlledInnerBlocks: true,
2547
+ } );
2548
+
2549
+ state = blocks( state, {
2550
+ type: 'REPLACE_INNER_BLOCKS',
2551
+ rootClientId: 'template',
2552
+ blocks: [ contentBlock ],
2553
+ } );
2554
+
2555
+ // Reset blocks completely, we expect that the controlled blocks are forgotten.
2556
+ state = blocks( state, {
2557
+ type: 'RESET_BLOCKS',
2558
+ blocks: [],
2559
+ } );
2560
+
2561
+ // Reset back to the template.
2562
+ state = blocks( state, {
2563
+ type: 'RESET_BLOCKS',
2564
+ blocks: [ templateBlock ],
2565
+ } );
2566
+
2567
+ // Expect that the `template`/`content` blocks are reconstructed.
2568
+ const fullState = { blocks: state };
2569
+ expect( getBlocks( fullState, 'template' ) ).toEqual( [] );
2570
+ expect( getBlockOrder( fullState, 'template' ) ).toEqual(
2571
+ []
2572
+ );
2573
+ } );
2574
+
2575
+ it( 'should not leave stale controlled tree entries after root replacement and reset', () => {
2576
+ const templateBlock = {
2577
+ clientId: 'template',
2578
+ name: 'core/post-content',
2579
+ attributes: {},
2580
+ innerBlocks: [],
2581
+ };
2582
+ const contentBlock = {
2583
+ clientId: 'content',
2584
+ name: 'core/paragraph',
2585
+ attributes: {},
2586
+ innerBlocks: [],
2587
+ };
2588
+
2589
+ // Initialize template, simulates root `useBlockSync` initialization.
2590
+ let state = blocks( undefined, {
2591
+ type: 'RESET_BLOCKS',
2592
+ blocks: [ templateBlock ],
2593
+ } );
2594
+
2595
+ // Add a controlled child to the template using two actions, simulates inner `useBlockSync` initialization.
2596
+ state = blocks( state, {
2597
+ type: 'SET_HAS_CONTROLLED_INNER_BLOCKS',
2598
+ clientId: 'template',
2599
+ hasControlledInnerBlocks: true,
2600
+ } );
2601
+
2602
+ state = blocks( state, {
2603
+ type: 'REPLACE_INNER_BLOCKS',
2604
+ rootClientId: 'template',
2605
+ blocks: [ contentBlock ],
2606
+ } );
2607
+
2608
+ // Reset blocks completely, simulates root `useBlockSync` cleanup.
2609
+ state = blocks( state, {
2610
+ type: 'RESET_BLOCKS',
2611
+ blocks: [],
2612
+ } );
2613
+
2614
+ // Unset controlled inner blocks, simulates inner `useBlockSync` cleanup.
2615
+ state = blocks( state, {
2616
+ type: 'SET_HAS_CONTROLLED_INNER_BLOCKS',
2617
+ clientId: 'template',
2618
+ hasControlledInnerBlocks: false,
2619
+ } );
2620
+
2621
+ // Initialize template again, simulates `useBlockSync` after navigation.
2622
+ state = blocks( state, {
2623
+ type: 'RESET_BLOCKS',
2624
+ blocks: [ templateBlock ],
2625
+ } );
2626
+
2627
+ // Set controlled inner blocks again, this time to empty.
2628
+ state = blocks( state, {
2629
+ type: 'SET_HAS_CONTROLLED_INNER_BLOCKS',
2630
+ clientId: 'template',
2631
+ hasControlledInnerBlocks: true,
2632
+ } );
2633
+
2634
+ state = blocks( state, {
2635
+ type: 'REPLACE_INNER_BLOCKS',
2636
+ rootClientId: 'template',
2637
+ blocks: [],
2638
+ } );
2639
+
2640
+ // At this point the template has empty content, and `useInnerBlockTemplateSync` should apply
2641
+ // its template content. It will check if `getBlocks` is empty before applying the template.
2642
+ const fullState = { blocks: state };
2643
+ expect( getBlockOrder( fullState, 'template' ) ).toEqual(
2644
+ []
2645
+ );
2646
+ expect( getBlocks( fullState, 'template' ) ).toEqual( [] );
2647
+ } );
2648
+
2481
2649
  it( 'should not create new state references when setting controlled inner blocks on a block with no inner blocks', () => {
2482
2650
  const original = blocks( undefined, {
2483
2651
  type: 'RESET_BLOCKS',
@@ -3579,17 +3747,18 @@ describe( 'state', () => {
3579
3747
 
3580
3748
  describe( 'blockEditingModes', () => {
3581
3749
  it( 'should return an empty map by default', () => {
3582
- expect( blockEditingModes( undefined, {} ) ).toEqual( new Map() );
3750
+ const state = blocks( undefined, {} );
3751
+ expect( state.blockEditingModes ).toEqual( new Map() );
3583
3752
  } );
3584
3753
 
3585
3754
  it( 'should set the editing mode for a block', () => {
3586
- const state = new Map();
3587
- const newState = blockEditingModes( state, {
3755
+ const state = blocks( undefined, {} );
3756
+ const newState = blocks( state, {
3588
3757
  type: 'SET_BLOCK_EDITING_MODE',
3589
3758
  clientId: '14501cc2-90a6-4f52-aa36-ab6e896135d1',
3590
3759
  mode: 'default',
3591
3760
  } );
3592
- expect( newState ).toEqual(
3761
+ expect( newState.blockEditingModes ).toEqual(
3593
3762
  new Map( [
3594
3763
  [ '14501cc2-90a6-4f52-aa36-ab6e896135d1', 'default' ],
3595
3764
  ] )
@@ -3597,28 +3766,126 @@ describe( 'state', () => {
3597
3766
  } );
3598
3767
 
3599
3768
  it( 'should clear the editing mode for a block', () => {
3600
- const state = new Map( [
3601
- [ '14501cc2-90a6-4f52-aa36-ab6e896135d1', 'default' ],
3602
- ] );
3603
- const newState = blockEditingModes( state, {
3769
+ let state = blocks( undefined, {} );
3770
+ state = blocks( state, {
3771
+ type: 'SET_BLOCK_EDITING_MODE',
3772
+ clientId: '14501cc2-90a6-4f52-aa36-ab6e896135d1',
3773
+ mode: 'default',
3774
+ } );
3775
+ const newState = blocks( state, {
3604
3776
  type: 'UNSET_BLOCK_EDITING_MODE',
3605
3777
  clientId: '14501cc2-90a6-4f52-aa36-ab6e896135d1',
3606
3778
  } );
3607
- expect( newState ).toEqual( new Map() );
3779
+ expect( newState.blockEditingModes ).toEqual( new Map() );
3608
3780
  } );
3609
3781
 
3610
- it( 'should clear editing modes when blocks are reset', () => {
3611
- const state = new Map( [
3612
- [ '', 'disabled' ],
3613
- [ '14501cc2-90a6-4f52-aa36-ab6e896135d1', 'default' ],
3614
- ] );
3615
- const newState = blockEditingModes( state, {
3782
+ it( 'should preserve editing modes when blocks are reset', () => {
3783
+ // Add a template with two template parts.
3784
+ let state = blocks( undefined, {} );
3785
+ state = blocks( state, {
3616
3786
  type: 'RESET_BLOCKS',
3787
+ blocks: [
3788
+ {
3789
+ name: 'core/template-part',
3790
+ clientId: 'template-part-1',
3791
+ attributes: {},
3792
+ innerBlocks: [],
3793
+ },
3794
+ {
3795
+ name: 'core/template-part',
3796
+ clientId: 'template-part-2',
3797
+ attributes: {},
3798
+ innerBlocks: [],
3799
+ },
3800
+ ],
3801
+ } );
3802
+
3803
+ // In each of the template parts add a controlled content (a paragraph block).
3804
+ state = blocks( state, {
3805
+ type: 'SET_HAS_CONTROLLED_INNER_BLOCKS',
3806
+ clientId: 'template-part-1',
3807
+ hasControlledInnerBlocks: true,
3808
+ } );
3809
+ state = blocks( state, {
3810
+ type: 'REPLACE_INNER_BLOCKS',
3811
+ rootClientId: 'template-part-1',
3812
+ blocks: [
3813
+ {
3814
+ name: 'core/paragraph',
3815
+ clientId: 'paragraph-1',
3816
+ attributes: {},
3817
+ innerBlocks: [],
3818
+ },
3819
+ ],
3820
+ } );
3821
+ state = blocks( state, {
3822
+ type: 'SET_HAS_CONTROLLED_INNER_BLOCKS',
3823
+ clientId: 'template-part-2',
3824
+ hasControlledInnerBlocks: true,
3825
+ } );
3826
+ state = blocks( state, {
3827
+ type: 'REPLACE_INNER_BLOCKS',
3828
+ rootClientId: 'template-part-2',
3829
+ blocks: [
3830
+ {
3831
+ name: 'core/paragraph',
3832
+ clientId: 'paragraph-2',
3833
+ attributes: {},
3834
+ innerBlocks: [],
3835
+ },
3836
+ ],
3837
+ } );
3838
+
3839
+ // Set block editing modes, just like `DisableNonPageContentBlocks` would do:
3840
+ // - the root block to 'disabled'
3841
+ // - the template parts to 'contentOnly'
3842
+ // - the template part children to 'disabled'
3843
+ state = blocks( state, {
3844
+ type: 'SET_BLOCK_EDITING_MODE',
3845
+ clientId: '',
3846
+ mode: 'disabled',
3847
+ } );
3848
+ state = blocks( state, {
3849
+ type: 'SET_BLOCK_EDITING_MODE',
3850
+ clientId: 'template-part-1',
3851
+ mode: 'contentOnly',
3852
+ } );
3853
+ state = blocks( state, {
3854
+ type: 'SET_BLOCK_EDITING_MODE',
3855
+ clientId: 'template-part-2',
3856
+ mode: 'contentOnly',
3857
+ } );
3858
+ state = blocks( state, {
3859
+ type: 'SET_BLOCK_EDITING_MODE',
3860
+ clientId: 'paragraph-1',
3861
+ mode: 'disabled',
3862
+ } );
3863
+ state = blocks( state, {
3864
+ type: 'SET_BLOCK_EDITING_MODE',
3865
+ clientId: 'paragraph-2',
3866
+ mode: 'disabled',
3867
+ } );
3868
+
3869
+ // Reset the template, keeping only one of the template parts.
3870
+ state = blocks( state, {
3871
+ type: 'RESET_BLOCKS',
3872
+ blocks: [
3873
+ {
3874
+ name: 'core/template-part',
3875
+ clientId: 'template-part-1',
3876
+ attributes: {},
3877
+ innerBlocks: [],
3878
+ },
3879
+ ],
3617
3880
  } );
3618
- expect( newState ).toEqual(
3881
+
3882
+ // Check that the editing modes for valid blocks are preserved, and the
3883
+ // editing modes for removed blocks are cleared.
3884
+ expect( state.blockEditingModes ).toEqual(
3619
3885
  new Map( [
3620
- // Root mode should be maintained.
3621
3886
  [ '', 'disabled' ],
3887
+ [ 'template-part-1', 'contentOnly' ],
3888
+ [ 'paragraph-1', 'disabled' ],
3622
3889
  ] )
3623
3890
  );
3624
3891
  } );
@@ -3649,6 +3916,119 @@ describe( 'state', () => {
3649
3916
  } );
3650
3917
  } );
3651
3918
 
3919
+ describe( 'editedContentOnlySection', () => {
3920
+ it( 'returns undefined by default', () => {
3921
+ expect(
3922
+ editedContentOnlySection( undefined, { type: 'UNKNOWN' } )
3923
+ ).toBeUndefined();
3924
+ } );
3925
+
3926
+ it( 'sets the clientId on EDIT_CONTENT_ONLY_SECTION', () => {
3927
+ const state = editedContentOnlySection( undefined, {
3928
+ type: 'EDIT_CONTENT_ONLY_SECTION',
3929
+ clientId: 'block-1',
3930
+ } );
3931
+ expect( state ).toBe( 'block-1' );
3932
+ } );
3933
+
3934
+ it( 'clears the clientId when EDIT_CONTENT_ONLY_SECTION has no clientId', () => {
3935
+ const state = editedContentOnlySection( 'block-1', {
3936
+ type: 'EDIT_CONTENT_ONLY_SECTION',
3937
+ } );
3938
+ expect( state ).toBeUndefined();
3939
+ } );
3940
+
3941
+ it( 'clears when the edited section is directly removed via REMOVE_BLOCKS', () => {
3942
+ const state = editedContentOnlySection( 'block-1', {
3943
+ type: 'REMOVE_BLOCKS',
3944
+ clientIds: [ 'block-1' ],
3945
+ } );
3946
+ expect( state ).toBeUndefined();
3947
+ } );
3948
+
3949
+ it( 'keeps state when REMOVE_BLOCKS targets other blocks', () => {
3950
+ const state = editedContentOnlySection( 'block-1', {
3951
+ type: 'REMOVE_BLOCKS',
3952
+ clientIds: [ 'block-2', 'block-3' ],
3953
+ } );
3954
+ expect( state ).toBe( 'block-1' );
3955
+ } );
3956
+
3957
+ it( 'clears when the edited section is directly replaced via REPLACE_BLOCKS', () => {
3958
+ const state = editedContentOnlySection( 'block-1', {
3959
+ type: 'REPLACE_BLOCKS',
3960
+ clientIds: [ 'block-1' ],
3961
+ blocks: [ { clientId: 'block-new', innerBlocks: [] } ],
3962
+ } );
3963
+ expect( state ).toBeUndefined();
3964
+ } );
3965
+
3966
+ it( 'keeps state when REPLACE_BLOCKS targets other blocks', () => {
3967
+ const state = editedContentOnlySection( 'block-1', {
3968
+ type: 'REPLACE_BLOCKS',
3969
+ clientIds: [ 'block-2' ],
3970
+ blocks: [ { clientId: 'block-new', innerBlocks: [] } ],
3971
+ } );
3972
+ expect( state ).toBe( 'block-1' );
3973
+ } );
3974
+
3975
+ it( 'clears when RESET_BLOCKS does not include the edited section', () => {
3976
+ const state = editedContentOnlySection( 'block-1', {
3977
+ type: 'RESET_BLOCKS',
3978
+ blocks: [
3979
+ { clientId: 'block-2', innerBlocks: [] },
3980
+ { clientId: 'block-3', innerBlocks: [] },
3981
+ ],
3982
+ } );
3983
+ expect( state ).toBeUndefined();
3984
+ } );
3985
+
3986
+ it( 'keeps state when RESET_BLOCKS includes the edited section at the top level', () => {
3987
+ const state = editedContentOnlySection( 'block-1', {
3988
+ type: 'RESET_BLOCKS',
3989
+ blocks: [
3990
+ { clientId: 'block-1', innerBlocks: [] },
3991
+ { clientId: 'block-2', innerBlocks: [] },
3992
+ ],
3993
+ } );
3994
+ expect( state ).toBe( 'block-1' );
3995
+ } );
3996
+
3997
+ it( 'keeps state when RESET_BLOCKS includes the edited section nested in innerBlocks', () => {
3998
+ const state = editedContentOnlySection( 'block-1', {
3999
+ type: 'RESET_BLOCKS',
4000
+ blocks: [
4001
+ {
4002
+ clientId: 'block-parent',
4003
+ innerBlocks: [
4004
+ {
4005
+ clientId: 'block-1',
4006
+ innerBlocks: [],
4007
+ },
4008
+ ],
4009
+ },
4010
+ ],
4011
+ } );
4012
+ expect( state ).toBe( 'block-1' );
4013
+ } );
4014
+
4015
+ it( 'does not clear on unrelated actions when state is set', () => {
4016
+ const state = editedContentOnlySection( 'block-1', {
4017
+ type: 'SELECT_BLOCK',
4018
+ clientId: 'block-2',
4019
+ } );
4020
+ expect( state ).toBe( 'block-1' );
4021
+ } );
4022
+
4023
+ it( 'does not run cleanup logic when state is already empty', () => {
4024
+ const state = editedContentOnlySection( undefined, {
4025
+ type: 'REMOVE_BLOCKS',
4026
+ clientIds: [ 'block-1' ],
4027
+ } );
4028
+ expect( state ).toBeUndefined();
4029
+ } );
4030
+ } );
4031
+
3652
4032
  describe( 'insertionPoint', () => {
3653
4033
  it( 'should default to null', () => {
3654
4034
  const state = insertionPoint( undefined, {} );
@@ -3691,7 +4071,6 @@ describe( 'state', () => {
3691
4071
  settings,
3692
4072
  zoomLevel,
3693
4073
  blockListSettings,
3694
- blockEditingModes,
3695
4074
  editedContentOnlySection,
3696
4075
  } )
3697
4076
  );