-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgatsby-browser.tsx
More file actions
108 lines (93 loc) · 3.58 KB
/
Copy pathgatsby-browser.tsx
File metadata and controls
108 lines (93 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import type { GatsbyBrowser } from 'gatsby';
import type { PageProps } from './src/contexts/page';
import React, {
useContext,
useEffect,
useLayoutEffect
} from 'react';
import metadata, { NO_SIDER_URI_PATTERN } from './gatsby-config/metadata';
import BasePackageProvider from './src/contexts/base-pkg';
import PageProvider, { UpdaterCtx as PageCtxUpdater } from './src/contexts/page';
import DarkmodeProvider, { ValueCtx as DarkmodeValueCtx } from './src/contexts/dark-mode';
import VersionOfInterestProvider from './src/contexts/version-of-interest';
import Layout from './src/partials/layouts/index/index';
import { Version } from './src/partials/version-tabs/utils/calc-version-vmodel';
import { fromLocalStorage } from './src/partials/version-tabs/component';
export const onRouteUpdate : GatsbyBrowser[ "onRouteUpdate" ] = ({
location: { href }, prevLocation
}) => {
setTimeout( () => {
sanitizeScroll( href );
sanitizePageTitle();
}, 100 );
};
const PageManager : React.FC<{
children: React.ReactNode,
props: PageProps
}> = ({ children, props }) => {
const updatePageCtx = useContext( PageCtxUpdater );
const darkmode = useContext( DarkmodeValueCtx );
useLayoutEffect(() => {
document.querySelector( 'body' )?.classList[
darkmode ? 'add' : 'remove'
]( 'dark' );
}, [ darkmode ]);
useEffect(() => updatePageCtx( s => ({ ...s, ...props }) ), [ props ]);
useEffect(() => updatePageCtx( s => ({
...s,
isNoSiderPage: NO_SIDER_URI_PATTERN.test( props.uri ?? '' )
}) ), [ props.uri ]);
return ( <Layout { ...props }>{ children }</Layout> );
};
export const wrapPageElement : GatsbyBrowser[ 'wrapPageElement' ] = ({ element, props }) => (
<PageManager props={ props }>
{ element }
</PageManager>
);
export const wrapRootElement : GatsbyBrowser[ 'wrapRootElement' ] = ({ element, pathname }) => (
<BasePackageProvider>
<PageProvider initState={{
isNoSiderPage: NO_SIDER_URI_PATTERN.test(
location?.pathname ?? pathname ?? ''
)
}}>
<DarkmodeProvider initValue={
window.localStorage?.getItem( metadata.darkmode.key ) !== 'false'
? metadata.darkmode.defaultValue
: false
}>
<VersionOfInterestProvider initValue={(
fromLocalStorage( metadata.versionOfInterest.key ) ?? metadata.versionOfInterest.defaultValue
) as Version }>
{ element }
</VersionOfInterestProvider>
</DarkmodeProvider>
</PageProvider>
</BasePackageProvider>
);
function sanitizePageTitle() {
const headElement = document.querySelector( 'head' );
if( !headElement || headElement.querySelector( ':scope > title' ) ) { return }
const titleElement = document.createElement( 'title' );
titleElement.setAttribute( 'data-gatsby-head', 'true' );
titleElement.appendChild(
document.createTextNode(
metadata.title
)
);
headElement.appendChild( titleElement );
}
function sanitizeScroll( href : string ) {
const sider = document.querySelector( '.site-body-sider' );
if( !sider ) { return restateHistory( href ) }
window.scroll( 0, 0 );
!( new URL( href ).hash ).length
? sider.parentNode?.querySelector( ':scope > main' )?.scroll( 0, 0 )
: restateHistory( href );
}
function restateHistory( href : string ) {
setTimeout(
() => window.history.replaceState( undefined, '', href ),
350
);
}