@@ -3,10 +3,71 @@ import type { Tab } from "./Tab";
33// history api emulation
44export type HistoryState = {
55 state : any ;
6- url : string ;
6+ url : URL ;
77} ;
88
9- export function injectHistoryEmulation ( client : ScramjetClient , tab : Tab ) {
9+ export class History {
10+ index : number = 0 ;
11+ states : HistoryState [ ] = [ ] ;
12+
13+ constructor ( private tab : Tab ) { }
14+
15+ push ( url : URL , state : any , navigate : boolean = true ) : HistoryState {
16+ this . states . push ( { url, state } ) ;
17+ this . index ++ ;
18+
19+ if ( navigate ) this . tab . navigate ( url ) ;
20+
21+ return this . states [ this . index ] ;
22+ }
23+ replace ( url : URL , state : any , navigate : boolean = true ) : HistoryState {
24+ if ( this . index < this . states . length ) {
25+ this . states [ this . index ] = { url, state } ;
26+ } else {
27+ this . push ( url , state ) ;
28+ }
29+
30+ if ( navigate ) this . tab . navigate ( url ) ;
31+
32+ return this . states [ this . index ] ;
33+ }
34+ go ( delta : number , navigate : boolean = true ) : HistoryState {
35+ this . index += delta ;
36+ if ( this . index < 0 ) {
37+ this . index = 0 ;
38+ } else if ( this . index >= this . states . length ) {
39+ this . index = this . states . length - 1 ;
40+ }
41+
42+ if ( navigate ) this . tab . navigate ( this . states [ this . index ] . url ) ;
43+
44+ return this . states [ this . index ] ;
45+ }
46+ canGoBack ( ) : boolean {
47+ return this . index > 0 ;
48+ }
49+ canGoForward ( ) : boolean {
50+ return this . index < this . states . length - 1 ;
51+ }
52+ }
53+
54+ export function injectHistoryEmulation ( frame : ScramjetFrame , tab : Tab ) {
55+ frame . addEventListener ( "navigate" , ( e ) => {
56+ // this event is fired whenever location.href is set, or similar
57+ // importantly not fired when replaceState is called (we overwrite it ourselves in injectContext)
58+
59+ // behavior here is just to create a new history entry
60+ const url = new URL ( e . url ) ;
61+ tab . history . push ( url , undefined , false ) ;
62+
63+ console . log ( "History push from navigate" , url , tab . history . states ) ;
64+ } ) ;
65+ frame . frame . addEventListener ( "beforeunload" , ( e : BeforeUnloadEvent ) => {
66+ console . log ( "History beforeunload" , e ) ;
67+ } ) ;
68+ }
69+
70+ function injectContext ( client : ScramjetClient , tab : Tab ) {
1071 client . Proxy ( "History.prototype.pushState" , {
1172 apply ( ctx ) {
1273 console . log ( "STATE PUSH" , ctx . args ) ;
0 commit comments