refactor(build): migrate from gui/ to webui/ directory and update assets
Completes the frontend migration by: - Removing old gui/ directory with legacy Svelte/Vite structure - Adding new webui/ directory with updated build configuration - Replacing gui_embed.go with webui_embed.go for asset embedding - Updating .gitignore and Makefile for new frontend location This migration supports the new architecture where frontend components are injected into web content via WebKit's content injection APIs.
- commit
- 225efeb366d68bd439243ce04c89887b2c179ec8
- author
- brice · · 2025-12-11 18:03 UTC
- committer
- brice · · 2025-12-11 21:42 UTC
- parent
- a970f83
- signature
- unsigned
M .gitignore +1 -1
| @@ -62,7 +62,7 @@ config.local.* | |||
| 62 | 62 | tmp/go-cache/ | |
| 63 | 63 | tmp/go-mod/ | |
| 64 | 64 | tmp/ | |
| 65 | - | assets/gui | |
| 65 | + | assets/webui | |
| 66 | 66 | ||
| 67 | 67 | # Node/TypeScript related | |
| 68 | 68 | node_modules/ | |
| @@ -62,7 +62,7 @@ config.local.* | |||||
| 62 | tmp/go-cache/ | 62 | tmp/go-cache/ | ||
| 63 | tmp/go-mod/ | 63 | tmp/go-mod/ | ||
| 64 | tmp/ | 64 | tmp/ | ||
| 65 | - | assets/gui | 65 | + | assets/webui |
| 66 | 66 | ||||
| 67 | # Node/TypeScript related | 67 | # Node/TypeScript related | ||
| 68 | node_modules/ | 68 | node_modules/ | ||
M Makefile +8 -3
| @@ -38,7 +38,7 @@ build: build-frontend ## Build the application (pure Go, no CGO) | |||
| 38 | 38 | ||
| 39 | 39 | build-frontend: ## Build Svelte GUI with Tailwind CSS and main-world script | |
| 40 | 40 | @echo "Building Svelte GUI with Tailwind CSS..." | |
| 41 | - | @cd gui && npm install --silent && npm run build | |
| 41 | + | @cd webui && npm install --silent && npm run build | |
| 42 | 42 | @echo "GUI build complete" | |
| 43 | 43 | ||
| 44 | 44 | build-quick: ## Build without frontend (faster for backend development) | |
| @@ -61,6 +61,11 @@ generate: ## Generate code (SQLC) | |||
| 61 | 61 | sqlc generate | |
| 62 | 62 | @echo "Code generation complete" | |
| 63 | 63 | ||
| 64 | + | mocks: ## Generate mock implementations with mockery | |
| 65 | + | @echo "Generating mocks with mockery..." | |
| 66 | + | mockery | |
| 67 | + | @echo "Mock generation complete" | |
| 68 | + | ||
| 64 | 69 | # Testing | |
| 65 | 70 | test: ## Run tests | |
| 66 | 71 | @echo "Running tests..." | |
| @@ -102,8 +107,8 @@ clean: ## Clean build artifacts | |||
| 102 | 107 | @echo "Cleaning build artifacts..." | |
| 103 | 108 | rm -rf $(DIST_DIR) | |
| 104 | 109 | rm -f $(BINARY_NAME) | |
| 105 | - | rm -rf gui/dist gui/node_modules | |
| 106 | - | rm -f assets/gui/gui.min.js assets/gui/homepage.min.js assets/gui/homepage.css assets/gui/main-world.min.js assets/gui/color-scheme.js | |
| 110 | + | rm -rf webui/dist webui/node_modules | |
| 111 | + | rm -f assets/webui/gui.min.js assets/webui/homepage.min.js assets/webui/homepage.css assets/webui/main-world.min.js assets/webui/color-scheme.js | |
| 107 | 112 | rm -f coverage.out coverage.html | |
| 108 | 113 | go clean -cache | |
| 109 | 114 | go clean -testcache | |
| @@ -38,7 +38,7 @@ build: build-frontend ## Build the application (pure Go, no CGO) | |||||
| 38 | 38 | ||||
| 39 | build-frontend: ## Build Svelte GUI with Tailwind CSS and main-world script | 39 | build-frontend: ## Build Svelte GUI with Tailwind CSS and main-world script | ||
| 40 | @echo "Building Svelte GUI with Tailwind CSS..." | 40 | @echo "Building Svelte GUI with Tailwind CSS..." | ||
| 41 | - | @cd gui && npm install --silent && npm run build | 41 | + | @cd webui && npm install --silent && npm run build |
| 42 | @echo "GUI build complete" | 42 | @echo "GUI build complete" | ||
| 43 | 43 | ||||
| 44 | build-quick: ## Build without frontend (faster for backend development) | 44 | build-quick: ## Build without frontend (faster for backend development) | ||
| @@ -61,6 +61,11 @@ generate: ## Generate code (SQLC) | |||||
| 61 | sqlc generate | 61 | sqlc generate | ||
| 62 | @echo "Code generation complete" | 62 | @echo "Code generation complete" | ||
| 63 | 63 | ||||
| 64 | + | mocks: ## Generate mock implementations with mockery | |||
| 65 | + | @echo "Generating mocks with mockery..." | |||
| 66 | + | mockery | |||
| 67 | + | @echo "Mock generation complete" | |||
| 68 | + | ||||
| 64 | # Testing | 69 | # Testing | ||
| 65 | test: ## Run tests | 70 | test: ## Run tests | ||
| 66 | @echo "Running tests..." | 71 | @echo "Running tests..." | ||
| @@ -102,8 +107,8 @@ clean: ## Clean build artifacts | |||||
| 102 | @echo "Cleaning build artifacts..." | 107 | @echo "Cleaning build artifacts..." | ||
| 103 | rm -rf $(DIST_DIR) | 108 | rm -rf $(DIST_DIR) | ||
| 104 | rm -f $(BINARY_NAME) | 109 | rm -f $(BINARY_NAME) | ||
| 105 | - | rm -rf gui/dist gui/node_modules | 110 | + | rm -rf webui/dist webui/node_modules |
| 106 | - | rm -f assets/gui/gui.min.js assets/gui/homepage.min.js assets/gui/homepage.css assets/gui/main-world.min.js assets/gui/color-scheme.js | 111 | + | rm -f assets/webui/gui.min.js assets/webui/homepage.min.js assets/webui/homepage.css assets/webui/main-world.min.js assets/webui/color-scheme.js |
| 107 | rm -f coverage.out coverage.html | 112 | rm -f coverage.out coverage.html | ||
| 108 | go clean -cache | 113 | go clean -cache | ||
| 109 | go clean -testcache | 114 | go clean -testcache | ||
R assets/gui_embed.go → assets/webui_embed.go +5 -5 renamed, 61% similar
| @@ -2,19 +2,19 @@ package assets | |||
| 2 | 2 | ||
| 3 | 3 | import _ "embed" | |
| 4 | 4 | ||
| 5 | - | // GUI scripts embedded at compile time | |
| 5 | + | // WebUI scripts embedded at compile time | |
| 6 | 6 | ||
| 7 | - | //go:embed gui/main-world.min.js | |
| 7 | + | //go:embed webui/main-world.min.js | |
| 8 | 8 | var MainWorldScript string | |
| 9 | 9 | ||
| 10 | - | //go:embed gui/gui.min.js | |
| 10 | + | //go:embed webui/gui.min.js | |
| 11 | 11 | var GUIScript string | |
| 12 | 12 | ||
| 13 | - | //go:embed gui/color-scheme.js | |
| 13 | + | //go:embed webui/color-scheme.js | |
| 14 | 14 | var ColorSchemeScript string | |
| 15 | 15 | ||
| 16 | 16 | // GUI component styles extracted from Svelte components | |
| 17 | 17 | // These are injected into the isolated world using UserStyleSheet | |
| 18 | 18 | // | |
| 19 | - | //go:embed gui/gui.min.css | |
| 19 | + | //go:embed webui/gui.min.css | |
| 20 | 20 | var ComponentStyles string | |
| @@ -2,19 +2,19 @@ package assets | |||||
| 2 | 2 | ||||
| 3 | import _ "embed" | 3 | import _ "embed" | ||
| 4 | 4 | ||||
| 5 | - | // GUI scripts embedded at compile time | 5 | + | // WebUI scripts embedded at compile time |
| 6 | 6 | ||||
| 7 | - | //go:embed gui/main-world.min.js | 7 | + | //go:embed webui/main-world.min.js |
| 8 | var MainWorldScript string | 8 | var MainWorldScript string | ||
| 9 | 9 | ||||
| 10 | - | //go:embed gui/gui.min.js | 10 | + | //go:embed webui/gui.min.js |
| 11 | var GUIScript string | 11 | var GUIScript string | ||
| 12 | 12 | ||||
| 13 | - | //go:embed gui/color-scheme.js | 13 | + | //go:embed webui/color-scheme.js |
| 14 | var ColorSchemeScript string | 14 | var ColorSchemeScript string | ||
| 15 | 15 | ||||
| 16 | // GUI component styles extracted from Svelte components | 16 | // GUI component styles extracted from Svelte components | ||
| 17 | // These are injected into the isolated world using UserStyleSheet | 17 | // These are injected into the isolated world using UserStyleSheet | ||
| 18 | // | 18 | // | ||
| 19 | - | //go:embed gui/gui.min.css | 19 | + | //go:embed webui/gui.min.css |
| 20 | var ComponentStyles string | 20 | var ComponentStyles string | ||
R gui/eslint.config.js → webui/eslint.config.js +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/package-lock.json → webui/package-lock.json +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/package.json → webui/package.json +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/postcss.config.js → webui/postcss.config.js +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/components/Footer.svelte → webui/src/components/Footer.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/components/omnibox/Omnibox.svelte → webui/src/components/omnibox/Omnibox.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/components/omnibox/OmniboxFind.svelte → webui/src/components/omnibox/OmniboxFind.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/components/omnibox/OmniboxInput.svelte → webui/src/components/omnibox/OmniboxInput.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/components/omnibox/OmniboxSuggestions.svelte → webui/src/components/omnibox/OmniboxSuggestions.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/components/omnibox/find.ts → webui/src/components/omnibox/find.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/components/omnibox/index.ts → webui/src/components/omnibox/index.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/components/omnibox/messaging.ts → webui/src/components/omnibox/messaging.ts +11 -7 renamed, 96% similar
| @@ -13,9 +13,14 @@ export class OmniboxBridge implements OmniboxMessageBridge { | |||
| 13 | 13 | postMessage(msg: OmniboxMessage): void { | |
| 14 | 14 | console.log("📤 [DEBUG] Posting message to backend via bridge:", msg); | |
| 15 | 15 | try { | |
| 16 | + | // Include webview_id for message routing | |
| 17 | + | const payload = { | |
| 18 | + | ...msg, | |
| 19 | + | webview_id: (window as any).__dumber_webview_id ?? 0, | |
| 20 | + | }; | |
| 16 | 21 | // Dispatch CustomEvent that main-world bridge will listen to | |
| 17 | 22 | document.dispatchEvent(new CustomEvent("dumber:isolated-message", { | |
| 18 | - | detail: { payload: msg } | |
| 23 | + | detail: { payload } | |
| 19 | 24 | })); | |
| 20 | 25 | console.log("✅ [DEBUG] Dispatched isolated message event"); | |
| 21 | 26 | } catch (e) { | |
| @@ -117,11 +122,10 @@ export class OmniboxBridge implements OmniboxMessageBridge { | |||
| 117 | 122 | // Send message to Go backend | |
| 118 | 123 | const bridge = window.webkit?.messageHandlers?.dumber; | |
| 119 | 124 | if (bridge && typeof bridge.postMessage === "function") { | |
| 120 | - | bridge.postMessage( | |
| 121 | - | JSON.stringify({ | |
| 122 | - | type: "get_search_shortcuts", | |
| 123 | - | }), | |
| 124 | - | ); | |
| 125 | + | bridge.postMessage({ | |
| 126 | + | type: "get_search_shortcuts", | |
| 127 | + | webview_id: (window as any).__dumber_webview_id ?? 0, | |
| 128 | + | }); | |
| 125 | 129 | } else { | |
| 126 | 130 | reject(new Error("WebKit message handler not available")); | |
| 127 | 131 | } | |
| @@ -307,7 +311,7 @@ declare global { | |||
| 307 | 311 | webkit?: { | |
| 308 | 312 | messageHandlers?: { | |
| 309 | 313 | dumber?: { | |
| 310 | - | postMessage: (message: string) => void; | |
| 314 | + | postMessage: (message: unknown) => void; | |
| 311 | 315 | }; | |
| 312 | 316 | }; | |
| 313 | 317 | }; | |
| @@ -13,9 +13,14 @@ export class OmniboxBridge implements OmniboxMessageBridge { | |||||
| 13 | postMessage(msg: OmniboxMessage): void { | 13 | postMessage(msg: OmniboxMessage): void { | ||
| 14 | console.log("📤 [DEBUG] Posting message to backend via bridge:", msg); | 14 | console.log("📤 [DEBUG] Posting message to backend via bridge:", msg); | ||
| 15 | try { | 15 | try { | ||
| 16 | + | // Include webview_id for message routing | |||
| 17 | + | const payload = { | |||
| 18 | + | ...msg, | |||
| 19 | + | webview_id: (window as any).__dumber_webview_id ?? 0, | |||
| 20 | + | }; | |||
| 16 | // Dispatch CustomEvent that main-world bridge will listen to | 21 | // Dispatch CustomEvent that main-world bridge will listen to | ||
| 17 | document.dispatchEvent(new CustomEvent("dumber:isolated-message", { | 22 | document.dispatchEvent(new CustomEvent("dumber:isolated-message", { | ||
| 18 | - | detail: { payload: msg } | 23 | + | detail: { payload } |
| 19 | })); | 24 | })); | ||
| 20 | console.log("✅ [DEBUG] Dispatched isolated message event"); | 25 | console.log("✅ [DEBUG] Dispatched isolated message event"); | ||
| 21 | } catch (e) { | 26 | } catch (e) { | ||
| @@ -117,11 +122,10 @@ export class OmniboxBridge implements OmniboxMessageBridge { | |||||
| 117 | // Send message to Go backend | 122 | // Send message to Go backend | ||
| 118 | const bridge = window.webkit?.messageHandlers?.dumber; | 123 | const bridge = window.webkit?.messageHandlers?.dumber; | ||
| 119 | if (bridge && typeof bridge.postMessage === "function") { | 124 | if (bridge && typeof bridge.postMessage === "function") { | ||
| 120 | - | bridge.postMessage( | 125 | + | bridge.postMessage({ |
| 121 | - | JSON.stringify({ | 126 | + | type: "get_search_shortcuts", |
| 122 | - | type: "get_search_shortcuts", | 127 | + | webview_id: (window as any).__dumber_webview_id ?? 0, |
| 123 | - | }), | 128 | + | }); |
| 124 | - | ); | |||
| 125 | } else { | 129 | } else { | ||
| 126 | reject(new Error("WebKit message handler not available")); | 130 | reject(new Error("WebKit message handler not available")); | ||
| 127 | } | 131 | } | ||
| @@ -307,7 +311,7 @@ declare global { | |||||
| 307 | webkit?: { | 311 | webkit?: { | ||
| 308 | messageHandlers?: { | 312 | messageHandlers?: { | ||
| 309 | dumber?: { | 313 | dumber?: { | ||
| 310 | - | postMessage: (message: string) => void; | 314 | + | postMessage: (message: unknown) => void; |
| 311 | }; | 315 | }; | ||
| 312 | }; | 316 | }; | ||
| 313 | }; | 317 | }; | ||
R gui/src/components/omnibox/stores.svelte.ts → webui/src/components/omnibox/stores.svelte.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/components/omnibox/types.ts → webui/src/components/omnibox/types.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/components/toast/Toast.svelte → webui/src/components/toast/Toast.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/components/toast/ToastContainer.svelte → webui/src/components/toast/ToastContainer.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/injected/bootstrap.ts → webui/src/injected/bootstrap.ts +35 -6 renamed, 89% similar
| @@ -41,6 +41,14 @@ declare global { | |||
| 41 | 41 | __dumber_find_query?: (query: string) => void; | |
| 42 | 42 | __dumber_dismissToast?: (id: number) => void; | |
| 43 | 43 | __dumber_clearToasts?: () => void; | |
| 44 | + | webkit?: { | |
| 45 | + | messageHandlers?: { | |
| 46 | + | dumber?: { | |
| 47 | + | postMessage: (message: unknown) => void; | |
| 48 | + | }; | |
| 49 | + | }; | |
| 50 | + | }; | |
| 51 | + | __dumber_webview_id?: number | string; | |
| 44 | 52 | } | |
| 45 | 53 | } | |
| 46 | 54 | ||
| @@ -108,6 +116,28 @@ export function bootstrapGUI(): void { | |||
| 108 | 116 | // Ignore environments without pagehide support | |
| 109 | 117 | } | |
| 110 | 118 | ||
| 119 | + | // Request color palettes from Go backend | |
| 120 | + | // The isolated world has access to webkit.messageHandlers, main world does not. | |
| 121 | + | // Main world has set up the __dumber_color_palettes callback handler. | |
| 122 | + | const requestColorPalettes = () => { | |
| 123 | + | try { | |
| 124 | + | const bridge = window.webkit?.messageHandlers?.dumber; | |
| 125 | + | if (bridge && typeof bridge.postMessage === "function") { | |
| 126 | + | const webviewId = window.__dumber_webview_id; | |
| 127 | + | console.log("[dumber-palette] Requesting color palettes from backend, webview_id:", webviewId); | |
| 128 | + | bridge.postMessage({ | |
| 129 | + | type: "get_color_palettes", | |
| 130 | + | webview_id: typeof webviewId === "number" ? webviewId : 0, | |
| 131 | + | }); | |
| 132 | + | } else { | |
| 133 | + | console.warn("[dumber-palette] WebKit message handler not available"); | |
| 134 | + | } | |
| 135 | + | } catch (err) { | |
| 136 | + | console.error("[dumber-palette] Failed to request color palettes:", err); | |
| 137 | + | } | |
| 138 | + | }; | |
| 139 | + | requestColorPalettes(); | |
| 140 | + | ||
| 111 | 141 | let workspaceHasFocus = false; | |
| 112 | 142 | const initialRawWebViewId = window.__dumber_webview_id; | |
| 113 | 143 | let currentWebViewId = normalizeWebviewId(initialRawWebViewId); | |
| @@ -119,12 +149,11 @@ export function bootstrapGUI(): void { | |||
| 119 | 149 | if (currentWebViewId === null) { | |
| 120 | 150 | console.log("[workspace] WebView ID unknown, requesting from Go backend"); | |
| 121 | 151 | if (window.webkit?.messageHandlers?.dumber) { | |
| 122 | - | window.webkit.messageHandlers.dumber.postMessage( | |
| 123 | - | JSON.stringify({ | |
| 124 | - | type: "request-webview-id", | |
| 125 | - | payload: { timestamp: Date.now() }, | |
| 126 | - | }), | |
| 127 | - | ); | |
| 152 | + | window.webkit.messageHandlers.dumber.postMessage({ | |
| 153 | + | type: "request-webview-id", | |
| 154 | + | webview_id: 0, | |
| 155 | + | payload: { timestamp: Date.now() }, | |
| 156 | + | }); | |
| 128 | 157 | } | |
| 129 | 158 | } | |
| 130 | 159 | ||
| @@ -41,6 +41,14 @@ declare global { | |||||
| 41 | __dumber_find_query?: (query: string) => void; | 41 | __dumber_find_query?: (query: string) => void; | ||
| 42 | __dumber_dismissToast?: (id: number) => void; | 42 | __dumber_dismissToast?: (id: number) => void; | ||
| 43 | __dumber_clearToasts?: () => void; | 43 | __dumber_clearToasts?: () => void; | ||
| 44 | + | webkit?: { | |||
| 45 | + | messageHandlers?: { | |||
| 46 | + | dumber?: { | |||
| 47 | + | postMessage: (message: unknown) => void; | |||
| 48 | + | }; | |||
| 49 | + | }; | |||
| 50 | + | }; | |||
| 51 | + | __dumber_webview_id?: number | string; | |||
| 44 | } | 52 | } | ||
| 45 | } | 53 | } | ||
| 46 | 54 | ||||
| @@ -108,6 +116,28 @@ export function bootstrapGUI(): void { | |||||
| 108 | // Ignore environments without pagehide support | 116 | // Ignore environments without pagehide support | ||
| 109 | } | 117 | } | ||
| 110 | 118 | ||||
| 119 | + | // Request color palettes from Go backend | |||
| 120 | + | // The isolated world has access to webkit.messageHandlers, main world does not. | |||
| 121 | + | // Main world has set up the __dumber_color_palettes callback handler. | |||
| 122 | + | const requestColorPalettes = () => { | |||
| 123 | + | try { | |||
| 124 | + | const bridge = window.webkit?.messageHandlers?.dumber; | |||
| 125 | + | if (bridge && typeof bridge.postMessage === "function") { | |||
| 126 | + | const webviewId = window.__dumber_webview_id; | |||
| 127 | + | console.log("[dumber-palette] Requesting color palettes from backend, webview_id:", webviewId); | |||
| 128 | + | bridge.postMessage({ | |||
| 129 | + | type: "get_color_palettes", | |||
| 130 | + | webview_id: typeof webviewId === "number" ? webviewId : 0, | |||
| 131 | + | }); | |||
| 132 | + | } else { | |||
| 133 | + | console.warn("[dumber-palette] WebKit message handler not available"); | |||
| 134 | + | } | |||
| 135 | + | } catch (err) { | |||
| 136 | + | console.error("[dumber-palette] Failed to request color palettes:", err); | |||
| 137 | + | } | |||
| 138 | + | }; | |||
| 139 | + | requestColorPalettes(); | |||
| 140 | + | ||||
| 111 | let workspaceHasFocus = false; | 141 | let workspaceHasFocus = false; | ||
| 112 | const initialRawWebViewId = window.__dumber_webview_id; | 142 | const initialRawWebViewId = window.__dumber_webview_id; | ||
| 113 | let currentWebViewId = normalizeWebviewId(initialRawWebViewId); | 143 | let currentWebViewId = normalizeWebviewId(initialRawWebViewId); | ||
| @@ -119,12 +149,11 @@ export function bootstrapGUI(): void { | |||||
| 119 | if (currentWebViewId === null) { | 149 | if (currentWebViewId === null) { | ||
| 120 | console.log("[workspace] WebView ID unknown, requesting from Go backend"); | 150 | console.log("[workspace] WebView ID unknown, requesting from Go backend"); | ||
| 121 | if (window.webkit?.messageHandlers?.dumber) { | 151 | if (window.webkit?.messageHandlers?.dumber) { | ||
| 122 | - | window.webkit.messageHandlers.dumber.postMessage( | 152 | + | window.webkit.messageHandlers.dumber.postMessage({ |
| 123 | - | JSON.stringify({ | 153 | + | type: "request-webview-id", |
| 124 | - | type: "request-webview-id", | 154 | + | webview_id: 0, |
| 125 | - | payload: { timestamp: Date.now() }, | 155 | + | payload: { timestamp: Date.now() }, |
| 126 | - | }), | 156 | + | }); |
| 127 | - | ); | |||
| 128 | } | 157 | } | ||
| 129 | } | 158 | } | ||
| 130 | 159 | ||||
R gui/src/injected/gui.ts → webui/src/injected/gui.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/injected/main-world.ts → webui/src/injected/main-world.ts +56 -73 renamed, 90% similar
| @@ -46,7 +46,7 @@ declare global { | |||
| 46 | 46 | webkit?: { | |
| 47 | 47 | messageHandlers?: { | |
| 48 | 48 | dumber?: { | |
| 49 | - | postMessage: (message: string) => void; | |
| 49 | + | postMessage: (message: unknown) => void; | |
| 50 | 50 | }; | |
| 51 | 51 | }; | |
| 52 | 52 | }; | |
| @@ -88,73 +88,58 @@ interface DumberAPI { | |||
| 88 | 88 | window.__dumber_is_active = "__WEBVIEW_ACTIVE__" as unknown as boolean; | |
| 89 | 89 | } | |
| 90 | 90 | ||
| 91 | - | // Request color palettes from Go backend | |
| 92 | - | try { | |
| 93 | - | console.log("[dumber-palette] Initializing color palette loading"); | |
| 94 | - | const bridge = window.webkit?.messageHandlers?.dumber; | |
| 95 | - | ||
| 96 | - | if (!bridge || typeof bridge.postMessage !== "function") { | |
| 97 | - | console.error("[dumber-palette] ERROR: No webkit message bridge available"); | |
| 98 | - | return; | |
| 99 | - | } | |
| 100 | - | ||
| 101 | - | console.log("[dumber-palette] WebKit bridge found, setting up handlers"); | |
| 102 | - | ||
| 103 | - | // Set up callback handler before requesting | |
| 104 | - | window.__dumber_color_palettes = (palettes: unknown) => { | |
| 105 | - | console.log("[dumber-palette] Received palettes from backend:", palettes); | |
| 106 | - | try { | |
| 107 | - | // Type guard to ensure palettes is a valid object | |
| 108 | - | if (typeof palettes !== "object" || palettes === null) { | |
| 109 | - | console.error("[dumber-palette] ERROR: Invalid palettes received - type:", typeof palettes); | |
| 110 | - | return; | |
| 111 | - | } | |
| 91 | + | // Set up color palette callback handlers (will be called from isolated world via CustomEvent) | |
| 92 | + | window.__dumber_color_palettes = (palettes: unknown) => { | |
| 93 | + | console.log("[dumber-palette] Received palettes from backend:", palettes); | |
| 94 | + | try { | |
| 95 | + | // Type guard to ensure palettes is a valid object | |
| 96 | + | if (typeof palettes !== "object" || palettes === null) { | |
| 97 | + | console.error("[dumber-palette] ERROR: Invalid palettes received - type:", typeof palettes); | |
| 98 | + | return; | |
| 99 | + | } | |
| 112 | 100 | ||
| 113 | - | window.__dumber_palette = palettes as Record<string, Record<string, string>>; | |
| 114 | - | console.log("[dumber-palette] Palette keys:", Object.keys(window.__dumber_palette || {})); | |
| 115 | - | ||
| 116 | - | // Normalize palette keys to lowercase | |
| 117 | - | const normalized: Record<string, Record<string, string>> = {}; | |
| 118 | - | if (window.__dumber_palette) { | |
| 119 | - | for (const key in window.__dumber_palette) { | |
| 120 | - | if (Object.prototype.hasOwnProperty.call(window.__dumber_palette, key)) { | |
| 121 | - | const paletteValue = window.__dumber_palette[key]; | |
| 122 | - | if (paletteValue) { | |
| 123 | - | normalized[key.toLowerCase()] = paletteValue; | |
| 124 | - | console.log(`[dumber-palette] Normalized: ${key} -> ${key.toLowerCase()}, colors:`, Object.keys(paletteValue)); | |
| 125 | - | } | |
| 101 | + | window.__dumber_palette = palettes as Record<string, Record<string, string>>; | |
| 102 | + | console.log("[dumber-palette] Palette keys:", Object.keys(window.__dumber_palette || {})); | |
| 103 | + | ||
| 104 | + | // Normalize palette keys to lowercase | |
| 105 | + | const normalized: Record<string, Record<string, string>> = {}; | |
| 106 | + | if (window.__dumber_palette) { | |
| 107 | + | for (const key in window.__dumber_palette) { | |
| 108 | + | if (Object.prototype.hasOwnProperty.call(window.__dumber_palette, key)) { | |
| 109 | + | const paletteValue = window.__dumber_palette[key]; | |
| 110 | + | if (paletteValue) { | |
| 111 | + | normalized[key.toLowerCase()] = paletteValue; | |
| 112 | + | console.log(`[dumber-palette] Normalized: ${key} -> ${key.toLowerCase()}, colors:`, Object.keys(paletteValue)); | |
| 126 | 113 | } | |
| 127 | 114 | } | |
| 128 | - | window.__dumber_palette = normalized; | |
| 129 | 115 | } | |
| 116 | + | window.__dumber_palette = normalized; | |
| 117 | + | } | |
| 130 | 118 | ||
| 131 | - | // Apply palette now that we have it | |
| 132 | - | const initialTheme: "light" | "dark" = document.documentElement.classList.contains("dark") ? "dark" : "light"; | |
| 133 | - | console.log(`[dumber-palette] Initial theme detected: ${initialTheme}`); | |
| 134 | - | window.__dumber_initial_theme = initialTheme; | |
| 119 | + | // Apply palette now that we have it | |
| 120 | + | const initialTheme: "light" | "dark" = document.documentElement.classList.contains("dark") ? "dark" : "light"; | |
| 121 | + | console.log(`[dumber-palette] Initial theme detected: ${initialTheme}`); | |
| 122 | + | window.__dumber_initial_theme = initialTheme; | |
| 135 | 123 | ||
| 136 | - | if (window.__dumber_applyPalette) { | |
| 137 | - | console.log("[dumber-palette] Applying palette..."); | |
| 138 | - | window.__dumber_applyPalette(initialTheme); | |
| 139 | - | } else { | |
| 140 | - | console.error("[dumber-palette] ERROR: __dumber_applyPalette function not found"); | |
| 141 | - | } | |
| 142 | - | } catch (err) { | |
| 143 | - | console.error("[dumber-palette] ERROR: Failed to apply received palette:", err); | |
| 124 | + | if (window.__dumber_applyPalette) { | |
| 125 | + | console.log("[dumber-palette] Applying palette..."); | |
| 126 | + | window.__dumber_applyPalette(initialTheme); | |
| 127 | + | } else { | |
| 128 | + | console.error("[dumber-palette] ERROR: __dumber_applyPalette function not found"); | |
| 144 | 129 | } | |
| 145 | - | }; | |
| 130 | + | } catch (err) { | |
| 131 | + | console.error("[dumber-palette] ERROR: Failed to apply received palette:", err); | |
| 132 | + | } | |
| 133 | + | }; | |
| 146 | 134 | ||
| 147 | - | window.__dumber_color_palettes_error = (error: string) => { | |
| 148 | - | console.error("[dumber-palette] ERROR from backend:", error); | |
| 149 | - | }; | |
| 135 | + | window.__dumber_color_palettes_error = (error: string) => { | |
| 136 | + | console.error("[dumber-palette] ERROR from backend:", error); | |
| 137 | + | }; | |
| 150 | 138 | ||
| 151 | - | // Request color palettes | |
| 152 | - | console.log("[dumber-palette] Sending get_color_palettes request to backend"); | |
| 153 | - | bridge.postMessage(JSON.stringify({ type: "get_color_palettes" })); | |
| 154 | - | console.log("[dumber-palette] Request sent, waiting for response..."); | |
| 155 | - | } catch (err) { | |
| 156 | - | console.error("[dumber-palette] EXCEPTION requesting color palettes:", err); | |
| 157 | - | } | |
| 139 | + | // Request color palettes from Go backend via isolated world bridge | |
| 140 | + | // Note: webkit.messageHandlers.dumber is only available in the isolated world, | |
| 141 | + | // not in the main world. The request will be sent from the isolated world (gui.ts). | |
| 142 | + | console.log("[dumber-palette] Color palette handlers registered, waiting for isolated world to request palettes"); | |
| 158 | 143 | ||
| 159 | 144 | // Palette application function | |
| 160 | 145 | window.__dumber_applyPalette = (theme: "light" | "dark") => { | |
| @@ -684,7 +669,7 @@ interface DumberAPI { | |||
| 684 | 669 | `[dumber-parent] Sending popup close request:`, | |
| 685 | 670 | closeMessage, | |
| 686 | 671 | ); | |
| 687 | - | bridge.postMessage(JSON.stringify(closeMessage)); | |
| 672 | + | bridge.postMessage(closeMessage); | |
| 688 | 673 | } catch (err) { | |
| 689 | 674 | console.warn( | |
| 690 | 675 | `[dumber-parent] Failed to send popup close request:`, | |
| @@ -821,7 +806,7 @@ interface DumberAPI { | |||
| 821 | 806 | `[oauth-callback] Sending popup close request:`, | |
| 822 | 807 | closeMessage, | |
| 823 | 808 | ); | |
| 824 | - | bridge.postMessage(JSON.stringify(closeMessage)); | |
| 809 | + | bridge.postMessage(closeMessage); | |
| 825 | 810 | } catch (err) { | |
| 826 | 811 | console.warn( | |
| 827 | 812 | `[oauth-callback] Failed to send popup close request:`, | |
| @@ -939,17 +924,15 @@ interface DumberAPI { | |||
| 939 | 924 | ||
| 940 | 925 | // Send to Go via existing message handler | |
| 941 | 926 | if (window.webkit?.messageHandlers?.dumber) { | |
| 942 | - | window.webkit.messageHandlers.dumber.postMessage( | |
| 943 | - | JSON.stringify({ | |
| 944 | - | type: "console-message", | |
| 945 | - | payload: { | |
| 946 | - | level, | |
| 947 | - | message: formattedMessage, | |
| 948 | - | url: window.location.href, | |
| 949 | - | webviewId: window.__dumber_webview_id, | |
| 950 | - | }, | |
| 951 | - | }), | |
| 952 | - | ); | |
| 927 | + | window.webkit.messageHandlers.dumber.postMessage({ | |
| 928 | + | type: "console-message", | |
| 929 | + | payload: { | |
| 930 | + | level, | |
| 931 | + | message: formattedMessage, | |
| 932 | + | url: window.location.href, | |
| 933 | + | webviewId: window.__dumber_webview_id, | |
| 934 | + | }, | |
| 935 | + | }); | |
| 953 | 936 | } | |
| 954 | 937 | } catch { | |
| 955 | 938 | // Silently ignore errors in console capture to avoid infinite loops | |
| @@ -989,7 +972,7 @@ interface DumberAPI { | |||
| 989 | 972 | try { | |
| 990 | 973 | const { payload } = event.detail; | |
| 991 | 974 | if (window.webkit?.messageHandlers?.dumber) { | |
| 992 | - | window.webkit.messageHandlers.dumber.postMessage(JSON.stringify(payload)); | |
| 975 | + | window.webkit.messageHandlers.dumber.postMessage(payload); | |
| 993 | 976 | console.log("[dumber-bridge] Forwarded isolated world message:", payload.type); | |
| 994 | 977 | } else { | |
| 995 | 978 | console.warn("[dumber-bridge] webkit message handler not available"); | |
| @@ -46,7 +46,7 @@ declare global { | |||||
| 46 | webkit?: { | 46 | webkit?: { | ||
| 47 | messageHandlers?: { | 47 | messageHandlers?: { | ||
| 48 | dumber?: { | 48 | dumber?: { | ||
| 49 | - | postMessage: (message: string) => void; | 49 | + | postMessage: (message: unknown) => void; |
| 50 | }; | 50 | }; | ||
| 51 | }; | 51 | }; | ||
| 52 | }; | 52 | }; | ||
| @@ -88,73 +88,58 @@ interface DumberAPI { | |||||
| 88 | window.__dumber_is_active = "__WEBVIEW_ACTIVE__" as unknown as boolean; | 88 | window.__dumber_is_active = "__WEBVIEW_ACTIVE__" as unknown as boolean; | ||
| 89 | } | 89 | } | ||
| 90 | 90 | ||||
| 91 | - | // Request color palettes from Go backend | 91 | + | // Set up color palette callback handlers (will be called from isolated world via CustomEvent) |
| 92 | - | try { | 92 | + | window.__dumber_color_palettes = (palettes: unknown) => { |
| 93 | - | console.log("[dumber-palette] Initializing color palette loading"); | 93 | + | console.log("[dumber-palette] Received palettes from backend:", palettes); |
| 94 | - | const bridge = window.webkit?.messageHandlers?.dumber; | 94 | + | try { |
| 95 | - | 95 | + | // Type guard to ensure palettes is a valid object | |
| 96 | - | if (!bridge || typeof bridge.postMessage !== "function") { | 96 | + | if (typeof palettes !== "object" || palettes === null) { |
| 97 | - | console.error("[dumber-palette] ERROR: No webkit message bridge available"); | 97 | + | console.error("[dumber-palette] ERROR: Invalid palettes received - type:", typeof palettes); |
| 98 | - | return; | 98 | + | return; |
| 99 | - | } | 99 | + | } |
| 100 | - | ||||
| 101 | - | console.log("[dumber-palette] WebKit bridge found, setting up handlers"); | |||
| 102 | - | ||||
| 103 | - | // Set up callback handler before requesting | |||
| 104 | - | window.__dumber_color_palettes = (palettes: unknown) => { | |||
| 105 | - | console.log("[dumber-palette] Received palettes from backend:", palettes); | |||
| 106 | - | try { | |||
| 107 | - | // Type guard to ensure palettes is a valid object | |||
| 108 | - | if (typeof palettes !== "object" || palettes === null) { | |||
| 109 | - | console.error("[dumber-palette] ERROR: Invalid palettes received - type:", typeof palettes); | |||
| 110 | - | return; | |||
| 111 | - | } | |||
| 112 | 100 | ||||
| 113 | - | window.__dumber_palette = palettes as Record<string, Record<string, string>>; | 101 | + | window.__dumber_palette = palettes as Record<string, Record<string, string>>; |
| 114 | - | console.log("[dumber-palette] Palette keys:", Object.keys(window.__dumber_palette || {})); | 102 | + | console.log("[dumber-palette] Palette keys:", Object.keys(window.__dumber_palette || {})); |
| 115 | - | 103 | + | ||
| 116 | - | // Normalize palette keys to lowercase | 104 | + | // Normalize palette keys to lowercase |
| 117 | - | const normalized: Record<string, Record<string, string>> = {}; | 105 | + | const normalized: Record<string, Record<string, string>> = {}; |
| 118 | - | if (window.__dumber_palette) { | 106 | + | if (window.__dumber_palette) { |
| 119 | - | for (const key in window.__dumber_palette) { | 107 | + | for (const key in window.__dumber_palette) { |
| 120 | - | if (Object.prototype.hasOwnProperty.call(window.__dumber_palette, key)) { | 108 | + | if (Object.prototype.hasOwnProperty.call(window.__dumber_palette, key)) { |
| 121 | - | const paletteValue = window.__dumber_palette[key]; | 109 | + | const paletteValue = window.__dumber_palette[key]; |
| 122 | - | if (paletteValue) { | 110 | + | if (paletteValue) { |
| 123 | - | normalized[key.toLowerCase()] = paletteValue; | 111 | + | normalized[key.toLowerCase()] = paletteValue; |
| 124 | - | console.log(`[dumber-palette] Normalized: ${key} -> ${key.toLowerCase()}, colors:`, Object.keys(paletteValue)); | 112 | + | console.log(`[dumber-palette] Normalized: ${key} -> ${key.toLowerCase()}, colors:`, Object.keys(paletteValue)); |
| 125 | - | } | |||
| 126 | } | 113 | } | ||
| 127 | } | 114 | } | ||
| 128 | - | window.__dumber_palette = normalized; | |||
| 129 | } | 115 | } | ||
| 116 | + | window.__dumber_palette = normalized; | |||
| 117 | + | } | |||
| 130 | 118 | ||||
| 131 | - | // Apply palette now that we have it | 119 | + | // Apply palette now that we have it |
| 132 | - | const initialTheme: "light" | "dark" = document.documentElement.classList.contains("dark") ? "dark" : "light"; | 120 | + | const initialTheme: "light" | "dark" = document.documentElement.classList.contains("dark") ? "dark" : "light"; |
| 133 | - | console.log(`[dumber-palette] Initial theme detected: ${initialTheme}`); | 121 | + | console.log(`[dumber-palette] Initial theme detected: ${initialTheme}`); |
| 134 | - | window.__dumber_initial_theme = initialTheme; | 122 | + | window.__dumber_initial_theme = initialTheme; |
| 135 | 123 | ||||
| 136 | - | if (window.__dumber_applyPalette) { | 124 | + | if (window.__dumber_applyPalette) { |
| 137 | - | console.log("[dumber-palette] Applying palette..."); | 125 | + | console.log("[dumber-palette] Applying palette..."); |
| 138 | - | window.__dumber_applyPalette(initialTheme); | 126 | + | window.__dumber_applyPalette(initialTheme); |
| 139 | - | } else { | 127 | + | } else { |
| 140 | - | console.error("[dumber-palette] ERROR: __dumber_applyPalette function not found"); | 128 | + | console.error("[dumber-palette] ERROR: __dumber_applyPalette function not found"); |
| 141 | - | } | |||
| 142 | - | } catch (err) { | |||
| 143 | - | console.error("[dumber-palette] ERROR: Failed to apply received palette:", err); | |||
| 144 | } | 129 | } | ||
| 145 | - | }; | 130 | + | } catch (err) { |
| 131 | + | console.error("[dumber-palette] ERROR: Failed to apply received palette:", err); | |||
| 132 | + | } | |||
| 133 | + | }; | |||
| 146 | 134 | ||||
| 147 | - | window.__dumber_color_palettes_error = (error: string) => { | 135 | + | window.__dumber_color_palettes_error = (error: string) => { |
| 148 | - | console.error("[dumber-palette] ERROR from backend:", error); | 136 | + | console.error("[dumber-palette] ERROR from backend:", error); |
| 149 | - | }; | 137 | + | }; |
| 150 | 138 | ||||
| 151 | - | // Request color palettes | 139 | + | // Request color palettes from Go backend via isolated world bridge |
| 152 | - | console.log("[dumber-palette] Sending get_color_palettes request to backend"); | 140 | + | // Note: webkit.messageHandlers.dumber is only available in the isolated world, |
| 153 | - | bridge.postMessage(JSON.stringify({ type: "get_color_palettes" })); | 141 | + | // not in the main world. The request will be sent from the isolated world (gui.ts). |
| 154 | - | console.log("[dumber-palette] Request sent, waiting for response..."); | 142 | + | console.log("[dumber-palette] Color palette handlers registered, waiting for isolated world to request palettes"); |
| 155 | - | } catch (err) { | |||
| 156 | - | console.error("[dumber-palette] EXCEPTION requesting color palettes:", err); | |||
| 157 | - | } | |||
| 158 | 143 | ||||
| 159 | // Palette application function | 144 | // Palette application function | ||
| 160 | window.__dumber_applyPalette = (theme: "light" | "dark") => { | 145 | window.__dumber_applyPalette = (theme: "light" | "dark") => { | ||
| @@ -684,7 +669,7 @@ interface DumberAPI { | |||||
| 684 | `[dumber-parent] Sending popup close request:`, | 669 | `[dumber-parent] Sending popup close request:`, | ||
| 685 | closeMessage, | 670 | closeMessage, | ||
| 686 | ); | 671 | ); | ||
| 687 | - | bridge.postMessage(JSON.stringify(closeMessage)); | 672 | + | bridge.postMessage(closeMessage); |
| 688 | } catch (err) { | 673 | } catch (err) { | ||
| 689 | console.warn( | 674 | console.warn( | ||
| 690 | `[dumber-parent] Failed to send popup close request:`, | 675 | `[dumber-parent] Failed to send popup close request:`, | ||
| @@ -821,7 +806,7 @@ interface DumberAPI { | |||||
| 821 | `[oauth-callback] Sending popup close request:`, | 806 | `[oauth-callback] Sending popup close request:`, | ||
| 822 | closeMessage, | 807 | closeMessage, | ||
| 823 | ); | 808 | ); | ||
| 824 | - | bridge.postMessage(JSON.stringify(closeMessage)); | 809 | + | bridge.postMessage(closeMessage); |
| 825 | } catch (err) { | 810 | } catch (err) { | ||
| 826 | console.warn( | 811 | console.warn( | ||
| 827 | `[oauth-callback] Failed to send popup close request:`, | 812 | `[oauth-callback] Failed to send popup close request:`, | ||
| @@ -939,17 +924,15 @@ interface DumberAPI { | |||||
| 939 | 924 | ||||
| 940 | // Send to Go via existing message handler | 925 | // Send to Go via existing message handler | ||
| 941 | if (window.webkit?.messageHandlers?.dumber) { | 926 | if (window.webkit?.messageHandlers?.dumber) { | ||
| 942 | - | window.webkit.messageHandlers.dumber.postMessage( | 927 | + | window.webkit.messageHandlers.dumber.postMessage({ |
| 943 | - | JSON.stringify({ | 928 | + | type: "console-message", |
| 944 | - | type: "console-message", | 929 | + | payload: { |
| 945 | - | payload: { | 930 | + | level, |
| 946 | - | level, | 931 | + | message: formattedMessage, |
| 947 | - | message: formattedMessage, | 932 | + | url: window.location.href, |
| 948 | - | url: window.location.href, | 933 | + | webviewId: window.__dumber_webview_id, |
| 949 | - | webviewId: window.__dumber_webview_id, | 934 | + | }, |
| 950 | - | }, | 935 | + | }); |
| 951 | - | }), | |||
| 952 | - | ); | |||
| 953 | } | 936 | } | ||
| 954 | } catch { | 937 | } catch { | ||
| 955 | // Silently ignore errors in console capture to avoid infinite loops | 938 | // Silently ignore errors in console capture to avoid infinite loops | ||
| @@ -989,7 +972,7 @@ interface DumberAPI { | |||||
| 989 | try { | 972 | try { | ||
| 990 | const { payload } = event.detail; | 973 | const { payload } = event.detail; | ||
| 991 | if (window.webkit?.messageHandlers?.dumber) { | 974 | if (window.webkit?.messageHandlers?.dumber) { | ||
| 992 | - | window.webkit.messageHandlers.dumber.postMessage(JSON.stringify(payload)); | 975 | + | window.webkit.messageHandlers.dumber.postMessage(payload); |
| 993 | console.log("[dumber-bridge] Forwarded isolated world message:", payload.type); | 976 | console.log("[dumber-bridge] Forwarded isolated world message:", payload.type); | ||
| 994 | } else { | 977 | } else { | ||
| 995 | console.warn("[dumber-bridge] webkit message handler not available"); | 978 | console.warn("[dumber-bridge] webkit message handler not available"); | ||
R gui/src/injected/modules/color-scheme.ts → webui/src/injected/modules/color-scheme.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/injected/modules/omnibox.ts → webui/src/injected/modules/omnibox.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/injected/modules/shadowHost.ts → webui/src/injected/modules/shadowHost.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/injected/modules/toast.ts → webui/src/injected/modules/toast.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/injected/modules/workspace.ts → webui/src/injected/modules/workspace.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/injected/styles-entry.css → webui/src/injected/styles-entry.css +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/lib/keyboard/KeyboardService.ts → webui/src/lib/keyboard/KeyboardService.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/lib/keyboard/index.ts → webui/src/lib/keyboard/index.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/lib/keyboard/types.ts → webui/src/lib/keyboard/types.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/lib/styles.css → webui/src/lib/styles.css +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/lib/types.ts → webui/src/lib/types.ts +1 -1 renamed, 97% similar
| @@ -36,7 +36,7 @@ declare global { | |||
| 36 | 36 | webkit?: { | |
| 37 | 37 | messageHandlers?: { | |
| 38 | 38 | dumber?: { | |
| 39 | - | postMessage: (message: string) => void; | |
| 39 | + | postMessage: (message: unknown) => void; | |
| 40 | 40 | }; | |
| 41 | 41 | }; | |
| 42 | 42 | }; | |
| @@ -36,7 +36,7 @@ declare global { | |||||
| 36 | webkit?: { | 36 | webkit?: { | ||
| 37 | messageHandlers?: { | 37 | messageHandlers?: { | ||
| 38 | dumber?: { | 38 | dumber?: { | ||
| 39 | - | postMessage: (message: string) => void; | 39 | + | postMessage: (message: unknown) => void; |
| 40 | }; | 40 | }; | ||
| 41 | }; | 41 | }; | ||
| 42 | }; | 42 | }; | ||
R gui/src/pages/BlockedPage.svelte → webui/src/pages/BlockedPage.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/Homepage.svelte → webui/src/pages/Homepage.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/blocked.ts → webui/src/pages/blocked.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage.ts → webui/src/pages/homepage.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/analytics/DailyVisitsChart.svelte → webui/src/pages/homepage/analytics/DailyVisitsChart.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/analytics/HourlyActivityChart.svelte → webui/src/pages/homepage/analytics/HourlyActivityChart.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/analytics/index.ts → webui/src/pages/homepage/analytics/index.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/favorites/FavoriteCard.svelte → webui/src/pages/homepage/favorites/FavoriteCard.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/favorites/FavoriteEditor.svelte → webui/src/pages/homepage/favorites/FavoriteEditor.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/favorites/FavoriteGrid.svelte → webui/src/pages/homepage/favorites/FavoriteGrid.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/favorites/FolderList.svelte → webui/src/pages/homepage/favorites/FolderList.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/favorites/TagCloud.svelte → webui/src/pages/homepage/favorites/TagCloud.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/favorites/index.ts → webui/src/pages/homepage/favorites/index.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/history/HistoryCleanup.svelte → webui/src/pages/homepage/history/HistoryCleanup.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/history/HistoryFilters.svelte → webui/src/pages/homepage/history/HistoryFilters.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/history/HistoryItem.svelte → webui/src/pages/homepage/history/HistoryItem.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/history/HistorySearch.svelte → webui/src/pages/homepage/history/HistorySearch.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/history/HistoryTimeline.svelte → webui/src/pages/homepage/history/HistoryTimeline.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/history/index.ts → webui/src/pages/homepage/history/index.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/keyboard.ts → webui/src/pages/homepage/keyboard.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/messaging.ts → webui/src/pages/homepage/messaging.ts +3 -3 renamed, 99% similar
| @@ -38,7 +38,7 @@ let callbacksInitialized = false; | |||
| 38 | 38 | // WEBKIT BRIDGE UTILITIES | |
| 39 | 39 | // ═══════════════════════════════════════════════════════════════════════════════ | |
| 40 | 40 | ||
| 41 | - | function getWebKitBridge(): { postMessage: (msg: string) => void } | null { | |
| 41 | + | function getWebKitBridge(): { postMessage: (msg: unknown) => void } | null { | |
| 42 | 42 | const bridge = (window as any).webkit?.messageHandlers?.dumber; | |
| 43 | 43 | if (bridge && typeof bridge.postMessage === 'function') { | |
| 44 | 44 | return bridge; | |
| @@ -167,11 +167,11 @@ async function sendMessage<T = unknown>( | |||
| 167 | 167 | pendingRequests.set(requestId, { resolve: resolve as any, reject, timeout }); | |
| 168 | 168 | ||
| 169 | 169 | try { | |
| 170 | - | bridge.postMessage(JSON.stringify({ | |
| 170 | + | bridge.postMessage({ | |
| 171 | 171 | type, | |
| 172 | 172 | requestId, | |
| 173 | 173 | ...payload, | |
| 174 | - | })); | |
| 174 | + | }); | |
| 175 | 175 | } catch (error) { | |
| 176 | 176 | clearTimeout(timeout); | |
| 177 | 177 | pendingRequests.delete(requestId); | |
| @@ -38,7 +38,7 @@ let callbacksInitialized = false; | |||||
| 38 | // WEBKIT BRIDGE UTILITIES | 38 | // WEBKIT BRIDGE UTILITIES | ||
| 39 | // ═══════════════════════════════════════════════════════════════════════════════ | 39 | // ═══════════════════════════════════════════════════════════════════════════════ | ||
| 40 | 40 | ||||
| 41 | - | function getWebKitBridge(): { postMessage: (msg: string) => void } | null { | 41 | + | function getWebKitBridge(): { postMessage: (msg: unknown) => void } | null { |
| 42 | const bridge = (window as any).webkit?.messageHandlers?.dumber; | 42 | const bridge = (window as any).webkit?.messageHandlers?.dumber; | ||
| 43 | if (bridge && typeof bridge.postMessage === 'function') { | 43 | if (bridge && typeof bridge.postMessage === 'function') { | ||
| 44 | return bridge; | 44 | return bridge; | ||
| @@ -167,11 +167,11 @@ async function sendMessage<T = unknown>( | |||||
| 167 | pendingRequests.set(requestId, { resolve: resolve as any, reject, timeout }); | 167 | pendingRequests.set(requestId, { resolve: resolve as any, reject, timeout }); | ||
| 168 | 168 | ||||
| 169 | try { | 169 | try { | ||
| 170 | - | bridge.postMessage(JSON.stringify({ | 170 | + | bridge.postMessage({ |
| 171 | type, | 171 | type, | ||
| 172 | requestId, | 172 | requestId, | ||
| 173 | ...payload, | 173 | ...payload, | ||
| 174 | - | })); | 174 | + | }); |
| 175 | } catch (error) { | 175 | } catch (error) { | ||
| 176 | clearTimeout(timeout); | 176 | clearTimeout(timeout); | ||
| 177 | pendingRequests.delete(requestId); | 177 | pendingRequests.delete(requestId); | ||
R gui/src/pages/homepage/panels/AnalyticsPanel.svelte → webui/src/pages/homepage/panels/AnalyticsPanel.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/panels/FavoritesPanel.svelte → webui/src/pages/homepage/panels/FavoritesPanel.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/panels/HistoryPanel.svelte → webui/src/pages/homepage/panels/HistoryPanel.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/panels/index.ts → webui/src/pages/homepage/panels/index.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/shell/CommandPalette.svelte → webui/src/pages/homepage/shell/CommandPalette.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/shell/HomepageShell.svelte → webui/src/pages/homepage/shell/HomepageShell.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/shell/KeyboardHints.svelte → webui/src/pages/homepage/shell/KeyboardHints.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/shell/StatusBar.svelte → webui/src/pages/homepage/shell/StatusBar.svelte +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/shell/index.ts → webui/src/pages/homepage/shell/index.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/state.svelte.ts → webui/src/pages/homepage/state.svelte.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/pages/homepage/types.ts → webui/src/pages/homepage/types.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/services/app.ts → webui/src/services/app.ts +4 -5 renamed, 96% similar
| @@ -112,11 +112,10 @@ export class AppService { | |||
| 112 | 112 | // Send message to Go backend | |
| 113 | 113 | const bridge = window.webkit?.messageHandlers?.dumber; | |
| 114 | 114 | if (bridge && typeof bridge.postMessage === "function") { | |
| 115 | - | bridge.postMessage( | |
| 116 | - | JSON.stringify({ | |
| 117 | - | type: "get_search_shortcuts", | |
| 118 | - | }), | |
| 119 | - | ); | |
| 115 | + | bridge.postMessage({ | |
| 116 | + | type: "get_search_shortcuts", | |
| 117 | + | webview_id: (window as any).__dumber_webview_id ?? 0, | |
| 118 | + | }); | |
| 120 | 119 | } else { | |
| 121 | 120 | reject(new Error("WebKit message handler not available")); | |
| 122 | 121 | } | |
| @@ -112,11 +112,10 @@ export class AppService { | |||||
| 112 | // Send message to Go backend | 112 | // Send message to Go backend | ||
| 113 | const bridge = window.webkit?.messageHandlers?.dumber; | 113 | const bridge = window.webkit?.messageHandlers?.dumber; | ||
| 114 | if (bridge && typeof bridge.postMessage === "function") { | 114 | if (bridge && typeof bridge.postMessage === "function") { | ||
| 115 | - | bridge.postMessage( | 115 | + | bridge.postMessage({ |
| 116 | - | JSON.stringify({ | 116 | + | type: "get_search_shortcuts", |
| 117 | - | type: "get_search_shortcuts", | 117 | + | webview_id: (window as any).__dumber_webview_id ?? 0, |
| 118 | - | }), | 118 | + | }); |
| 119 | - | ); | |||
| 120 | } else { | 119 | } else { | ||
| 121 | reject(new Error("WebKit message handler not available")); | 120 | reject(new Error("WebKit message handler not available")); | ||
| 122 | } | 121 | } | ||
R gui/src/services/browser-controls.ts → webui/src/services/browser-controls.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/services/debug-console.ts → webui/src/services/debug-console.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/services/notifications.ts → webui/src/services/notifications.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/styles/design-tokens.css → webui/src/styles/design-tokens.css +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/styles/tailwind.css → webui/src/styles/tailwind.css +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/types/app.ts → webui/src/types/app.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/types/frappe-charts.d.ts → webui/src/types/frappe-charts.d.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/types/generated.ts → webui/src/types/generated.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/types/inline-css.d.ts → webui/src/types/inline-css.d.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/types/raw-css.d.ts → webui/src/types/raw-css.d.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/src/utils/dom.ts → webui/src/utils/dom.ts +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/svelte.config.js → webui/svelte.config.js +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/tailwind.config.js → webui/tailwind.config.js +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/tsconfig.json → webui/tsconfig.json +0 -0 renamed, 100% similar
renamed, 100% similar
R gui/vite-plugin-pages.ts → webui/vite-plugin-pages.ts +2 -2 renamed, 95% similar
| @@ -50,7 +50,7 @@ export function pageGenerator(pages: PageConfig[]): Plugin { | |||
| 50 | 50 | return { | |
| 51 | 51 | name: "dumb-page-generator", | |
| 52 | 52 | writeBundle() { | |
| 53 | - | const assetsDir = resolve(__dirname, "..", "assets", "gui"); | |
| 53 | + | const assetsDir = resolve(__dirname, "..", "assets", "webui"); | |
| 54 | 54 | ||
| 55 | 55 | try { | |
| 56 | 56 | // Generate HTML files for each page | |
| @@ -67,7 +67,7 @@ export function pageGenerator(pages: PageConfig[]): Plugin { | |||
| 67 | 67 | console.log("✓ Generated favicon.svg"); | |
| 68 | 68 | ||
| 69 | 69 | // Copy pre-generated PNG and ICO favicons if they exist | |
| 70 | - | const sourceDir = resolve(__dirname, "..", "assets", "gui"); | |
| 70 | + | const sourceDir = resolve(__dirname, "..", "assets", "webui"); | |
| 71 | 71 | try { | |
| 72 | 72 | const pngPath = resolve(sourceDir, "favicon.png"); | |
| 73 | 73 | const icoPath = resolve(sourceDir, "favicon.ico"); | |
| @@ -50,7 +50,7 @@ export function pageGenerator(pages: PageConfig[]): Plugin { | |||||
| 50 | return { | 50 | return { | ||
| 51 | name: "dumb-page-generator", | 51 | name: "dumb-page-generator", | ||
| 52 | writeBundle() { | 52 | writeBundle() { | ||
| 53 | - | const assetsDir = resolve(__dirname, "..", "assets", "gui"); | 53 | + | const assetsDir = resolve(__dirname, "..", "assets", "webui"); |
| 54 | 54 | ||||
| 55 | try { | 55 | try { | ||
| 56 | // Generate HTML files for each page | 56 | // Generate HTML files for each page | ||
| @@ -67,7 +67,7 @@ export function pageGenerator(pages: PageConfig[]): Plugin { | |||||
| 67 | console.log("✓ Generated favicon.svg"); | 67 | console.log("✓ Generated favicon.svg"); | ||
| 68 | 68 | ||||
| 69 | // Copy pre-generated PNG and ICO favicons if they exist | 69 | // Copy pre-generated PNG and ICO favicons if they exist | ||
| 70 | - | const sourceDir = resolve(__dirname, "..", "assets", "gui"); | 70 | + | const sourceDir = resolve(__dirname, "..", "assets", "webui"); |
| 71 | try { | 71 | try { | ||
| 72 | const pngPath = resolve(sourceDir, "favicon.png"); | 72 | const pngPath = resolve(sourceDir, "favicon.png"); | ||
| 73 | const icoPath = resolve(sourceDir, "favicon.ico"); | 73 | const icoPath = resolve(sourceDir, "favicon.ico"); | ||
R gui/vite.config.blocked.ts → webui/vite.config.blocked.ts +1 -1 renamed, 97% similar
| @@ -21,7 +21,7 @@ export default defineConfig({ | |||
| 21 | 21 | rollupOptions: { | |
| 22 | 22 | input: resolve(__dirname, "src/pages/blocked.ts"), | |
| 23 | 23 | output: { | |
| 24 | - | dir: "../assets/gui", | |
| 24 | + | dir: "../assets/webui", | |
| 25 | 25 | entryFileNames: "blocked.min.js", | |
| 26 | 26 | chunkFileNames: "[name].js", | |
| 27 | 27 | assetFileNames: "[name].[ext]", | |
| @@ -21,7 +21,7 @@ export default defineConfig({ | |||||
| 21 | rollupOptions: { | 21 | rollupOptions: { | ||
| 22 | input: resolve(__dirname, "src/pages/blocked.ts"), | 22 | input: resolve(__dirname, "src/pages/blocked.ts"), | ||
| 23 | output: { | 23 | output: { | ||
| 24 | - | dir: "../assets/gui", | 24 | + | dir: "../assets/webui", |
| 25 | entryFileNames: "blocked.min.js", | 25 | entryFileNames: "blocked.min.js", | ||
| 26 | chunkFileNames: "[name].js", | 26 | chunkFileNames: "[name].js", | ||
| 27 | assetFileNames: "[name].[ext]", | 27 | assetFileNames: "[name].[ext]", | ||
R gui/vite.config.color-scheme.ts → webui/vite.config.color-scheme.ts +1 -1 renamed, 95% similar
| @@ -6,7 +6,7 @@ export default defineConfig({ | |||
| 6 | 6 | rollupOptions: { | |
| 7 | 7 | input: resolve(__dirname, "src/injected/modules/color-scheme.ts"), | |
| 8 | 8 | output: { | |
| 9 | - | dir: "../assets/gui", | |
| 9 | + | dir: "../assets/webui", | |
| 10 | 10 | format: "iife", | |
| 11 | 11 | entryFileNames: "color-scheme.js", | |
| 12 | 12 | inlineDynamicImports: true, | |
| @@ -6,7 +6,7 @@ export default defineConfig({ | |||||
| 6 | rollupOptions: { | 6 | rollupOptions: { | ||
| 7 | input: resolve(__dirname, "src/injected/modules/color-scheme.ts"), | 7 | input: resolve(__dirname, "src/injected/modules/color-scheme.ts"), | ||
| 8 | output: { | 8 | output: { | ||
| 9 | - | dir: "../assets/gui", | 9 | + | dir: "../assets/webui", |
| 10 | format: "iife", | 10 | format: "iife", | ||
| 11 | entryFileNames: "color-scheme.js", | 11 | entryFileNames: "color-scheme.js", | ||
| 12 | inlineDynamicImports: true, | 12 | inlineDynamicImports: true, | ||
R gui/vite.config.gui.ts → webui/vite.config.gui.ts +1 -1 renamed, 97% similar
| @@ -12,7 +12,7 @@ export default defineConfig({ | |||
| 12 | 12 | rollupOptions: { | |
| 13 | 13 | input: resolve(__dirname, "src/injected/gui.ts"), | |
| 14 | 14 | output: { | |
| 15 | - | dir: "../assets/gui", | |
| 15 | + | dir: "../assets/webui", | |
| 16 | 16 | format: "iife", | |
| 17 | 17 | entryFileNames: "gui.min.js", | |
| 18 | 18 | name: "__dumberGUI", | |
| @@ -12,7 +12,7 @@ export default defineConfig({ | |||||
| 12 | rollupOptions: { | 12 | rollupOptions: { | ||
| 13 | input: resolve(__dirname, "src/injected/gui.ts"), | 13 | input: resolve(__dirname, "src/injected/gui.ts"), | ||
| 14 | output: { | 14 | output: { | ||
| 15 | - | dir: "../assets/gui", | 15 | + | dir: "../assets/webui", |
| 16 | format: "iife", | 16 | format: "iife", | ||
| 17 | entryFileNames: "gui.min.js", | 17 | entryFileNames: "gui.min.js", | ||
| 18 | name: "__dumberGUI", | 18 | name: "__dumberGUI", | ||
R gui/vite.config.homepage.ts → webui/vite.config.homepage.ts +1 -1 renamed, 97% similar
| @@ -21,7 +21,7 @@ export default defineConfig({ | |||
| 21 | 21 | rollupOptions: { | |
| 22 | 22 | input: resolve(__dirname, "src/pages/homepage.ts"), | |
| 23 | 23 | output: { | |
| 24 | - | dir: "../assets/gui", | |
| 24 | + | dir: "../assets/webui", | |
| 25 | 25 | entryFileNames: "homepage.min.js", | |
| 26 | 26 | chunkFileNames: "[name].js", | |
| 27 | 27 | assetFileNames: "[name].[ext]", | |
| @@ -21,7 +21,7 @@ export default defineConfig({ | |||||
| 21 | rollupOptions: { | 21 | rollupOptions: { | ||
| 22 | input: resolve(__dirname, "src/pages/homepage.ts"), | 22 | input: resolve(__dirname, "src/pages/homepage.ts"), | ||
| 23 | output: { | 23 | output: { | ||
| 24 | - | dir: "../assets/gui", | 24 | + | dir: "../assets/webui", |
| 25 | entryFileNames: "homepage.min.js", | 25 | entryFileNames: "homepage.min.js", | ||
| 26 | chunkFileNames: "[name].js", | 26 | chunkFileNames: "[name].js", | ||
| 27 | assetFileNames: "[name].[ext]", | 27 | assetFileNames: "[name].[ext]", | ||
R gui/vite.config.main-world.ts → webui/vite.config.main-world.ts +1 -1 renamed, 95% similar
| @@ -6,7 +6,7 @@ export default defineConfig({ | |||
| 6 | 6 | rollupOptions: { | |
| 7 | 7 | input: resolve(__dirname, "src/injected/main-world.ts"), | |
| 8 | 8 | output: { | |
| 9 | - | dir: "../assets/gui", | |
| 9 | + | dir: "../assets/webui", | |
| 10 | 10 | format: "iife", | |
| 11 | 11 | entryFileNames: "main-world.min.js", | |
| 12 | 12 | name: "__dumberMainWorld", | |
| @@ -6,7 +6,7 @@ export default defineConfig({ | |||||
| 6 | rollupOptions: { | 6 | rollupOptions: { | ||
| 7 | input: resolve(__dirname, "src/injected/main-world.ts"), | 7 | input: resolve(__dirname, "src/injected/main-world.ts"), | ||
| 8 | output: { | 8 | output: { | ||
| 9 | - | dir: "../assets/gui", | 9 | + | dir: "../assets/webui", |
| 10 | format: "iife", | 10 | format: "iife", | ||
| 11 | entryFileNames: "main-world.min.js", | 11 | entryFileNames: "main-world.min.js", | ||
| 12 | name: "__dumberMainWorld", | 12 | name: "__dumberMainWorld", | ||