blob: 42e6394dbe50e9c2b5ad05f0423151b3fd2f6418 [file] [log] [blame]
<!DOCTYPE html> <!-- webkit-test-runner [ AsyncOverflowScrollingEnabled=true ] -->
<html>
<head>
<style>
.viewport {
border: 1px solid #000;
height: 200px;
width: 300px;
overflow: auto;
}
.grid {
position: relative;
background-color: red;
display: inline-grid;
grid-template-columns: repeat(2, 120px);
grid-template-rows: repeat(25px);
grid-gap: 1px;
}
.grid > div {
background-color: white;
box-sizing: border-box;
height: 25px;
}
</style>
<script src="../../resources/js-test-pre.js"></script>
<script>
jsTestIsAsync = true;
window.addEventListener('load', () => {
let viewport = document.querySelector('.viewport');
let canvas = document.querySelector('.canvas');
let grid = document.querySelector('.grid');
const gridGap = 1;
const rowHeight = 25;
const rowHeightWithGridGap = rowHeight + gridGap;
let data = Array(500).fill(null).map((i, index) => [
index,
index + 1
]);
canvas.style = `
height: ${(rowHeight + gridGap) * 500}px;
width: ${(120 + gridGap) * 10}px
`;
viewport.addEventListener('scroll', getVisibleRows);
function getVisibleRows()
{
let { first, last } = getVisibleRowsRange();
let top = first * rowHeightWithGridGap;
redrawRows(data.slice(first, last), top);
}
function getVisibleRowsRange()
{
const { offsetHeight, scrollTop } = viewport;
const firstVisibleRow = Math.max(Math.floor((scrollTop + gridGap) / rowHeightWithGridGap), 0);
const lastVisibleRow = Math.min(Math.floor((scrollTop + offsetHeight) / rowHeightWithGridGap), data.length - 1);
return { first: firstVisibleRow, last: lastVisibleRow + 1 };
}
function redrawRows(rows, top)
{
clearExistingRows();
grid.style.top = `${top}px`;
drawRows(rows);
}
function clearExistingRows()
{
while (grid.firstChild)
grid.removeChild(grid.firstChild);
}
function drawRows(rows)
{
rows.forEach(row => {
row.forEach((cell, i) => {
let el = document.createElement('div');
el.style = i < 1 ? 'position: sticky' : '';
el.textContent = cell;
grid.appendChild(el);
});
});
}
getVisibleRows();
requestAnimationFrame(() => {
viewport.scrollTo(0, 200);
requestAnimationFrame(() => {
viewport.scrollTo(0, 400);
shouldBeTrue("window.internals?.scrollingStateTreeAsText().indexOf('unparented node count') == -1");
finishJSTest();
})
})
}, false);
</script>
</head>
<body>
<div class="viewport">
<div class="canvas">
<div class="grid"></div>
</div>
</div>
<div id="console"></div>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>