Skip to content

Commit 0a26428

Browse files
committed
[frontend] add global history
1 parent 60d1874 commit 0a26428

File tree

2 files changed

+68
-22
lines changed

2 files changed

+68
-22
lines changed

frontend/src/Browser.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
import { createState, type Stateful } from "dreamland/core";
2-
import { ThemeVars, type Theme } from "./theme";
3-
import { Tabs } from "./components/TabStrip";
4-
import { Omnibox } from "./components/Omnibox";
52
import { browser, scramjet } from "./main";
6-
import iconAdd from "@ktibow/iconset-ion/add";
7-
import { Shell } from "./components/Shell";
8-
import { createMenu } from "./components/Menu";
93
import { StatefulClass } from "./StatefulClass";
104
import { Tab, type SerializedTab } from "./Tab";
115
import { createDelegate } from "dreamland/core";
126
import tlds from "tlds";
7+
import type { SerializedHistoryState } from "./History";
8+
import { HistoryState } from "./History";
139

1410
export const pushTab = createDelegate<Tab>();
1511
export const popTab = createDelegate<Tab>();
@@ -43,6 +39,7 @@ export const config = createState({
4339

4440
export type SerializedBrowser = {
4541
tabs: SerializedTab[];
42+
globalhistory: SerializedHistoryState[];
4643
activetab: number;
4744
};
4845

@@ -59,7 +56,7 @@ export class Browser extends StatefulClass {
5956
tabs: Tab[] = [];
6057
activetab: Tab;
6158

62-
globalhistory: string[];
59+
globalhistory: HistoryState[];
6360

6461
unfocusframes: boolean = false;
6562

@@ -71,13 +68,18 @@ export class Browser extends StatefulClass {
7168
return {
7269
tabs: this.tabs.map((t) => t.serialize()),
7370
activetab: this.activetab.id,
71+
globalhistory: this.globalhistory.map((s) => s.serialize()),
7472
};
7573
}
7674
deserialize(de: SerializedBrowser) {
7775
this.tabs = [];
76+
this.globalhistory = de.globalhistory.map((s) => {
77+
const state = new HistoryState();
78+
state.deserialize(s);
79+
return state;
80+
});
7881
for (let detab of de.tabs) {
7982
let tab = this.newTab();
80-
console.log(tab);
8183
tab.deserialize(detab);
8284
}
8385
this.activetab = this.tabs[0]; // TODO

frontend/src/History.ts

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,46 @@
1+
import { browser } from "./main";
12
import type { Tab } from "./Tab";
23

34
// history api emulation
4-
export type HistoryState = {
5-
state: any;
5+
export class HistoryState {
66
url: URL;
7+
tab: Tab;
8+
state: any;
9+
title?: string;
10+
favicon?: string;
11+
12+
constructor(partial?: Partial<HistoryState>) {
13+
Object.assign(this, partial);
14+
}
15+
16+
serialize(): SerializedHistoryState {
17+
return {
18+
state: this.state,
19+
url: this.url.href,
20+
tab: this.tab.id,
21+
title: this.title,
22+
favicon: this.favicon,
23+
};
24+
}
25+
deserialize(de: SerializedHistoryState) {
26+
this.state = de.state;
27+
this.url = new URL(de.url);
28+
this.tab = browser.tabs.find((t) => t.id === de.tab) || this.tab;
29+
this.title = de.title;
30+
this.favicon = de.favicon;
31+
}
32+
}
33+
export type SerializedHistoryState = {
34+
state: any;
35+
url: string;
36+
tab: number;
37+
title?: string;
38+
favicon?: string;
739
};
840

941
export type SerializedHistory = {
1042
index: number;
11-
states: {
12-
state: any;
13-
url: string;
14-
}[];
43+
states: SerializedHistoryState[];
1544
};
1645

1746
export class History {
@@ -23,19 +52,30 @@ export class History {
2352
serialize(): SerializedHistory {
2453
return {
2554
index: this.index,
26-
states: this.states.map((s) => ({ state: s.state, url: s.url.href })),
55+
states: this.states.map((s) => s.serialize()),
2756
};
2857
}
2958
deserialize(de: SerializedHistory) {
3059
this.index = de.index;
31-
this.states = de.states.map((s) => ({
32-
state: s.state,
33-
url: new URL(s.url),
34-
}));
60+
this.states = de.states.map((s) => {
61+
const state = new HistoryState();
62+
state.deserialize(s);
63+
64+
return state;
65+
});
66+
}
67+
current(): HistoryState {
68+
if (this.index < 0 || this.index >= this.states.length) {
69+
throw new Error("No current history state");
70+
}
71+
72+
return this.states[this.index];
3573
}
3674

3775
push(url: URL, state: any = null, navigate: boolean = true): HistoryState {
38-
this.states.push({ url, state });
76+
const hstate = new HistoryState({ url, state, tab: this.tab });
77+
browser.globalhistory.push(hstate);
78+
this.states.push(hstate);
3979
this.index++;
4080

4181
if (navigate) this.tab._directnavigate(url);
@@ -47,9 +87,13 @@ export class History {
4787
}
4888
replace(url: URL, state: any, navigate: boolean = true): HistoryState {
4989
if (this.index < this.states.length) {
50-
this.states[this.index] = { url, state };
90+
this.current().url = url;
91+
this.current().state = state;
92+
this.current().tab = this.tab;
93+
this.current().title = undefined;
94+
this.current().favicon = undefined;
5195
} else {
52-
this.push(url, state);
96+
return this.push(url, state);
5397
}
5498

5599
if (navigate) this.tab._directnavigate(url);

0 commit comments

Comments
 (0)