methanol 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/index.js +7 -2
- package/package.json +9 -3
- package/src/build-system.js +50 -8
- package/src/client/sw.js +751 -0
- package/src/{assets.js → client/virtual-module/assets.js} +7 -3
- package/src/{virtual-module → client/virtual-module}/inject.js +1 -0
- package/src/{virtual-module → client/virtual-module}/loader.js +5 -5
- package/src/{virtual-module → client/virtual-module}/pagefind-loader.js +1 -1
- package/src/client/virtual-module/pwa-inject.js +25 -0
- package/src/components.js +5 -5
- package/src/config.js +38 -7
- package/src/dev-server.js +64 -66
- package/src/logger.js +84 -0
- package/src/main.js +11 -0
- package/src/mdx.js +33 -38
- package/src/pagefind.js +16 -5
- package/src/pages.js +61 -51
- package/src/public-assets.js +1 -1
- package/src/{rewind.js → reframe.js} +1 -1
- package/src/rehype-plugins/link-resolve.js +2 -2
- package/src/stage-logger.js +10 -6
- package/src/state.js +31 -4
- package/src/utils.js +23 -1
- package/src/vite-plugins.js +17 -4
- package/themes/default/components/ThemeSearchBox.client.jsx +120 -11
- package/themes/default/index.js +2 -2
- package/themes/default/pages/404.mdx +4 -0
- package/themes/default/pages/index.mdx +7 -9
- package/themes/default/pages/offline.mdx +11 -0
- package/themes/default/sources/style.css +248 -169
- package/themes/default/src/nav-tree.jsx +112 -0
- package/themes/default/{page.jsx → src/page.jsx} +10 -55
- /package/themes/default/{heading.jsx → src/heading.jsx} +0 -0
|
@@ -2,205 +2,88 @@
|
|
|
2
2
|
|
|
3
3
|
:root {
|
|
4
4
|
interpolate-size: allow-keywords;
|
|
5
|
-
color-scheme: dark;
|
|
6
|
-
--bg: #09090b;
|
|
7
|
-
--surface: #0c0c0e;
|
|
8
|
-
--surface-muted: #17171a;
|
|
9
|
-
--surface-elevated: #1c1c21;
|
|
10
|
-
--text: #fafafa;
|
|
11
|
-
--muted: #a1a1aa;
|
|
12
|
-
--border: #27272a;
|
|
13
|
-
--accent: #ffa000;
|
|
5
|
+
color-scheme: light dark;
|
|
6
|
+
--bg: light-dark(#ffffff, #09090b);
|
|
7
|
+
--surface: light-dark(#fafafa, #0c0c0e);
|
|
8
|
+
--surface-muted: light-dark(#f4f4f5, #17171a);
|
|
9
|
+
--surface-elevated: light-dark(#ffffff, #1c1c21);
|
|
10
|
+
--text: light-dark(#09090b, #fafafa);
|
|
11
|
+
--muted: light-dark(#71717a, #a1a1aa);
|
|
12
|
+
--border: light-dark(#e4e4e7, #27272a);
|
|
13
|
+
--accent: light-dark(#ff8f00, #ffa000);
|
|
14
14
|
--accent-foreground: #ffffff;
|
|
15
|
-
--accent-soft: rgba(255, 160, 0, 0.1);
|
|
15
|
+
--accent-soft: light-dark(rgba(255, 143, 0, 0.08), rgba(255, 160, 0, 0.1));
|
|
16
16
|
--radius: 8px;
|
|
17
17
|
--sidebar-width: 260px;
|
|
18
18
|
--toc-width: 240px;
|
|
19
19
|
--header-height: 0px;
|
|
20
|
-
--hover-bg: rgba(255, 255, 255, 0.05);
|
|
20
|
+
--hover-bg: light-dark(rgba(0, 0, 0, 0.04), rgba(255, 255, 255, 0.05));
|
|
21
|
+
|
|
22
|
+
/* Starry Night Syntax Highlighting */
|
|
23
|
+
--color-prettylights-syntax-brackethighlighter-angle: light-dark(#59636e, #9198a1);
|
|
24
|
+
--color-prettylights-syntax-brackethighlighter-unmatched: light-dark(#82071e, #f85149);
|
|
25
|
+
--color-prettylights-syntax-carriage-return-bg: light-dark(#cf222e, #b62324);
|
|
26
|
+
--color-prettylights-syntax-carriage-return-text: light-dark(#f6f8fa, #f0f6fc);
|
|
27
|
+
--color-prettylights-syntax-comment: light-dark(#59636e, #9198a1);
|
|
28
|
+
--color-prettylights-syntax-constant: light-dark(#0550ae, #79c0ff);
|
|
29
|
+
--color-prettylights-syntax-constant-other-reference-link: light-dark(#0a3069, #a5d6ff);
|
|
30
|
+
--color-prettylights-syntax-entity: light-dark(#6639ba, #d2a8ff);
|
|
31
|
+
--color-prettylights-syntax-entity-tag: light-dark(#0550ae, #7ee787);
|
|
32
|
+
--color-prettylights-syntax-invalid-illegal-bg: light-dark(#82071e, #8e1519);
|
|
33
|
+
--color-prettylights-syntax-invalid-illegal-text: light-dark(#f6f8fa, #f0f6fc);
|
|
34
|
+
--color-prettylights-syntax-keyword: light-dark(#cf222e, #ff7b72);
|
|
35
|
+
--color-prettylights-syntax-markup-changed-bg: light-dark(#ffd8b5, #5a1e02);
|
|
36
|
+
--color-prettylights-syntax-markup-changed-text: light-dark(#953800, #ffdfb6);
|
|
37
|
+
--color-prettylights-syntax-markup-deleted-bg: light-dark(#ffebe9, #67060c);
|
|
38
|
+
--color-prettylights-syntax-markup-deleted-text: light-dark(#82071e, #ffdcd7);
|
|
39
|
+
--color-prettylights-syntax-markup-heading: light-dark(#0550ae, #1f6feb);
|
|
40
|
+
--color-prettylights-syntax-markup-ignored-bg: light-dark(#0550ae, #1158c7);
|
|
41
|
+
--color-prettylights-syntax-markup-ignored-text: light-dark(#d1d9e0, #f0f6fc);
|
|
42
|
+
--color-prettylights-syntax-markup-inserted-bg: light-dark(#dafbe1, #033a16);
|
|
43
|
+
--color-prettylights-syntax-markup-inserted-text: light-dark(#116329, #aff5b4);
|
|
44
|
+
--color-prettylights-syntax-markup-list: light-dark(#3b2300, #f2cc60);
|
|
45
|
+
--color-prettylights-syntax-meta-diff-range: light-dark(#8250df, #d2a8ff);
|
|
46
|
+
--color-prettylights-syntax-string: light-dark(#0a3069, #a5d6ff);
|
|
47
|
+
--color-prettylights-syntax-string-regexp: light-dark(#116329, #7ee787);
|
|
48
|
+
--color-prettylights-syntax-sublimelinter-gutter-mark: light-dark(#818b98, #3d444d);
|
|
49
|
+
--color-prettylights-syntax-variable: light-dark(#953800, #ffa657);
|
|
50
|
+
--color-prettylights-syntax-markup-bold: light-dark(#1f2328, #f0f6fc);
|
|
51
|
+
--color-prettylights-syntax-markup-italic: light-dark(#1f2328, #f0f6fc);
|
|
52
|
+
--color-prettylights-syntax-storage-modifier-import: light-dark(#1f2328, #f0f6fc);
|
|
21
53
|
|
|
22
54
|
@media (prefers-color-scheme: light) {
|
|
23
|
-
|
|
55
|
+
&:not(.dark) {
|
|
24
56
|
color-scheme: light;
|
|
25
|
-
--bg: #ffffff;
|
|
26
|
-
--surface: #fafafa;
|
|
27
|
-
--surface-muted: #f4f4f5;
|
|
28
|
-
--surface-elevated: #ffffff;
|
|
29
|
-
--text: #09090b;
|
|
30
|
-
--muted: #71717a;
|
|
31
|
-
--border: #e4e4e7;
|
|
32
|
-
--accent: #ff8f00;
|
|
33
|
-
--accent-foreground: #ffffff;
|
|
34
|
-
--accent-soft: rgba(255, 143, 0, 0.08);
|
|
35
|
-
--hover-bg: rgba(0, 0, 0, 0.04);
|
|
36
57
|
}
|
|
37
58
|
}
|
|
38
59
|
|
|
39
60
|
&.light {
|
|
40
61
|
color-scheme: light;
|
|
41
|
-
--bg: #ffffff;
|
|
42
|
-
--surface: #fafafa;
|
|
43
|
-
--surface-muted: #f4f4f5;
|
|
44
|
-
--surface-elevated: #ffffff;
|
|
45
|
-
--text: #09090b;
|
|
46
|
-
--muted: #71717a;
|
|
47
|
-
--border: #e4e4e7;
|
|
48
|
-
--accent: #ff8f00;
|
|
49
|
-
--accent-foreground: #ffffff;
|
|
50
|
-
--accent-soft: rgba(255, 143, 0, 0.08);
|
|
51
|
-
--hover-bg: rgba(0, 0, 0, 0.04);
|
|
52
|
-
|
|
53
|
-
/* Starry Night Light Theme */
|
|
54
|
-
--color-prettylights-syntax-brackethighlighter-angle: #59636e;
|
|
55
|
-
--color-prettylights-syntax-brackethighlighter-unmatched: #82071e;
|
|
56
|
-
--color-prettylights-syntax-carriage-return-bg: #cf222e;
|
|
57
|
-
--color-prettylights-syntax-carriage-return-text: #f6f8fa;
|
|
58
|
-
--color-prettylights-syntax-comment: #59636e;
|
|
59
|
-
--color-prettylights-syntax-constant: #0550ae;
|
|
60
|
-
--color-prettylights-syntax-constant-other-reference-link: #0a3069;
|
|
61
|
-
--color-prettylights-syntax-entity: #6639ba;
|
|
62
|
-
--color-prettylights-syntax-entity-tag: #0550ae;
|
|
63
|
-
--color-prettylights-syntax-invalid-illegal-bg: #82071e;
|
|
64
|
-
--color-prettylights-syntax-invalid-illegal-text: #f6f8fa;
|
|
65
|
-
--color-prettylights-syntax-keyword: #cf222e;
|
|
66
|
-
--color-prettylights-syntax-markup-changed-bg: #ffd8b5;
|
|
67
|
-
--color-prettylights-syntax-markup-changed-text: #953800;
|
|
68
|
-
--color-prettylights-syntax-markup-deleted-bg: #ffebe9;
|
|
69
|
-
--color-prettylights-syntax-markup-deleted-text: #82071e;
|
|
70
|
-
--color-prettylights-syntax-markup-heading: #0550ae;
|
|
71
|
-
--color-prettylights-syntax-markup-ignored-bg: #0550ae;
|
|
72
|
-
--color-prettylights-syntax-markup-ignored-text: #d1d9e0;
|
|
73
|
-
--color-prettylights-syntax-markup-inserted-bg: #dafbe1;
|
|
74
|
-
--color-prettylights-syntax-markup-inserted-text: #116329;
|
|
75
|
-
--color-prettylights-syntax-markup-list: #3b2300;
|
|
76
|
-
--color-prettylights-syntax-meta-diff-range: #8250df;
|
|
77
|
-
--color-prettylights-syntax-string: #0a3069;
|
|
78
|
-
--color-prettylights-syntax-string-regexp: #116329;
|
|
79
|
-
--color-prettylights-syntax-sublimelinter-gutter-mark: #818b98;
|
|
80
|
-
--color-prettylights-syntax-variable: #953800;
|
|
81
|
-
--color-prettylights-syntax-markup-bold: #1f2328;
|
|
82
|
-
--color-prettylights-syntax-markup-italic: #1f2328;
|
|
83
|
-
--color-prettylights-syntax-storage-modifier-import: #1f2328;
|
|
84
62
|
}
|
|
85
63
|
|
|
86
64
|
&.dark {
|
|
87
65
|
color-scheme: dark;
|
|
88
|
-
--bg: #09090b;
|
|
89
|
-
--surface: #0c0c0e;
|
|
90
|
-
--surface-muted: #17171a;
|
|
91
|
-
--surface-elevated: #1c1c21;
|
|
92
|
-
--text: #fafafa;
|
|
93
|
-
--muted: #a1a1aa;
|
|
94
|
-
--border: #27272a;
|
|
95
|
-
--accent: #ffa000;
|
|
96
|
-
--accent-foreground: #ffffff;
|
|
97
|
-
--accent-soft: rgba(255, 160, 0, 0.1);
|
|
98
|
-
--radius: 8px;
|
|
99
|
-
--hover-bg: rgba(255, 255, 255, 0.05);
|
|
100
|
-
|
|
101
|
-
/* Starry Night Dark Theme */
|
|
102
|
-
--color-prettylights-syntax-brackethighlighter-angle: #9198a1;
|
|
103
|
-
--color-prettylights-syntax-brackethighlighter-unmatched: #f85149;
|
|
104
|
-
--color-prettylights-syntax-carriage-return-bg: #b62324;
|
|
105
|
-
--color-prettylights-syntax-carriage-return-text: #f0f6fc;
|
|
106
|
-
--color-prettylights-syntax-comment: #9198a1;
|
|
107
|
-
--color-prettylights-syntax-constant: #79c0ff;
|
|
108
|
-
--color-prettylights-syntax-constant-other-reference-link: #a5d6ff;
|
|
109
|
-
--color-prettylights-syntax-entity: #d2a8ff;
|
|
110
|
-
--color-prettylights-syntax-entity-tag: #7ee787;
|
|
111
|
-
--color-prettylights-syntax-invalid-illegal-bg: #8e1519;
|
|
112
|
-
--color-prettylights-syntax-invalid-illegal-text: #f0f6fc;
|
|
113
|
-
--color-prettylights-syntax-keyword: #ff7b72;
|
|
114
|
-
--color-prettylights-syntax-markup-bold: #f0f6fc;
|
|
115
|
-
--color-prettylights-syntax-markup-changed-bg: #5a1e02;
|
|
116
|
-
--color-prettylights-syntax-markup-changed-text: #ffdfb6;
|
|
117
|
-
--color-prettylights-syntax-markup-deleted-bg: #67060c;
|
|
118
|
-
--color-prettylights-syntax-markup-deleted-text: #ffdcd7;
|
|
119
|
-
--color-prettylights-syntax-markup-heading: #1f6feb;
|
|
120
|
-
--color-prettylights-syntax-markup-ignored-bg: #1158c7;
|
|
121
|
-
--color-prettylights-syntax-markup-ignored-text: #f0f6fc;
|
|
122
|
-
--color-prettylights-syntax-markup-inserted-bg: #033a16;
|
|
123
|
-
--color-prettylights-syntax-markup-inserted-text: #aff5b4;
|
|
124
|
-
--color-prettylights-syntax-markup-italic: #f0f6fc;
|
|
125
|
-
--color-prettylights-syntax-markup-list: #f2cc60;
|
|
126
|
-
--color-prettylights-syntax-meta-diff-range: #d2a8ff;
|
|
127
|
-
--color-prettylights-syntax-storage-modifier-import: #f0f6fc;
|
|
128
|
-
--color-prettylights-syntax-string: #a5d6ff;
|
|
129
|
-
--color-prettylights-syntax-string-regexp: #7ee787;
|
|
130
|
-
--color-prettylights-syntax-sublimelinter-gutter-mark: #3d444d;
|
|
131
|
-
--color-prettylights-syntax-variable: #ffa657;
|
|
132
66
|
}
|
|
133
67
|
|
|
134
68
|
/* Accent Colors */
|
|
135
69
|
&.accent-rose {
|
|
136
|
-
--accent: #f43f5e;
|
|
137
|
-
--accent-soft: rgba(244, 63, 94, 0.15);
|
|
138
|
-
@media (prefers-color-scheme: light) {
|
|
139
|
-
--accent: #e11d48;
|
|
140
|
-
--accent-soft: rgba(225, 29, 72, 0.1);
|
|
141
|
-
}
|
|
142
|
-
&.light {
|
|
143
|
-
--accent: #e11d48;
|
|
144
|
-
--accent-soft: rgba(225, 29, 72, 0.1);
|
|
145
|
-
}
|
|
146
|
-
&.dark {
|
|
147
|
-
--accent: #f43f5e;
|
|
148
|
-
--accent-soft: rgba(244, 63, 94, 0.15);
|
|
149
|
-
}
|
|
70
|
+
--accent: light-dark(#e11d48, #f43f5e);
|
|
71
|
+
--accent-soft: light-dark(rgba(225, 29, 72, 0.1), rgba(244, 63, 94, 0.15));
|
|
150
72
|
}
|
|
151
73
|
|
|
152
74
|
&.accent-blue {
|
|
153
|
-
|
|
154
|
-
--accent:
|
|
155
|
-
--accent-soft: rgba(129, 140, 248, 0.15);
|
|
156
|
-
@media (prefers-color-scheme: light) {
|
|
157
|
-
--accent: #4f46e5;
|
|
158
|
-
--accent-soft: rgba(79, 70, 229, 0.1);
|
|
159
|
-
}
|
|
160
|
-
&.light {
|
|
161
|
-
--accent: #4f46e5;
|
|
162
|
-
--accent-soft: rgba(79, 70, 229, 0.1);
|
|
163
|
-
}
|
|
164
|
-
&.dark {
|
|
165
|
-
--accent: #818cf8;
|
|
166
|
-
--accent-soft: rgba(129, 140, 248, 0.15);
|
|
167
|
-
}
|
|
75
|
+
--accent: light-dark(#4f46e5, #818cf8);
|
|
76
|
+
--accent-soft: light-dark(rgba(79, 70, 229, 0.1), rgba(129, 140, 248, 0.15));
|
|
168
77
|
}
|
|
169
78
|
|
|
170
79
|
&.accent-green {
|
|
171
|
-
|
|
172
|
-
--accent:
|
|
173
|
-
--accent-soft: rgba(45, 212, 191, 0.15);
|
|
174
|
-
@media (prefers-color-scheme: light) {
|
|
175
|
-
--accent: #0d9488;
|
|
176
|
-
--accent-soft: rgba(13, 148, 136, 0.1);
|
|
177
|
-
}
|
|
178
|
-
&.light {
|
|
179
|
-
--accent: #0d9488;
|
|
180
|
-
--accent-soft: rgba(13, 148, 136, 0.1);
|
|
181
|
-
}
|
|
182
|
-
&.dark {
|
|
183
|
-
--accent: #2dd4bf;
|
|
184
|
-
--accent-soft: rgba(45, 212, 191, 0.15);
|
|
185
|
-
}
|
|
80
|
+
--accent: light-dark(#0d9488, #2dd4bf);
|
|
81
|
+
--accent-soft: light-dark(rgba(13, 148, 136, 0.1), rgba(45, 212, 191, 0.15));
|
|
186
82
|
}
|
|
187
83
|
|
|
188
84
|
&.accent-purple {
|
|
189
|
-
|
|
190
|
-
--accent:
|
|
191
|
-
--accent-soft: rgba(167, 139, 250, 0.15);
|
|
192
|
-
@media (prefers-color-scheme: light) {
|
|
193
|
-
--accent: #7c3aed;
|
|
194
|
-
--accent-soft: rgba(124, 58, 237, 0.1);
|
|
195
|
-
}
|
|
196
|
-
&.light {
|
|
197
|
-
--accent: #7c3aed;
|
|
198
|
-
--accent-soft: rgba(124, 58, 237, 0.1);
|
|
199
|
-
}
|
|
200
|
-
&.dark {
|
|
201
|
-
--accent: #a78bfa;
|
|
202
|
-
--accent-soft: rgba(167, 139, 250, 0.15);
|
|
203
|
-
}
|
|
85
|
+
--accent: light-dark(#7c3aed, #a78bfa);
|
|
86
|
+
--accent-soft: light-dark(rgba(124, 58, 237, 0.1), rgba(167, 139, 250, 0.15));
|
|
204
87
|
}
|
|
205
88
|
}
|
|
206
89
|
|
|
@@ -1190,6 +1073,13 @@ a {
|
|
|
1190
1073
|
margin-bottom: 1rem;
|
|
1191
1074
|
}
|
|
1192
1075
|
|
|
1076
|
+
img {
|
|
1077
|
+
max-width: 100%;
|
|
1078
|
+
height: auto;
|
|
1079
|
+
border-radius: var(--radius);
|
|
1080
|
+
margin: 1rem 0;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1193
1083
|
p {
|
|
1194
1084
|
color: var(--muted);
|
|
1195
1085
|
margin-bottom: 1.25rem;
|
|
@@ -1735,6 +1625,47 @@ a {
|
|
|
1735
1625
|
justify-content: flex-end;
|
|
1736
1626
|
}
|
|
1737
1627
|
|
|
1628
|
+
/* --- Tables (GFM) --- */
|
|
1629
|
+
|
|
1630
|
+
.main-content table {
|
|
1631
|
+
width: 100%;
|
|
1632
|
+
border-collapse: collapse;
|
|
1633
|
+
margin: 1.5rem 0;
|
|
1634
|
+
font-size: 0.95rem;
|
|
1635
|
+
overflow-x: auto;
|
|
1636
|
+
display: block; /* Enables horizontal scroll for large tables */
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
.main-content table thead tr {
|
|
1640
|
+
border-bottom: 2px solid var(--border);
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
.main-content table th {
|
|
1644
|
+
text-align: left;
|
|
1645
|
+
padding: 0.75rem 1rem;
|
|
1646
|
+
font-weight: 600;
|
|
1647
|
+
color: var(--text);
|
|
1648
|
+
white-space: nowrap;
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
.main-content table tbody tr {
|
|
1652
|
+
border-bottom: 1px solid var(--border);
|
|
1653
|
+
transition: background-color 0.1s ease;
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
.main-content table tbody tr:last-child {
|
|
1657
|
+
border-bottom: none;
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
.main-content table td {
|
|
1661
|
+
padding: 0.75rem 1rem;
|
|
1662
|
+
color: var(--muted);
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
.main-content table tbody tr:hover {
|
|
1666
|
+
background-color: var(--hover-bg);
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1738
1669
|
/* --- View Transitions --- */
|
|
1739
1670
|
|
|
1740
1671
|
@view-transition {
|
|
@@ -1747,3 +1678,151 @@ a {
|
|
|
1747
1678
|
view-transition-name: active-sidebar-bg;
|
|
1748
1679
|
contain: layout paint;
|
|
1749
1680
|
}
|
|
1681
|
+
|
|
1682
|
+
/* --- Print Styles --- */
|
|
1683
|
+
|
|
1684
|
+
@media print {
|
|
1685
|
+
:root {
|
|
1686
|
+
--bg: #ffffff;
|
|
1687
|
+
--surface: #ffffff;
|
|
1688
|
+
--surface-muted: #f4f4f5;
|
|
1689
|
+
--surface-elevated: #ffffff;
|
|
1690
|
+
--text: #09090b;
|
|
1691
|
+
--muted: #52525b;
|
|
1692
|
+
--border: #e4e4e7;
|
|
1693
|
+
--accent: #000000;
|
|
1694
|
+
--accent-soft: #f4f4f5;
|
|
1695
|
+
--hover-bg: transparent;
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
body {
|
|
1699
|
+
background-color: white !important;
|
|
1700
|
+
background-image: none !important;
|
|
1701
|
+
color: black !important;
|
|
1702
|
+
width: 100% !important;
|
|
1703
|
+
margin: 0 !important;
|
|
1704
|
+
padding: 0 !important;
|
|
1705
|
+
overflow: visible !important;
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1708
|
+
/* Hide UI Elements */
|
|
1709
|
+
.sidebar,
|
|
1710
|
+
.toc-panel,
|
|
1711
|
+
.nav-toggle-label,
|
|
1712
|
+
.toc-toggle-label,
|
|
1713
|
+
.search-toggle-label,
|
|
1714
|
+
.search-modal,
|
|
1715
|
+
.page-nav,
|
|
1716
|
+
.copy-btn,
|
|
1717
|
+
.heading-anchor,
|
|
1718
|
+
.theme-switch-wrapper,
|
|
1719
|
+
.lang-switch-wrapper,
|
|
1720
|
+
.page-meta {
|
|
1721
|
+
display: none !important;
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
/* Layout Overrides */
|
|
1725
|
+
.layout-container,
|
|
1726
|
+
.layout-container.no-toc {
|
|
1727
|
+
display: block !important;
|
|
1728
|
+
max-width: none !important;
|
|
1729
|
+
width: 100% !important;
|
|
1730
|
+
margin: 0 !important;
|
|
1731
|
+
padding: 0 !important;
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
.main-content {
|
|
1735
|
+
padding: 0 !important;
|
|
1736
|
+
width: 100% !important;
|
|
1737
|
+
max-width: none !important;
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
/* Typography & Content */
|
|
1741
|
+
body {
|
|
1742
|
+
font-size: 11pt !important;
|
|
1743
|
+
line-height: 1.5 !important;
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
.main-content {
|
|
1747
|
+
h1 {
|
|
1748
|
+
font-size: 24pt !important;
|
|
1749
|
+
margin-bottom: 1rem !important;
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
h2 {
|
|
1753
|
+
font-size: 18pt !important;
|
|
1754
|
+
margin-top: 1.5rem !important;
|
|
1755
|
+
margin-bottom: 0.75rem !important;
|
|
1756
|
+
}
|
|
1757
|
+
|
|
1758
|
+
h3 {
|
|
1759
|
+
font-size: 14pt !important;
|
|
1760
|
+
margin-top: 1.25rem !important;
|
|
1761
|
+
margin-bottom: 0.5rem !important;
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
p, li {
|
|
1765
|
+
font-size: 11pt !important;
|
|
1766
|
+
margin-bottom: 0.75rem !important;
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
pre, code {
|
|
1770
|
+
font-size: 10pt !important;
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
h1, h2, h3, h4, h5, h6 {
|
|
1775
|
+
color: black !important;
|
|
1776
|
+
page-break-after: avoid;
|
|
1777
|
+
break-after: avoid;
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
h2 {
|
|
1781
|
+
border-bottom: 1px solid #000 !important;
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
p, li {
|
|
1785
|
+
orphans: 3;
|
|
1786
|
+
widows: 3;
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
a {
|
|
1790
|
+
text-decoration: underline !important;
|
|
1791
|
+
color: black !important;
|
|
1792
|
+
}
|
|
1793
|
+
|
|
1794
|
+
/* Expand external links */
|
|
1795
|
+
a[href^="http"]::after {
|
|
1796
|
+
content: " (" attr(href) ")";
|
|
1797
|
+
font-size: 0.85em;
|
|
1798
|
+
color: #555;
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
/* Clean up code blocks */
|
|
1802
|
+
pre {
|
|
1803
|
+
border: 1px solid #ccc !important;
|
|
1804
|
+
white-space: pre-wrap !important;
|
|
1805
|
+
break-inside: avoid;
|
|
1806
|
+
background: #fafafa !important;
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
/* Blockquotes */
|
|
1810
|
+
blockquote {
|
|
1811
|
+
border-left: 3px solid #ccc !important;
|
|
1812
|
+
background: transparent !important;
|
|
1813
|
+
color: #333 !important;
|
|
1814
|
+
break-inside: avoid;
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
/* Tables */
|
|
1818
|
+
table {
|
|
1819
|
+
break-inside: avoid;
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
/* Page Setup */
|
|
1823
|
+
@page {
|
|
1824
|
+
margin: 2cm;
|
|
1825
|
+
size: auto;
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/* Copyright Yukino Song, SudoMaker Ltd.
|
|
2
|
+
*
|
|
3
|
+
* Licensed to the Apache Software Foundation (ASF) under one
|
|
4
|
+
* or more contributor license agreements. See the NOTICE file
|
|
5
|
+
* distributed with this work for additional information
|
|
6
|
+
* regarding copyright ownership. The ASF licenses this file
|
|
7
|
+
* to you under the Apache License, Version 2.0 (the
|
|
8
|
+
* "License"); you may not use this file except in compliance
|
|
9
|
+
* with the License. You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing,
|
|
14
|
+
* software distributed under the License is distributed on an
|
|
15
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
16
|
+
* KIND, either express or implied. See the License for the
|
|
17
|
+
* specific language governing permissions and limitations
|
|
18
|
+
* under the License.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { If, For, $, signal, onCondition, read, extract } from 'refui'
|
|
22
|
+
import NullProtoObj from 'null-prototype-object'
|
|
23
|
+
import { HTMLRenderer } from 'methanol'
|
|
24
|
+
|
|
25
|
+
const navEntryMap = new Map()
|
|
26
|
+
|
|
27
|
+
const currentPath = signal('')
|
|
28
|
+
const matchCurrentPath = onCondition(currentPath)
|
|
29
|
+
|
|
30
|
+
const toSignal = (i) => {
|
|
31
|
+
const clone = Object.assign(new NullProtoObj(), i)
|
|
32
|
+
|
|
33
|
+
let sig = navEntryMap.get(clone.path)
|
|
34
|
+
if (!sig) {
|
|
35
|
+
sig = signal(clone)
|
|
36
|
+
navEntryMap.set(clone.path, sig)
|
|
37
|
+
} else {
|
|
38
|
+
sig.value = clone
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (clone.type === 'directory') {
|
|
42
|
+
clone.children = clone.children.map(toSignal)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return sig
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const NavTree = ({ nodes, depth }) => (
|
|
49
|
+
<For entries={nodes}>
|
|
50
|
+
{({ item }) => {
|
|
51
|
+
const node = read(item)
|
|
52
|
+
const { routeHref: href, routePath, type, name, isRoot } = node
|
|
53
|
+
const { title } = extract(item, 'title')
|
|
54
|
+
|
|
55
|
+
const isActive = matchCurrentPath(routePath)
|
|
56
|
+
|
|
57
|
+
if (type === 'directory') {
|
|
58
|
+
const label = title.or(name)
|
|
59
|
+
const { children } = extract(item, 'children')
|
|
60
|
+
|
|
61
|
+
const isOpen = $(() => {
|
|
62
|
+
if (depth < 1) {
|
|
63
|
+
return true
|
|
64
|
+
}
|
|
65
|
+
const _active = isActive.value
|
|
66
|
+
const _currentPath = currentPath.value
|
|
67
|
+
return _active || _currentPath.startsWith(routePath)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
const header = href ? (
|
|
71
|
+
<a class={isActive.choose('nav-dir-link active', 'nav-dir-link')} href={href}>
|
|
72
|
+
{label}
|
|
73
|
+
</a>
|
|
74
|
+
) : (
|
|
75
|
+
<span class="nav-dir-label">{label}</span>
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<li class={isActive.choose('is-active', null)}>
|
|
80
|
+
<details class="sidebar-collapsible" open={isOpen.choose(true, null)}>
|
|
81
|
+
<summary class="sb-dir-header">{header}</summary>
|
|
82
|
+
<If condition={() => children.value.length}>{() => (
|
|
83
|
+
<ul data-depth={depth + 1}>
|
|
84
|
+
<NavTree nodes={children} depth={depth + 1} />
|
|
85
|
+
</ul>
|
|
86
|
+
)}
|
|
87
|
+
</If>
|
|
88
|
+
</details>
|
|
89
|
+
</li>
|
|
90
|
+
)
|
|
91
|
+
} else {
|
|
92
|
+
const label = title.or(node.isIndex ? 'Home' : name)
|
|
93
|
+
return (
|
|
94
|
+
<li>
|
|
95
|
+
<a class={isActive.choose('active', null)} href={href}>
|
|
96
|
+
{label}
|
|
97
|
+
</a>
|
|
98
|
+
</li>
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
}}
|
|
102
|
+
</For>
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
const rootNodes = signal()
|
|
106
|
+
const rootTree = HTMLRenderer.createElement(NavTree, { nodes: rootNodes, depth: 0 })
|
|
107
|
+
|
|
108
|
+
export const renderNavTree = (nodes, path) => {
|
|
109
|
+
currentPath.value = path
|
|
110
|
+
rootNodes.value = nodes.map(toSignal)
|
|
111
|
+
return rootTree
|
|
112
|
+
}
|
|
@@ -18,68 +18,22 @@
|
|
|
18
18
|
* under the License.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import { HTMLRenderer as R } from 'methanol'
|
|
22
|
-
import { renderToc } from '
|
|
21
|
+
import { HTMLRenderer as R, DOCTYPE_HTML } from 'methanol'
|
|
22
|
+
import { renderToc } from '../components/ThemeToCContainer.static.jsx'
|
|
23
|
+
import { renderNavTree } from './nav-tree.jsx'
|
|
23
24
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
const renderPageTree = (nodes = [], currentRoute, depth = 0) => {
|
|
27
|
-
const items = []
|
|
28
|
-
let hasActive = false
|
|
29
|
-
for (const node of nodes) {
|
|
30
|
-
const nodeRoute = node.routeHref || ''
|
|
31
|
-
if (node.type === 'directory') {
|
|
32
|
-
const label = node.title || node.name
|
|
33
|
-
const isActive = nodeRoute === currentRoute
|
|
34
|
-
const href = node.routeHref
|
|
35
|
-
const childResult = renderPageTree(node.children || [], currentRoute, depth + 1)
|
|
36
|
-
const isOpen = depth < 1 || isActive || childResult.hasActive
|
|
37
|
-
if (isOpen) hasActive = true
|
|
38
|
-
const header = href ? (
|
|
39
|
-
<a class={isActive ? 'nav-dir-link active' : 'nav-dir-link'} href={href}>
|
|
40
|
-
{label}
|
|
41
|
-
</a>
|
|
42
|
-
) : (
|
|
43
|
-
<span class="nav-dir-label">{label}</span>
|
|
44
|
-
)
|
|
45
|
-
items.push(
|
|
46
|
-
<li class={isActive ? 'is-active' : null}>
|
|
47
|
-
<details class="sidebar-collapsible" open={isOpen ? true : null}>
|
|
48
|
-
<summary class="sb-dir-header">{header}</summary>
|
|
49
|
-
{childResult.items.length ? <ul data-depth={depth + 1}>{childResult.items}</ul> : null}
|
|
50
|
-
</details>
|
|
51
|
-
</li>
|
|
52
|
-
)
|
|
53
|
-
continue
|
|
54
|
-
}
|
|
55
|
-
const label = node.title || (node.isIndex ? 'Home' : node.name)
|
|
56
|
-
const isActive = nodeRoute === currentRoute
|
|
57
|
-
if (isActive) hasActive = true
|
|
58
|
-
const href = node.routeHref
|
|
59
|
-
items.push(
|
|
60
|
-
<li>
|
|
61
|
-
<a class={isActive ? 'active' : null} href={href}>
|
|
62
|
-
{label}
|
|
63
|
-
</a>
|
|
64
|
-
</li>
|
|
65
|
-
)
|
|
66
|
-
}
|
|
67
|
-
return { items, hasActive }
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const PAGE_TEMPLATE = ({ PageContent, ExtraHead, components, ctx }) => {
|
|
25
|
+
const PAGE_TEMPLATE = async ({ PageContent, ExtraHead, components, ctx }) => {
|
|
71
26
|
const page = ctx.page
|
|
72
27
|
const pagesByRoute = ctx.pagesByRoute
|
|
73
28
|
const pages = ctx.pages || []
|
|
74
29
|
const pagesTree = ctx.pagesTree || []
|
|
75
30
|
const siteName = ctx.site.name || 'Methanol Site'
|
|
76
31
|
const title = page.title || siteName
|
|
77
|
-
const
|
|
78
|
-
|
|
32
|
+
const baseHref =
|
|
33
|
+
page.routeHref === '/404' || page.routeHref === '/offline' ? ctx.site.base || '/' : null
|
|
79
34
|
const toc = page.toc?.length ? renderToc(page.toc) : null
|
|
80
35
|
const hasToc = Boolean(toc)
|
|
81
36
|
const layoutClass = hasToc ? 'layout-container' : 'layout-container no-toc'
|
|
82
|
-
const tree = renderPageTree(pagesTree, currentRoute, 0)
|
|
83
37
|
const { ThemeSearchBox, ThemeColorSwitch, ThemeAccentSwitch, ThemeToCContainer } = components
|
|
84
38
|
const rootPage = pagesByRoute.get('/') || pages.find((entry) => entry.routeHref === '/')
|
|
85
39
|
const pageFrontmatter = page.frontmatter || {}
|
|
@@ -146,9 +100,10 @@ const PAGE_TEMPLATE = ({ PageContent, ExtraHead, components, ctx }) => {
|
|
|
146
100
|
</div>
|
|
147
101
|
</div>
|
|
148
102
|
) : null
|
|
103
|
+
|
|
149
104
|
return (
|
|
150
105
|
<>
|
|
151
|
-
{
|
|
106
|
+
{DOCTYPE_HTML}
|
|
152
107
|
<html lang={htmlLang}>
|
|
153
108
|
<head>
|
|
154
109
|
<meta charset="UTF-8" />
|
|
@@ -244,7 +199,7 @@ const PAGE_TEMPLATE = ({ PageContent, ExtraHead, components, ctx }) => {
|
|
|
244
199
|
{pagefindEnabled ? <ThemeSearchBox options={pagefindOptions} /> : null}
|
|
245
200
|
</div>
|
|
246
201
|
<nav>
|
|
247
|
-
<ul data-depth="0">{
|
|
202
|
+
<ul data-depth="0">{renderNavTree(pagesTree, page.routePath)}</ul>
|
|
248
203
|
</nav>
|
|
249
204
|
<div class="sidebar-footer">
|
|
250
205
|
{languageSelector}
|
|
@@ -294,7 +249,7 @@ const PAGE_TEMPLATE = ({ PageContent, ExtraHead, components, ctx }) => {
|
|
|
294
249
|
<span style="margin: 0 0.5rem; opacity: 0.5;">•</span>
|
|
295
250
|
</>
|
|
296
251
|
) : null}
|
|
297
|
-
Updated: {page.updatedAt || '-'}
|
|
252
|
+
Updated: {page.stats.updatedAt || '-'}
|
|
298
253
|
</div>
|
|
299
254
|
<div class="page-meta-item">
|
|
300
255
|
Powered by{' '}
|
|
File without changes
|