v0.10.0 0f4e9eb

vite-plugin-pages.ts RawHistoryFolder

1import type { Plugin } from "vite";
2import { writeFileSync, readFileSync, existsSync, copyFileSync } from "fs";
3import { resolve } from "path";
4
5interface PageConfig {
6  /** Page name (used for filename and script name) */
7  name: string;
8  /** Page title */
9  title: string;
10  /** Script filename (e.g., 'homepage.min.js') */
11  script: string;
12  /** Optional CSS filename */
13  css?: string;
14  /** Target filename (defaults to name + '.html') */
15  filename?: string;
16}
17
18// Load the favicon SVG from assets
19function getFaviconSVG(): string {
20  const logoPath = resolve(__dirname, "..", "assets", "logo.svg");
21  return readFileSync(logoPath, "utf-8");
22}
23
24
25// Generate HTML content for a page
26function generatePageHTML(config: PageConfig): string {
27  const cssLink = config.css
28    ? `<link rel="stylesheet" href="./${config.css}">`
29    : "";
30
31  return `<!DOCTYPE html>
32<html lang="en">
33<head>
34    <meta charset="UTF-8">
35    <meta name="viewport" content="width=device-width, initial-scale=1.0">
36    <title>${config.title}</title>
37    <link rel="icon" type="image/x-icon" href="dumb://homepage/favicon.ico">
38    ${cssLink}
39</head>
40<body>
41    <script src="./${config.script}"></script>
42</body>
43</html>`;
44}
45
46/**
47 * Vite plugin to generate dumb:// protocol pages
48 * Supports multiple pages like homepage, config, about, etc.
49 */
50export function pageGenerator(pages: PageConfig[]): Plugin {
51  return {
52    name: "dumb-page-generator",
53    writeBundle() {
54      const assetsDir = resolve(__dirname, "..", "assets", "gui");
55
56      try {
57        // Generate HTML files for each page
58        for (const page of pages) {
59          const htmlContent = generatePageHTML(page);
60          const filename = page.filename || `${page.name}.html`;
61          writeFileSync(resolve(assetsDir, filename), htmlContent);
62          console.log(`✓ Generated ${filename} for dumb://${page.name}`);
63        }
64
65        // Generate favicon files for scheme handler lookups
66        const faviconContent = getFaviconSVG();
67        writeFileSync(resolve(assetsDir, "favicon.svg"), faviconContent);
68        console.log("✓ Generated favicon.svg");
69
70        // Copy pre-generated PNG and ICO favicons if they exist
71        const sourceDir = resolve(__dirname, "..", "assets", "gui");
72        try {
73          const pngPath = resolve(sourceDir, "favicon.png");
74          const icoPath = resolve(sourceDir, "favicon.ico");
75
76          if (existsSync(pngPath)) {
77            copyFileSync(pngPath, resolve(assetsDir, "favicon.png"));
78            console.log("✓ Copied favicon.png");
79          }
80
81          if (existsSync(icoPath)) {
82            copyFileSync(icoPath, resolve(assetsDir, "favicon.ico"));
83            console.log("✓ Copied favicon.ico");
84          }
85        } catch (err) {
86          console.warn("⚠ Could not copy favicon PNG/ICO files:", err);
87        }
88      } catch (error) {
89        console.error("✗ Failed to generate page files:", error);
90        throw error;
91      }
92    },
93  };
94}
95
96/**
97 * Convenience function for homepage generation
98 * @deprecated Use pageGenerator with homepage config instead
99 */
100export function homepageGenerator(): Plugin {
101  return pageGenerator([
102    {
103      name: "homepage",
104      title: "Dumber Browser",
105      script: "homepage.min.js",
106      filename: "index.html", // Special case: homepage uses index.html
107    },
108  ]);
109}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close