| <!DOCTYPE html> |
| <script src="../../resources/testharness.js"></script> |
| <script src="../../resources/testharnessreport.js"></script> |
| <style> |
| ::-webkit-scrollbar { |
| width: 10px; |
| height: 10px; |
| } |
| ::-webkit-scrollbar-thumb { |
| background: #aaa; |
| } |
| #grid { |
| display:grid; |
| grid-template-columns: 310px 310px; |
| grid-gap: 30px; |
| } |
| .spacer { |
| width: 2000px; |
| height: 2000px; |
| } |
| .container { |
| width: 310px; |
| height: 310px; |
| position: absolute; |
| overflow: scroll; |
| background-color: lightgrey; |
| } |
| .focusable { |
| position: absolute; |
| background-color: coral; |
| left: 400px; |
| top: 400px; |
| border: 1px solid black; |
| box-sizing: border-box; |
| } |
| |
| .focusable.smaller { |
| width: 100px; |
| height: 100px; |
| } |
| .focusable.larger { |
| width: 400px; |
| height: 400px; |
| } |
| |
| .bullseye { |
| width: 10px; |
| height: 10px; |
| position: absolute; |
| left: calc(50% - 5px); |
| top: calc(50% - 5px); |
| background-color: red; |
| } |
| </style> |
| <p> |
| Tests that scrollable areas are scrolled to the correct location when an |
| element is focused. |
| </p> |
| <p> |
| Focus should center the element when fully offscreen; avoid scrolling if |
| fully onscreen. When partially offscreen, horizontal axis shouldn't scroll |
| and vertical axis should align the nearest edges. |
| </p> |
| <div id="grid"> |
| <div id="testSmaller"> |
| <p> |
| Element smaller than scrollport. |
| <button onclick="focusSmaller()">Focus</button> |
| </p> |
| <div class="container"> |
| <div class="spacer"></div> |
| <div class="focusable smaller" tabindex="-1"></div> |
| </div> |
| </div> |
| |
| <div id="testLarger"> |
| <p> |
| Element larger than scrollport. |
| <button onclick="focusLarger()">Focus</button> |
| </p> |
| <div class="container"> |
| <div class="spacer"></div> |
| <div class="focusable larger" tabindex="-1"> |
| <div class="bullseye"></div> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| <script> |
| function focusSmaller() { |
| const e = document.querySelector('#testSmaller .focusable'); |
| e.focus(); |
| e.blur() |
| } |
| function focusLarger() { |
| const e = document.querySelector('#testLarger .focusable'); |
| e.focus(); |
| e.blur(); |
| } |
| |
| function runTest(container, initialScroll, expectedFinalScroll) { |
| container.scrollLeft = initialScroll.x; |
| container.scrollTop = initialScroll.y; |
| |
| const focusable = container.querySelector('.focusable'); |
| focusable.focus(); |
| focusable.blur(); |
| |
| assert_equals(container.scrollLeft, expectedFinalScroll.x, "Expected horizontal scroll."); |
| assert_equals(container.scrollTop, expectedFinalScroll.y, "Expected vertical scroll."); |
| }; |
| |
| const smallerContainer = document.querySelector('#testSmaller .container'); |
| const largerContainer = document.querySelector('#testLarger .container'); |
| |
| // Smaller fully offscreen element. |
| test(runTest.bind(null, smallerContainer, {x: 10, y: 10}, {x: 300, y: 300}), |
| "Smaller fully offscreen element is centered when focused from left/top."); |
| test(runTest.bind(null, smallerContainer, {x: 500, y: 500}, {x: 300, y: 300}), |
| "Smaller fully offscreen element is centered when focused right/bottom."); |
| |
| // Smaller fully onscreen element. |
| test(runTest.bind(null, smallerContainer, {x: 395, y: 395}, {x: 395, y: 395}), |
| "Smaller fully onscreen element at top/left does not scroll when focused."); |
| test(runTest.bind(null, smallerContainer, {x: 205, y: 205}, {x: 205, y: 205}), |
| "Smaller fully onscreen element at bottom/right does not scroll when focused."); |
| |
| // Smaller partially onscreen element. |
| test(runTest.bind(null, smallerContainer, {x: 450, y: 450}, {x: 450, y: 400}), |
| "Smaller partially onscreen element at top/left aligns only top edges."); |
| test(runTest.bind(null, smallerContainer, {x: 150, y: 150}, {x: 150, y: 200}), |
| "Smaller partially onscreen element at bottom/right aligns only bottom edges."); |
| |
| // Larger fully offscreen element. |
| test(runTest.bind(null, largerContainer, {x: 10, y: 10}, {x: 450, y: 450}), |
| "Larger fully offscreen element is centered when focused from left/top."); |
| test(runTest.bind(null, largerContainer, {x: 800, y: 800}, {x: 450, y: 450}), |
| "Larger fully offscreen element is centered when focused right/bottom."); |
| |
| // Larger fully onscreen element. |
| test(runTest.bind(null, largerContainer, {x: 405, y: 405}, {x: 405, y: 405}), |
| "Larger fully onscreen element does not scroll when focused from left/top."); |
| test(runTest.bind(null, largerContainer, {x: 495, y: 495}, {x: 495, y: 495}), |
| "Larger fully onscreen element does not scroll when focused from right/bottom."); |
| |
| // Larger partially onscreen element. |
| test(runTest.bind(null, largerContainer, {x: 650, y: 650}, {x: 650, y: 500}), |
| "Larger partially onscreen element at top/left aligns only bottom edges."); |
| test(runTest.bind(null, largerContainer, {x: 250, y: 250}, {x: 250, y: 400}), |
| "Larger partially onscreen element at bottom/right aligns only top edges."); |
| </script> |