@bbc/tv-lrud-spatial
Advanced tools
Comparing version 0.0.9 to 0.0.10
@@ -320,3 +320,5 @@ /** | ||
if (elem.id) parentContainer?.setAttribute('data-focus', elem.id); | ||
const candidateActiveChild = candidateContainer?.getAttribute('data-focus'); | ||
parentContainer?.setAttribute('data-focus', elem.id); | ||
candidateContainer?.setAttribute('data-focus', bestCandidate.id); | ||
@@ -330,5 +332,7 @@ if (!isCurrentContainer && (!isNestedContainer || isBestCandidateAContainer)) { | ||
// are already nested in | ||
const lastActiveChild = document.getElementById(candidateContainer.getAttribute('data-focus')); | ||
const lastActiveChild = document.getElementById(candidateActiveChild); | ||
return lastActiveChild || getFocusables(candidateContainer)?.[0]; | ||
const newFocus = lastActiveChild || getFocusables(candidateContainer)?.[0]; | ||
candidateContainer?.setAttribute('data-focus', newFocus?.id); | ||
return newFocus; | ||
} | ||
@@ -338,3 +342,2 @@ } | ||
if (bestCandidate?.id) parentContainer?.setAttribute('data-focus', bestCandidate.id); | ||
return bestCandidate; | ||
@@ -341,0 +344,0 @@ }; |
@@ -1,1 +0,1 @@ | ||
"use strict";exports.__esModule=true;exports.getNextFocus=void 0;var focusableSelector="[tabindex], a, input, button";var containerSelector="nav, section, .lrud-container";var focusableContainerSelector="[data-lrud-consider-container-distance]";var ignoredClass="lrud-ignore";var matches=function matches(element,selectors){var fn=Element.prototype.matches||Element.prototype.matchesSelector||Element.prototype.mozMatchesSelector||Element.prototype.msMatchesSelector||Element.prototype.oMatchesSelector||Element.prototype.webkitMatchesSelector||function(s){var matches=(this.document||this.ownerDocument).querySelectorAll(s),i=matches.length;while(--i>=0&&matches.item(i)!==this){}return i>-1};return fn.call(element,selectors)};var toArray=function toArray(nodeList){return Array.prototype.slice.call(nodeList)};var getParentContainer=function getParentContainer(elem){if(!elem.parentElement||elem.parentElement.tagName==="BODY"){return null}else if(matches(elem.parentElement,containerSelector)){return elem.parentElement}return getParentContainer(elem.parentElement)};var getFocusables=function getFocusables(scope){if(!scope)return[];var ignoredElements=toArray(scope.querySelectorAll("."+ignoredClass));if(scope.className.indexOf(ignoredClass)>-1)ignoredElements.push(scope);return toArray(scope.querySelectorAll(focusableSelector)).filter(function(node){return!ignoredElements.some(function(ignored){return ignored==node||ignored.contains(node)})})};var collectContainers=function collectContainers(initialContainer){if(!initialContainer)return[];var acc=[initialContainer];var cur=initialContainer;while(cur){cur=getParentContainer(cur);if(cur)acc.push(cur)}return acc};var getMidpointForEdge=function getMidpointForEdge(rect,dir){switch(dir){case"left":return{x:rect.left,y:(rect.top+rect.bottom)/2};case"right":return{x:rect.right,y:(rect.top+rect.bottom)/2};case"up":return{x:(rect.left+rect.right)/2,y:rect.top};case"down":return{x:(rect.left+rect.right)/2,y:rect.bottom};}};var getNearestPoint=function getNearestPoint(point,dir,rect){if(dir==="left"||dir==="right"){var x=dir==="left"?rect.right:rect.left;if(point.y<rect.top)return{x:x,y:rect.top};if(point.y>rect.bottom)return{x:x,y:rect.bottom};return{x:x,y:point.y}}else if(dir==="up"||dir==="down"){var y=dir==="up"?rect.bottom:rect.top;if(point.x<rect.left)return{x:rect.left,y:y};if(point.x>rect.right)return{x:rect.right,y:y};return{x:point.x,y:y}}};var getDistanceBetweenPoints=function getDistanceBetweenPoints(a,b){return Math.sqrt(Math.pow(a.x-b.x,2)+Math.pow(a.y-b.y,2))};var isBelow=function isBelow(a,b){return a.y>b.y};var isRight=function isRight(a,b){return a.x>b.x};var getBlockedExitDirs=function getBlockedExitDirs(container,candidateContainer){var currentAncestorContainers=collectContainers(container);var candidateAncestorContainers=collectContainers(candidateContainer);for(var i=0;i<candidateAncestorContainers.length;i++){var commonCandidate=candidateAncestorContainers[i];var spliceIndex=currentAncestorContainers.indexOf(commonCandidate);if(spliceIndex>-1){currentAncestorContainers.splice(spliceIndex);break}}return currentAncestorContainers.reduce(function(acc,cur){var dirs=((cur===null||cur===void 0?void 0:cur.getAttribute("data-block-exit"))||"").split(" ");return acc.concat(dirs)},[])};var isValidCandidate=function isValidCandidate(entryRect,exitDir,exitPoint,entryWeighting){if(entryRect.width===0&&entryRect.height===0)return false;if(!entryWeighting&&entryWeighting!=0)entryWeighting=0.3;var weightedEntryPoint={x:entryRect.left+entryRect.width*(exitDir==="left"?1-entryWeighting:exitDir==="right"?entryWeighting:0.5),y:entryRect.top+entryRect.height*(exitDir==="up"?1-entryWeighting:exitDir==="down"?entryWeighting:0.5)};if(exitDir==="left"&&isRight(exitPoint,weightedEntryPoint)||exitDir==="right"&&isRight(weightedEntryPoint,exitPoint)||exitDir==="up"&&isBelow(exitPoint,weightedEntryPoint)||exitDir==="down"&&isBelow(weightedEntryPoint,exitPoint))return true;return false};var getBestCandidate=function getBestCandidate(elem,candidates,exitDir){var bestCandidate=null;var bestDistance=Infinity;var exitRect=elem.getBoundingClientRect();var exitPoint=getMidpointForEdge(exitRect,exitDir);for(var i=0;i<candidates.length;++i){var candidate=candidates[i];var entryRect=candidate.getBoundingClientRect();var allowedOverlap=parseFloat(candidate.getAttribute("data-lrud-overlap-threshold"));if(!isValidCandidate(entryRect,exitDir,exitPoint,allowedOverlap))continue;var nearestPoint=getNearestPoint(exitPoint,exitDir,entryRect);var distance=getDistanceBetweenPoints(exitPoint,nearestPoint);if(bestDistance>distance){bestDistance=distance;bestCandidate=candidate}}return bestCandidate};var getNextFocus=function getNextFocus(elem,keyOrKeyCode,scope){var _getFocusables,_bestCandidate;if(!scope||!scope.querySelector)scope=document.body;if(!elem)return(_getFocusables=getFocusables(scope))===null||_getFocusables===void 0?void 0:_getFocusables[0];var exitDir=_keyMap[keyOrKeyCode];var parentContainer=getParentContainer(elem);var bestCandidate;if((parentContainer===null||parentContainer===void 0?void 0:parentContainer.getAttribute("data-lrud-prioritise-children"))!=="false"&&scope.contains(parentContainer)){var focusableSiblings=getFocusables(parentContainer);bestCandidate=getBestCandidate(elem,focusableSiblings,exitDir)}if(!bestCandidate){var focusableCandidates=[].concat(getFocusables(scope),toArray(scope.querySelectorAll(focusableContainerSelector)).filter(function(container){var _getFocusables2;return((_getFocusables2=getFocusables(container))===null||_getFocusables2===void 0?void 0:_getFocusables2.length)>0&&container!==parentContainer}));bestCandidate=getBestCandidate(elem,focusableCandidates,exitDir)}if(bestCandidate){var isBestCandidateAContainer=matches(bestCandidate,containerSelector);var candidateContainer=isBestCandidateAContainer?bestCandidate:getParentContainer(bestCandidate);var isCurrentContainer=candidateContainer===parentContainer;var isNestedContainer=parentContainer===null||parentContainer===void 0?void 0:parentContainer.contains(candidateContainer);var isAnscestorContainer=candidateContainer===null||candidateContainer===void 0?void 0:candidateContainer.contains(parentContainer);if(elem.id)parentContainer===null||parentContainer===void 0?void 0:parentContainer.setAttribute("data-focus",elem.id);if(!isCurrentContainer&&(!isNestedContainer||isBestCandidateAContainer)){var blockedExitDirs=getBlockedExitDirs(parentContainer,candidateContainer);if(blockedExitDirs.indexOf(exitDir)>-1)return;if(candidateContainer&&!isAnscestorContainer){var _getFocusables3;var lastActiveChild=document.getElementById(candidateContainer.getAttribute("data-focus"));return lastActiveChild||((_getFocusables3=getFocusables(candidateContainer))===null||_getFocusables3===void 0?void 0:_getFocusables3[0])}}}if((_bestCandidate=bestCandidate)===null||_bestCandidate===void 0?void 0:_bestCandidate.id)parentContainer===null||parentContainer===void 0?void 0:parentContainer.setAttribute("data-focus",bestCandidate.id);return bestCandidate};exports.getNextFocus=getNextFocus;var _left="left",_right="right",_up="up",_down="down";var _keyMap={4:_left,21:_left,37:_left,214:_left,205:_left,218:_left,5:_right,22:_right,39:_right,213:_right,206:_right,217:_right,29460:_up,19:_up,38:_up,211:_up,203:_up,215:_up,29461:_down,20:_down,40:_down,212:_down,204:_down,216:_down,"ArrowLeft":_left,"ArrowRight":_right,"ArrowUp":_up,"ArrowDown":_down}; | ||
"use strict";exports.__esModule=true;exports.getNextFocus=void 0;var focusableSelector="[tabindex], a, input, button";var containerSelector="nav, section, .lrud-container";var focusableContainerSelector="[data-lrud-consider-container-distance]";var ignoredClass="lrud-ignore";var matches=function matches(element,selectors){var fn=Element.prototype.matches||Element.prototype.matchesSelector||Element.prototype.mozMatchesSelector||Element.prototype.msMatchesSelector||Element.prototype.oMatchesSelector||Element.prototype.webkitMatchesSelector||function(s){var matches=(this.document||this.ownerDocument).querySelectorAll(s),i=matches.length;while(--i>=0&&matches.item(i)!==this){}return i>-1};return fn.call(element,selectors)};var toArray=function toArray(nodeList){return Array.prototype.slice.call(nodeList)};var getParentContainer=function getParentContainer(elem){if(!elem.parentElement||elem.parentElement.tagName==="BODY"){return null}else if(matches(elem.parentElement,containerSelector)){return elem.parentElement}return getParentContainer(elem.parentElement)};var getFocusables=function getFocusables(scope){if(!scope)return[];var ignoredElements=toArray(scope.querySelectorAll("."+ignoredClass));if(scope.className.indexOf(ignoredClass)>-1)ignoredElements.push(scope);return toArray(scope.querySelectorAll(focusableSelector)).filter(function(node){return!ignoredElements.some(function(ignored){return ignored==node||ignored.contains(node)})})};var collectContainers=function collectContainers(initialContainer){if(!initialContainer)return[];var acc=[initialContainer];var cur=initialContainer;while(cur){cur=getParentContainer(cur);if(cur)acc.push(cur)}return acc};var getMidpointForEdge=function getMidpointForEdge(rect,dir){switch(dir){case"left":return{x:rect.left,y:(rect.top+rect.bottom)/2};case"right":return{x:rect.right,y:(rect.top+rect.bottom)/2};case"up":return{x:(rect.left+rect.right)/2,y:rect.top};case"down":return{x:(rect.left+rect.right)/2,y:rect.bottom};}};var getNearestPoint=function getNearestPoint(point,dir,rect){if(dir==="left"||dir==="right"){var x=dir==="left"?rect.right:rect.left;if(point.y<rect.top)return{x:x,y:rect.top};if(point.y>rect.bottom)return{x:x,y:rect.bottom};return{x:x,y:point.y}}else if(dir==="up"||dir==="down"){var y=dir==="up"?rect.bottom:rect.top;if(point.x<rect.left)return{x:rect.left,y:y};if(point.x>rect.right)return{x:rect.right,y:y};return{x:point.x,y:y}}};var getDistanceBetweenPoints=function getDistanceBetweenPoints(a,b){return Math.sqrt(Math.pow(a.x-b.x,2)+Math.pow(a.y-b.y,2))};var isBelow=function isBelow(a,b){return a.y>b.y};var isRight=function isRight(a,b){return a.x>b.x};var getBlockedExitDirs=function getBlockedExitDirs(container,candidateContainer){var currentAncestorContainers=collectContainers(container);var candidateAncestorContainers=collectContainers(candidateContainer);for(var i=0;i<candidateAncestorContainers.length;i++){var commonCandidate=candidateAncestorContainers[i];var spliceIndex=currentAncestorContainers.indexOf(commonCandidate);if(spliceIndex>-1){currentAncestorContainers.splice(spliceIndex);break}}return currentAncestorContainers.reduce(function(acc,cur){var dirs=((cur===null||cur===void 0?void 0:cur.getAttribute("data-block-exit"))||"").split(" ");return acc.concat(dirs)},[])};var isValidCandidate=function isValidCandidate(entryRect,exitDir,exitPoint,entryWeighting){if(entryRect.width===0&&entryRect.height===0)return false;if(!entryWeighting&&entryWeighting!=0)entryWeighting=0.3;var weightedEntryPoint={x:entryRect.left+entryRect.width*(exitDir==="left"?1-entryWeighting:exitDir==="right"?entryWeighting:0.5),y:entryRect.top+entryRect.height*(exitDir==="up"?1-entryWeighting:exitDir==="down"?entryWeighting:0.5)};if(exitDir==="left"&&isRight(exitPoint,weightedEntryPoint)||exitDir==="right"&&isRight(weightedEntryPoint,exitPoint)||exitDir==="up"&&isBelow(exitPoint,weightedEntryPoint)||exitDir==="down"&&isBelow(weightedEntryPoint,exitPoint))return true;return false};var getBestCandidate=function getBestCandidate(elem,candidates,exitDir){var bestCandidate=null;var bestDistance=Infinity;var exitRect=elem.getBoundingClientRect();var exitPoint=getMidpointForEdge(exitRect,exitDir);for(var i=0;i<candidates.length;++i){var candidate=candidates[i];var entryRect=candidate.getBoundingClientRect();var allowedOverlap=parseFloat(candidate.getAttribute("data-lrud-overlap-threshold"));if(!isValidCandidate(entryRect,exitDir,exitPoint,allowedOverlap))continue;var nearestPoint=getNearestPoint(exitPoint,exitDir,entryRect);var distance=getDistanceBetweenPoints(exitPoint,nearestPoint);if(bestDistance>distance){bestDistance=distance;bestCandidate=candidate}}return bestCandidate};var getNextFocus=function getNextFocus(elem,keyOrKeyCode,scope){var _getFocusables;if(!scope||!scope.querySelector)scope=document.body;if(!elem)return(_getFocusables=getFocusables(scope))===null||_getFocusables===void 0?void 0:_getFocusables[0];var exitDir=_keyMap[keyOrKeyCode];var parentContainer=getParentContainer(elem);var bestCandidate;if((parentContainer===null||parentContainer===void 0?void 0:parentContainer.getAttribute("data-lrud-prioritise-children"))!=="false"&&scope.contains(parentContainer)){var focusableSiblings=getFocusables(parentContainer);bestCandidate=getBestCandidate(elem,focusableSiblings,exitDir)}if(!bestCandidate){var focusableCandidates=[].concat(getFocusables(scope),toArray(scope.querySelectorAll(focusableContainerSelector)).filter(function(container){var _getFocusables2;return((_getFocusables2=getFocusables(container))===null||_getFocusables2===void 0?void 0:_getFocusables2.length)>0&&container!==parentContainer}));bestCandidate=getBestCandidate(elem,focusableCandidates,exitDir)}if(bestCandidate){var isBestCandidateAContainer=matches(bestCandidate,containerSelector);var candidateContainer=isBestCandidateAContainer?bestCandidate:getParentContainer(bestCandidate);var isCurrentContainer=candidateContainer===parentContainer;var isNestedContainer=parentContainer===null||parentContainer===void 0?void 0:parentContainer.contains(candidateContainer);var isAnscestorContainer=candidateContainer===null||candidateContainer===void 0?void 0:candidateContainer.contains(parentContainer);var candidateActiveChild=candidateContainer===null||candidateContainer===void 0?void 0:candidateContainer.getAttribute("data-focus");parentContainer===null||parentContainer===void 0?void 0:parentContainer.setAttribute("data-focus",elem.id);candidateContainer===null||candidateContainer===void 0?void 0:candidateContainer.setAttribute("data-focus",bestCandidate.id);if(!isCurrentContainer&&(!isNestedContainer||isBestCandidateAContainer)){var blockedExitDirs=getBlockedExitDirs(parentContainer,candidateContainer);if(blockedExitDirs.indexOf(exitDir)>-1)return;if(candidateContainer&&!isAnscestorContainer){var _getFocusables3;var lastActiveChild=document.getElementById(candidateActiveChild);var newFocus=lastActiveChild||((_getFocusables3=getFocusables(candidateContainer))===null||_getFocusables3===void 0?void 0:_getFocusables3[0]);candidateContainer===null||candidateContainer===void 0?void 0:candidateContainer.setAttribute("data-focus",newFocus===null||newFocus===void 0?void 0:newFocus.id);return newFocus}}}return bestCandidate};exports.getNextFocus=getNextFocus;var _left="left",_right="right",_up="up",_down="down";var _keyMap={4:_left,21:_left,37:_left,214:_left,205:_left,218:_left,5:_right,22:_right,39:_right,213:_right,206:_right,217:_right,29460:_up,19:_up,38:_up,211:_up,203:_up,215:_up,29461:_down,20:_down,40:_down,212:_down,204:_down,216:_down,"ArrowLeft":_left,"ArrowRight":_right,"ArrowUp":_up,"ArrowDown":_down}; |
{ | ||
"name": "@bbc/tv-lrud-spatial", | ||
"version": "0.0.9", | ||
"version": "0.0.10", | ||
"description": "Spatial navigation library", | ||
@@ -5,0 +5,0 @@ "main": "lib/lrud.min.js", |
@@ -681,3 +681,23 @@ const puppeteer = require('puppeteer'); | ||
}); | ||
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'); | ||
expect(await page.evaluate(() => document.activeElement.id)).toEqual('item-2'); | ||
expect(await getParentContainerDataFocus('item-1')).toEqual('item-1'); | ||
expect(await getParentContainerDataFocus('item-2')).toEqual('item-2'); | ||
await page.keyboard.press('ArrowDown'); | ||
expect(await page.evaluate(() => document.activeElement.id)).toEqual('item-3'); | ||
expect(await getParentContainerDataFocus('item-1')).toEqual('item-3'); | ||
expect(await getParentContainerDataFocus('item-2')).toEqual('item-2'); | ||
await page.keyboard.press('ArrowUp'); | ||
expect(await getParentContainerDataFocus('item-1')).toEqual('item-3'); | ||
expect(await getParentContainerDataFocus('item-2')).toEqual('item-2'); | ||
await page.keyboard.press('ArrowUp'); | ||
expect(await getParentContainerDataFocus('item-1')).toEqual('item-1'); | ||
expect(await getParentContainerDataFocus('item-2')).toEqual('item-2'); | ||
}); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
95600
1112