mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-14 20:14:39 +00:00
fix scrolling to deep links
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { nextTick } from 'svelte';
|
import { tick } from 'svelte';
|
||||||
import RootComponent, * as RootComponentStatic from '__ROOT__';
|
import RootComponent, * as RootComponentStatic from '__ROOT__';
|
||||||
import ErrorComponent from '__ERROR__';
|
import ErrorComponent from '__ERROR__';
|
||||||
import {
|
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 (current_token !== token) return;
|
||||||
|
|
||||||
if (root_component) {
|
if (root_component) {
|
||||||
@@ -162,12 +162,16 @@ function render(props: any, nullable_depth: number, scroll: ScrollPosition, nosc
|
|||||||
level.component = null;
|
level.component = null;
|
||||||
root_component.$set({ child: props.child });
|
root_component.$set({ child: props.child });
|
||||||
|
|
||||||
nextTick(() => {
|
await tick();
|
||||||
// then render new stuff
|
|
||||||
// TODO do we need to call `flush` before doing this?
|
// then render new stuff
|
||||||
level.component = component;
|
// TODO do we need to call `flush` before doing this?
|
||||||
root_component.$set(props);
|
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 {
|
} else {
|
||||||
// first load — remove SSR'd <head> contents
|
// first load — remove SSR'd <head> contents
|
||||||
const start = document.querySelector('#sapper-head-start');
|
const start = document.querySelector('#sapper-head-start');
|
||||||
@@ -193,6 +197,7 @@ function render(props: any, nullable_depth: number, scroll: ScrollPosition, nosc
|
|||||||
if (hash) {
|
if (hash) {
|
||||||
// scroll is an element id (from a hash), we need to compute y.
|
// scroll is an element id (from a hash), we need to compute y.
|
||||||
const deep_linked = document.querySelector(hash);
|
const deep_linked = document.querySelector(hash);
|
||||||
|
|
||||||
if (deep_linked) {
|
if (deep_linked) {
|
||||||
scroll = {
|
scroll = {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
|||||||
@@ -20,19 +20,18 @@ describe('basics', function() {
|
|||||||
let prefetchRoutes: () => Promise<void>;
|
let prefetchRoutes: () => Promise<void>;
|
||||||
let prefetch: (href: string) => Promise<void>;
|
let prefetch: (href: string) => Promise<void>;
|
||||||
let goto: (href: string) => Promise<void>;
|
let goto: (href: string) => Promise<void>;
|
||||||
|
let title: () => Promise<string>;
|
||||||
|
|
||||||
// hooks
|
// hooks
|
||||||
before(async () => {
|
before(async () => {
|
||||||
await build({ cwd: __dirname });
|
await build({ cwd: __dirname });
|
||||||
|
|
||||||
runner = new AppRunner(__dirname, '__sapper__/build/server/server.js');
|
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());
|
after(() => runner.end());
|
||||||
|
|
||||||
const title = () => page.$eval('h1', node => node.textContent);
|
|
||||||
|
|
||||||
it('serves /', async () => {
|
it('serves /', async () => {
|
||||||
await page.goto(base);
|
await page.goto(base);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import * as path from 'path';
|
|
||||||
import * as assert from 'assert';
|
import * as assert from 'assert';
|
||||||
import * as puppeteer from 'puppeteer';
|
import * as puppeteer from 'puppeteer';
|
||||||
import { build } from '../../../api';
|
import { build } from '../../../api';
|
||||||
@@ -17,19 +16,18 @@ describe('preloading', function() {
|
|||||||
// helpers
|
// helpers
|
||||||
let start: () => Promise<void>;
|
let start: () => Promise<void>;
|
||||||
let prefetchRoutes: () => Promise<void>;
|
let prefetchRoutes: () => Promise<void>;
|
||||||
|
let title: () => Promise<string>;
|
||||||
|
|
||||||
// hooks
|
// hooks
|
||||||
before(async () => {
|
before(async () => {
|
||||||
await build({ cwd: __dirname });
|
await build({ cwd: __dirname });
|
||||||
|
|
||||||
runner = new AppRunner(__dirname, '__sapper__/build/server/server.js');
|
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());
|
after(() => runner.end());
|
||||||
|
|
||||||
const title = () => page.$eval('h1', node => node.textContent);
|
|
||||||
|
|
||||||
it('serializes Set objects returned from preload', async () => {
|
it('serializes Set objects returned from preload', async () => {
|
||||||
await page.goto(`${base}/preload-values/set`);
|
await page.goto(`${base}/preload-values/set`);
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,4 @@
|
|||||||
|
<h1>Another tall page</h1>
|
||||||
|
|
||||||
<div style="height: 9999px"></div>
|
<div style="height: 9999px"></div>
|
||||||
<p id="bar">element</p>
|
<p id="bar">element</p>
|
||||||
@@ -8,6 +8,8 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<h1>A tall page</h1>
|
||||||
|
|
||||||
<a href="tall-page#foo">scroll to foo</a>
|
<a href="tall-page#foo">scroll to foo</a>
|
||||||
<div style="height: 9999px"></div>
|
<div style="height: 9999px"></div>
|
||||||
|
|
||||||
|
|||||||
@@ -14,13 +14,14 @@ describe('scroll', function() {
|
|||||||
// helpers
|
// helpers
|
||||||
let start: () => Promise<void>;
|
let start: () => Promise<void>;
|
||||||
let prefetchRoutes: () => Promise<void>;
|
let prefetchRoutes: () => Promise<void>;
|
||||||
|
let title: () => Promise<string>;
|
||||||
|
|
||||||
// hooks
|
// hooks
|
||||||
before(async () => {
|
before(async () => {
|
||||||
await build({ cwd: __dirname });
|
await build({ cwd: __dirname });
|
||||||
|
|
||||||
runner = new AppRunner(__dirname, '__sapper__/build/server/server.js');
|
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());
|
after(() => runner.end());
|
||||||
@@ -85,6 +86,7 @@ describe('scroll', function() {
|
|||||||
|
|
||||||
await page.click('[href="another-tall-page#bar"]');
|
await page.click('[href="another-tall-page#bar"]');
|
||||||
await wait(50);
|
await wait(50);
|
||||||
|
assert.equal(await title(), 'Another tall page');
|
||||||
const scrollY = await page.evaluate(() => window.scrollY);
|
const scrollY = await page.evaluate(() => window.scrollY);
|
||||||
assert.ok(scrollY > 0);
|
assert.ok(scrollY > 0);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -12,19 +12,18 @@ describe('store', function() {
|
|||||||
|
|
||||||
// helpers
|
// helpers
|
||||||
let start: () => Promise<void>;
|
let start: () => Promise<void>;
|
||||||
|
let title: () => Promise<string>;
|
||||||
|
|
||||||
// hooks
|
// hooks
|
||||||
before(async () => {
|
before(async () => {
|
||||||
await build({ cwd: __dirname });
|
await build({ cwd: __dirname });
|
||||||
|
|
||||||
runner = new AppRunner(__dirname, '__sapper__/build/server/server.js');
|
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());
|
after(() => runner.end());
|
||||||
|
|
||||||
const title = () => page.$eval('h1', node => node.textContent);
|
|
||||||
|
|
||||||
it('renders store props', async () => {
|
it('renders store props', async () => {
|
||||||
await page.goto(`${base}/store`);
|
await page.goto(`${base}/store`);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user