Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

Handle tag click from another page #473

Merged
merged 1 commit into from
Oct 16, 2018
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
29 changes: 19 additions & 10 deletions templates/src/client/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,18 +106,17 @@ export function scroll_state() {
};
}

export function navigate(target: Target, id: number, noscroll = false): Promise<any> {
export function navigate(target: Target, id: number, scroll_to?: ScrollPosition | string): Promise<any> {
let scroll: ScrollPosition | string;
if (id) {
// popstate or initial navigation
cid = id;
scroll = scroll_to ? scroll_to : scroll_history[id];
} else {
const current_scroll = scroll_state();

// clicked on a link. preserve scroll state
scroll_history[cid] = current_scroll;

scroll_history[cid] = scroll_state();
id = cid = ++uid;
scroll_history[cid] = noscroll ? current_scroll : { x: 0, y: 0 };
scroll = scroll_to ? scroll_to : { x: 0, y: 0 };
}

cid = id;
Expand All @@ -137,13 +136,12 @@ export function navigate(target: Target, id: number, noscroll = false): Promise<
if (redirect) {
return goto(redirect.location, { replaceState: true });
}

render(data, nullable_depth, scroll_history[id], token);
render(data, nullable_depth, scroll, token);
if (document.activeElement) document.activeElement.blur();
});
}

function render(data: any, nullable_depth: number, scroll: ScrollPosition, token: {}) {
function render(data: any, nullable_depth: number, scroll: ScrollPosition | string, token: {}) {
if (current_token !== token) return;

if (root_component) {
Expand Down Expand Up @@ -183,7 +181,18 @@ function render(data: any, nullable_depth: number, scroll: ScrollPosition, token
}

if (scroll) {
scrollTo(scroll.x, scroll.y);
let scrollPos: ScrollPosition;
if (typeof scroll === 'string') {
// scroll is an element id (from a hash), we need to compute y.
const deep_linked = document.getElementById(scroll);
scrollPos = deep_linked ?
{ x: 0, y: deep_linked.getBoundingClientRect().top } :
scroll_state();
} else {
scrollPos = scroll;
}
scroll_history[cid] = scrollPos;
scrollTo(scrollPos.x, scrollPos.y);
}

Object.assign(root_props, data);
Expand Down
21 changes: 13 additions & 8 deletions templates/src/client/start/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
set_cid
} from '../app';
import prefetch from '../prefetch/index';
import { Store } from '../types';
import { Store, ScrollPosition } from '../types';

export default function start(opts: {
target: Node,
Expand All @@ -35,17 +35,13 @@ export default function start(opts: {

return Promise.resolve().then(() => {
const { hash, href } = location;

const deep_linked = hash && document.getElementById(hash.slice(1));
scroll_history[uid] = deep_linked ?
{ x: 0, y: deep_linked.getBoundingClientRect().top } :
scroll_state();
const scroll_to = hash ? hash.slice(1) : scroll_state();

history.replaceState({ id: uid }, '', href);

if (!initial_data.error) {
const target = select_route(new URL(location.href));
if (target) return navigate(target, uid);
if (target) return navigate(target, uid, scroll_to);
}
});
}
Expand Down Expand Up @@ -104,7 +100,16 @@ function handle_click(event: MouseEvent) {
const target = select_route(url);
if (target) {
const noscroll = a.hasAttribute('sapper-noscroll');
navigate(target, null, noscroll);
let scroll_to: ScrollPosition | string;
if (noscroll) {
scroll_to = scroll_state();
} else if (url.hash) {
scroll_to = url.hash.slice(1);
} else {
scroll_to = { x: 0, y: 0 };
}

navigate(target, null, scroll_to);
event.preventDefault();
history.pushState({ id: cid }, '', url.href);
}
Expand Down
3 changes: 2 additions & 1 deletion test/apps/scroll/src/routes/another-tall-page.html
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
<div style="height: 9999px"></div>
<div style="height: 9999px"></div>
<p id="bar">element</p>
19 changes: 18 additions & 1 deletion test/apps/scroll/src/routes/tall-page.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,21 @@
<div id="foo">
<a href="another-tall-page">link</a>
<a href="another-tall-page" sapper-noscroll>link</a>
</div>
{#if barLink}
<a href="another-tall-page#bar">link</a>
{/if}
</div>

<script>
export default {
data() {
return {
barLink: false
};
},

oncreate() {
this.set({ barLink: true })
}
}
</script>
11 changes: 11 additions & 0 deletions test/apps/scroll/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,15 @@ describe('scroll', function() {

assert.ok(scrollY > 0);
});

it('scrolls into a deeplink on a new page', async () => {
await page.goto(`${base}/tall-page#foo`);
await start();
await prefetchRoutes();

await page.click('[href="another-tall-page#bar"]');
await wait(50);
const scrollY = await page.evaluate(() => window.scrollY);
assert.ok(scrollY > 0);
});
});