Skip to content

Commit cd5cb60

Browse files
authored
Merge pull request #99 from takker99/page-transition
✨ リンク先へスクロールする
2 parents 1f0e5c2 + d672f57 commit cd5cb60

File tree

4 files changed

+84
-1
lines changed

4 files changed

+84
-1
lines changed

browser/dom/mod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ export * from "./cache.ts";
1111
export * from "./cursor.ts";
1212
export * from "./selection.ts";
1313
export * from "./stores.ts";
14+
export * from "./pushPageTransition.ts";

browser/dom/open.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
/// <reference lib="dom" />
44

55
import { encodeTitleURI } from "../../title.ts";
6+
import {
7+
PageTransitionContext,
8+
pushPageTransition,
9+
} from "./pushPageTransition.ts";
610
import type { Scrapbox } from "../../deps/scrapbox.ts";
711
declare const scrapbox: Scrapbox;
812

@@ -24,6 +28,9 @@ export interface OpenOptions {
2428
* @default 同じprojectの場合は再読み込みせず、違うprojectの場合は再読込する
2529
*/
2630
reload?: boolean;
31+
32+
/** リンク先へスクロールする機能を使うために必要な情報 */
33+
context?: Omit<PageTransitionContext, "to">;
2734
}
2835

2936
/** ページを開く
@@ -41,6 +48,12 @@ export const open = (
4148
if (options?.body) url.search = `?body=${encodeURIComponent(options.body)}`;
4249
if (options?.id) url.hash = `#${options.id}`;
4350

51+
if (options?.context) {
52+
pushPageTransition(
53+
{ ...options?.context, to: { project, title } } as PageTransitionContext,
54+
);
55+
}
56+
4457
if (
4558
options?.newTab !== false &&
4659
(options?.newTab === true || project !== scrapbox.Project.name)

browser/dom/pushPageTransition.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { toTitleLc } from "../../title.ts";
2+
3+
/** ページリンク */
4+
export interface Link {
5+
/** リンク先のproject name */
6+
project: string;
7+
8+
/** リンク先のpage title */
9+
title: string;
10+
}
11+
12+
/** ページから別のページに遷移するときの状態を表す */
13+
export interface PageTransitionContextLink {
14+
type: "page";
15+
16+
/** 遷移元ページのリンク */
17+
from: Link;
18+
19+
/** 遷移先ページのリンク */
20+
to: Link;
21+
}
22+
23+
/** 全文検索結果から別のページに遷移するときの状態を表す */
24+
export interface PageTransitionContextQuery {
25+
type: "search";
26+
27+
/** 全文検索での検索語句 */
28+
query: string;
29+
30+
/** 遷移先ページのリンク */
31+
to: Link;
32+
}
33+
34+
export type PageTransitionContext =
35+
| PageTransitionContextLink
36+
| PageTransitionContextQuery;
37+
38+
/** ページ遷移状態を登録し、次回のページ遷移時にリンク先へスクロールする
39+
*
40+
* @param context 遷移状態
41+
*/
42+
export const pushPageTransition = (context: PageTransitionContext): void => {
43+
const pageTransitionContext: Record<string, unknown> = JSON.parse(
44+
localStorage.getItem("pageTransitionContext") ?? "",
45+
);
46+
const value = context.type === "page"
47+
? context.from.project === context.to.project
48+
? context.from.title === context.to.title
49+
? {
50+
titleHint: context.to.title,
51+
}
52+
: {
53+
linkFrom: context.from.title,
54+
}
55+
: {
56+
linkFrom: `/${context.from.project}/${context.from.title}`,
57+
}
58+
: {
59+
searchQuery: context.query,
60+
};
61+
pageTransitionContext[`page_${toTitleLc(context.to.title)}`] = value;
62+
localStorage.setItem(
63+
"pageTransitionContext",
64+
JSON.stringify(pageTransitionContext),
65+
);
66+
};

title.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ import { assertStrictEquals } from "./deps/testing.ts";
88

99
Deno.test("toTitleLc()", async (t) => {
1010
await t.step("` ` -> `_`", () => {
11-
assertStrictEquals<string>(toTitleLc("空白入り タイトル"), "空白入り_タイトル");
11+
assertStrictEquals<string>(
12+
toTitleLc("空白入り タイトル"),
13+
"空白入り_タイトル",
14+
);
1215
assertStrictEquals<string>(
1316
toTitleLc(" 前後にも 空白入り _タイトル "),
1417
"_前後にも_空白入り__タイトル_",

0 commit comments

Comments
 (0)