detached c693591

refactor(port): add WebUIMessageHandler/WebUIHandlerRouter interfaces

Add shared message handler interfaces to port so both WebKit and CEF
engines can use the same handler registration code:

- WebUIMessageHandler: Handle(ctx, WebViewID, json.RawMessage) (any, error)
- WebUIMessageHandlerFunc: function adapter
- WebUIHandlerRouter: RegisterHandler + RegisterHandlerWithCallbacks

Expand HandlerDependencies with SaveConfig and keybinding usecases
that were previously only available in webkit/handlers.Config.

Remove unused legacy MessageRouter interface.
commit
c693591537a7f19f493d4e4a8f360e794b75e815
author
brice · · 2026-03-21 21:40 UTC
committer
brice · · 2026-03-28 04:38 UTC
parent
1455aeb
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
1 file · +36 -18
M internal/application/port/engine.go +36 -18
@@ -3,7 +3,10 @@
33 // remain independent of specific implementations (WebKit, GTK, etc.).
44 package port
55
6-import "context"
6+import (
7+ "context"
8+ "encoding/json"
9+)
710
811 // CookiePolicy controls cookie acceptance behavior for the engine's network session.
912 type CookiePolicy string
@@ -157,13 +160,40 @@ type EngineSettingsUpdate struct {
157160 Raw any //nolint:iface // intentional: see type comment above
158161 }
159162
163+// WebUIMessageHandler handles a decoded message payload from the JS bridge.
164+// Used by both WebKit and CEF message routers via the shared handlers package.
165+type WebUIMessageHandler interface {
166+ Handle(ctx context.Context, webviewID WebViewID, payload json.RawMessage) (any, error)
167+}
168+
169+// WebUIMessageHandlerFunc adapts a function to the WebUIMessageHandler interface.
170+type WebUIMessageHandlerFunc func(ctx context.Context, webviewID WebViewID, payload json.RawMessage) (any, error)
171+
172+// Handle calls f(ctx, webviewID, payload).
173+func (f WebUIMessageHandlerFunc) Handle(ctx context.Context, webviewID WebViewID, payload json.RawMessage) (any, error) {
174+ return f(ctx, webviewID, payload)
175+}
176+
177+// WebUIHandlerRouter registers message handlers for the JS↔Go bridge.
178+// Both WebKit's MessageRouter and CEF's MessageRouter implement this interface,
179+// allowing shared handler registration code.
180+type WebUIHandlerRouter interface {
181+ RegisterHandler(msgType string, handler WebUIMessageHandler) error
182+ RegisterHandlerWithCallbacks(msgType, callback, errorCallback, worldName string, handler WebUIMessageHandler) error
183+}
184+
160185 // HandlerDependencies holds use cases needed by WebUI message handlers.
161186 type HandlerDependencies struct {
162- HistoryUC HomepageHistory
163- FavoritesUC HomepageFavorites
164- Clipboard Clipboard
165- AutoCopyConfig AutoCopyConfig
166- OnClipboardCopied func(textLen int)
187+ HistoryUC HomepageHistory
188+ FavoritesUC HomepageFavorites
189+ Clipboard Clipboard
190+ AutoCopyConfig AutoCopyConfig
191+ OnClipboardCopied func(textLen int)
192+ SaveConfig func(context.Context, WebUIConfig) error
193+ KeybindingsGetter KeybindingsGetter
194+ KeybindingSetter KeybindingSetter
195+ KeybindingResetter KeybindingResetter
196+ AllKeybindingsResetter AllKeybindingsResetter
167197 }
168198
169199 // SchemeHandler defines the port interface for registering custom URI schemes.
@@ -176,18 +206,6 @@ type SchemeHandler interface {
176206 RegisterScheme(scheme string, handler func(uri string) ([]byte, string, error))
177207 }
178208
179-// MessageRouter defines the port interface for bidirectional JS-to-Go messaging.
180-// It allows JavaScript running in a WebView to invoke named Go handlers,
181-// and allows Go code to post messages back to a specific WebView.
182-type MessageRouter interface {
183- // RegisterHandler registers a named message handler callable from JavaScript.
184- // The handler receives a JSON-encoded message string and returns a
185- // JSON-encoded response string.
186- RegisterHandler(name string, handler func(message string) (string, error))
187-
188- // PostMessage sends a message to the JavaScript context of the given WebView.
189- PostMessage(webviewID WebViewID, message string) error
190-}
191209
192210 // SettingsApplier defines the port interface for applying browser settings to WebViews.
193211 // Implementations apply engine-specific settings (security, features, etc.) uniformly
@@ -3,7 +3,10 @@
3 // remain independent of specific implementations (WebKit, GTK, etc.).3 // remain independent of specific implementations (WebKit, GTK, etc.).
4 package port4 package port
5 5
6-import "context"6+import (
7+ "context"
8+ "encoding/json"
9+)
7 10
8 // CookiePolicy controls cookie acceptance behavior for the engine's network session.11 // CookiePolicy controls cookie acceptance behavior for the engine's network session.
9 type CookiePolicy string12 type CookiePolicy string
@@ -157,13 +160,40 @@ type EngineSettingsUpdate struct {
157 Raw any //nolint:iface // intentional: see type comment above160 Raw any //nolint:iface // intentional: see type comment above
158 }161 }
159 162
163+// WebUIMessageHandler handles a decoded message payload from the JS bridge.
164+// Used by both WebKit and CEF message routers via the shared handlers package.
165+type WebUIMessageHandler interface {
166+ Handle(ctx context.Context, webviewID WebViewID, payload json.RawMessage) (any, error)
167+}
168+
169+// WebUIMessageHandlerFunc adapts a function to the WebUIMessageHandler interface.
170+type WebUIMessageHandlerFunc func(ctx context.Context, webviewID WebViewID, payload json.RawMessage) (any, error)
171+
172+// Handle calls f(ctx, webviewID, payload).
173+func (f WebUIMessageHandlerFunc) Handle(ctx context.Context, webviewID WebViewID, payload json.RawMessage) (any, error) {
174+ return f(ctx, webviewID, payload)
175+}
176+
177+// WebUIHandlerRouter registers message handlers for the JS↔Go bridge.
178+// Both WebKit's MessageRouter and CEF's MessageRouter implement this interface,
179+// allowing shared handler registration code.
180+type WebUIHandlerRouter interface {
181+ RegisterHandler(msgType string, handler WebUIMessageHandler) error
182+ RegisterHandlerWithCallbacks(msgType, callback, errorCallback, worldName string, handler WebUIMessageHandler) error
183+}
184+
160 // HandlerDependencies holds use cases needed by WebUI message handlers.185 // HandlerDependencies holds use cases needed by WebUI message handlers.
161 type HandlerDependencies struct {186 type HandlerDependencies struct {
162- HistoryUC HomepageHistory187+ HistoryUC HomepageHistory
163- FavoritesUC HomepageFavorites188+ FavoritesUC HomepageFavorites
164- Clipboard Clipboard189+ Clipboard Clipboard
165- AutoCopyConfig AutoCopyConfig190+ AutoCopyConfig AutoCopyConfig
166- OnClipboardCopied func(textLen int)191+ OnClipboardCopied func(textLen int)
192+ SaveConfig func(context.Context, WebUIConfig) error
193+ KeybindingsGetter KeybindingsGetter
194+ KeybindingSetter KeybindingSetter
195+ KeybindingResetter KeybindingResetter
196+ AllKeybindingsResetter AllKeybindingsResetter
167 }197 }
168 198
169 // SchemeHandler defines the port interface for registering custom URI schemes.199 // SchemeHandler defines the port interface for registering custom URI schemes.
@@ -176,18 +206,6 @@ type SchemeHandler interface {
176 RegisterScheme(scheme string, handler func(uri string) ([]byte, string, error))206 RegisterScheme(scheme string, handler func(uri string) ([]byte, string, error))
177 }207 }
178 208
179-// MessageRouter defines the port interface for bidirectional JS-to-Go messaging.
180-// It allows JavaScript running in a WebView to invoke named Go handlers,
181-// and allows Go code to post messages back to a specific WebView.
182-type MessageRouter interface {
183- // RegisterHandler registers a named message handler callable from JavaScript.
184- // The handler receives a JSON-encoded message string and returns a
185- // JSON-encoded response string.
186- RegisterHandler(name string, handler func(message string) (string, error))
187-
188- // PostMessage sends a message to the JavaScript context of the given WebView.
189- PostMessage(webviewID WebViewID, message string) error
190-}
191 209
192 // SettingsApplier defines the port interface for applying browser settings to WebViews.210 // SettingsApplier defines the port interface for applying browser settings to WebViews.
193 // Implementations apply engine-specific settings (security, features, etc.) uniformly211 // Implementations apply engine-specific settings (security, features, etc.) uniformly

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