fix scrolling to deep links

This commit is contained in:
Rich Harris
2019-01-30 15:43:42 -05:00
parent 3499631e8e
commit 1f9efd353c
7 changed files with 26 additions and 19 deletions

View File

@@ -1,4 +1,4 @@
import { nextTick } from 'svelte';
import { tick } from 'svelte';
import RootComponent, * as RootComponentStatic from '__ROOT__';
import ErrorComponent from '__ERROR__';
import {
@@ -147,7 +147,7 @@ export function navigate(target: Target, id: number, noscroll?: boolean, hash?:
});
}
function render(props: any, nullable_depth: number, scroll: ScrollPosition, noscroll: boolean, hash: string, token: {}) {
async function render(props: any, nullable_depth: number, scroll: ScrollPosition, noscroll: boolean, hash: string, token: {}) {
if (current_token !== token) return;
if (root_component) {
@@ -162,12 +162,16 @@ function render(props: any, nullable_depth: number, scroll: ScrollPosition, nosc
level.component = null;
root_component.$set({ child: props.child });
nextTick(() => {
// then render new stuff
// TODO do we need to call `flush` before doing this?
level.component = component;
root_component.$set(props);
});
await tick();
// then render new stuff
// TODO do we need to call `flush` before doing this?
level.component = component;
root_component.$set(props);
// if we need to scroll to a deep link, we need to
// wait for the current update to happen first
if (!noscroll && hash) await tick();
} else {
// first load — remove SSR'd <head> contents
const start = document.querySelector('#sapper-head-start');
@@ -193,6 +197,7 @@ function render(props: any, nullable_depth: number, scroll: ScrollPosition, nosc
if (hash) {
// scroll is an element id (from a hash), we need to compute y.
const deep_linked = document.querySelector(hash);
if (deep_linked) {
scroll = {
x: 0,

View File

@@ -20,19 +20,18 @@ describe('basics', function() {
let prefetchRoutes: () => Promise<void>;
let prefetch: (href: string) => Promise<void>;
let goto: (href: string) => Promise<void>;
let title: () => Promise<string>;
// hooks
before(async () => {
await build({ cwd: __dirname });
runner = new AppRunner(__dirname, '__sapper__/build/server/server.js');
({ base, page, start, prefetchRoutes, prefetch, goto } = await runner.start());
({ base, page, start, prefetchRoutes, prefetch, goto, title } = await runner.start());
});
after(() => runner.end());
const title = () => page.$eval('h1', node => node.textContent);
it('serves /', async () => {
await page.goto(base);

View File

@@ -1,4 +1,3 @@
import * as path from 'path';
import * as assert from 'assert';
import * as puppeteer from 'puppeteer';
import { build } from '../../../api';
@@ -17,19 +16,18 @@ describe('preloading', function() {
// helpers
let start: () => Promise<void>;
let prefetchRoutes: () => Promise<void>;
let title: () => Promise<string>;
// hooks
before(async () => {
await build({ cwd: __dirname });
runner = new AppRunner(__dirname, '__sapper__/build/server/server.js');
({ base, page, start, prefetchRoutes } = await runner.start());
({ base, page, start, prefetchRoutes, title } = await runner.start());
});
after(() => runner.end());
const title = () => page.$eval('h1', node => node.textContent);
it('serializes Set objects returned from preload', async () => {
await page.goto(`${base}/preload-values/set`);

View File

@@ -1,2 +1,4 @@
<h1>Another tall page</h1>
<div style="height: 9999px"></div>
<p id="bar">element</p>

View File

@@ -8,6 +8,8 @@
});
</script>
<h1>A tall page</h1>
<a href="tall-page#foo">scroll to foo</a>
<div style="height: 9999px"></div>

View File

@@ -14,13 +14,14 @@ describe('scroll', function() {
// helpers
let start: () => Promise<void>;
let prefetchRoutes: () => Promise<void>;
let title: () => Promise<string>;
// hooks
before(async () => {
await build({ cwd: __dirname });
runner = new AppRunner(__dirname, '__sapper__/build/server/server.js');
({ base, page, start, prefetchRoutes } = await runner.start());
({ base, page, start, prefetchRoutes, title } = await runner.start());
});
after(() => runner.end());
@@ -85,6 +86,7 @@ describe('scroll', function() {
await page.click('[href="another-tall-page#bar"]');
await wait(50);
assert.equal(await title(), 'Another tall page');
const scrollY = await page.evaluate(() => window.scrollY);
assert.ok(scrollY > 0);
});

View File

@@ -12,19 +12,18 @@ describe('store', function() {
// helpers
let start: () => Promise<void>;
let title: () => Promise<string>;
// hooks
before(async () => {
await build({ cwd: __dirname });
runner = new AppRunner(__dirname, '__sapper__/build/server/server.js');
({ base, page, start } = await runner.start());
({ base, page, start, title } = await runner.start());
});
after(() => runner.end());
const title = () => page.$eval('h1', node => node.textContent);
it('renders store props', async () => {
await page.goto(`${base}/store`);