blob: 82cf035fae79929dcd32ddffaf5048f46890b211 [file] [log] [blame]
<!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>