Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions integration/__snapshots__/viewport-100-percent.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`scrollMode: if-needed (outside the scrollingElement bounding box) horizontal completely in view 1`] = `[]`;

exports[`scrollMode: if-needed (outside the scrollingElement bounding box) horizontal completely overflowing 1`] = `
[
{
"el": "html",
"left": 100,
"top": 0,
},
]
`;

exports[`scrollMode: if-needed (outside the scrollingElement bounding box) horizontal fully negative overflowing 1`] = `
[
{
"el": "html",
"left": 800,
"top": 0,
},
]
`;

exports[`scrollMode: if-needed (outside the scrollingElement bounding box) horizontal partially negative overflowing 1`] = `
[
{
"el": "html",
"left": 800,
"top": 0,
},
]
`;

exports[`scrollMode: if-needed (outside the scrollingElement bounding box) horizontal partially overflowing 1`] = `
[
{
"el": "html",
"left": 100,
"top": 0,
},
]
`;

exports[`scrollMode: if-needed (outside the scrollingElement bounding box) vertical completely above the fold 1`] = `
[
{
"el": "html",
"left": 0,
"top": 350,
},
]
`;

exports[`scrollMode: if-needed (outside the scrollingElement bounding box) vertical completely below the fold 1`] = `
[
{
"el": "html",
"left": 0,
"top": 350,
},
]
`;

exports[`scrollMode: if-needed (outside the scrollingElement bounding box) vertical completely in view 1`] = `[]`;

exports[`scrollMode: if-needed (outside the scrollingElement bounding box) vertical partially above the fold 1`] = `
[
{
"el": "html",
"left": 0,
"top": 350,
},
]
`;

exports[`scrollMode: if-needed (outside the scrollingElement bounding box) vertical partially below the fold 1`] = `
[
{
"el": "html",
"left": 0,
"top": 350,
},
]
`;
47 changes: 47 additions & 0 deletions integration/viewport-100-percent.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<script type="module" src="./utils.js"></script>
<style>
html,
body {
width: 100%;
height: 100%;
}
body {
margin: 0;
}
.padding {
width: 100vw;
height: 100vh;
}
.target {
background: crimson;
height: 100px;
width: 100px;
}

.horizontal-scroll {
display: flex;
position: absolute;
top: 0;
height: 100vh;
}

.horizontal-scroll * {
flex-shrink: 0;
}
</style>
<div class="vertical-scroll">
<div class="padding"></div>
<div class="target"></div>
<div class="padding"></div>
</div>
<div class="horizontal-scroll">
<div class="padding"></div>
<div class="target"></div>
<div class="padding"></div>
</div>
139 changes: 139 additions & 0 deletions integration/viewport-100-percent.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
beforeAll(async () => {
await page.goto('http://localhost:3000/integration/viewport-100-percent')
})

describe('scrollMode: if-needed (outside the scrollingElement bounding box)', () => {
describe('vertical', () => {
test('completely below the fold', async () => {
const actual = await page.evaluate(() => {
window.scrollTo(0, 0)
return window
.computeScrollIntoView(document.querySelector('.vertical-scroll .target'), {
scrollMode: 'if-needed',
})
.map(window.mapActions)
})
expect(actual).toHaveLength(1)
expect(actual).toMatchSnapshot()
})

test('partially below the fold', async () => {
const actual = await page.evaluate(() => {
window.scrollTo(0, 50)
return window
.computeScrollIntoView(document.querySelector('.vertical-scroll .target'), {
scrollMode: 'if-needed',
})
.map(window.mapActions)
})
expect(actual).toHaveLength(1)
expect(actual).toMatchSnapshot()
})

test('completely in view', async () => {
const actual = await page.evaluate(() => {
window.scrollTo(0, window.innerHeight / 2);
return window
.computeScrollIntoView(document.querySelector('.vertical-scroll .target'), {
scrollMode: 'if-needed',
})
.map(window.mapActions)
})
expect(actual).toHaveLength(0)
expect(actual).toMatchSnapshot()
})

test('partially above the fold', async () => {
const actual = await page.evaluate(() => {
window.scrollTo(0, window.innerHeight + 50)
return window
.computeScrollIntoView(document.querySelector('.vertical-scroll .target'), {
scrollMode: 'if-needed',
})
.map(window.mapActions)
})
expect(actual).toHaveLength(1)
expect(actual).toMatchSnapshot()
})

test('completely above the fold', async () => {
const actual = await page.evaluate(() => {
window.scrollTo(0, window.innerHeight + 100)
return window
.computeScrollIntoView(document.querySelector('.vertical-scroll .target'), {
scrollMode: 'if-needed',
})
.map(window.mapActions)
})
expect(actual).toHaveLength(1)
expect(actual).toMatchSnapshot()
})
})

describe('horizontal', () => {
test('completely overflowing', async () => {
const actual = await page.evaluate(() => {
window.scrollTo(0, 0)
return window
.computeScrollIntoView(document.querySelector('.horizontal-scroll .target'), {
scrollMode: 'if-needed',
})
.map(window.mapActions)
})
expect(actual).toHaveLength(1)
expect(actual).toMatchSnapshot()
})

test('partially overflowing', async () => {
const actual = await page.evaluate(() => {
window.scrollTo(50, 0)
return window
.computeScrollIntoView(document.querySelector('.horizontal-scroll .target'), {
scrollMode: 'if-needed',
})
.map(window.mapActions)
})
expect(actual).toHaveLength(1)
expect(actual).toMatchSnapshot()
})

test('completely in view', async () => {
const actual = await page.evaluate(() => {
window.scrollTo(window.innerWidth / 2, 0);
return window
.computeScrollIntoView(document.querySelector('.horizontal-scroll .target'), {
scrollMode: 'if-needed',
})
.map(window.mapActions)
})
expect(actual).toHaveLength(0)
expect(actual).toMatchSnapshot()
})

test('partially negative overflowing', async () => {
const actual = await page.evaluate(() => {
window.scrollTo(window.innerWidth + 50, 0)
return window
.computeScrollIntoView(document.querySelector('.horizontal-scroll .target'), {
scrollMode: 'if-needed',
})
.map(window.mapActions)
})
expect(actual).toHaveLength(1)
expect(actual).toMatchSnapshot()
})

test('fully negative overflowing', async () => {
const actual = await page.evaluate(() => {
window.scrollTo(window.innerWidth + 100, 0)
return window
.computeScrollIntoView(document.querySelector('.horizontal-scroll .target'), {
scrollMode: 'if-needed',
})
.map(window.mapActions)
})
expect(actual).toHaveLength(1)
expect(actual).toMatchSnapshot()
})
})
})
11 changes: 7 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,10 +392,13 @@ export const compute = (target: Element, options: Options): ScrollAction[] => {
targetLeft >= 0 &&
targetBottom <= viewportHeight &&
targetRight <= viewportWidth &&
targetTop >= top &&
targetBottom <= bottom &&
targetLeft >= left &&
targetRight <= right

// scrollingElement is added to the frames array even if it's not scrollable, in which case checking its bounds is not required
((frame === scrollingElement && !isScrollable(frame)) ||
(targetTop >= top &&
targetBottom <= bottom &&
targetLeft >= left &&
targetRight <= right))
) {
// Break the loop and return the computations for things that are not fully visible
return computations
Expand Down