@wordpress/block-editor 15.13.2-next.v.202602241322.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.
- package/build/components/block-bindings/attribute-control.cjs +5 -2
- package/build/components/block-bindings/attribute-control.cjs.map +2 -2
- package/build/components/block-inspector/edit-contents.cjs +5 -4
- package/build/components/block-inspector/edit-contents.cjs.map +2 -2
- package/build/components/block-list/block-html.cjs +6 -2
- package/build/components/block-list/block-html.cjs.map +2 -2
- package/build/components/block-list/block.cjs +9 -1
- package/build/components/block-list/block.cjs.map +2 -2
- package/build/components/block-list/use-block-props/index.cjs +10 -1
- package/build/components/block-list/use-block-props/index.cjs.map +2 -2
- package/build/components/block-settings-menu-controls/index.cjs +1 -0
- package/build/components/block-settings-menu-controls/index.cjs.map +2 -2
- package/build/components/block-styles/index.cjs +7 -1
- package/build/components/block-styles/index.cjs.map +3 -3
- package/build/components/block-switcher/block-transformations-menu.cjs +2 -0
- package/build/components/block-switcher/block-transformations-menu.cjs.map +2 -2
- package/build/components/block-switcher/block-variation-transformations.cjs +2 -0
- package/build/components/block-switcher/block-variation-transformations.cjs.map +2 -2
- package/build/components/block-toolbar/block-toolbar-icon.cjs +1 -1
- package/build/components/block-toolbar/block-toolbar-icon.cjs.map +2 -2
- package/build/components/block-toolbar/index.cjs +8 -4
- package/build/components/block-toolbar/index.cjs.map +2 -2
- package/build/components/block-tools/index.cjs +4 -3
- package/build/components/block-tools/index.cjs.map +2 -2
- package/build/components/block-variation-transforms/index.cjs +11 -5
- package/build/components/block-variation-transforms/index.cjs.map +2 -2
- package/build/components/block-visibility/modal.cjs +2 -2
- package/build/components/block-visibility/modal.cjs.map +1 -1
- package/build/components/block-visibility/use-block-visibility.cjs +4 -3
- package/build/components/block-visibility/use-block-visibility.cjs.map +2 -2
- package/build/components/block-visibility/viewport-visibility-info.cjs +6 -1
- package/build/components/block-visibility/viewport-visibility-info.cjs.map +2 -2
- package/build/components/dimensions-tool/scale-tool.cjs +2 -2
- package/build/components/dimensions-tool/scale-tool.cjs.map +2 -2
- package/build/components/iframe/index.cjs +1 -3
- package/build/components/iframe/index.cjs.map +2 -2
- package/build/components/iframe/use-scale-canvas.cjs +0 -1
- package/build/components/iframe/use-scale-canvas.cjs.map +2 -2
- package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.cjs +8 -4
- package/build/components/inspector-controls-tabs/use-inspector-controls-tabs.cjs.map +2 -2
- package/build/components/link-picker/link-preview.cjs +2 -1
- package/build/components/link-picker/link-preview.cjs.map +3 -3
- package/build/components/provider/index.cjs +23 -7
- package/build/components/provider/index.cjs.map +2 -2
- package/build/components/provider/use-media-upload-settings.cjs +1 -0
- package/build/components/provider/use-media-upload-settings.cjs.map +2 -2
- package/build/components/writing-flow/use-arrow-nav.cjs +1 -1
- package/build/components/writing-flow/use-arrow-nav.cjs.map +2 -2
- package/build/hooks/auto-inspector-controls.cjs +26 -2
- package/build/hooks/auto-inspector-controls.cjs.map +3 -3
- package/build/hooks/cross-origin-isolation.cjs +9 -75
- package/build/hooks/cross-origin-isolation.cjs.map +2 -2
- package/build/hooks/custom-css.cjs +26 -0
- package/build/hooks/custom-css.cjs.map +3 -3
- package/build/private-apis.cjs +1 -0
- package/build/private-apis.cjs.map +2 -2
- package/build/store/actions.cjs +0 -8
- package/build/store/actions.cjs.map +2 -2
- package/build/store/private-keys.cjs +3 -0
- package/build/store/private-keys.cjs.map +2 -2
- package/build/store/private-selectors.cjs +4 -3
- package/build/store/private-selectors.cjs.map +2 -2
- package/build/store/reducer.cjs +78 -74
- package/build/store/reducer.cjs.map +2 -2
- package/build/store/selectors.cjs +16 -14
- package/build/store/selectors.cjs.map +2 -2
- package/build-module/components/block-bindings/attribute-control.mjs +5 -2
- package/build-module/components/block-bindings/attribute-control.mjs.map +2 -2
- package/build-module/components/block-inspector/edit-contents.mjs +5 -4
- package/build-module/components/block-inspector/edit-contents.mjs.map +2 -2
- package/build-module/components/block-list/block-html.mjs +7 -3
- package/build-module/components/block-list/block-html.mjs.map +2 -2
- package/build-module/components/block-list/block.mjs +10 -2
- package/build-module/components/block-list/block.mjs.map +2 -2
- package/build-module/components/block-list/use-block-props/index.mjs +11 -2
- package/build-module/components/block-list/use-block-props/index.mjs.map +2 -2
- package/build-module/components/block-settings-menu-controls/index.mjs +1 -0
- package/build-module/components/block-settings-menu-controls/index.mjs.map +2 -2
- package/build-module/components/block-styles/index.mjs +7 -1
- package/build-module/components/block-styles/index.mjs.map +2 -2
- package/build-module/components/block-switcher/block-transformations-menu.mjs +2 -0
- package/build-module/components/block-switcher/block-transformations-menu.mjs.map +2 -2
- package/build-module/components/block-switcher/block-variation-transformations.mjs +2 -0
- package/build-module/components/block-switcher/block-variation-transformations.mjs.map +2 -2
- package/build-module/components/block-toolbar/block-toolbar-icon.mjs +1 -1
- package/build-module/components/block-toolbar/block-toolbar-icon.mjs.map +2 -2
- package/build-module/components/block-toolbar/index.mjs +8 -4
- package/build-module/components/block-toolbar/index.mjs.map +2 -2
- package/build-module/components/block-tools/index.mjs +4 -3
- package/build-module/components/block-tools/index.mjs.map +2 -2
- package/build-module/components/block-variation-transforms/index.mjs +11 -5
- package/build-module/components/block-variation-transforms/index.mjs.map +2 -2
- package/build-module/components/block-visibility/modal.mjs +2 -2
- package/build-module/components/block-visibility/modal.mjs.map +1 -1
- package/build-module/components/block-visibility/use-block-visibility.mjs +4 -3
- package/build-module/components/block-visibility/use-block-visibility.mjs.map +2 -2
- package/build-module/components/block-visibility/viewport-visibility-info.mjs +6 -1
- package/build-module/components/block-visibility/viewport-visibility-info.mjs.map +2 -2
- package/build-module/components/dimensions-tool/scale-tool.mjs +2 -2
- package/build-module/components/dimensions-tool/scale-tool.mjs.map +2 -2
- package/build-module/components/iframe/index.mjs +2 -9
- package/build-module/components/iframe/index.mjs.map +2 -2
- package/build-module/components/iframe/use-scale-canvas.mjs +0 -1
- package/build-module/components/iframe/use-scale-canvas.mjs.map +2 -2
- package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.mjs +8 -4
- package/build-module/components/inspector-controls-tabs/use-inspector-controls-tabs.mjs.map +2 -2
- package/build-module/components/link-picker/link-preview.mjs +2 -1
- package/build-module/components/link-picker/link-preview.mjs.map +2 -2
- package/build-module/components/provider/index.mjs +23 -7
- package/build-module/components/provider/index.mjs.map +2 -2
- package/build-module/components/provider/use-media-upload-settings.mjs +1 -0
- package/build-module/components/provider/use-media-upload-settings.mjs.map +2 -2
- package/build-module/components/writing-flow/use-arrow-nav.mjs +1 -1
- package/build-module/components/writing-flow/use-arrow-nav.mjs.map +2 -2
- package/build-module/hooks/auto-inspector-controls.mjs +28 -4
- package/build-module/hooks/auto-inspector-controls.mjs.map +2 -2
- package/build-module/hooks/cross-origin-isolation.mjs +9 -75
- package/build-module/hooks/cross-origin-isolation.mjs.map +2 -2
- package/build-module/hooks/custom-css.mjs +28 -2
- package/build-module/hooks/custom-css.mjs.map +2 -2
- package/build-module/private-apis.mjs +3 -1
- package/build-module/private-apis.mjs.map +2 -2
- package/build-module/store/actions.mjs +0 -8
- package/build-module/store/actions.mjs.map +2 -2
- package/build-module/store/private-keys.mjs +2 -0
- package/build-module/store/private-keys.mjs.map +2 -2
- package/build-module/store/private-selectors.mjs +4 -3
- package/build-module/store/private-selectors.mjs.map +2 -2
- package/build-module/store/reducer.mjs +78 -73
- package/build-module/store/reducer.mjs.map +2 -2
- package/build-module/store/selectors.mjs +16 -14
- package/build-module/store/selectors.mjs.map +2 -2
- package/build-style/content-rtl.css +25 -0
- package/build-style/content.css +25 -0
- package/build-style/style-rtl.css +3 -0
- package/build-style/style.css +3 -0
- package/package.json +39 -39
- package/src/components/block-bindings/attribute-control.js +8 -3
- package/src/components/block-inspector/edit-contents.js +5 -3
- package/src/components/block-list/block-html.js +13 -3
- package/src/components/block-list/block.js +10 -1
- package/src/components/block-list/content.scss +35 -0
- package/src/components/block-list/use-block-props/index.js +11 -1
- package/src/components/block-settings-menu-controls/index.js +1 -0
- package/src/components/block-styles/index.js +7 -1
- package/src/components/block-switcher/block-transformations-menu.js +2 -0
- package/src/components/block-switcher/block-variation-transformations.js +2 -0
- package/src/components/block-toolbar/block-toolbar-icon.js +6 -1
- package/src/components/block-toolbar/index.js +7 -2
- package/src/components/block-tools/index.js +11 -4
- package/src/components/block-tools/style.scss +5 -0
- package/src/components/block-variation-transforms/index.js +41 -36
- package/src/components/block-visibility/use-block-visibility.js +4 -2
- package/src/components/block-visibility/viewport-visibility-info.js +8 -1
- package/src/components/dimensions-tool/scale-tool.js +2 -2
- package/src/components/iframe/index.js +2 -12
- package/src/components/iframe/use-scale-canvas.js +0 -1
- package/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js +9 -5
- package/src/components/link-picker/link-preview.js +2 -1
- package/src/components/provider/index.js +49 -6
- package/src/components/provider/use-media-upload-settings.js +1 -0
- package/src/components/writing-flow/use-arrow-nav.js +9 -2
- package/src/hooks/auto-inspector-controls.js +31 -4
- package/src/hooks/cross-origin-isolation.js +10 -109
- package/src/hooks/custom-css.js +36 -2
- package/src/hooks/test/cross-origin-isolation.js +15 -42
- package/src/private-apis.js +2 -0
- package/src/store/actions.js +0 -8
- package/src/store/private-keys.js +1 -0
- package/src/store/private-selectors.js +6 -3
- package/src/store/reducer.js +119 -97
- package/src/store/selectors.js +59 -22
- package/src/store/test/private-selectors.js +67 -34
- package/src/store/test/reducer.js +545 -57
- package/src/store/test/selectors.js +611 -53
|
@@ -152,60 +152,33 @@ describe( 'cross-origin-isolation', () => {
|
|
|
152
152
|
expect( observeSpy ).not.toHaveBeenCalled();
|
|
153
153
|
} );
|
|
154
154
|
|
|
155
|
-
it( 'should
|
|
155
|
+
it( 'should not add crossorigin="anonymous" to images', async () => {
|
|
156
156
|
Object.defineProperty( window, 'crossOriginIsolated', {
|
|
157
157
|
value: true,
|
|
158
158
|
writable: true,
|
|
159
159
|
configurable: true,
|
|
160
160
|
} );
|
|
161
161
|
|
|
162
|
-
// Re-import the module
|
|
162
|
+
// Re-import the module to trigger the side effects
|
|
163
163
|
jest.isolateModules( () => {
|
|
164
164
|
require( '../cross-origin-isolation' );
|
|
165
165
|
} );
|
|
166
166
|
|
|
167
|
-
// Create an
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
throw new Error( 'Cross-origin access denied' );
|
|
172
|
-
},
|
|
173
|
-
} );
|
|
174
|
-
|
|
175
|
-
// This should not throw an error
|
|
176
|
-
expect( () => {
|
|
177
|
-
document.body.appendChild( iframe );
|
|
178
|
-
iframe.dispatchEvent( new Event( 'load' ) );
|
|
179
|
-
} ).not.toThrow();
|
|
180
|
-
} );
|
|
181
|
-
|
|
182
|
-
it( 'should register embed preview filter when cross-origin isolated', () => {
|
|
183
|
-
Object.defineProperty( window, 'crossOriginIsolated', {
|
|
184
|
-
value: true,
|
|
185
|
-
writable: true,
|
|
186
|
-
configurable: true,
|
|
187
|
-
} );
|
|
188
|
-
|
|
189
|
-
const hasFilter = jest.spyOn(
|
|
190
|
-
require( '@wordpress/hooks' ),
|
|
191
|
-
'hasFilter'
|
|
192
|
-
);
|
|
167
|
+
// Create an image and add it to the DOM
|
|
168
|
+
const img = document.createElement( 'img' );
|
|
169
|
+
img.setAttribute( 'src', 'https://example.com/image.jpg' );
|
|
170
|
+
document.body.appendChild( img );
|
|
193
171
|
|
|
194
|
-
//
|
|
195
|
-
|
|
196
|
-
require( '../cross-origin-isolation' );
|
|
197
|
-
} );
|
|
172
|
+
// Wait for MutationObserver callback to fire (async microtask).
|
|
173
|
+
await new Promise( ( resolve ) => setTimeout( resolve, 0 ) );
|
|
198
174
|
|
|
199
|
-
//
|
|
200
|
-
//
|
|
201
|
-
//
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
'media-experiments/disable-embed-previews'
|
|
206
|
-
);
|
|
207
|
-
} ).not.toThrow();
|
|
175
|
+
// Images should NOT get the crossorigin attribute.
|
|
176
|
+
// Under Document-Isolation-Policy: isolate-and-credentialless,
|
|
177
|
+
// the credentialless mode handles image loading without CORS headers.
|
|
178
|
+
// Adding crossorigin="anonymous" would override this and break
|
|
179
|
+
// external images that don't serve CORS headers.
|
|
180
|
+
expect( img ).not.toHaveAttribute( 'crossorigin' );
|
|
208
181
|
|
|
209
|
-
|
|
182
|
+
document.body.removeChild( img );
|
|
210
183
|
} );
|
|
211
184
|
} );
|
package/src/private-apis.js
CHANGED
|
@@ -48,6 +48,7 @@ import {
|
|
|
48
48
|
deviceTypeKey,
|
|
49
49
|
isIsolatedEditorKey,
|
|
50
50
|
isNavigationOverlayContextKey,
|
|
51
|
+
mediaUploadOnSuccessKey,
|
|
51
52
|
} from './store/private-keys';
|
|
52
53
|
import { requiresWrapperOnCopy } from './components/writing-flow/utils';
|
|
53
54
|
import { PrivateRichText } from './components/rich-text/';
|
|
@@ -129,6 +130,7 @@ lock( privateApis, {
|
|
|
129
130
|
deviceTypeKey,
|
|
130
131
|
isIsolatedEditorKey,
|
|
131
132
|
isNavigationOverlayContextKey,
|
|
133
|
+
mediaUploadOnSuccessKey,
|
|
132
134
|
useBlockElement,
|
|
133
135
|
useBlockElementRef,
|
|
134
136
|
LinkPicker,
|
package/src/store/actions.js
CHANGED
|
@@ -1767,10 +1767,6 @@ export const insertBeforeBlock =
|
|
|
1767
1767
|
return;
|
|
1768
1768
|
}
|
|
1769
1769
|
const rootClientId = select.getBlockRootClientId( clientId );
|
|
1770
|
-
const isLocked = select.getTemplateLock( rootClientId );
|
|
1771
|
-
if ( isLocked ) {
|
|
1772
|
-
return;
|
|
1773
|
-
}
|
|
1774
1770
|
|
|
1775
1771
|
const blockIndex = select.getBlockIndex( clientId );
|
|
1776
1772
|
const directInsertBlock = rootClientId
|
|
@@ -1810,10 +1806,6 @@ export const insertAfterBlock =
|
|
|
1810
1806
|
return;
|
|
1811
1807
|
}
|
|
1812
1808
|
const rootClientId = select.getBlockRootClientId( clientId );
|
|
1813
|
-
const isLocked = select.getTemplateLock( rootClientId );
|
|
1814
|
-
if ( isLocked ) {
|
|
1815
|
-
return;
|
|
1816
|
-
}
|
|
1817
1809
|
|
|
1818
1810
|
const blockIndex = select.getBlockIndex( clientId );
|
|
1819
1811
|
const directInsertBlock = rootClientId
|
|
@@ -147,7 +147,7 @@ export const getEnabledClientIdsTree = createRegistrySelector( () =>
|
|
|
147
147
|
createSelector( getEnabledClientIdsTreeUnmemoized, ( state ) => [
|
|
148
148
|
state.blocks.order,
|
|
149
149
|
state.derivedBlockEditingModes,
|
|
150
|
-
state.blockEditingModes,
|
|
150
|
+
state.blocks.blockEditingModes,
|
|
151
151
|
] )
|
|
152
152
|
);
|
|
153
153
|
|
|
@@ -170,7 +170,7 @@ export const getEnabledBlockParents = createSelector(
|
|
|
170
170
|
},
|
|
171
171
|
( state ) => [
|
|
172
172
|
state.blocks.parents,
|
|
173
|
-
state.blockEditingModes,
|
|
173
|
+
state.blocks.blockEditingModes,
|
|
174
174
|
state.settings.templateLock,
|
|
175
175
|
state.blockListSettings,
|
|
176
176
|
]
|
|
@@ -501,10 +501,13 @@ function isSectionBlockCandidate( state, clientId ) {
|
|
|
501
501
|
const disableContentOnlyForUnsyncedPatterns =
|
|
502
502
|
state.settings?.disableContentOnlyForUnsyncedPatterns;
|
|
503
503
|
|
|
504
|
+
const disableContentOnlyForTemplateParts =
|
|
505
|
+
state.settings?.disableContentOnlyForTemplateParts;
|
|
506
|
+
|
|
504
507
|
if (
|
|
505
508
|
( ( ! disableContentOnlyForUnsyncedPatterns &&
|
|
506
509
|
attributes?.metadata?.patternName ) ||
|
|
507
|
-
isTemplatePart ) &&
|
|
510
|
+
( isTemplatePart && ! disableContentOnlyForTemplateParts ) ) &&
|
|
508
511
|
! isIsolatedEditor
|
|
509
512
|
) {
|
|
510
513
|
return true;
|
package/src/store/reducer.js
CHANGED
|
@@ -601,26 +601,23 @@ const withBlockReset = ( reducer ) => ( state, action ) => {
|
|
|
601
601
|
if ( action.type === 'RESET_BLOCKS' ) {
|
|
602
602
|
/**
|
|
603
603
|
* Preserve controlled inner block flags across RESET_BLOCKS.
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
*
|
|
607
|
-
*
|
|
608
|
-
*
|
|
604
|
+
* If there are old and new blocks that:
|
|
605
|
+
* - have the same `clientId`
|
|
606
|
+
* - have the `controlledInnerBlocks` flag
|
|
607
|
+
* - don't have any own, uncontrolled children
|
|
608
|
+
* then we preserve the `controlledInnerBlocks` flag and the controlled sub-trees.
|
|
609
|
+
* Nested controllers (e.g., `post-content`, patterns) don't lose their
|
|
610
|
+
* controlled status and don't unnecessarily re-clone blocks.
|
|
609
611
|
*/
|
|
612
|
+
const newState = reducer( undefined, {
|
|
613
|
+
type: 'INSERT_BLOCKS',
|
|
614
|
+
rootClientId: '',
|
|
615
|
+
blocks: action.blocks,
|
|
616
|
+
} );
|
|
617
|
+
|
|
610
618
|
const preservedControlledInnerBlocks =
|
|
611
619
|
state?.controlledInnerBlocks ?? {};
|
|
612
620
|
|
|
613
|
-
const newState = {
|
|
614
|
-
...state,
|
|
615
|
-
byClientId: new Map(
|
|
616
|
-
getFlattenedBlocksWithoutAttributes( action.blocks )
|
|
617
|
-
),
|
|
618
|
-
attributes: new Map( getFlattenedBlockAttributes( action.blocks ) ),
|
|
619
|
-
order: mapBlockOrder( action.blocks ),
|
|
620
|
-
parents: new Map( mapBlockParents( action.blocks ) ),
|
|
621
|
-
controlledInnerBlocks: preservedControlledInnerBlocks,
|
|
622
|
-
};
|
|
623
|
-
|
|
624
621
|
// Preserve controlled inner blocks data from the old state.
|
|
625
622
|
// The maps above are rebuilt solely from action.blocks, but
|
|
626
623
|
// controlled inner blocks live under cloned IDs that aren't
|
|
@@ -637,23 +634,24 @@ const withBlockReset = ( reducer ) => ( state, action ) => {
|
|
|
637
634
|
if ( ! newState.byClientId.has( clientId ) ) {
|
|
638
635
|
continue;
|
|
639
636
|
}
|
|
637
|
+
newState.controlledInnerBlocks[ clientId ] = true;
|
|
640
638
|
const oldOrder = state.order.get( clientId );
|
|
641
639
|
if ( ! oldOrder?.length ) {
|
|
642
640
|
continue;
|
|
643
641
|
}
|
|
644
642
|
newState.order.set( clientId, oldOrder );
|
|
645
643
|
const preserveBlock = ( blockId, parentId ) => {
|
|
646
|
-
const blockData = state.byClientId
|
|
644
|
+
const blockData = state.byClientId.get( blockId );
|
|
647
645
|
if ( ! blockData ) {
|
|
648
646
|
return;
|
|
649
647
|
}
|
|
650
648
|
newState.byClientId.set( blockId, blockData );
|
|
651
649
|
newState.attributes.set(
|
|
652
650
|
blockId,
|
|
653
|
-
state.attributes
|
|
651
|
+
state.attributes.get( blockId )
|
|
654
652
|
);
|
|
655
653
|
newState.parents.set( blockId, parentId );
|
|
656
|
-
const childOrder = state.order
|
|
654
|
+
const childOrder = state.order.get( blockId ) || [];
|
|
657
655
|
newState.order.set( blockId, childOrder );
|
|
658
656
|
childOrder.forEach( ( childId ) =>
|
|
659
657
|
preserveBlock( childId, blockId )
|
|
@@ -663,42 +661,47 @@ const withBlockReset = ( reducer ) => ( state, action ) => {
|
|
|
663
661
|
}
|
|
664
662
|
}
|
|
665
663
|
|
|
666
|
-
newState.tree = new Map( state?.tree );
|
|
667
|
-
updateBlockTreeForBlocks( newState, action.blocks );
|
|
668
|
-
|
|
669
664
|
// Fix tree entries for controlled blocks. updateBlockTreeForBlocks
|
|
670
665
|
// built tree entries using action.blocks' inner block structure
|
|
671
666
|
// (entity-level IDs), but we need them to reference the preserved
|
|
672
667
|
// cloned inner blocks instead. Mutating the existing object
|
|
673
668
|
// preserves references held by ancestor tree entries.
|
|
674
669
|
for ( const clientId of Object.keys(
|
|
675
|
-
|
|
670
|
+
newState.controlledInnerBlocks
|
|
676
671
|
) ) {
|
|
677
|
-
if ( ! preservedControlledInnerBlocks[ clientId ] ) {
|
|
678
|
-
continue;
|
|
679
|
-
}
|
|
680
|
-
if ( ! newState.byClientId.has( clientId ) ) {
|
|
681
|
-
continue;
|
|
682
|
-
}
|
|
683
672
|
const controlledOrder = newState.order.get( clientId );
|
|
684
673
|
if ( ! controlledOrder?.length ) {
|
|
685
674
|
continue;
|
|
686
675
|
}
|
|
687
676
|
const innerBlocks = controlledOrder.map( ( id ) =>
|
|
688
|
-
|
|
677
|
+
state.tree.get( id )
|
|
689
678
|
);
|
|
690
679
|
const existingEntry = newState.tree.get( clientId );
|
|
691
680
|
if ( existingEntry ) {
|
|
692
681
|
existingEntry.innerBlocks = innerBlocks;
|
|
693
682
|
}
|
|
694
683
|
newState.tree.set( 'controlled||' + clientId, { innerBlocks } );
|
|
684
|
+
const preserveTreeEntry = ( blockId ) => {
|
|
685
|
+
const treeEntry = state.tree.get( blockId );
|
|
686
|
+
if ( ! treeEntry ) {
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
newState.tree.set( blockId, treeEntry );
|
|
690
|
+
const childOrder = newState.order.get( blockId ) || [];
|
|
691
|
+
childOrder.forEach( preserveTreeEntry );
|
|
692
|
+
};
|
|
693
|
+
controlledOrder.forEach( preserveTreeEntry );
|
|
695
694
|
}
|
|
696
695
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
696
|
+
// Preserve block editing modes for blocks that are not removed.
|
|
697
|
+
const preservedBlockEditingModes =
|
|
698
|
+
state?.blockEditingModes ?? new Map();
|
|
699
|
+
for ( const [ clientId, mode ] of preservedBlockEditingModes ) {
|
|
700
|
+
if ( ! newState.tree.has( clientId ) ) {
|
|
701
|
+
continue;
|
|
702
|
+
}
|
|
703
|
+
newState.blockEditingModes.set( clientId, mode );
|
|
704
|
+
}
|
|
702
705
|
|
|
703
706
|
return newState;
|
|
704
707
|
}
|
|
@@ -1083,9 +1086,6 @@ export const blocks = pipe(
|
|
|
1083
1086
|
if ( fromRootClientId === toRootClientId ) {
|
|
1084
1087
|
const subState = state.get( toRootClientId );
|
|
1085
1088
|
const fromIndex = subState.indexOf( clientIds[ 0 ] );
|
|
1086
|
-
if ( fromIndex === -1 ) {
|
|
1087
|
-
return state;
|
|
1088
|
-
}
|
|
1089
1089
|
const newState = new Map( state );
|
|
1090
1090
|
newState.set(
|
|
1091
1091
|
toRootClientId,
|
|
@@ -1290,6 +1290,25 @@ export const blocks = pipe(
|
|
|
1290
1290
|
}
|
|
1291
1291
|
return state;
|
|
1292
1292
|
},
|
|
1293
|
+
|
|
1294
|
+
blockEditingModes( state = new Map(), action ) {
|
|
1295
|
+
switch ( action.type ) {
|
|
1296
|
+
case 'SET_BLOCK_EDITING_MODE':
|
|
1297
|
+
if ( state.get( action.clientId ) === action.mode ) {
|
|
1298
|
+
return state;
|
|
1299
|
+
}
|
|
1300
|
+
return new Map( state ).set( action.clientId, action.mode );
|
|
1301
|
+
case 'UNSET_BLOCK_EDITING_MODE': {
|
|
1302
|
+
if ( ! state.has( action.clientId ) ) {
|
|
1303
|
+
return state;
|
|
1304
|
+
}
|
|
1305
|
+
const newState = new Map( state );
|
|
1306
|
+
newState.delete( action.clientId );
|
|
1307
|
+
return newState;
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
return state;
|
|
1311
|
+
},
|
|
1293
1312
|
} );
|
|
1294
1313
|
|
|
1295
1314
|
/**
|
|
@@ -2104,38 +2123,33 @@ export function editedContentOnlySection( state, action ) {
|
|
|
2104
2123
|
if ( action.type === 'EDIT_CONTENT_ONLY_SECTION' ) {
|
|
2105
2124
|
return action.clientId;
|
|
2106
2125
|
}
|
|
2107
|
-
return state;
|
|
2108
|
-
}
|
|
2109
2126
|
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
*
|
|
2116
|
-
* @return {Map} Updated state.
|
|
2117
|
-
*/
|
|
2118
|
-
export function blockEditingModes( state = new Map(), action ) {
|
|
2127
|
+
// Early return if there's no section being edited.
|
|
2128
|
+
if ( ! state ) {
|
|
2129
|
+
return state;
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2119
2132
|
switch ( action.type ) {
|
|
2120
|
-
case '
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2133
|
+
case 'REMOVE_BLOCKS':
|
|
2134
|
+
case 'REPLACE_BLOCKS':
|
|
2135
|
+
// Clear if the edited section is directly among the removed/replaced blocks.
|
|
2136
|
+
// Note: this doesn't catch the case where a parent of the edited section
|
|
2137
|
+
// is removed, since action.clientIds only contains the top-level IDs.
|
|
2138
|
+
// That edge case is handled by the StopEditingContentOnlySectionOnOutsideSelect
|
|
2139
|
+
// component in block-list/index.js.
|
|
2140
|
+
if ( action.clientIds.includes( state ) ) {
|
|
2141
|
+
return undefined;
|
|
2142
|
+
}
|
|
2143
|
+
break;
|
|
2144
|
+
case 'RESET_BLOCKS':
|
|
2145
|
+
// When all blocks are reset (e.g. navigating to a different post),
|
|
2146
|
+
// check whether the edited section still exists in the new block tree.
|
|
2147
|
+
if ( ! getFlattenedClientIds( action.blocks )[ state ] ) {
|
|
2148
|
+
return undefined;
|
|
2128
2149
|
}
|
|
2129
|
-
|
|
2130
|
-
newState.delete( action.clientId );
|
|
2131
|
-
return newState;
|
|
2132
|
-
}
|
|
2133
|
-
case 'RESET_BLOCKS': {
|
|
2134
|
-
return state.has( '' )
|
|
2135
|
-
? new Map().set( '', state.get( '' ) )
|
|
2136
|
-
: state;
|
|
2137
|
-
}
|
|
2150
|
+
break;
|
|
2138
2151
|
}
|
|
2152
|
+
|
|
2139
2153
|
return state;
|
|
2140
2154
|
}
|
|
2141
2155
|
|
|
@@ -2279,9 +2293,6 @@ function openedListViewPanels(
|
|
|
2279
2293
|
} );
|
|
2280
2294
|
return hasChanges ? { ...state, panels: newPanels } : state;
|
|
2281
2295
|
}
|
|
2282
|
-
case 'RESET_BLOCKS':
|
|
2283
|
-
// Clear all panel state when blocks are reset
|
|
2284
|
-
return { allOpen: false, panels: {} };
|
|
2285
2296
|
}
|
|
2286
2297
|
return state;
|
|
2287
2298
|
}
|
|
@@ -2378,7 +2389,6 @@ const combinedReducers = combineReducers( {
|
|
|
2378
2389
|
editedContentOnlySection,
|
|
2379
2390
|
blockVisibility,
|
|
2380
2391
|
viewportModalClientIds,
|
|
2381
|
-
blockEditingModes,
|
|
2382
2392
|
styleOverrides,
|
|
2383
2393
|
removalPromptData,
|
|
2384
2394
|
blockRemovalRules,
|
|
@@ -2509,7 +2519,7 @@ function getDerivedBlockEditingModesForTree( state, treeClientId = '' ) {
|
|
|
2509
2519
|
// so the default block editing mode is set to disabled.
|
|
2510
2520
|
const sectionRootClientId = state.settings?.[ sectionRootClientIdKey ];
|
|
2511
2521
|
const sectionClientIds = state.blocks.order.get( sectionRootClientId );
|
|
2512
|
-
const hasDisabledBlocks = Array.from( state.blockEditingModes ).some(
|
|
2522
|
+
const hasDisabledBlocks = Array.from( state.blocks.blockEditingModes ).some(
|
|
2513
2523
|
( [ , mode ] ) => mode === 'disabled'
|
|
2514
2524
|
);
|
|
2515
2525
|
const templatePartClientIds = [];
|
|
@@ -2550,18 +2560,42 @@ function getDerivedBlockEditingModesForTree( state, treeClientId = '' ) {
|
|
|
2550
2560
|
state.blocks.attributes.get( clientId )?.metadata
|
|
2551
2561
|
?.patternName
|
|
2552
2562
|
);
|
|
2563
|
+
const disableContentOnlyForTemplateParts =
|
|
2564
|
+
state.settings?.disableContentOnlyForTemplateParts;
|
|
2565
|
+
|
|
2553
2566
|
const contentOnlyParents = [
|
|
2554
2567
|
...contentOnlyTemplateLockedClientIds,
|
|
2555
2568
|
...unsyncedPatternClientIds,
|
|
2556
|
-
...( isIsolatedEditor
|
|
2569
|
+
...( isIsolatedEditor || disableContentOnlyForTemplateParts
|
|
2570
|
+
? []
|
|
2571
|
+
: templatePartClientIds ),
|
|
2557
2572
|
];
|
|
2558
2573
|
|
|
2559
2574
|
traverseBlockTree( state, treeClientId, ( block ) => {
|
|
2560
2575
|
const { clientId, name: blockName } = block;
|
|
2561
2576
|
|
|
2577
|
+
const hasEditedContentOnlySection = !! state.editedContentOnlySection;
|
|
2578
|
+
let isWithinEditedContentOnlySection = false;
|
|
2579
|
+
if ( hasEditedContentOnlySection ) {
|
|
2580
|
+
isWithinEditedContentOnlySection =
|
|
2581
|
+
clientId === state.editedContentOnlySection ||
|
|
2582
|
+
!! findParentInClientIdsList( state, clientId, [
|
|
2583
|
+
state.editedContentOnlySection,
|
|
2584
|
+
] );
|
|
2585
|
+
|
|
2586
|
+
// When a contentOnly section is being edited, all blocks outside
|
|
2587
|
+
// the section are disabled. This should never be overridable by any
|
|
2588
|
+
// other block editing modes, it helps to constrain keyboard navigation
|
|
2589
|
+
// to within the edited section.
|
|
2590
|
+
if ( ! isWithinEditedContentOnlySection ) {
|
|
2591
|
+
derivedBlockEditingModes.set( clientId, 'disabled' );
|
|
2592
|
+
return;
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
|
|
2562
2596
|
// If the block already has an explicit block editing mode set,
|
|
2563
2597
|
// don't override it.
|
|
2564
|
-
if ( state.blockEditingModes.has( clientId ) ) {
|
|
2598
|
+
if ( state.blocks.blockEditingModes.has( clientId ) ) {
|
|
2565
2599
|
return;
|
|
2566
2600
|
}
|
|
2567
2601
|
|
|
@@ -2572,12 +2606,12 @@ function getDerivedBlockEditingModesForTree( state, treeClientId = '' ) {
|
|
|
2572
2606
|
let ancestorBlockEditingMode;
|
|
2573
2607
|
let parent = state.blocks.parents.get( clientId );
|
|
2574
2608
|
while ( parent !== undefined ) {
|
|
2575
|
-
if ( state.blockEditingModes.has( parent ) ) {
|
|
2609
|
+
if ( state.blocks.blockEditingModes.has( parent ) ) {
|
|
2576
2610
|
// Checking the explicit block editing mode will be slower,
|
|
2577
2611
|
// as the block editing mode is more likely to be set on a
|
|
2578
2612
|
// distant ancestor.
|
|
2579
2613
|
ancestorBlockEditingMode =
|
|
2580
|
-
state.blockEditingModes.get( parent );
|
|
2614
|
+
state.blocks.blockEditingModes.get( parent );
|
|
2581
2615
|
}
|
|
2582
2616
|
if ( ancestorBlockEditingMode ) {
|
|
2583
2617
|
break;
|
|
@@ -2670,26 +2704,10 @@ function getDerivedBlockEditingModesForTree( state, treeClientId = '' ) {
|
|
|
2670
2704
|
}
|
|
2671
2705
|
|
|
2672
2706
|
// Set the edited section and all blocks within it to 'default', so that all changes can be made.
|
|
2673
|
-
if (
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
return;
|
|
2678
|
-
}
|
|
2679
|
-
|
|
2680
|
-
// If the block is within the edited section also use the default mode.
|
|
2681
|
-
const parentTempEditedClientId = findParentInClientIdsList(
|
|
2682
|
-
state,
|
|
2683
|
-
clientId,
|
|
2684
|
-
[ state.editedContentOnlySection ]
|
|
2685
|
-
);
|
|
2686
|
-
if ( parentTempEditedClientId ) {
|
|
2687
|
-
derivedBlockEditingModes.set( clientId, 'default' );
|
|
2688
|
-
return;
|
|
2689
|
-
}
|
|
2690
|
-
|
|
2691
|
-
// Disable blocks that are outside of the edited section.
|
|
2692
|
-
derivedBlockEditingModes.set( clientId, 'disabled' );
|
|
2707
|
+
if ( hasEditedContentOnlySection && isWithinEditedContentOnlySection ) {
|
|
2708
|
+
derivedBlockEditingModes.set( clientId, 'default' );
|
|
2709
|
+
// When there's an editedContentOnlySection, it overrides any modes that are usually
|
|
2710
|
+
// set for `contentOnlyParents`, return early to prevent continuing to code below.
|
|
2693
2711
|
return;
|
|
2694
2712
|
}
|
|
2695
2713
|
|
|
@@ -3069,7 +3087,8 @@ export function withDerivedBlockEditingModes( reducer ) {
|
|
|
3069
3087
|
case 'UPDATE_SETTINGS': {
|
|
3070
3088
|
// Recompute the entire tree if the section root,
|
|
3071
3089
|
// the effective disableContentOnlyForUnsyncedPatterns value,
|
|
3072
|
-
//
|
|
3090
|
+
// the isIsolatedEditor value, or the
|
|
3091
|
+
// disableContentOnlyForTemplateParts value changes.
|
|
3073
3092
|
// These are all values that affect the computation.
|
|
3074
3093
|
if (
|
|
3075
3094
|
state?.settings?.[ sectionRootClientIdKey ] !==
|
|
@@ -3079,7 +3098,10 @@ export function withDerivedBlockEditingModes( reducer ) {
|
|
|
3079
3098
|
!! nextState?.settings
|
|
3080
3099
|
?.disableContentOnlyForUnsyncedPatterns ||
|
|
3081
3100
|
!! state?.settings?.[ isIsolatedEditorKey ] !==
|
|
3082
|
-
!! nextState?.settings?.[ isIsolatedEditorKey ]
|
|
3101
|
+
!! nextState?.settings?.[ isIsolatedEditorKey ] ||
|
|
3102
|
+
!! state?.settings?.disableContentOnlyForTemplateParts !==
|
|
3103
|
+
!! nextState?.settings
|
|
3104
|
+
?.disableContentOnlyForTemplateParts
|
|
3083
3105
|
) {
|
|
3084
3106
|
return {
|
|
3085
3107
|
...nextState,
|
package/src/store/selectors.js
CHANGED
|
@@ -1705,9 +1705,21 @@ const canInsertBlockTypeUnmemoized = (
|
|
|
1705
1705
|
}
|
|
1706
1706
|
|
|
1707
1707
|
const blockEditingMode = getBlockEditingMode( state, rootClientId ?? '' );
|
|
1708
|
+
|
|
1709
|
+
// Compute section context early so the disabled check below can use it.
|
|
1710
|
+
const isParentSectionBlock = !! isSectionBlock( state, rootClientId );
|
|
1711
|
+
const sectionClientId = isParentSectionBlock
|
|
1712
|
+
? rootClientId
|
|
1713
|
+
: getParentSectionBlock( state, rootClientId );
|
|
1714
|
+
const isWithinSection = !! sectionClientId;
|
|
1715
|
+
|
|
1716
|
+
// Disabled containers reject all blocks, with one exception: within a
|
|
1717
|
+
// section, the default block (paragraph) is allowed through so it can
|
|
1718
|
+
// reach the content-insertion logic further down (lines 1748-1772)
|
|
1719
|
+
// which conditionally permits it where a sibling paragraph exists.
|
|
1708
1720
|
if (
|
|
1709
1721
|
blockEditingMode === 'disabled' &&
|
|
1710
|
-
blockName !== getDefaultBlockName()
|
|
1722
|
+
( ! isWithinSection || blockName !== getDefaultBlockName() )
|
|
1711
1723
|
) {
|
|
1712
1724
|
return false;
|
|
1713
1725
|
}
|
|
@@ -1723,11 +1735,6 @@ const canInsertBlockTypeUnmemoized = (
|
|
|
1723
1735
|
// It shouldn't be possible to insert inside a section block unless in
|
|
1724
1736
|
// some cases when the block is a content block.
|
|
1725
1737
|
const isContentRoleBlock = isContentBlock( blockName );
|
|
1726
|
-
const isParentSectionBlock = !! isSectionBlock( state, rootClientId );
|
|
1727
|
-
const sectionClientId = isParentSectionBlock
|
|
1728
|
-
? rootClientId
|
|
1729
|
-
: getParentSectionBlock( state, rootClientId );
|
|
1730
|
-
const isWithinSection = !! sectionClientId;
|
|
1731
1738
|
if ( isWithinSection && ! isContentRoleBlock ) {
|
|
1732
1739
|
return false;
|
|
1733
1740
|
}
|
|
@@ -1740,22 +1747,40 @@ const canInsertBlockTypeUnmemoized = (
|
|
|
1740
1747
|
return false;
|
|
1741
1748
|
}
|
|
1742
1749
|
|
|
1743
|
-
|
|
1750
|
+
/*
|
|
1751
|
+
* In content only mode, check if this container allows insertion.
|
|
1752
|
+
* We need the `isParentSectionBlock` check because section blocks
|
|
1753
|
+
* (synced patterns, contentOnly groups) have a `getBlockEditingMode`
|
|
1754
|
+
* of 'default', not 'contentOnly' — the 'contentOnly' mode is only
|
|
1755
|
+
* set on their *children*.
|
|
1756
|
+
*
|
|
1757
|
+
* Also include `disabled` alongside `contentOnly`: structural inner blocks
|
|
1758
|
+
* (e.g. Column) inside a content-only section use `disabled` mode, and they
|
|
1759
|
+
* need the same default-block sibling rules so insertion stays aligned with
|
|
1760
|
+
* `canRemoveBlock`.
|
|
1761
|
+
*/
|
|
1744
1762
|
if (
|
|
1745
|
-
|
|
1763
|
+
isWithinSection &&
|
|
1764
|
+
( isParentSectionBlock ||
|
|
1765
|
+
blockEditingMode === 'contentOnly' ||
|
|
1766
|
+
blockEditingMode === 'disabled' ) &&
|
|
1746
1767
|
! isContainerInsertableToInContentOnlyMode(
|
|
1747
1768
|
state,
|
|
1748
1769
|
blockName,
|
|
1749
1770
|
rootClientId
|
|
1750
1771
|
)
|
|
1751
1772
|
) {
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1773
|
+
const defaultBlockName = getDefaultBlockName();
|
|
1774
|
+
/*
|
|
1775
|
+
* Allow inserting the default block anywhere that another default block already exists
|
|
1776
|
+
* when in contentOnly mode. The same sibling rule applies when the parent is `disabled`
|
|
1777
|
+
* within a content-only section (see the condition above).
|
|
1778
|
+
*/
|
|
1779
|
+
if ( blockName === defaultBlockName ) {
|
|
1755
1780
|
const existingBlocks = getBlockOrder( state, rootClientId );
|
|
1756
1781
|
const hasDefaultBlock = existingBlocks.some(
|
|
1757
1782
|
( clientId ) =>
|
|
1758
|
-
getBlockName( state, clientId ) ===
|
|
1783
|
+
getBlockName( state, clientId ) === defaultBlockName
|
|
1759
1784
|
);
|
|
1760
1785
|
if ( ! hasDefaultBlock ) {
|
|
1761
1786
|
return false;
|
|
@@ -1938,11 +1963,18 @@ export function canRemoveBlock( state, clientId ) {
|
|
|
1938
1963
|
|
|
1939
1964
|
const rootBlockEditingMode = getBlockEditingMode( state, rootClientId );
|
|
1940
1965
|
const blockName = getBlockName( state, clientId );
|
|
1941
|
-
|
|
1966
|
+
const defaultBlockName = getDefaultBlockName();
|
|
1967
|
+
|
|
1968
|
+
// Check if the parent container allows insertion/removal in contentOnly
|
|
1969
|
+
// mode. We need the `isParentSectionBlock` check because section blocks
|
|
1970
|
+
// (synced patterns, contentOnly groups) have a `getBlockEditingMode` of
|
|
1971
|
+
// 'default', not 'contentOnly' — the 'contentOnly' mode is only set on
|
|
1972
|
+
// their *children*.
|
|
1942
1973
|
if (
|
|
1974
|
+
isWithinSection &&
|
|
1943
1975
|
( isParentSectionBlock ||
|
|
1944
|
-
|
|
1945
|
-
|
|
1976
|
+
blockName === defaultBlockName ||
|
|
1977
|
+
rootBlockEditingMode === 'contentOnly' ) &&
|
|
1946
1978
|
! isContainerInsertableToInContentOnlyMode(
|
|
1947
1979
|
state,
|
|
1948
1980
|
getBlockName( state, clientId ),
|
|
@@ -1951,18 +1983,18 @@ export function canRemoveBlock( state, clientId ) {
|
|
|
1951
1983
|
) {
|
|
1952
1984
|
// Allow removing the default block when other default blocks exist
|
|
1953
1985
|
// in contentOnly mode.
|
|
1954
|
-
if ( blockName ===
|
|
1986
|
+
if ( blockName === defaultBlockName ) {
|
|
1955
1987
|
const existingBlocks = getBlockOrder( state, rootClientId );
|
|
1956
1988
|
const defaultBlocks = existingBlocks.filter(
|
|
1957
|
-
( id ) => getBlockName( state, id ) ===
|
|
1989
|
+
( id ) => getBlockName( state, id ) === defaultBlockName
|
|
1958
1990
|
);
|
|
1959
1991
|
// Allow removal if there are other default blocks besides this one
|
|
1960
1992
|
if ( defaultBlocks.length > 1 ) {
|
|
1961
1993
|
return true;
|
|
1962
1994
|
}
|
|
1963
|
-
} else {
|
|
1964
1995
|
return false;
|
|
1965
1996
|
}
|
|
1997
|
+
return false;
|
|
1966
1998
|
}
|
|
1967
1999
|
|
|
1968
2000
|
return rootBlockEditingMode !== 'disabled';
|
|
@@ -2016,11 +2048,16 @@ export function canMoveBlock( state, clientId ) {
|
|
|
2016
2048
|
return false;
|
|
2017
2049
|
}
|
|
2018
2050
|
|
|
2019
|
-
// If the
|
|
2020
|
-
//
|
|
2051
|
+
// If the block is within a section and the parent is either a section
|
|
2052
|
+
// block itself or has contentOnly editing mode, check whether the inner
|
|
2053
|
+
// block should be allowed to move. We need the `isParentSectionBlock`
|
|
2054
|
+
// check because section blocks (synced patterns, contentOnly groups)
|
|
2055
|
+
// have a `getBlockEditingMode` of 'default', not 'contentOnly' — the
|
|
2056
|
+
// 'contentOnly' mode is only set on their *children*.
|
|
2021
2057
|
const isParentSectionBlock = !! isSectionBlock( state, rootClientId );
|
|
2022
2058
|
const rootBlockEditingMode = getBlockEditingMode( state, rootClientId );
|
|
2023
2059
|
if (
|
|
2060
|
+
isBlockWithinSection &&
|
|
2024
2061
|
( isParentSectionBlock || rootBlockEditingMode === 'contentOnly' ) &&
|
|
2025
2062
|
! isContainerInsertableToInContentOnlyMode(
|
|
2026
2063
|
state,
|
|
@@ -3217,8 +3254,8 @@ export function getBlockEditingMode( state, clientId = '' ) {
|
|
|
3217
3254
|
}
|
|
3218
3255
|
|
|
3219
3256
|
// In normal mode, consider that an explicitly set editing mode takes over.
|
|
3220
|
-
if ( state.blockEditingModes.has( clientId ) ) {
|
|
3221
|
-
return state.blockEditingModes.get( clientId );
|
|
3257
|
+
if ( state.blocks.blockEditingModes.has( clientId ) ) {
|
|
3258
|
+
return state.blocks.blockEditingModes.get( clientId );
|
|
3222
3259
|
}
|
|
3223
3260
|
|
|
3224
3261
|
return 'default';
|