Skip to content

Commit fd5aa74

Browse files
getdavetalldanjeryjramonjddraganescu
authored andcommitted
Disable Zoom Out if no section root to allow for Theme opt in (WordPress#67232)
* Disable toolbar and auto inserter behaviour if no section root * Remove useless coercion Co-authored-by: Ramon <[email protected]> * Remove more coercion copy/paste Co-authored-by: Ramon <[email protected]> * Add section root to Zoom Out e2e test * Add test coverage * Add some test coverage * Try e2e test fix by reverting all template part changes in Theme * Remove need to exit Zoom Out * Ensure a main tag * Update tests to expect the click-through behavior * Simplify selection --------- Co-authored-by: getdave <[email protected]> Co-authored-by: talldan <[email protected]> Co-authored-by: jeryj <[email protected]> Co-authored-by: ramonjd <[email protected]> Co-authored-by: draganescu <[email protected]>
1 parent a2ef851 commit fd5aa74

File tree

5 files changed

+127
-16
lines changed

5 files changed

+127
-16
lines changed

packages/block-editor/src/components/inserter/menu.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ function InserterMenu(
5858
( select ) => unlock( select( blockEditorStore ) ).isZoomOut(),
5959
[]
6060
);
61+
const hasSectionRootClientId = useSelect(
62+
( select ) =>
63+
!! unlock( select( blockEditorStore ) ).getSectionRootClientId(),
64+
[]
65+
);
6166
const [ filterValue, setFilterValue, delayedFilterValue ] =
6267
useDebouncedInput( __experimentalFilterValue );
6368
const [ hoveredItem, setHoveredItem ] = useState( null );
@@ -81,7 +86,9 @@ function InserterMenu(
8186
const [ selectedTab, setSelectedTab ] = useState( getInitialTab() );
8287

8388
const shouldUseZoomOut =
84-
selectedTab === 'patterns' || selectedTab === 'media';
89+
hasSectionRootClientId &&
90+
( selectedTab === 'patterns' || selectedTab === 'media' );
91+
8592
useZoomOut( shouldUseZoomOut && isLargeViewport );
8693

8794
const [ destinationRootClientId, onInsertBlocks, onToggleInsertionPoint ] =

packages/editor/src/components/header/index.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
PATTERN_POST_TYPE,
3131
NAVIGATION_POST_TYPE,
3232
} from '../../store/constants';
33+
import { unlock } from '../../lock-unlock';
3334

3435
const toolbarVariations = {
3536
distractionFreeDisabled: { y: '-50px' },
@@ -102,6 +103,13 @@ function Header( {
102103
( hasFixedToolbar &&
103104
( ! hasBlockSelection || isBlockToolsCollapsed ) ) );
104105
const hasBackButton = useHasBackButton();
106+
107+
const hasSectionRootClientId = useSelect(
108+
( select ) =>
109+
!! unlock( select( blockEditorStore ) ).getSectionRootClientId(),
110+
[]
111+
);
112+
105113
/*
106114
* The edit-post-header classname is only kept for backward compatability
107115
* as some plugins might be relying on its presence.
@@ -169,9 +177,11 @@ function Header( {
169177
forceIsAutosaveable={ forceIsDirty }
170178
/>
171179

172-
{ canBeZoomedOut && isWideViewport && (
173-
<ZoomOutToggle disabled={ forceDisableBlockTools } />
174-
) }
180+
{ canBeZoomedOut &&
181+
isWideViewport &&
182+
hasSectionRootClientId && (
183+
<ZoomOutToggle disabled={ forceDisableBlockTools } />
184+
) }
175185

176186
{ ( isWideViewport || ! showIconLabels ) && (
177187
<PinnedItems.Slot scope="core" />

test/e2e/specs/editor/various/parsing-patterns.spec.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,8 @@ test.describe( 'Parsing patterns', () => {
3737
} );
3838
} );
3939

40-
// Exit zoom out mode and select the inner buttons block to ensure
40+
// Select the inner buttons block to ensure
4141
// the correct insertion point is selected.
42-
await page.getByRole( 'button', { name: 'Zoom Out' } ).click();
4342
await editor.selectBlocks(
4443
editor.canvas.locator( 'role=document[name="Block: Button"i]' )
4544
);

test/e2e/specs/editor/various/pattern-overrides.spec.js

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -268,12 +268,25 @@ test.describe( 'Pattern Overrides', () => {
268268
} );
269269

270270
await editor.setContent( '' );
271+
await editor.switchEditorTool( 'Design' );
271272

273+
// Insert a `<main>` group block.
274+
// In zoomed out and write mode it acts as the section root.
275+
// Inside is a pattern that acts as a section.
272276
await editor.insertBlock( {
273-
name: 'core/block',
274-
attributes: { ref: id },
277+
name: 'core/group',
278+
attributes: { tagName: 'main' },
279+
innerBlocks: [
280+
{
281+
name: 'core/block',
282+
attributes: { ref: id },
283+
},
284+
],
275285
} );
276286

287+
const groupBlock = editor.canvas.getByRole( 'document', {
288+
name: 'Block: Group',
289+
} );
277290
const patternBlock = editor.canvas.getByRole( 'document', {
278291
name: 'Block: Pattern',
279292
} );
@@ -290,14 +303,35 @@ test.describe( 'Pattern Overrides', () => {
290303
hasText: 'No Overrides or Binding',
291304
} );
292305

293-
await test.step( 'Zoomed in / Design mode', async () => {
294-
await editor.switchEditorTool( 'Design' );
295-
// In zoomed in and design mode the pattern block and child blocks
296-
// with bindings are editable.
306+
await test.step( 'Click-through behavior', async () => {
307+
// With the group block selected, all the inner blocks of the pattern
308+
// are inert due to the 'click-through' behavior, that requires the
309+
// pattern block be selected first before its inner blocks are selectable.
310+
await editor.selectBlocks( groupBlock );
297311
await expect( patternBlock ).not.toHaveAttribute(
298312
'inert',
299313
'true'
300314
);
315+
await expect( blockWithOverrides ).toHaveAttribute(
316+
'inert',
317+
'true'
318+
);
319+
await expect( blockWithBindings ).toHaveAttribute(
320+
'inert',
321+
'true'
322+
);
323+
await expect( blockWithoutOverridesOrBindings ).toHaveAttribute(
324+
'inert',
325+
'true'
326+
);
327+
} );
328+
329+
await test.step( 'Zoomed in / Design mode', async () => {
330+
await editor.selectBlocks( patternBlock );
331+
332+
// Once selected and in zoomed in/design mode the child blocks
333+
// of the pattern with bindings are editable, but unbound
334+
// blocks are inert.
301335
await expect( blockWithOverrides ).not.toHaveAttribute(
302336
'inert',
303337
'true'
@@ -314,11 +348,16 @@ test.describe( 'Pattern Overrides', () => {
314348

315349
await test.step( 'Zoomed in / Write mode - pattern as a section', async () => {
316350
await editor.switchEditorTool( 'Write' );
351+
317352
// The pattern block is still editable as a section.
318353
await expect( patternBlock ).not.toHaveAttribute(
319354
'inert',
320355
'true'
321356
);
357+
358+
// Ensure the pattern block is selected.
359+
await editor.selectBlocks( patternBlock );
360+
322361
// Child blocks of the pattern with bindings are editable.
323362
await expect( blockWithOverrides ).not.toHaveAttribute(
324363
'inert',
@@ -336,11 +375,18 @@ test.describe( 'Pattern Overrides', () => {
336375

337376
await test.step( 'Zoomed out / Write mode - pattern as a section', async () => {
338377
await page.getByLabel( 'Zoom Out' ).click();
339-
// In zoomed out only the pattern block is editable, as in this scenario it's a section.
378+
// In zoomed out only the pattern block is editable,
379+
// as in this scenario it's a section.
340380
await expect( patternBlock ).not.toHaveAttribute(
341381
'inert',
342382
'true'
343383
);
384+
385+
// Ensure the pattern block is selected before checking the child blocks
386+
// to ensure the click-through behavior isn't interfering.
387+
await editor.selectBlocks( patternBlock );
388+
389+
// None of the child blocks are editable in zoomed out mode.
344390
await expect( blockWithOverrides ).toHaveAttribute(
345391
'inert',
346392
'true'
@@ -357,11 +403,17 @@ test.describe( 'Pattern Overrides', () => {
357403

358404
await test.step( 'Zoomed out / Design mode - pattern as a section', async () => {
359405
await editor.switchEditorTool( 'Design' );
360-
// In zoomed out only the pattern block is editable, as in this scenario it's a section.
406+
// In zoomed out only the pattern block is editable,
407+
// as in this scenario it's a section.
361408
await expect( patternBlock ).not.toHaveAttribute(
362409
'inert',
363410
'true'
364411
);
412+
413+
// Ensure the pattern block is selected before checking the child blocks
414+
// to ensure the click-through behavior isn't interfering.
415+
await editor.selectBlocks( patternBlock );
416+
365417
await expect( blockWithOverrides ).toHaveAttribute(
366418
'inert',
367419
'true'
@@ -376,7 +428,7 @@ test.describe( 'Pattern Overrides', () => {
376428
);
377429
} );
378430

379-
// Zoom out and group the pattern.
431+
// Zoom out and group the pattern so that it's no longer a section.
380432
await page.getByLabel( 'Zoom Out' ).click();
381433
await editor.selectBlocks( patternBlock );
382434
await editor.clickBlockOptionsMenuItem( 'Group' );

test/e2e/specs/site-editor/zoom-out.spec.js

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' );
55

66
const EDITOR_ZOOM_OUT_CONTENT = `
7-
<!-- wp:group {"style":{"spacing":{"padding":{"top":"0","bottom":"0","left":"0","right":"0"}},"dimensions":{"minHeight":"100vh"}},"backgroundColor":"base-2","layout":{"type":"flex","orientation":"vertical","verticalAlignment":"space-between"}} -->
7+
<!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->
8+
<main class="wp-block-group"><!-- wp:group {"style":{"spacing":{"padding":{"top":"0","bottom":"0","left":"0","right":"0"}},"dimensions":{"minHeight":"100vh"}},"backgroundColor":"base-2","layout":{"type":"flex","orientation":"vertical","verticalAlignment":"space-between"}} -->
89
<div class="wp-block-group has-base-2-background-color has-background" style="min-height:100vh;padding-top:0;padding-right:0;padding-bottom:0;padding-left:0"><!-- wp:paragraph -->
910
<p>First Section Start</p>
1011
<!-- /wp:paragraph -->
@@ -58,6 +59,21 @@ const EDITOR_ZOOM_OUT_CONTENT = `
5859
<!-- wp:paragraph -->
5960
<p>Fourth Section End</p>
6061
<!-- /wp:paragraph --></div>
62+
<!-- /wp:group --></main>
63+
<!-- /wp:group -->`;
64+
65+
const EDITOR_ZOOM_OUT_CONTENT_NO_SECTION_ROOT = `<!-- wp:group {"style":{"spacing":{"padding":{"top":"0","bottom":"0","left":"0","right":"0"}},"dimensions":{"minHeight":"100vh"}},"backgroundColor":"base-2","layout":{"type":"flex","orientation":"vertical","verticalAlignment":"space-between"}} -->
66+
<div class="wp-block-group has-base-2-background-color has-background" style="min-height:100vh;padding-top:0;padding-right:0;padding-bottom:0;padding-left:0"><!-- wp:paragraph -->
67+
<p>First Section Start</p>
68+
<!-- /wp:paragraph -->
69+
70+
<!-- wp:paragraph {"style":{"layout":{"selfStretch":"fit","flexSize":null}}} -->
71+
<p>First Section Center</p>
72+
<!-- /wp:paragraph -->
73+
74+
<!-- wp:paragraph -->
75+
<p>First Section End</p>
76+
<!-- /wp:paragraph --></div>
6177
<!-- /wp:group -->`;
6278

6379
test.describe( 'Zoom Out', () => {
@@ -67,6 +83,8 @@ test.describe( 'Zoom Out', () => {
6783

6884
test.afterAll( async ( { requestUtils } ) => {
6985
await requestUtils.activateTheme( 'twentytwentyone' );
86+
await requestUtils.deleteAllTemplates( 'wp_template' );
87+
await requestUtils.deleteAllTemplates( 'wp_template_part' );
7088
} );
7189

7290
test.beforeEach( async ( { admin } ) => {
@@ -215,4 +233,29 @@ test.describe( 'Zoom Out', () => {
215233
await expect( thirdSectionEnd ).toBeInViewport();
216234
await expect( fourthSectionStart ).not.toBeInViewport();
217235
} );
236+
237+
test( 'Zoom Out cannot be activated when the section root is missing', async ( {
238+
page,
239+
editor,
240+
} ) => {
241+
await editor.setContent( EDITOR_ZOOM_OUT_CONTENT_NO_SECTION_ROOT );
242+
243+
// Check that the Zoom Out toggle button is not visible.
244+
await expect(
245+
page.getByRole( 'button', { name: 'Zoom Out' } )
246+
).toBeHidden();
247+
248+
// Check that activating the Patterns tab in the Inserter does not activate
249+
// Zoom Out.
250+
await page
251+
.getByRole( 'button', {
252+
name: 'Block Inserter',
253+
exact: true,
254+
} )
255+
.click();
256+
257+
await page.getByRole( 'tab', { name: 'Patterns' } ).click();
258+
259+
await expect( page.locator( '.is-zoomed-out' ) ).toBeHidden();
260+
} );
218261
} );

0 commit comments

Comments
 (0)