-
Notifications
You must be signed in to change notification settings - Fork 27k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Re-enable scroll restoration behind flag (#14046)
This updates the scroll position saving to occur as the scroll position changes instead of trying to do it when the navigation is changing since the `popState` event doesn't allow us to update the leaving history state once the `popState` has occurred. The order of events that was previously attempted to save scroll position on a `popState` event (back/forward navigation) 1. history.state is already updated with state from `popState` 2. we replace state with the currently rendered page adding scroll info 3. we replace state again with the `popState` event state overriding scroll info Using this approach the above event order is no longer in conflict since we don't attempt to populate the state with scroll position while it's leaving the state and instead do it while it is still the active state in history This approach resembles existing solutions: https://www.npmjs.com/package/scroll-behavior https://twitter.com/ryanflorence/status/1029121580855488512 Fixes: #13990 Fixes: #12530 x-ref: #14075
- Loading branch information
Showing
12 changed files
with
361 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module.exports = { | ||
experimental: { | ||
scrollRestoration: true, | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import Link from 'next/link' | ||
|
||
export default () => ( | ||
<> | ||
<p id="another">hi from another</p> | ||
<Link href="/"> | ||
<a id="to-index">to index</a> | ||
</Link> | ||
</> | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import Link from 'next/link' | ||
|
||
const Page = ({ loaded }) => { | ||
const link = ( | ||
<Link href="/another"> | ||
<a | ||
id="to-another" | ||
style={{ | ||
marginLeft: 5000, | ||
width: 95000, | ||
display: 'block', | ||
}} | ||
> | ||
to another | ||
</a> | ||
</Link> | ||
) | ||
|
||
if (typeof window !== 'undefined') { | ||
window.didHydrate = true | ||
} | ||
|
||
if (loaded) { | ||
return ( | ||
<> | ||
<div | ||
style={{ | ||
width: 10000, | ||
height: 10000, | ||
background: 'orange', | ||
}} | ||
/> | ||
{link} | ||
<div id="end-el">the end</div> | ||
</> | ||
) | ||
} | ||
|
||
return link | ||
} | ||
|
||
export default Page | ||
|
||
export const getServerSideProps = () => { | ||
return { | ||
props: { | ||
loaded: true, | ||
}, | ||
} | ||
} |
89 changes: 89 additions & 0 deletions
89
test/integration/scroll-back-restoration/test/index.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* eslint-env jest */ | ||
|
||
import { join } from 'path' | ||
import webdriver from 'next-webdriver' | ||
import { | ||
killApp, | ||
findPort, | ||
launchApp, | ||
nextStart, | ||
nextBuild, | ||
check, | ||
} from 'next-test-utils' | ||
|
||
jest.setTimeout(1000 * 60 * 2) | ||
|
||
const appDir = join(__dirname, '../') | ||
let appPort | ||
let app | ||
|
||
const runTests = () => { | ||
it('should restore the scroll position on navigating back', async () => { | ||
const browser = await webdriver(appPort, '/') | ||
await browser.eval(() => | ||
document.querySelector('#to-another').scrollIntoView() | ||
) | ||
const scrollRestoration = await browser.eval( | ||
() => window.history.scrollRestoration | ||
) | ||
|
||
expect(scrollRestoration).toBe('manual') | ||
|
||
const scrollX = Math.floor(await browser.eval(() => window.scrollX)) | ||
const scrollY = Math.floor(await browser.eval(() => window.scrollY)) | ||
|
||
expect(scrollX).not.toBe(0) | ||
expect(scrollY).not.toBe(0) | ||
|
||
await browser.eval(() => window.next.router.push('/another')) | ||
|
||
await check( | ||
() => browser.eval(() => document.documentElement.innerHTML), | ||
/hi from another/ | ||
) | ||
await browser.eval(() => (window.didHydrate = false)) | ||
|
||
await browser.eval(() => window.history.back()) | ||
await check(() => browser.eval(() => window.didHydrate), { | ||
test(content) { | ||
return content | ||
}, | ||
}) | ||
|
||
const newScrollX = Math.floor(await browser.eval(() => window.scrollX)) | ||
const newScrollY = Math.floor(await browser.eval(() => window.scrollY)) | ||
|
||
console.log({ | ||
scrollX, | ||
scrollY, | ||
newScrollX, | ||
newScrollY, | ||
}) | ||
|
||
expect(scrollX).toBe(newScrollX) | ||
expect(scrollY).toBe(newScrollY) | ||
}) | ||
} | ||
|
||
describe('Scroll Restoration Support', () => { | ||
describe('dev mode', () => { | ||
beforeAll(async () => { | ||
appPort = await findPort() | ||
app = await launchApp(appDir, appPort) | ||
}) | ||
afterAll(() => killApp(app)) | ||
|
||
runTests() | ||
}) | ||
|
||
describe('server mode', () => { | ||
beforeAll(async () => { | ||
await nextBuild(appDir) | ||
appPort = await findPort() | ||
app = await nextStart(appDir, appPort) | ||
}) | ||
afterAll(() => killApp(app)) | ||
|
||
runTests() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module.exports = { | ||
experimental: { | ||
scrollRestoration: true, | ||
}, | ||
} |
10 changes: 10 additions & 0 deletions
10
test/integration/scroll-forward-restoration/pages/another.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import Link from 'next/link' | ||
|
||
export default () => ( | ||
<> | ||
<p id="another">hi from another</p> | ||
<Link href="/"> | ||
<a id="to-index">to index</a> | ||
</Link> | ||
</> | ||
) |
50 changes: 50 additions & 0 deletions
50
test/integration/scroll-forward-restoration/pages/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import Link from 'next/link' | ||
|
||
const Page = ({ loaded }) => { | ||
const link = ( | ||
<Link href="/another"> | ||
<a | ||
id="to-another" | ||
style={{ | ||
marginLeft: 5000, | ||
width: 95000, | ||
display: 'block', | ||
}} | ||
> | ||
to another | ||
</a> | ||
</Link> | ||
) | ||
|
||
if (typeof window !== 'undefined') { | ||
window.didHydrate = true | ||
} | ||
|
||
if (loaded) { | ||
return ( | ||
<> | ||
<div | ||
style={{ | ||
width: 10000, | ||
height: 10000, | ||
background: 'orange', | ||
}} | ||
/> | ||
{link} | ||
<div id="end-el">the end</div> | ||
</> | ||
) | ||
} | ||
|
||
return link | ||
} | ||
|
||
export default Page | ||
|
||
export const getServerSideProps = () => { | ||
return { | ||
props: { | ||
loaded: true, | ||
}, | ||
} | ||
} |
Oops, something went wrong.
38bd1a0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this still experimental?