From e061cae12a7958181e39f3185c64c4eda75844a1 Mon Sep 17 00:00:00 2001 From: Ella van Durpe Date: Tue, 5 May 2020 15:44:16 +0200 Subject: [PATCH 1/3] Writing flow: fix arrow nav in table (and generally gird) --- .../src/components/writing-flow/index.js | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/writing-flow/index.js b/packages/block-editor/src/components/writing-flow/index.js index 91b0dcfe274ec..9d77ada45eba3 100644 --- a/packages/block-editor/src/components/writing-flow/index.js +++ b/packages/block-editor/src/components/writing-flow/index.js @@ -93,10 +93,18 @@ export function isNavigationCandidate( element, keyCode, hasModifier ) { * @param {Element} target Currently focused text field. * @param {boolean} isReverse True if considering as the first field. * @param {Element} containerElement Element containing all blocks. + * @param {boolean} onlyVertical Wether to only consider tabbable elements + * that are visually above or under the + * target. * * @return {?Element} Optimal tab target, if one exists. */ -export function getClosestTabbable( target, isReverse, containerElement ) { +export function getClosestTabbable( + target, + isReverse, + containerElement, + onlyVertical +) { // Since the current focus target is not guaranteed to be a text field, // find all focusables. Tabbability is considered later. let focusableNodes = focus.focusable.find( containerElement ); @@ -112,12 +120,29 @@ export function getClosestTabbable( target, isReverse, containerElement ) { focusableNodes.indexOf( target ) + 1 ); + let targetRect; + + if ( onlyVertical ) { + targetRect = target.getBoundingClientRect(); + } + function isTabCandidate( node, i, array ) { // Not a candidate if the node is not tabbable. if ( ! focus.tabbable.isTabbableIndex( node ) ) { return false; } + if ( onlyVertical ) { + const nodeRect = node.getBoundingClientRect(); + + if ( + nodeRect.left >= targetRect.right || + nodeRect.right <= targetRect.left + ) { + return false; + } + } + // Prefer text fields... if ( isTextField( node ) ) { return true; @@ -517,7 +542,8 @@ export default function WritingFlow( { children } ) { const closestTabbable = getClosestTabbable( target, isReverse, - container.current + container.current, + true ); if ( closestTabbable ) { From b0b951569253c481a8cb4c2c27166aa92cea960e Mon Sep 17 00:00:00 2001 From: Ella van Durpe Date: Tue, 5 May 2020 16:01:17 +0200 Subject: [PATCH 2/3] Add e2e test --- .../blocks/__snapshots__/table.test.js.snap | 6 ++++++ .../specs/editor/blocks/table.test.js | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap b/packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap index c3545a01d8254..fc9d85e415e5c 100644 --- a/packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap +++ b/packages/e2e-tests/specs/editor/blocks/__snapshots__/table.test.js.snap @@ -53,3 +53,9 @@ exports[`Table displays a form for choosing the row and column count of the tabl
" `; + +exports[`Table up and down arrow navigation 1`] = ` +" +
14
23
+" +`; diff --git a/packages/e2e-tests/specs/editor/blocks/table.test.js b/packages/e2e-tests/specs/editor/blocks/table.test.js index 96bb008e613df..f67f42565baf8 100644 --- a/packages/e2e-tests/specs/editor/blocks/table.test.js +++ b/packages/e2e-tests/specs/editor/blocks/table.test.js @@ -267,4 +267,22 @@ describe( 'Table', () => { expect( await getEditedPostContent() ).toMatchSnapshot(); } ); + + it( 'up and down arrow navigation', async () => { + await insertBlock( 'Table' ); + + // Create the table. + await clickButton( createButtonLabel ); + + await page.keyboard.press( 'Tab' ); + await page.keyboard.type( '1' ); + await page.keyboard.press( 'ArrowDown' ); + await page.keyboard.type( '2' ); + await page.keyboard.press( 'ArrowRight' ); + await page.keyboard.type( '3' ); + await page.keyboard.press( 'ArrowUp' ); + await page.keyboard.type( '4' ); + + expect( await getEditedPostContent() ).toMatchSnapshot(); + } ); } ); From 2ca1e8e44a5a42b07e8e701bbeef82abf1fe14be Mon Sep 17 00:00:00 2001 From: Ella van Durpe Date: Tue, 5 May 2020 16:58:48 +0200 Subject: [PATCH 3/3] fix columns e2e test --- .../specs/editor/various/writing-flow.test.js | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/packages/e2e-tests/specs/editor/various/writing-flow.test.js b/packages/e2e-tests/specs/editor/various/writing-flow.test.js index 7a379731f8789..6f36daec78f9d 100644 --- a/packages/e2e-tests/specs/editor/various/writing-flow.test.js +++ b/packages/e2e-tests/specs/editor/various/writing-flow.test.js @@ -80,25 +80,7 @@ describe( 'Writing Flow', () => { activeBlockName = await getActiveBlockName(); expect( activeBlockName ).toBe( 'core/column' ); await page.keyboard.press( 'ArrowUp' ); - activeBlockName = await getActiveBlockName(); - expect( activeBlockName ).toBe( 'core/paragraph' ); - activeElementText = await page.evaluate( - () => document.activeElement.textContent - ); - expect( activeElementText ).toBe( '1st col' ); - - // Arrow up from first text field in nested context focuses column and - // columns wrappers before escaping out. - let activeElementBlockType; - await page.keyboard.press( 'ArrowUp' ); - activeElementBlockType = await page.evaluate( () => - document.activeElement.getAttribute( 'data-type' ) - ); - expect( activeElementBlockType ).toBe( 'core/column' ); - activeBlockName = await getActiveBlockName(); - expect( activeBlockName ).toBe( 'core/column' ); - await page.keyboard.press( 'ArrowUp' ); - activeElementBlockType = await page.evaluate( () => + const activeElementBlockType = await page.evaluate( () => document.activeElement.getAttribute( 'data-type' ) ); expect( activeElementBlockType ).toBe( 'core/columns' );