|
68 | 68 | navigate(dir); |
69 | 69 |
|
70 | 70 | spatNavManager.startingPosition = null; |
71 | | - } |
| 71 | + } |
72 | 72 | } |
73 | | - |
| 73 | + |
74 | 74 | if (e.keyCode === TAB_KEY_CODE) |
75 | 75 | spatNavManager.startingPosition = null; |
76 | 76 | }); |
77 | 77 |
|
78 | 78 | /** |
79 | 79 | * mouseup EventListener : |
80 | 80 | * If the mouse click a point in the page, the point will be the starting point. |
| 81 | + * *NOTE: Let UA set the spatial navigation starting point based on click |
81 | 82 | */ |
82 | 83 | document.addEventListener('mouseup', function(e) { |
83 | 84 | spatNavManager.startingPosition = {xPosition: e.clientX, yPosition: e.clientY}; |
|
95 | 96 | // spatial navigation steps |
96 | 97 |
|
97 | 98 | // 1 |
98 | | - const startingPoint = findStartingPoint(); |
99 | | - |
100 | | - // 2 Optional step, not handled |
101 | | - // UA defined starting point |
| 99 | + let startingPoint = findStartingPoint(); |
| 100 | + let eventTarget = null; |
| 101 | + let elementFromPosition = null; |
102 | 102 |
|
103 | | - // 3 |
104 | | - let eventTarget = startingPoint; |
105 | | - |
106 | | - // 3-2 : the mouse clicked position will be come the starting point |
| 103 | + // 2 Optional step, UA defined starting point |
107 | 104 | if (spatNavManager.startingPosition) { |
108 | | - eventTarget = document.elementFromPoint(spatNavManager.startingPosition.xPosition, spatNavManager.startingPosition.yPosition); |
| 105 | + elementFromPosition = document.elementFromPoint(spatNavManager.startingPosition.xPosition, spatNavManager.startingPosition.yPosition); |
| 106 | + } |
109 | 107 |
|
| 108 | + if (elementFromPosition && startingPoint.contains(elementFromPosition)) { |
| 109 | + startingPoint = spatNavManager.startingPosition; |
110 | 110 | spatNavManager.startingPosition = null; |
| 111 | + |
| 112 | + // 3 |
| 113 | + eventTarget = elementFromPosition; |
| 114 | + } |
| 115 | + else { |
| 116 | + // 3 |
| 117 | + eventTarget = startingPoint; |
111 | 118 | } |
112 | 119 |
|
113 | 120 | // 4 |
|
310 | 317 | // find the best candidate within startingPoint |
311 | 318 | if (candidates && candidates.length > 0) { |
312 | 319 | if ((isContainer(targetElement) || targetElement.nodeName === 'BODY') && !(targetElement.nodeName === 'INPUT')) { |
313 | | - if (candidates.every(x => targetElement.focusableAreas().includes(x))) { |
| 320 | + if (candidates.every(x => targetElement.focusableAreas().includes(x))) { |
314 | 321 | // if candidates are contained in the targetElement, then the focus moves inside the targetElement |
315 | 322 | bestCandidate = selectBestCandidateFromEdge(targetElement, candidates, dir); |
316 | 323 | } |
|
320 | 327 | } |
321 | 328 | else { |
322 | 329 | bestCandidate = selectBestCandidate(targetElement, candidates, dir); |
323 | | - } |
| 330 | + } |
324 | 331 | } |
325 | | - |
| 332 | + |
326 | 333 | return bestCandidate; |
327 | 334 | } |
328 | 335 |
|
|
647 | 654 | } |
648 | 655 | } |
649 | 656 |
|
650 | | - /** |
| 657 | + /** |
651 | 658 | * isOverflow |
652 | 659 | * Whether this element is overflow or not |
653 | 660 | * @function |
|
737 | 744 | return false; |
738 | 745 | else |
739 | 746 | return ((!element.parentElement) || |
740 | | - (element.nodeName === 'IFRAME') || |
741 | 747 | (element.tabIndex >= 0) || |
742 | 748 | (isScrollable(element) && isOverflow(element))); |
743 | 749 | } |
|
1116 | 1122 | } |
1117 | 1123 |
|
1118 | 1124 | window.addEventListener('load', function() { |
1119 | | - |
| 1125 | + |
1120 | 1126 | // load SpatNav polyfill |
1121 | 1127 | focusNavigationHeuristics(); |
1122 | 1128 | }); |
|
0 commit comments