From dd9d2b9a737ed31b3bd6f9fa1bf27f24c02e1fb1 Mon Sep 17 00:00:00 2001 From: Murray Coghill <7268569+Murreey@users.noreply.github.com> Date: Fri, 26 Jan 2024 16:23:28 +0000 Subject: [PATCH 1/2] Refactor how data-focus is applied --- lib/lrud.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/lrud.js b/lib/lrud.js index 54e6df1..3715977 100644 --- a/lib/lrud.js +++ b/lib/lrud.js @@ -291,6 +291,9 @@ export const getNextFocus = (elem, keyOrKeyCode, scope) => { // Get parent focus container const parentContainer = getParentContainer(elem); + if (parentContainer && matches(elem, focusableSelector)) { + parentContainer.setAttribute('data-focus', elem.id); + } let bestCandidate; @@ -317,10 +320,6 @@ export const getNextFocus = (elem, keyOrKeyCode, scope) => { const isNestedContainer = parentContainer?.contains(candidateContainer); const isAnscestorContainer = candidateContainer?.contains(parentContainer); - const candidateActiveChild = candidateContainer?.getAttribute('data-focus'); - parentContainer?.setAttribute('data-focus', elem.id); - candidateContainer?.setAttribute('data-focus', bestCandidate.id); - if (!isCurrentContainer && (!isNestedContainer || isBestCandidateAContainer)) { const blockedExitDirs = getBlockedExitDirs(parentContainer, candidateContainer); if (blockedExitDirs.indexOf(exitDir) > -1) return; @@ -328,13 +327,15 @@ export const getNextFocus = (elem, keyOrKeyCode, scope) => { if (candidateContainer && !isAnscestorContainer) { // Ignore active child behaviour when moving into a container that we // are already nested in - const lastActiveChild = document.getElementById(candidateActiveChild); + const lastActiveChild = document.getElementById(candidateContainer?.getAttribute('data-focus')); const newFocus = lastActiveChild || getFocusables(candidateContainer)?.[0]; candidateContainer?.setAttribute('data-focus', newFocus?.id); return newFocus; } } + + candidateContainer?.setAttribute('data-focus', bestCandidate.id); } return bestCandidate; From 3d6f7846ec996f030cfb43b273fd4c1752809d5e Mon Sep 17 00:00:00 2001 From: Murray Coghill <7268569+Murreey@users.noreply.github.com> Date: Fri, 26 Jan 2024 16:24:01 +0000 Subject: [PATCH 2/2] New test --- test/lrud.test.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/lrud.test.js b/test/lrud.test.js index 7b73e08..7869781 100644 --- a/test/lrud.test.js +++ b/test/lrud.test.js @@ -8,6 +8,8 @@ describe('LRUD spatial', () => { let page; let context; + const getParentContainerDataFocus = (id) => page.evaluate((id) => document.getElementById(id).parentElement.getAttribute('data-focus'), id); + beforeAll(async () => { try { await server.listen(); @@ -688,7 +690,6 @@ describe('LRUD spatial', () => { }); it('should only store the last active child ID if the child is not inside another container', async () => { - const getParentContainerDataFocus = (id) => page.evaluate((id) => document.getElementById(id).parentElement.getAttribute('data-focus'), id); await page.goto(`${testPath}/4c-v-5f-nested.html`); await page.evaluate(() => document.getElementById('item-1').focus()); await page.keyboard.press('ArrowDown'); @@ -706,5 +707,14 @@ describe('LRUD spatial', () => { expect(await getParentContainerDataFocus('item-1')).toEqual('item-1'); expect(await getParentContainerDataFocus('item-2')).toEqual('item-2'); }); + + it('does not update the new active child ID if the exit was blocked', async () => { + await page.goto(`${testPath}/3c-h-6f-blocked-exit.html`); + await page.evaluate(() => document.getElementById('item-2').focus()); + await page.keyboard.press('ArrowDown'); + expect(await getParentContainerDataFocus('item-2')).toEqual('item-2'); + expect(await page.evaluate(() => document.activeElement.id)).toEqual('item-2'); + expect(await getParentContainerDataFocus('item-3')).toEqual(null); + }); }); });