fix(config): use messaging bridge for config and fix palette key mapping
- Replace fetch /api/config with webkit messageHandlers bridge to avoid CORS - Add get_search_shortcuts and get_color_palettes message handlers - Fix palette token key mapping (background vs Background, surface_variant vs SurfaceVariant) - Add detailed logging for palette loading and application - Use proper TypeScript types (unknown instead of any) - Search shortcuts now work via messaging bridge in both app.ts and omnibox
- commit
- 65e3547fcb408b5ac1bb4f3185c402a9782323bf
- author
- bamen · · 2025-10-06 18:52 UTC
- committer
- bamen · · 2025-10-06 16:58 UTC
- parent
- 2cbda56
- signature
- unsigned
2 files · +129 -68
M gui/src/components/omnibox/messaging.ts +46 -16
| @@ -74,25 +74,55 @@ export class OmniboxBridge implements OmniboxMessageBridge { | |||
| 74 | 74 | } | |
| 75 | 75 | ||
| 76 | 76 | /** | |
| 77 | - | * Fetch search shortcuts from backend config | |
| 77 | + | * Fetch search shortcuts from backend via messaging bridge | |
| 78 | 78 | */ | |
| 79 | 79 | async fetchSearchShortcuts(): Promise<void> { | |
| 80 | - | try { | |
| 81 | - | const cfg = await fetch("/api/config").then((r) => r.json()); | |
| 82 | - | const raw = cfg?.search_shortcuts || {}; | |
| 83 | - | // Normalize to match our SearchShortcut type | |
| 84 | - | const normalized: Record<string, SearchShortcut> = {}; | |
| 85 | - | for (const [key, value] of Object.entries(raw)) { | |
| 86 | - | const v = value as Record<string, unknown>; | |
| 87 | - | normalized[key] = { | |
| 88 | - | url: (v.url ?? v.URL ?? "") as string, | |
| 89 | - | description: (v.description ?? v.Description ?? "") as string, | |
| 90 | - | }; | |
| 80 | + | return new Promise((resolve, reject) => { | |
| 81 | + | // Set up one-time response handler | |
| 82 | + | const originalCallback = (window as any).__dumber_search_shortcuts; | |
| 83 | + | (window as any).__dumber_search_shortcuts = (data: unknown) => { | |
| 84 | + | try { | |
| 85 | + | // Type guard | |
| 86 | + | if (typeof data !== "object" || data === null) { | |
| 87 | + | reject(new Error("Invalid shortcuts data")); | |
| 88 | + | return; | |
| 89 | + | } | |
| 90 | + | const dataObj = data as Record<string, unknown>; | |
| 91 | + | // Normalize to match our SearchShortcut type | |
| 92 | + | const normalized: Record<string, SearchShortcut> = {}; | |
| 93 | + | for (const [key, value] of Object.entries(dataObj)) { | |
| 94 | + | const v = value as Record<string, unknown>; | |
| 95 | + | normalized[key] = { | |
| 96 | + | url: (v.url ?? v.URL ?? "") as string, | |
| 97 | + | description: (v.description ?? v.Description ?? "") as string, | |
| 98 | + | }; | |
| 99 | + | } | |
| 100 | + | this.setSearchShortcuts(normalized); | |
| 101 | + | ||
| 102 | + | // Restore original callback if it existed | |
| 103 | + | if (originalCallback) { | |
| 104 | + | (window as any).__dumber_search_shortcuts = originalCallback; | |
| 105 | + | } | |
| 106 | + | ||
| 107 | + | resolve(); | |
| 108 | + | } catch (error) { | |
| 109 | + | console.error("Failed to process search shortcuts:", error); | |
| 110 | + | reject(error); | |
| 111 | + | } | |
| 112 | + | }; | |
| 113 | + | ||
| 114 | + | // Send message to Go backend | |
| 115 | + | const bridge = window.webkit?.messageHandlers?.dumber; | |
| 116 | + | if (bridge && typeof bridge.postMessage === "function") { | |
| 117 | + | bridge.postMessage( | |
| 118 | + | JSON.stringify({ | |
| 119 | + | type: "get_search_shortcuts", | |
| 120 | + | }), | |
| 121 | + | ); | |
| 122 | + | } else { | |
| 123 | + | reject(new Error("WebKit message handler not available")); | |
| 91 | 124 | } | |
| 92 | - | this.setSearchShortcuts(normalized); | |
| 93 | - | } catch (error) { | |
| 94 | - | console.error("Failed to fetch search shortcuts:", error); | |
| 95 | - | } | |
| 125 | + | }); | |
| 96 | 126 | } | |
| 97 | 127 | ||
| 98 | 128 | // Suggestions are returned via setSuggestions() when native handler responds | |
| @@ -74,25 +74,55 @@ export class OmniboxBridge implements OmniboxMessageBridge { | |||||
| 74 | } | 74 | } | ||
| 75 | 75 | ||||
| 76 | /** | 76 | /** | ||
| 77 | - | * Fetch search shortcuts from backend config | 77 | + | * Fetch search shortcuts from backend via messaging bridge |
| 78 | */ | 78 | */ | ||
| 79 | async fetchSearchShortcuts(): Promise<void> { | 79 | async fetchSearchShortcuts(): Promise<void> { | ||
| 80 | - | try { | 80 | + | return new Promise((resolve, reject) => { |
| 81 | - | const cfg = await fetch("/api/config").then((r) => r.json()); | 81 | + | // Set up one-time response handler |
| 82 | - | const raw = cfg?.search_shortcuts || {}; | 82 | + | const originalCallback = (window as any).__dumber_search_shortcuts; |
| 83 | - | // Normalize to match our SearchShortcut type | 83 | + | (window as any).__dumber_search_shortcuts = (data: unknown) => { |
| 84 | - | const normalized: Record<string, SearchShortcut> = {}; | 84 | + | try { |
| 85 | - | for (const [key, value] of Object.entries(raw)) { | 85 | + | // Type guard |
| 86 | - | const v = value as Record<string, unknown>; | 86 | + | if (typeof data !== "object" || data === null) { |
| 87 | - | normalized[key] = { | 87 | + | reject(new Error("Invalid shortcuts data")); |
| 88 | - | url: (v.url ?? v.URL ?? "") as string, | 88 | + | return; |
| 89 | - | description: (v.description ?? v.Description ?? "") as string, | 89 | + | } |
| 90 | - | }; | 90 | + | const dataObj = data as Record<string, unknown>; |
| 91 | + | // Normalize to match our SearchShortcut type | |||
| 92 | + | const normalized: Record<string, SearchShortcut> = {}; | |||
| 93 | + | for (const [key, value] of Object.entries(dataObj)) { | |||
| 94 | + | const v = value as Record<string, unknown>; | |||
| 95 | + | normalized[key] = { | |||
| 96 | + | url: (v.url ?? v.URL ?? "") as string, | |||
| 97 | + | description: (v.description ?? v.Description ?? "") as string, | |||
| 98 | + | }; | |||
| 99 | + | } | |||
| 100 | + | this.setSearchShortcuts(normalized); | |||
| 101 | + | ||||
| 102 | + | // Restore original callback if it existed | |||
| 103 | + | if (originalCallback) { | |||
| 104 | + | (window as any).__dumber_search_shortcuts = originalCallback; | |||
| 105 | + | } | |||
| 106 | + | ||||
| 107 | + | resolve(); | |||
| 108 | + | } catch (error) { | |||
| 109 | + | console.error("Failed to process search shortcuts:", error); | |||
| 110 | + | reject(error); | |||
| 111 | + | } | |||
| 112 | + | }; | |||
| 113 | + | ||||
| 114 | + | // Send message to Go backend | |||
| 115 | + | const bridge = window.webkit?.messageHandlers?.dumber; | |||
| 116 | + | if (bridge && typeof bridge.postMessage === "function") { | |||
| 117 | + | bridge.postMessage( | |||
| 118 | + | JSON.stringify({ | |||
| 119 | + | type: "get_search_shortcuts", | |||
| 120 | + | }), | |||
| 121 | + | ); | |||
| 122 | + | } else { | |||
| 123 | + | reject(new Error("WebKit message handler not available")); | |||
| 91 | } | 124 | } | ||
| 92 | - | this.setSearchShortcuts(normalized); | 125 | + | }); |
| 93 | - | } catch (error) { | |||
| 94 | - | console.error("Failed to fetch search shortcuts:", error); | |||
| 95 | - | } | |||
| 96 | } | 126 | } | ||
| 97 | 127 | ||||
| 98 | // Suggestions are returned via setSuggestions() when native handler responds | 128 | // Suggestions are returned via setSuggestions() when native handler responds | ||
M gui/src/injected/main-world.ts +83 -52
| @@ -126,98 +126,129 @@ function detectWindowType(features?: string | null): string { | |||
| 126 | 126 | ||
| 127 | 127 | // Request color palettes from Go backend | |
| 128 | 128 | try { | |
| 129 | + | console.log("[dumber-palette] Initializing color palette loading"); | |
| 129 | 130 | const bridge = window.webkit?.messageHandlers?.dumber; | |
| 130 | - | if (bridge && typeof bridge.postMessage === "function") { | |
| 131 | - | // Set up callback handler before requesting | |
| 132 | - | window.__dumber_color_palettes = (palettes: unknown) => { | |
| 133 | - | try { | |
| 134 | - | // Type guard to ensure palettes is a valid object | |
| 135 | - | if (typeof palettes !== "object" || palettes === null) { | |
| 136 | - | console.error("[dumber] Invalid palettes received"); | |
| 137 | - | return; | |
| 138 | - | } | |
| 139 | 131 | ||
| 140 | - | window.__dumber_palette = palettes as Record<string, Record<string, string>>; | |
| 132 | + | if (!bridge || typeof bridge.postMessage !== "function") { | |
| 133 | + | console.error("[dumber-palette] ERROR: No webkit message bridge available"); | |
| 134 | + | return; | |
| 135 | + | } | |
| 136 | + | ||
| 137 | + | console.log("[dumber-palette] WebKit bridge found, setting up handlers"); | |
| 141 | 138 | ||
| 142 | - | // Normalize palette keys to lowercase | |
| 143 | - | const normalized: Record<string, Record<string, string>> = {}; | |
| 144 | - | if (window.__dumber_palette) { | |
| 145 | - | for (const key in window.__dumber_palette) { | |
| 146 | - | if (Object.prototype.hasOwnProperty.call(window.__dumber_palette, key)) { | |
| 147 | - | normalized[key.toLowerCase()] = window.__dumber_palette[key]; | |
| 139 | + | // Set up callback handler before requesting | |
| 140 | + | window.__dumber_color_palettes = (palettes: unknown) => { | |
| 141 | + | console.log("[dumber-palette] Received palettes from backend:", palettes); | |
| 142 | + | try { | |
| 143 | + | // Type guard to ensure palettes is a valid object | |
| 144 | + | if (typeof palettes !== "object" || palettes === null) { | |
| 145 | + | console.error("[dumber-palette] ERROR: Invalid palettes received - type:", typeof palettes); | |
| 146 | + | return; | |
| 147 | + | } | |
| 148 | + | ||
| 149 | + | window.__dumber_palette = palettes as Record<string, Record<string, string>>; | |
| 150 | + | console.log("[dumber-palette] Palette keys:", Object.keys(window.__dumber_palette || {})); | |
| 151 | + | ||
| 152 | + | // Normalize palette keys to lowercase | |
| 153 | + | const normalized: Record<string, Record<string, string>> = {}; | |
| 154 | + | if (window.__dumber_palette) { | |
| 155 | + | for (const key in window.__dumber_palette) { | |
| 156 | + | if (Object.prototype.hasOwnProperty.call(window.__dumber_palette, key)) { | |
| 157 | + | const paletteValue = window.__dumber_palette[key]; | |
| 158 | + | if (paletteValue) { | |
| 159 | + | normalized[key.toLowerCase()] = paletteValue; | |
| 160 | + | console.log(`[dumber-palette] Normalized: ${key} -> ${key.toLowerCase()}, colors:`, Object.keys(paletteValue)); | |
| 148 | 161 | } | |
| 149 | 162 | } | |
| 150 | - | window.__dumber_palette = normalized; | |
| 151 | 163 | } | |
| 164 | + | window.__dumber_palette = normalized; | |
| 165 | + | } | |
| 152 | 166 | ||
| 153 | - | // Apply palette now that we have it | |
| 154 | - | const initialTheme: "light" | "dark" = document.documentElement.classList.contains("dark") ? "dark" : "light"; | |
| 155 | - | window.__dumber_initial_theme = initialTheme; | |
| 156 | - | if (window.__dumber_applyPalette) { | |
| 157 | - | window.__dumber_applyPalette(initialTheme); | |
| 158 | - | } | |
| 159 | - | } catch (err) { | |
| 160 | - | console.error("[dumber] Failed to apply received palette", err); | |
| 167 | + | // Apply palette now that we have it | |
| 168 | + | const initialTheme: "light" | "dark" = document.documentElement.classList.contains("dark") ? "dark" : "light"; | |
| 169 | + | console.log(`[dumber-palette] Initial theme detected: ${initialTheme}`); | |
| 170 | + | window.__dumber_initial_theme = initialTheme; | |
| 171 | + | ||
| 172 | + | if (window.__dumber_applyPalette) { | |
| 173 | + | console.log("[dumber-palette] Applying palette..."); | |
| 174 | + | window.__dumber_applyPalette(initialTheme); | |
| 175 | + | } else { | |
| 176 | + | console.error("[dumber-palette] ERROR: __dumber_applyPalette function not found"); | |
| 161 | 177 | } | |
| 162 | - | }; | |
| 178 | + | } catch (err) { | |
| 179 | + | console.error("[dumber-palette] ERROR: Failed to apply received palette:", err); | |
| 180 | + | } | |
| 181 | + | }; | |
| 163 | 182 | ||
| 164 | - | window.__dumber_color_palettes_error = (error: string) => { | |
| 165 | - | console.error("[dumber] Failed to get color palettes:", error); | |
| 166 | - | }; | |
| 183 | + | window.__dumber_color_palettes_error = (error: string) => { | |
| 184 | + | console.error("[dumber-palette] ERROR from backend:", error); | |
| 185 | + | }; | |
| 167 | 186 | ||
| 168 | - | // Request color palettes | |
| 169 | - | bridge.postMessage(JSON.stringify({ type: "get_color_palettes" })); | |
| 170 | - | } | |
| 187 | + | // Request color palettes | |
| 188 | + | console.log("[dumber-palette] Sending get_color_palettes request to backend"); | |
| 189 | + | bridge.postMessage(JSON.stringify({ type: "get_color_palettes" })); | |
| 190 | + | console.log("[dumber-palette] Request sent, waiting for response..."); | |
| 171 | 191 | } catch (err) { | |
| 172 | - | console.error("[dumber] Failed to request color palettes", err); | |
| 192 | + | console.error("[dumber-palette] EXCEPTION requesting color palettes:", err); | |
| 173 | 193 | } | |
| 174 | 194 | ||
| 175 | 195 | // Palette application function | |
| 176 | 196 | window.__dumber_applyPalette = (theme: "light" | "dark") => { | |
| 197 | + | console.log(`[dumber-palette] applyPalette called with theme: ${theme}`); | |
| 177 | 198 | try { | |
| 178 | 199 | const palette = window.__dumber_palette?.[theme] || window.__dumber_palette?.["light"]; | |
| 179 | 200 | if (!palette) { | |
| 201 | + | console.error(`[dumber-palette] ERROR: No palette found for theme "${theme}". Available:`, Object.keys(window.__dumber_palette || {})); | |
| 180 | 202 | return; | |
| 181 | 203 | } | |
| 204 | + | console.log(`[dumber-palette] Found palette for theme "${theme}":`, palette); | |
| 182 | 205 | ||
| 183 | 206 | const tokenMap: Record<string, string> = { | |
| 184 | - | Background: "--color-browser-bg", | |
| 185 | - | Surface: "--color-browser-surface", | |
| 186 | - | SurfaceVariant: "--color-browser-surface-variant", | |
| 187 | - | Text: "--color-browser-text", | |
| 188 | - | Muted: "--color-browser-muted", | |
| 189 | - | Accent: "--color-browser-accent", | |
| 190 | - | Border: "--color-browser-border", | |
| 207 | + | background: "--color-browser-bg", | |
| 208 | + | surface: "--color-browser-surface", | |
| 209 | + | surface_variant: "--color-browser-surface-variant", | |
| 210 | + | text: "--color-browser-text", | |
| 211 | + | muted: "--color-browser-muted", | |
| 212 | + | accent: "--color-browser-accent", | |
| 213 | + | border: "--color-browser-border", | |
| 191 | 214 | }; | |
| 192 | 215 | ||
| 193 | 216 | const dynamicMap: Record<string, string> = { | |
| 194 | - | Background: "--dynamic-bg", | |
| 195 | - | Surface: "--dynamic-surface", | |
| 196 | - | SurfaceVariant: "--dynamic-surface-variant", | |
| 197 | - | Text: "--dynamic-text", | |
| 198 | - | Muted: "--dynamic-muted", | |
| 199 | - | Accent: "--dynamic-accent", | |
| 200 | - | Border: "--dynamic-border", | |
| 217 | + | background: "--dynamic-bg", | |
| 218 | + | surface: "--dynamic-surface", | |
| 219 | + | surface_variant: "--dynamic-surface-variant", | |
| 220 | + | text: "--dynamic-text", | |
| 221 | + | muted: "--dynamic-muted", | |
| 222 | + | accent: "--dynamic-accent", | |
| 223 | + | border: "--dynamic-border", | |
| 201 | 224 | }; | |
| 202 | 225 | ||
| 203 | 226 | const root = document.documentElement; | |
| 227 | + | let appliedCount = 0; | |
| 204 | 228 | for (const key in tokenMap) { | |
| 205 | 229 | if (Object.prototype.hasOwnProperty.call(tokenMap, key)) { | |
| 206 | 230 | const colorValue = palette[key]; | |
| 207 | - | if (colorValue) { | |
| 208 | - | root.style.setProperty(tokenMap[key], colorValue); | |
| 209 | - | if (Object.prototype.hasOwnProperty.call(dynamicMap, key)) { | |
| 210 | - | root.style.setProperty(dynamicMap[key], colorValue); | |
| 231 | + | const tokenVar = tokenMap[key]; | |
| 232 | + | const dynamicVar = dynamicMap[key]; | |
| 233 | + | if (colorValue && typeof colorValue === "string" && tokenVar) { | |
| 234 | + | root.style.setProperty(tokenVar, colorValue); | |
| 235 | + | if (dynamicVar) { | |
| 236 | + | root.style.setProperty(dynamicVar, colorValue); | |
| 211 | 237 | } | |
| 238 | + | console.log(`[dumber-palette] Applied ${key}: ${colorValue} -> ${tokenVar}`); | |
| 239 | + | appliedCount++; | |
| 240 | + | } else { | |
| 241 | + | console.warn(`[dumber-palette] Skipped ${key}: colorValue=${colorValue}, tokenVar=${tokenVar}`); | |
| 212 | 242 | } | |
| 213 | 243 | } | |
| 214 | 244 | } | |
| 215 | 245 | ||
| 246 | + | console.log(`[dumber-palette] Applied ${appliedCount} colors successfully`); | |
| 216 | 247 | document.dispatchEvent( | |
| 217 | 248 | new CustomEvent("dumber:palette-updated", { detail: { theme } }) | |
| 218 | 249 | ); | |
| 219 | 250 | } catch (err) { | |
| 220 | - | console.error("[dumber] Failed to apply palette", err); | |
| 251 | + | console.error("[dumber-palette] EXCEPTION applying palette:", err); | |
| 221 | 252 | } | |
| 222 | 253 | }; | |
| 223 | 254 | ||
| @@ -126,98 +126,129 @@ function detectWindowType(features?: string | null): string { | |||||
| 126 | 126 | ||||
| 127 | // Request color palettes from Go backend | 127 | // Request color palettes from Go backend | ||
| 128 | try { | 128 | try { | ||
| 129 | + | console.log("[dumber-palette] Initializing color palette loading"); | |||
| 129 | const bridge = window.webkit?.messageHandlers?.dumber; | 130 | const bridge = window.webkit?.messageHandlers?.dumber; | ||
| 130 | - | if (bridge && typeof bridge.postMessage === "function") { | |||
| 131 | - | // Set up callback handler before requesting | |||
| 132 | - | window.__dumber_color_palettes = (palettes: unknown) => { | |||
| 133 | - | try { | |||
| 134 | - | // Type guard to ensure palettes is a valid object | |||
| 135 | - | if (typeof palettes !== "object" || palettes === null) { | |||
| 136 | - | console.error("[dumber] Invalid palettes received"); | |||
| 137 | - | return; | |||
| 138 | - | } | |||
| 139 | 131 | ||||
| 140 | - | window.__dumber_palette = palettes as Record<string, Record<string, string>>; | 132 | + | if (!bridge || typeof bridge.postMessage !== "function") { |
| 133 | + | console.error("[dumber-palette] ERROR: No webkit message bridge available"); | |||
| 134 | + | return; | |||
| 135 | + | } | |||
| 136 | + | ||||
| 137 | + | console.log("[dumber-palette] WebKit bridge found, setting up handlers"); | |||
| 141 | 138 | ||||
| 142 | - | // Normalize palette keys to lowercase | 139 | + | // Set up callback handler before requesting |
| 143 | - | const normalized: Record<string, Record<string, string>> = {}; | 140 | + | window.__dumber_color_palettes = (palettes: unknown) => { |
| 144 | - | if (window.__dumber_palette) { | 141 | + | console.log("[dumber-palette] Received palettes from backend:", palettes); |
| 145 | - | for (const key in window.__dumber_palette) { | 142 | + | try { |
| 146 | - | if (Object.prototype.hasOwnProperty.call(window.__dumber_palette, key)) { | 143 | + | // Type guard to ensure palettes is a valid object |
| 147 | - | normalized[key.toLowerCase()] = window.__dumber_palette[key]; | 144 | + | if (typeof palettes !== "object" || palettes === null) { |
| 145 | + | console.error("[dumber-palette] ERROR: Invalid palettes received - type:", typeof palettes); | |||
| 146 | + | return; | |||
| 147 | + | } | |||
| 148 | + | ||||
| 149 | + | window.__dumber_palette = palettes as Record<string, Record<string, string>>; | |||
| 150 | + | console.log("[dumber-palette] Palette keys:", Object.keys(window.__dumber_palette || {})); | |||
| 151 | + | ||||
| 152 | + | // Normalize palette keys to lowercase | |||
| 153 | + | const normalized: Record<string, Record<string, string>> = {}; | |||
| 154 | + | if (window.__dumber_palette) { | |||
| 155 | + | for (const key in window.__dumber_palette) { | |||
| 156 | + | if (Object.prototype.hasOwnProperty.call(window.__dumber_palette, key)) { | |||
| 157 | + | const paletteValue = window.__dumber_palette[key]; | |||
| 158 | + | if (paletteValue) { | |||
| 159 | + | normalized[key.toLowerCase()] = paletteValue; | |||
| 160 | + | console.log(`[dumber-palette] Normalized: ${key} -> ${key.toLowerCase()}, colors:`, Object.keys(paletteValue)); | |||
| 148 | } | 161 | } | ||
| 149 | } | 162 | } | ||
| 150 | - | window.__dumber_palette = normalized; | |||
| 151 | } | 163 | } | ||
| 164 | + | window.__dumber_palette = normalized; | |||
| 165 | + | } | |||
| 152 | 166 | ||||
| 153 | - | // Apply palette now that we have it | 167 | + | // Apply palette now that we have it |
| 154 | - | const initialTheme: "light" | "dark" = document.documentElement.classList.contains("dark") ? "dark" : "light"; | 168 | + | const initialTheme: "light" | "dark" = document.documentElement.classList.contains("dark") ? "dark" : "light"; |
| 155 | - | window.__dumber_initial_theme = initialTheme; | 169 | + | console.log(`[dumber-palette] Initial theme detected: ${initialTheme}`); |
| 156 | - | if (window.__dumber_applyPalette) { | 170 | + | window.__dumber_initial_theme = initialTheme; |
| 157 | - | window.__dumber_applyPalette(initialTheme); | 171 | + | |
| 158 | - | } | 172 | + | if (window.__dumber_applyPalette) { |
| 159 | - | } catch (err) { | 173 | + | console.log("[dumber-palette] Applying palette..."); |
| 160 | - | console.error("[dumber] Failed to apply received palette", err); | 174 | + | window.__dumber_applyPalette(initialTheme); |
| 175 | + | } else { | |||
| 176 | + | console.error("[dumber-palette] ERROR: __dumber_applyPalette function not found"); | |||
| 161 | } | 177 | } | ||
| 162 | - | }; | 178 | + | } catch (err) { |
| 179 | + | console.error("[dumber-palette] ERROR: Failed to apply received palette:", err); | |||
| 180 | + | } | |||
| 181 | + | }; | |||
| 163 | 182 | ||||
| 164 | - | window.__dumber_color_palettes_error = (error: string) => { | 183 | + | window.__dumber_color_palettes_error = (error: string) => { |
| 165 | - | console.error("[dumber] Failed to get color palettes:", error); | 184 | + | console.error("[dumber-palette] ERROR from backend:", error); |
| 166 | - | }; | 185 | + | }; |
| 167 | 186 | ||||
| 168 | - | // Request color palettes | 187 | + | // Request color palettes |
| 169 | - | bridge.postMessage(JSON.stringify({ type: "get_color_palettes" })); | 188 | + | console.log("[dumber-palette] Sending get_color_palettes request to backend"); |
| 170 | - | } | 189 | + | bridge.postMessage(JSON.stringify({ type: "get_color_palettes" })); |
| 190 | + | console.log("[dumber-palette] Request sent, waiting for response..."); | |||
| 171 | } catch (err) { | 191 | } catch (err) { | ||
| 172 | - | console.error("[dumber] Failed to request color palettes", err); | 192 | + | console.error("[dumber-palette] EXCEPTION requesting color palettes:", err); |
| 173 | } | 193 | } | ||
| 174 | 194 | ||||
| 175 | // Palette application function | 195 | // Palette application function | ||
| 176 | window.__dumber_applyPalette = (theme: "light" | "dark") => { | 196 | window.__dumber_applyPalette = (theme: "light" | "dark") => { | ||
| 197 | + | console.log(`[dumber-palette] applyPalette called with theme: ${theme}`); | |||
| 177 | try { | 198 | try { | ||
| 178 | const palette = window.__dumber_palette?.[theme] || window.__dumber_palette?.["light"]; | 199 | const palette = window.__dumber_palette?.[theme] || window.__dumber_palette?.["light"]; | ||
| 179 | if (!palette) { | 200 | if (!palette) { | ||
| 201 | + | console.error(`[dumber-palette] ERROR: No palette found for theme "${theme}". Available:`, Object.keys(window.__dumber_palette || {})); | |||
| 180 | return; | 202 | return; | ||
| 181 | } | 203 | } | ||
| 204 | + | console.log(`[dumber-palette] Found palette for theme "${theme}":`, palette); | |||
| 182 | 205 | ||||
| 183 | const tokenMap: Record<string, string> = { | 206 | const tokenMap: Record<string, string> = { | ||
| 184 | - | Background: "--color-browser-bg", | 207 | + | background: "--color-browser-bg", |
| 185 | - | Surface: "--color-browser-surface", | 208 | + | surface: "--color-browser-surface", |
| 186 | - | SurfaceVariant: "--color-browser-surface-variant", | 209 | + | surface_variant: "--color-browser-surface-variant", |
| 187 | - | Text: "--color-browser-text", | 210 | + | text: "--color-browser-text", |
| 188 | - | Muted: "--color-browser-muted", | 211 | + | muted: "--color-browser-muted", |
| 189 | - | Accent: "--color-browser-accent", | 212 | + | accent: "--color-browser-accent", |
| 190 | - | Border: "--color-browser-border", | 213 | + | border: "--color-browser-border", |
| 191 | }; | 214 | }; | ||
| 192 | 215 | ||||
| 193 | const dynamicMap: Record<string, string> = { | 216 | const dynamicMap: Record<string, string> = { | ||
| 194 | - | Background: "--dynamic-bg", | 217 | + | background: "--dynamic-bg", |
| 195 | - | Surface: "--dynamic-surface", | 218 | + | surface: "--dynamic-surface", |
| 196 | - | SurfaceVariant: "--dynamic-surface-variant", | 219 | + | surface_variant: "--dynamic-surface-variant", |
| 197 | - | Text: "--dynamic-text", | 220 | + | text: "--dynamic-text", |
| 198 | - | Muted: "--dynamic-muted", | 221 | + | muted: "--dynamic-muted", |
| 199 | - | Accent: "--dynamic-accent", | 222 | + | accent: "--dynamic-accent", |
| 200 | - | Border: "--dynamic-border", | 223 | + | border: "--dynamic-border", |
| 201 | }; | 224 | }; | ||
| 202 | 225 | ||||
| 203 | const root = document.documentElement; | 226 | const root = document.documentElement; | ||
| 227 | + | let appliedCount = 0; | |||
| 204 | for (const key in tokenMap) { | 228 | for (const key in tokenMap) { | ||
| 205 | if (Object.prototype.hasOwnProperty.call(tokenMap, key)) { | 229 | if (Object.prototype.hasOwnProperty.call(tokenMap, key)) { | ||
| 206 | const colorValue = palette[key]; | 230 | const colorValue = palette[key]; | ||
| 207 | - | if (colorValue) { | 231 | + | const tokenVar = tokenMap[key]; |
| 208 | - | root.style.setProperty(tokenMap[key], colorValue); | 232 | + | const dynamicVar = dynamicMap[key]; |
| 209 | - | if (Object.prototype.hasOwnProperty.call(dynamicMap, key)) { | 233 | + | if (colorValue && typeof colorValue === "string" && tokenVar) { |
| 210 | - | root.style.setProperty(dynamicMap[key], colorValue); | 234 | + | root.style.setProperty(tokenVar, colorValue); |
| 235 | + | if (dynamicVar) { | |||
| 236 | + | root.style.setProperty(dynamicVar, colorValue); | |||
| 211 | } | 237 | } | ||
| 238 | + | console.log(`[dumber-palette] Applied ${key}: ${colorValue} -> ${tokenVar}`); | |||
| 239 | + | appliedCount++; | |||
| 240 | + | } else { | |||
| 241 | + | console.warn(`[dumber-palette] Skipped ${key}: colorValue=${colorValue}, tokenVar=${tokenVar}`); | |||
| 212 | } | 242 | } | ||
| 213 | } | 243 | } | ||
| 214 | } | 244 | } | ||
| 215 | 245 | ||||
| 246 | + | console.log(`[dumber-palette] Applied ${appliedCount} colors successfully`); | |||
| 216 | document.dispatchEvent( | 247 | document.dispatchEvent( | ||
| 217 | new CustomEvent("dumber:palette-updated", { detail: { theme } }) | 248 | new CustomEvent("dumber:palette-updated", { detail: { theme } }) | ||
| 218 | ); | 249 | ); | ||
| 219 | } catch (err) { | 250 | } catch (err) { | ||
| 220 | - | console.error("[dumber] Failed to apply palette", err); | 251 | + | console.error("[dumber-palette] EXCEPTION applying palette:", err); |
| 221 | } | 252 | } | ||
| 222 | }; | 253 | }; | ||
| 223 | 254 | ||||