detached a844552

refactor: extract shared WebUI message handlers, wire CEF RegisterHandlers

Move message handlers from webkit/handlers/ to infrastructure/handlers/
(engine-agnostic shared package). Both WebKit and CEF now use the same
handler code via the port.WebUIHandlerRouter interface.

Port layer:
- Add WebUIMessageHandler, WebUIMessageHandlerFunc, WebUIHandlerRouter
- Expand HandlerDependencies with SaveConfig and keybinding usecases
- Remove unused legacy MessageRouter interface

Shared handlers (internal/infrastructure/handlers/):
- Moved from webkit/handlers/: register, config, keybindings, clipboard
- Moved homepage/: history, favorites, folders, tags, response, registry
- All use port.WebUIMessageHandler instead of webkit.MessageHandler
- RegisterAll takes port.WebUIHandlerRouter + port.HandlerDependencies

WebKit adapter:
- MessageHandler/MessageHandlerFunc are now aliases for port types
- MessageRouter implements port.WebUIHandlerRouter (compile-time check)
- Engine registrar signatures updated to use port.WebUIHandlerRouter

CEF adapter:
- MessageRouter implements port.WebUIHandlerRouter via portHandlerAdapter
- RegisterHandlers now calls handlers.RegisterAll (was a stub)
- registerInternalHandler for accent handlers (bare uint64 webviewID)

Bootstrap:
- Updated to pass keybinding deps and SaveConfig in HandlerDependencies
- Import path changed from webkit/handlers to infrastructure/handlers
commit
a8445528998ad4cafa5e87f5c9738512c71680b6
author
brice · · 2026-03-21 21:49 UTC
committer
brice · · 2026-03-28 04:38 UTC
parent
c693591
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
19 files · +256 -193
M internal/application/port/engine.go +0 -1
@@ -206,7 +206,6 @@ type SchemeHandler interface {
206206 RegisterScheme(scheme string, handler func(uri string) ([]byte, string, error))
207207 }
208208
209-
210209 // SettingsApplier defines the port interface for applying browser settings to WebViews.
211210 // Implementations apply engine-specific settings (security, features, etc.) uniformly
212211 // across a set of WebView instances.
@@ -206,7 +206,6 @@ type SchemeHandler interface {
206 RegisterScheme(scheme string, handler func(uri string) ([]byte, string, error))206 RegisterScheme(scheme string, handler func(uri string) ([]byte, string, error))
207 }207 }
208 208
209-
210 // SettingsApplier defines the port interface for applying browser settings to WebViews.209 // SettingsApplier defines the port interface for applying browser settings to WebViews.
211 // Implementations apply engine-specific settings (security, features, etc.) uniformly210 // Implementations apply engine-specific settings (security, features, etc.) uniformly
212 // across a set of WebView instances.211 // across a set of WebView instances.
M internal/bootstrap/engine.go +31 -23
@@ -8,8 +8,8 @@ import (
88 "github.com/bnema/dumber/internal/application/usecase"
99 "github.com/bnema/dumber/internal/infrastructure/cef"
1010 "github.com/bnema/dumber/internal/infrastructure/config"
11+ "github.com/bnema/dumber/internal/infrastructure/handlers"
1112 "github.com/bnema/dumber/internal/infrastructure/webkit"
12- "github.com/bnema/dumber/internal/infrastructure/webkit/handlers"
1313 "github.com/bnema/dumber/internal/ui/theme"
1414 "github.com/rs/zerolog"
1515 )
@@ -38,10 +38,10 @@ func BuildEngine(input EngineInput) (port.Engine, error) {
3838 }
3939 wkCfg := webkit.EngineConfigFromConfig(cfg.Engine.WebKit)
4040
41- // Pre-build keybindings handler for handler registration.
42- keybindingsHandler, err := buildKeybindingsHandler()
41+ // Pre-build keybinding use cases for handler registration.
42+ keybindingDeps, err := buildKeybindingDeps()
4343 if err != nil {
44- return nil, fmt.Errorf("failed to build keybindings handler: %w", err)
44+ return nil, fmt.Errorf("failed to build keybinding deps: %w", err)
4545 }
4646
4747 // Pre-build config save function for handler registration.
@@ -53,18 +53,18 @@ func BuildEngine(input EngineInput) (port.Engine, error) {
5353 return webkit.NewEngine(
5454 input.Ctx, cfg, opts, wkCfg,
5555 input.ThemeManager, input.ColorResolver, input.Logger,
56- func(ctx context.Context, router *webkit.MessageRouter, deps port.HandlerDependencies) error {
57- return handlers.RegisterAll(ctx, router, handlers.Config{
58- HistoryUC: deps.HistoryUC,
59- FavoritesUC: deps.FavoritesUC,
60- Clipboard: deps.Clipboard,
61- AutoCopyConfig: deps.AutoCopyConfig,
62- SaveConfig: saveConfigFunc,
63- KeybindingsHandler: keybindingsHandler,
64- OnClipboardCopied: deps.OnClipboardCopied,
65- })
56+ func(ctx context.Context, router port.WebUIHandlerRouter, deps port.HandlerDependencies) error {
57+ // Inject pre-built dependencies that come from bootstrap, not from the engine.
58+ deps.SaveConfig = saveConfigFunc
59+ deps.KeybindingsGetter = keybindingDeps.KeybindingsGetter
60+ deps.KeybindingSetter = keybindingDeps.KeybindingSetter
61+ deps.KeybindingResetter = keybindingDeps.KeybindingResetter
62+ deps.AllKeybindingsResetter = keybindingDeps.AllKeybindingsResetter
63+ return handlers.RegisterAll(ctx, router, deps)
64+ },
65+ func(ctx context.Context, router port.WebUIHandlerRouter, handler port.AccentKeyHandler) error {
66+ return handlers.RegisterAccentHandlers(ctx, router, handler)
6667 },
67- handlers.RegisterAccentHandlers,
6868 )
6969 case "cef":
7070 cefCfg := cfg.Engine.CEF
@@ -74,8 +74,16 @@ func BuildEngine(input EngineInput) (port.Engine, error) {
7474 }
7575 }
7676
77-// buildKeybindingsHandler constructs the keybindings handler using the config manager.
78-func buildKeybindingsHandler() (*handlers.KeybindingsHandler, error) {
77+// keybindingDeps holds keybinding use cases built at bootstrap time.
78+type keybindingDeps struct {
79+ KeybindingsGetter port.KeybindingsGetter
80+ KeybindingSetter port.KeybindingSetter
81+ KeybindingResetter port.KeybindingResetter
82+ AllKeybindingsResetter port.AllKeybindingsResetter
83+}
84+
85+// buildKeybindingDeps constructs keybinding use cases using the config manager.
86+func buildKeybindingDeps() (*keybindingDeps, error) {
7987 mgr := config.GetManager()
8088 if mgr == nil {
8189 return nil, fmt.Errorf("config manager not initialized")
@@ -83,12 +91,12 @@ func buildKeybindingsHandler() (*handlers.KeybindingsHandler, error) {
8391
8492 gateway := config.NewKeybindingsGateway(mgr)
8593
86- return handlers.NewKeybindingsHandler(
87- usecase.NewGetKeybindingsUseCase(gateway),
88- usecase.NewSetKeybindingUseCase(gateway, gateway),
89- usecase.NewResetKeybindingUseCase(gateway),
90- usecase.NewResetAllKeybindingsUseCase(gateway),
91- ), nil
94+ return &keybindingDeps{
95+ KeybindingsGetter: usecase.NewGetKeybindingsUseCase(gateway),
96+ KeybindingSetter: usecase.NewSetKeybindingUseCase(gateway, gateway),
97+ KeybindingResetter: usecase.NewResetKeybindingUseCase(gateway),
98+ AllKeybindingsResetter: usecase.NewResetAllKeybindingsUseCase(gateway),
99+ }, nil
92100 }
93101
94102 // buildSaveConfigFunc constructs the config save function using the config manager.
@@ -8,8 +8,8 @@ import (
8 "github.com/bnema/dumber/internal/application/usecase"8 "github.com/bnema/dumber/internal/application/usecase"
9 "github.com/bnema/dumber/internal/infrastructure/cef"9 "github.com/bnema/dumber/internal/infrastructure/cef"
10 "github.com/bnema/dumber/internal/infrastructure/config"10 "github.com/bnema/dumber/internal/infrastructure/config"
11+ "github.com/bnema/dumber/internal/infrastructure/handlers"
11 "github.com/bnema/dumber/internal/infrastructure/webkit"12 "github.com/bnema/dumber/internal/infrastructure/webkit"
12- "github.com/bnema/dumber/internal/infrastructure/webkit/handlers"
13 "github.com/bnema/dumber/internal/ui/theme"13 "github.com/bnema/dumber/internal/ui/theme"
14 "github.com/rs/zerolog"14 "github.com/rs/zerolog"
15 )15 )
@@ -38,10 +38,10 @@ func BuildEngine(input EngineInput) (port.Engine, error) {
38 }38 }
39 wkCfg := webkit.EngineConfigFromConfig(cfg.Engine.WebKit)39 wkCfg := webkit.EngineConfigFromConfig(cfg.Engine.WebKit)
40 40
41- // Pre-build keybindings handler for handler registration.41+ // Pre-build keybinding use cases for handler registration.
42- keybindingsHandler, err := buildKeybindingsHandler()42+ keybindingDeps, err := buildKeybindingDeps()
43 if err != nil {43 if err != nil {
44- return nil, fmt.Errorf("failed to build keybindings handler: %w", err)44+ return nil, fmt.Errorf("failed to build keybinding deps: %w", err)
45 }45 }
46 46
47 // Pre-build config save function for handler registration.47 // Pre-build config save function for handler registration.
@@ -53,18 +53,18 @@ func BuildEngine(input EngineInput) (port.Engine, error) {
53 return webkit.NewEngine(53 return webkit.NewEngine(
54 input.Ctx, cfg, opts, wkCfg,54 input.Ctx, cfg, opts, wkCfg,
55 input.ThemeManager, input.ColorResolver, input.Logger,55 input.ThemeManager, input.ColorResolver, input.Logger,
56- func(ctx context.Context, router *webkit.MessageRouter, deps port.HandlerDependencies) error {56+ func(ctx context.Context, router port.WebUIHandlerRouter, deps port.HandlerDependencies) error {
57- return handlers.RegisterAll(ctx, router, handlers.Config{57+ // Inject pre-built dependencies that come from bootstrap, not from the engine.
58- HistoryUC: deps.HistoryUC,58+ deps.SaveConfig = saveConfigFunc
59- FavoritesUC: deps.FavoritesUC,59+ deps.KeybindingsGetter = keybindingDeps.KeybindingsGetter
60- Clipboard: deps.Clipboard,60+ deps.KeybindingSetter = keybindingDeps.KeybindingSetter
61- AutoCopyConfig: deps.AutoCopyConfig,61+ deps.KeybindingResetter = keybindingDeps.KeybindingResetter
62- SaveConfig: saveConfigFunc,62+ deps.AllKeybindingsResetter = keybindingDeps.AllKeybindingsResetter
63- KeybindingsHandler: keybindingsHandler,63+ return handlers.RegisterAll(ctx, router, deps)
64- OnClipboardCopied: deps.OnClipboardCopied,64+ },
65- })65+ func(ctx context.Context, router port.WebUIHandlerRouter, handler port.AccentKeyHandler) error {
66+ return handlers.RegisterAccentHandlers(ctx, router, handler)
66 },67 },
67- handlers.RegisterAccentHandlers,
68 )68 )
69 case "cef":69 case "cef":
70 cefCfg := cfg.Engine.CEF70 cefCfg := cfg.Engine.CEF
@@ -74,8 +74,16 @@ func BuildEngine(input EngineInput) (port.Engine, error) {
74 }74 }
75 }75 }
76 76
77-// buildKeybindingsHandler constructs the keybindings handler using the config manager.77+// keybindingDeps holds keybinding use cases built at bootstrap time.
78-func buildKeybindingsHandler() (*handlers.KeybindingsHandler, error) {78+type keybindingDeps struct {
79+ KeybindingsGetter port.KeybindingsGetter
80+ KeybindingSetter port.KeybindingSetter
81+ KeybindingResetter port.KeybindingResetter
82+ AllKeybindingsResetter port.AllKeybindingsResetter
83+}
84+
85+// buildKeybindingDeps constructs keybinding use cases using the config manager.
86+func buildKeybindingDeps() (*keybindingDeps, error) {
79 mgr := config.GetManager()87 mgr := config.GetManager()
80 if mgr == nil {88 if mgr == nil {
81 return nil, fmt.Errorf("config manager not initialized")89 return nil, fmt.Errorf("config manager not initialized")
@@ -83,12 +91,12 @@ func buildKeybindingsHandler() (*handlers.KeybindingsHandler, error) {
83 91
84 gateway := config.NewKeybindingsGateway(mgr)92 gateway := config.NewKeybindingsGateway(mgr)
85 93
86- return handlers.NewKeybindingsHandler(94+ return &keybindingDeps{
87- usecase.NewGetKeybindingsUseCase(gateway),95+ KeybindingsGetter: usecase.NewGetKeybindingsUseCase(gateway),
88- usecase.NewSetKeybindingUseCase(gateway, gateway),96+ KeybindingSetter: usecase.NewSetKeybindingUseCase(gateway, gateway),
89- usecase.NewResetKeybindingUseCase(gateway),97+ KeybindingResetter: usecase.NewResetKeybindingUseCase(gateway),
90- usecase.NewResetAllKeybindingsUseCase(gateway),98+ AllKeybindingsResetter: usecase.NewResetAllKeybindingsUseCase(gateway),
91- ), nil99+ }, nil
92 }100 }
93 101
94 // buildSaveConfigFunc constructs the config save function using the config manager.102 // buildSaveConfigFunc constructs the config save function using the config manager.
M internal/infrastructure/cef/engine.go +4 -11
@@ -12,6 +12,7 @@ import (
1212 "github.com/bnema/puregotk/v4/glib"
1313
1414 "github.com/bnema/dumber/internal/application/port"
15+ "github.com/bnema/dumber/internal/infrastructure/handlers"
1516 "github.com/bnema/dumber/internal/logging"
1617 )
1718
@@ -135,15 +136,7 @@ func (e *Engine) RegisterHandlers(ctx context.Context, deps port.HandlerDependen
135136 if e.messageRouter == nil {
136137 return nil
137138 }
138- log := logging.FromContext(ctx)
139- // TODO: Wire homepage, config, keybindings, and clipboard handlers
140- // into e.messageRouter. Each handler implements MessageHandler and is
141- // registered by message type (e.g. "get_recent_history", "get_favorites").
142- // The CEF MessageRouter dispatches based on Message.Type from the JS bridge.
143- _ = deps
144-
145- log.Warn().Msg("cef: RegisterHandlers stub — handler wiring not yet implemented")
146- return nil
139+ return handlers.RegisterAll(ctx, e.messageRouter, deps)
147140 }
148141
149142 // RegisterAccentHandlers registers accent/dead-key input handlers with the message router.
@@ -153,7 +146,7 @@ func (e *Engine) RegisterAccentHandlers(ctx context.Context, handler port.Accent
153146 }
154147 log := logging.FromContext(ctx)
155148
156- if err := e.messageRouter.RegisterHandler("accent_key_press", MessageHandlerFunc(
149+ if err := e.messageRouter.registerInternalHandler("accent_key_press", MessageHandlerFunc(
157150 func(ctx context.Context, _ uint64, payload json.RawMessage) (any, error) {
158151 var p struct {
159152 Char string `json:"char"`
@@ -171,7 +164,7 @@ func (e *Engine) RegisterAccentHandlers(ctx context.Context, handler port.Accent
171164 return err
172165 }
173166
174- if err := e.messageRouter.RegisterHandler("accent_key_release", MessageHandlerFunc(
167+ if err := e.messageRouter.registerInternalHandler("accent_key_release", MessageHandlerFunc(
175168 func(ctx context.Context, _ uint64, payload json.RawMessage) (any, error) {
176169 var p struct {
177170 Char string `json:"char"`
@@ -12,6 +12,7 @@ import (
12 "github.com/bnema/puregotk/v4/glib"12 "github.com/bnema/puregotk/v4/glib"
13 13
14 "github.com/bnema/dumber/internal/application/port"14 "github.com/bnema/dumber/internal/application/port"
15+ "github.com/bnema/dumber/internal/infrastructure/handlers"
15 "github.com/bnema/dumber/internal/logging"16 "github.com/bnema/dumber/internal/logging"
16 )17 )
17 18
@@ -135,15 +136,7 @@ func (e *Engine) RegisterHandlers(ctx context.Context, deps port.HandlerDependen
135 if e.messageRouter == nil {136 if e.messageRouter == nil {
136 return nil137 return nil
137 }138 }
138- log := logging.FromContext(ctx)139+ return handlers.RegisterAll(ctx, e.messageRouter, deps)
139- // TODO: Wire homepage, config, keybindings, and clipboard handlers
140- // into e.messageRouter. Each handler implements MessageHandler and is
141- // registered by message type (e.g. "get_recent_history", "get_favorites").
142- // The CEF MessageRouter dispatches based on Message.Type from the JS bridge.
143- _ = deps
144-
145- log.Warn().Msg("cef: RegisterHandlers stub — handler wiring not yet implemented")
146- return nil
147 }140 }
148 141
149 // RegisterAccentHandlers registers accent/dead-key input handlers with the message router.142 // RegisterAccentHandlers registers accent/dead-key input handlers with the message router.
@@ -153,7 +146,7 @@ func (e *Engine) RegisterAccentHandlers(ctx context.Context, handler port.Accent
153 }146 }
154 log := logging.FromContext(ctx)147 log := logging.FromContext(ctx)
155 148
156- if err := e.messageRouter.RegisterHandler("accent_key_press", MessageHandlerFunc(149+ if err := e.messageRouter.registerInternalHandler("accent_key_press", MessageHandlerFunc(
157 func(ctx context.Context, _ uint64, payload json.RawMessage) (any, error) {150 func(ctx context.Context, _ uint64, payload json.RawMessage) (any, error) {
158 var p struct {151 var p struct {
159 Char string `json:"char"`152 Char string `json:"char"`
@@ -171,7 +164,7 @@ func (e *Engine) RegisterAccentHandlers(ctx context.Context, handler port.Accent
171 return err164 return err
172 }165 }
173 166
174- if err := e.messageRouter.RegisterHandler("accent_key_release", MessageHandlerFunc(167+ if err := e.messageRouter.registerInternalHandler("accent_key_release", MessageHandlerFunc(
175 func(ctx context.Context, _ uint64, payload json.RawMessage) (any, error) {168 func(ctx context.Context, _ uint64, payload json.RawMessage) (any, error) {
176 var p struct {169 var p struct {
177 Char string `json:"char"`170 Char string `json:"char"`
M internal/infrastructure/cef/messaging.go +37 -4
@@ -7,9 +7,13 @@ import (
77 "fmt"
88 "sync"
99
10+ "github.com/bnema/dumber/internal/application/port"
1011 "github.com/bnema/dumber/internal/logging"
1112 )
1213
14+// Compile-time check: MessageRouter implements port.WebUIHandlerRouter.
15+var _ port.WebUIHandlerRouter = (*MessageRouter)(nil)
16+
1317 // Message represents a JS -> Go message envelope sent via fetch to /api/message.
1418 type Message struct {
1519 Type string `json:"type"`
@@ -70,7 +74,8 @@ func (r *MessageRouter) SetBaseContext(ctx context.Context) {
7074 }
7175
7276 // RegisterHandler registers a handler for a message type.
73-func (r *MessageRouter) RegisterHandler(msgType string, handler MessageHandler) error {
77+// Satisfies port.WebUIHandlerRouter.
78+func (r *MessageRouter) RegisterHandler(msgType string, handler port.WebUIMessageHandler) error {
7479 if msgType == "" {
7580 return errors.New("message type cannot be empty")
7681 }
@@ -79,14 +84,17 @@ func (r *MessageRouter) RegisterHandler(msgType string, handler MessageHandler)
7984 }
8085 r.mu.Lock()
8186 defer r.mu.Unlock()
82- r.handlers[msgType] = handlerEntry{handler: handler}
87+ r.handlers[msgType] = handlerEntry{handler: portHandlerAdapter{handler}}
8388 return nil
8489 }
8590
8691 // RegisterHandlerWithCallbacks registers a handler with response callback names.
8792 // callback is invoked on success, errorCallback (optional) on failure.
8893 // worldName allows targeting a specific script world (unused in CEF fetch bridge).
89-func (r *MessageRouter) RegisterHandlerWithCallbacks(msgType, callback, errorCallback, worldName string, handler MessageHandler) error {
94+// Satisfies port.WebUIHandlerRouter.
95+func (r *MessageRouter) RegisterHandlerWithCallbacks(
96+ msgType, callback, errorCallback, worldName string, handler port.WebUIMessageHandler,
97+) error {
9098 if msgType == "" {
9199 return errors.New("message type cannot be empty")
92100 }
@@ -99,7 +107,7 @@ func (r *MessageRouter) RegisterHandlerWithCallbacks(msgType, callback, errorCal
99107 r.mu.Lock()
100108 defer r.mu.Unlock()
101109 r.handlers[msgType] = handlerEntry{
102- handler: handler,
110+ handler: portHandlerAdapter{handler},
103111 callback: callback,
104112 errorCallback: errorCallback,
105113 world: worldName,
@@ -107,6 +115,31 @@ func (r *MessageRouter) RegisterHandlerWithCallbacks(msgType, callback, errorCal
107115 return nil
108116 }
109117
118+// registerInternalHandler registers a CEF-internal handler for a message type.
119+// Used for engine-internal handlers that work directly with uint64 webview IDs.
120+func (r *MessageRouter) registerInternalHandler(msgType string, handler MessageHandler) error {
121+ if msgType == "" {
122+ return errors.New("message type cannot be empty")
123+ }
124+ if handler == nil {
125+ return errors.New("message handler cannot be nil")
126+ }
127+ r.mu.Lock()
128+ defer r.mu.Unlock()
129+ r.handlers[msgType] = handlerEntry{handler: handler}
130+ return nil
131+}
132+
133+// portHandlerAdapter wraps a port.WebUIMessageHandler as a cef.MessageHandler,
134+// converting the WebViewID type.
135+type portHandlerAdapter struct {
136+ inner port.WebUIMessageHandler
137+}
138+
139+func (a portHandlerAdapter) Handle(ctx context.Context, webviewID uint64, payload json.RawMessage) (any, error) {
140+ return a.inner.Handle(ctx, port.WebViewID(webviewID), payload)
141+}
142+
110143 // HandleMessage decodes a raw JSON message body and routes it to the correct handler.
111144 // Returns the JSON-encoded response. Called by the scheme handler for /api/message POST.
112145 func (r *MessageRouter) HandleMessage(ctx context.Context, webviewID uint64, body []byte) ([]byte, error) {
@@ -7,9 +7,13 @@ import (
7 "fmt"7 "fmt"
8 "sync"8 "sync"
9 9
10+ "github.com/bnema/dumber/internal/application/port"
10 "github.com/bnema/dumber/internal/logging"11 "github.com/bnema/dumber/internal/logging"
11 )12 )
12 13
14+// Compile-time check: MessageRouter implements port.WebUIHandlerRouter.
15+var _ port.WebUIHandlerRouter = (*MessageRouter)(nil)
16+
13 // Message represents a JS -> Go message envelope sent via fetch to /api/message.17 // Message represents a JS -> Go message envelope sent via fetch to /api/message.
14 type Message struct {18 type Message struct {
15 Type string `json:"type"`19 Type string `json:"type"`
@@ -70,7 +74,8 @@ func (r *MessageRouter) SetBaseContext(ctx context.Context) {
70 }74 }
71 75
72 // RegisterHandler registers a handler for a message type.76 // RegisterHandler registers a handler for a message type.
73-func (r *MessageRouter) RegisterHandler(msgType string, handler MessageHandler) error {77+// Satisfies port.WebUIHandlerRouter.
78+func (r *MessageRouter) RegisterHandler(msgType string, handler port.WebUIMessageHandler) error {
74 if msgType == "" {79 if msgType == "" {
75 return errors.New("message type cannot be empty")80 return errors.New("message type cannot be empty")
76 }81 }
@@ -79,14 +84,17 @@ func (r *MessageRouter) RegisterHandler(msgType string, handler MessageHandler)
79 }84 }
80 r.mu.Lock()85 r.mu.Lock()
81 defer r.mu.Unlock()86 defer r.mu.Unlock()
82- r.handlers[msgType] = handlerEntry{handler: handler}87+ r.handlers[msgType] = handlerEntry{handler: portHandlerAdapter{handler}}
83 return nil88 return nil
84 }89 }
85 90
86 // RegisterHandlerWithCallbacks registers a handler with response callback names.91 // RegisterHandlerWithCallbacks registers a handler with response callback names.
87 // callback is invoked on success, errorCallback (optional) on failure.92 // callback is invoked on success, errorCallback (optional) on failure.
88 // worldName allows targeting a specific script world (unused in CEF fetch bridge).93 // worldName allows targeting a specific script world (unused in CEF fetch bridge).
89-func (r *MessageRouter) RegisterHandlerWithCallbacks(msgType, callback, errorCallback, worldName string, handler MessageHandler) error {94+// Satisfies port.WebUIHandlerRouter.
95+func (r *MessageRouter) RegisterHandlerWithCallbacks(
96+ msgType, callback, errorCallback, worldName string, handler port.WebUIMessageHandler,
97+) error {
90 if msgType == "" {98 if msgType == "" {
91 return errors.New("message type cannot be empty")99 return errors.New("message type cannot be empty")
92 }100 }
@@ -99,7 +107,7 @@ func (r *MessageRouter) RegisterHandlerWithCallbacks(msgType, callback, errorCal
99 r.mu.Lock()107 r.mu.Lock()
100 defer r.mu.Unlock()108 defer r.mu.Unlock()
101 r.handlers[msgType] = handlerEntry{109 r.handlers[msgType] = handlerEntry{
102- handler: handler,110+ handler: portHandlerAdapter{handler},
103 callback: callback,111 callback: callback,
104 errorCallback: errorCallback,112 errorCallback: errorCallback,
105 world: worldName,113 world: worldName,
@@ -107,6 +115,31 @@ func (r *MessageRouter) RegisterHandlerWithCallbacks(msgType, callback, errorCal
107 return nil115 return nil
108 }116 }
109 117
118+// registerInternalHandler registers a CEF-internal handler for a message type.
119+// Used for engine-internal handlers that work directly with uint64 webview IDs.
120+func (r *MessageRouter) registerInternalHandler(msgType string, handler MessageHandler) error {
121+ if msgType == "" {
122+ return errors.New("message type cannot be empty")
123+ }
124+ if handler == nil {
125+ return errors.New("message handler cannot be nil")
126+ }
127+ r.mu.Lock()
128+ defer r.mu.Unlock()
129+ r.handlers[msgType] = handlerEntry{handler: handler}
130+ return nil
131+}
132+
133+// portHandlerAdapter wraps a port.WebUIMessageHandler as a cef.MessageHandler,
134+// converting the WebViewID type.
135+type portHandlerAdapter struct {
136+ inner port.WebUIMessageHandler
137+}
138+
139+func (a portHandlerAdapter) Handle(ctx context.Context, webviewID uint64, payload json.RawMessage) (any, error) {
140+ return a.inner.Handle(ctx, port.WebViewID(webviewID), payload)
141+}
142+
110 // HandleMessage decodes a raw JSON message body and routes it to the correct handler.143 // HandleMessage decodes a raw JSON message body and routes it to the correct handler.
111 // Returns the JSON-encoded response. Called by the scheme handler for /api/message POST.144 // Returns the JSON-encoded response. Called by the scheme handler for /api/message POST.
112 func (r *MessageRouter) HandleMessage(ctx context.Context, webviewID uint64, body []byte) ([]byte, error) {145 func (r *MessageRouter) HandleMessage(ctx context.Context, webviewID uint64, body []byte) ([]byte, error) {
R internal/infrastructure/webkit/handlers/clipboard.go → internal/infrastructure/handlers/clipboard.go +3 -4 renamed, 89% similar
@@ -5,7 +5,6 @@ import (
55 "encoding/json"
66
77 "github.com/bnema/dumber/internal/application/port"
8- "github.com/bnema/dumber/internal/infrastructure/webkit"
98 "github.com/bnema/dumber/internal/logging"
109 )
1110
@@ -32,8 +31,8 @@ type autoCopyRequest struct {
3231
3332 // HandleAutoCopySelection handles the auto_copy_selection message from JS.
3433 // It copies the selected text to the clipboard if the feature is enabled.
35-func (h *ClipboardHandler) HandleAutoCopySelection() webkit.MessageHandler {
36- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
34+func (h *ClipboardHandler) HandleAutoCopySelection() port.WebUIMessageHandler {
35+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
3736 log := logging.FromContext(ctx)
3837
3938 // Check if feature is enabled
@@ -71,7 +70,7 @@ func (h *ClipboardHandler) HandleAutoCopySelection() webkit.MessageHandler {
7170 // RegisterClipboardHandlers registers clipboard handlers with the router.
7271 func RegisterClipboardHandlers(
7372 ctx context.Context,
74- router *webkit.MessageRouter,
73+ router port.WebUIHandlerRouter,
7574 clipboard port.Clipboard,
7675 autoCopyConfig port.AutoCopyConfig,
7776 onCopied func(textLen int),
@@ -5,7 +5,6 @@ import (
5 "encoding/json"5 "encoding/json"
6 6
7 "github.com/bnema/dumber/internal/application/port"7 "github.com/bnema/dumber/internal/application/port"
8- "github.com/bnema/dumber/internal/infrastructure/webkit"
9 "github.com/bnema/dumber/internal/logging"8 "github.com/bnema/dumber/internal/logging"
10 )9 )
11 10
@@ -32,8 +31,8 @@ type autoCopyRequest struct {
32 31
33 // HandleAutoCopySelection handles the auto_copy_selection message from JS.32 // HandleAutoCopySelection handles the auto_copy_selection message from JS.
34 // It copies the selected text to the clipboard if the feature is enabled.33 // It copies the selected text to the clipboard if the feature is enabled.
35-func (h *ClipboardHandler) HandleAutoCopySelection() webkit.MessageHandler {34+func (h *ClipboardHandler) HandleAutoCopySelection() port.WebUIMessageHandler {
36- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {35+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
37 log := logging.FromContext(ctx)36 log := logging.FromContext(ctx)
38 37
39 // Check if feature is enabled38 // Check if feature is enabled
@@ -71,7 +70,7 @@ func (h *ClipboardHandler) HandleAutoCopySelection() webkit.MessageHandler {
71 // RegisterClipboardHandlers registers clipboard handlers with the router.70 // RegisterClipboardHandlers registers clipboard handlers with the router.
72 func RegisterClipboardHandlers(71 func RegisterClipboardHandlers(
73 ctx context.Context,72 ctx context.Context,
74- router *webkit.MessageRouter,73+ router port.WebUIHandlerRouter,
75 clipboard port.Clipboard,74 clipboard port.Clipboard,
76 autoCopyConfig port.AutoCopyConfig,75 autoCopyConfig port.AutoCopyConfig,
77 onCopied func(textLen int),76 onCopied func(textLen int),
R internal/infrastructure/webkit/handlers/config.go → internal/infrastructure/handlers/config.go +2 -3 renamed, 90% similar
@@ -6,7 +6,6 @@ import (
66 "fmt"
77
88 "github.com/bnema/dumber/internal/application/port"
9- "github.com/bnema/dumber/internal/infrastructure/webkit"
109 "github.com/bnema/dumber/internal/logging"
1110 )
1211
@@ -25,7 +24,7 @@ func NewConfigHandler(saveConfig func(context.Context, port.WebUIConfig) error)
2524 }
2625
2726 // Handle processes the save_config message.
28-func (h *ConfigHandler) Handle(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
27+func (h *ConfigHandler) Handle(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
2928 if h == nil {
3029 return nil, fmt.Errorf("config handler is nil")
3130 }
@@ -52,7 +51,7 @@ func (h *ConfigHandler) Handle(ctx context.Context, _ webkit.WebViewID, payload
5251
5352 // RegisterConfigHandlers registers configuration handlers with the router.
5453 func RegisterConfigHandlers(
55- ctx context.Context, router *webkit.MessageRouter,
54+ ctx context.Context, router port.WebUIHandlerRouter,
5655 saveConfig func(context.Context, port.WebUIConfig) error,
5756 ) error {
5857 handler := NewConfigHandler(saveConfig)
@@ -6,7 +6,6 @@ import (
6 "fmt"6 "fmt"
7 7
8 "github.com/bnema/dumber/internal/application/port"8 "github.com/bnema/dumber/internal/application/port"
9- "github.com/bnema/dumber/internal/infrastructure/webkit"
10 "github.com/bnema/dumber/internal/logging"9 "github.com/bnema/dumber/internal/logging"
11 )10 )
12 11
@@ -25,7 +24,7 @@ func NewConfigHandler(saveConfig func(context.Context, port.WebUIConfig) error)
25 }24 }
26 25
27 // Handle processes the save_config message.26 // Handle processes the save_config message.
28-func (h *ConfigHandler) Handle(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {27+func (h *ConfigHandler) Handle(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
29 if h == nil {28 if h == nil {
30 return nil, fmt.Errorf("config handler is nil")29 return nil, fmt.Errorf("config handler is nil")
31 }30 }
@@ -52,7 +51,7 @@ func (h *ConfigHandler) Handle(ctx context.Context, _ webkit.WebViewID, payload
52 51
53 // RegisterConfigHandlers registers configuration handlers with the router.52 // RegisterConfigHandlers registers configuration handlers with the router.
54 func RegisterConfigHandlers(53 func RegisterConfigHandlers(
55- ctx context.Context, router *webkit.MessageRouter,54+ ctx context.Context, router port.WebUIHandlerRouter,
56 saveConfig func(context.Context, port.WebUIConfig) error,55 saveConfig func(context.Context, port.WebUIConfig) error,
57 ) error {56 ) error {
58 handler := NewConfigHandler(saveConfig)57 handler := NewConfigHandler(saveConfig)
R internal/infrastructure/webkit/handlers/homepage/favorites.go → internal/infrastructure/handlers/homepage/favorites.go +8 -9 renamed, 80% similar
@@ -6,7 +6,6 @@ import (
66
77 "github.com/bnema/dumber/internal/application/port"
88 "github.com/bnema/dumber/internal/domain/entity"
9- "github.com/bnema/dumber/internal/infrastructure/webkit"
109 "github.com/bnema/dumber/internal/logging"
1110 )
1211
@@ -21,8 +20,8 @@ func NewFavoritesHandlers(favoritesUC port.HomepageFavorites) *FavoritesHandlers
2120 }
2221
2322 // HandleList handles favorite_list messages.
24-func (h *FavoritesHandlers) HandleList() webkit.MessageHandler {
25- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
23+func (h *FavoritesHandlers) HandleList() port.WebUIMessageHandler {
24+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
2625 log := logging.FromContext(ctx)
2726
2827 requestID := ParseRequestID(payload)
@@ -48,8 +47,8 @@ type setShortcutRequest struct {
4847 }
4948
5049 // HandleSetShortcut handles favorite_set_shortcut messages.
51-func (h *FavoritesHandlers) HandleSetShortcut() webkit.MessageHandler {
52- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
50+func (h *FavoritesHandlers) HandleSetShortcut() port.WebUIMessageHandler {
51+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
5352 log := logging.FromContext(ctx)
5453
5554 var req setShortcutRequest
@@ -77,8 +76,8 @@ type getByShortcutRequest struct {
7776 }
7877
7978 // HandleGetByShortcut handles favorite_get_by_shortcut messages.
80-func (h *FavoritesHandlers) HandleGetByShortcut() webkit.MessageHandler {
81- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
79+func (h *FavoritesHandlers) HandleGetByShortcut() port.WebUIMessageHandler {
80+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
8281 log := logging.FromContext(ctx)
8382
8483 var req getByShortcutRequest
@@ -108,8 +107,8 @@ type setFolderRequest struct {
108107 }
109108
110109 // HandleSetFolder handles favorite_set_folder messages.
111-func (h *FavoritesHandlers) HandleSetFolder() webkit.MessageHandler {
112- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
110+func (h *FavoritesHandlers) HandleSetFolder() port.WebUIMessageHandler {
111+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
113112 log := logging.FromContext(ctx)
114113
115114 var req setFolderRequest
@@ -6,7 +6,6 @@ import (
6 6
7 "github.com/bnema/dumber/internal/application/port"7 "github.com/bnema/dumber/internal/application/port"
8 "github.com/bnema/dumber/internal/domain/entity"8 "github.com/bnema/dumber/internal/domain/entity"
9- "github.com/bnema/dumber/internal/infrastructure/webkit"
10 "github.com/bnema/dumber/internal/logging"9 "github.com/bnema/dumber/internal/logging"
11 )10 )
12 11
@@ -21,8 +20,8 @@ func NewFavoritesHandlers(favoritesUC port.HomepageFavorites) *FavoritesHandlers
21 }20 }
22 21
23 // HandleList handles favorite_list messages.22 // HandleList handles favorite_list messages.
24-func (h *FavoritesHandlers) HandleList() webkit.MessageHandler {23+func (h *FavoritesHandlers) HandleList() port.WebUIMessageHandler {
25- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {24+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
26 log := logging.FromContext(ctx)25 log := logging.FromContext(ctx)
27 26
28 requestID := ParseRequestID(payload)27 requestID := ParseRequestID(payload)
@@ -48,8 +47,8 @@ type setShortcutRequest struct {
48 }47 }
49 48
50 // HandleSetShortcut handles favorite_set_shortcut messages.49 // HandleSetShortcut handles favorite_set_shortcut messages.
51-func (h *FavoritesHandlers) HandleSetShortcut() webkit.MessageHandler {50+func (h *FavoritesHandlers) HandleSetShortcut() port.WebUIMessageHandler {
52- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {51+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
53 log := logging.FromContext(ctx)52 log := logging.FromContext(ctx)
54 53
55 var req setShortcutRequest54 var req setShortcutRequest
@@ -77,8 +76,8 @@ type getByShortcutRequest struct {
77 }76 }
78 77
79 // HandleGetByShortcut handles favorite_get_by_shortcut messages.78 // HandleGetByShortcut handles favorite_get_by_shortcut messages.
80-func (h *FavoritesHandlers) HandleGetByShortcut() webkit.MessageHandler {79+func (h *FavoritesHandlers) HandleGetByShortcut() port.WebUIMessageHandler {
81- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {80+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
82 log := logging.FromContext(ctx)81 log := logging.FromContext(ctx)
83 82
84 var req getByShortcutRequest83 var req getByShortcutRequest
@@ -108,8 +107,8 @@ type setFolderRequest struct {
108 }107 }
109 108
110 // HandleSetFolder handles favorite_set_folder messages.109 // HandleSetFolder handles favorite_set_folder messages.
111-func (h *FavoritesHandlers) HandleSetFolder() webkit.MessageHandler {110+func (h *FavoritesHandlers) HandleSetFolder() port.WebUIMessageHandler {
112- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {111+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
113 log := logging.FromContext(ctx)112 log := logging.FromContext(ctx)
114 113
115 var req setFolderRequest114 var req setFolderRequest
R internal/infrastructure/webkit/handlers/homepage/folders.go → internal/infrastructure/handlers/homepage/folders.go +8 -9 renamed, 81% similar
@@ -6,7 +6,6 @@ import (
66
77 "github.com/bnema/dumber/internal/application/port"
88 "github.com/bnema/dumber/internal/domain/entity"
9- "github.com/bnema/dumber/internal/infrastructure/webkit"
109 "github.com/bnema/dumber/internal/logging"
1110 )
1211
@@ -21,8 +20,8 @@ func NewFolderHandlers(favoritesUC port.HomepageFavorites) *FolderHandlers {
2120 }
2221
2322 // HandleList handles folder_list messages.
24-func (h *FolderHandlers) HandleList() webkit.MessageHandler {
25- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
23+func (h *FolderHandlers) HandleList() port.WebUIMessageHandler {
24+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
2625 log := logging.FromContext(ctx)
2726
2827 requestID := ParseRequestID(payload)
@@ -48,8 +47,8 @@ type createFolderRequest struct {
4847 }
4948
5049 // HandleCreate handles folder_create messages.
51-func (h *FolderHandlers) HandleCreate() webkit.MessageHandler {
52- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
50+func (h *FolderHandlers) HandleCreate() port.WebUIMessageHandler {
51+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
5352 log := logging.FromContext(ctx)
5453
5554 var req createFolderRequest
@@ -86,8 +85,8 @@ type deleteFolderRequest struct {
8685 }
8786
8887 // HandleDelete handles folder_delete messages.
89-func (h *FolderHandlers) HandleDelete() webkit.MessageHandler {
90- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
88+func (h *FolderHandlers) HandleDelete() port.WebUIMessageHandler {
89+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
9190 log := logging.FromContext(ctx)
9291
9392 var req deleteFolderRequest
@@ -118,8 +117,8 @@ type updateFolderRequest struct {
118117
119118 // HandleUpdate handles folder_update messages.
120119 // It delegates to the port.HomepageFavorites interface's UpdateFolder method.
121-func (h *FolderHandlers) HandleUpdate() webkit.MessageHandler {
122- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
120+func (h *FolderHandlers) HandleUpdate() port.WebUIMessageHandler {
121+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
123122 log := logging.FromContext(ctx)
124123
125124 var req updateFolderRequest
@@ -6,7 +6,6 @@ import (
6 6
7 "github.com/bnema/dumber/internal/application/port"7 "github.com/bnema/dumber/internal/application/port"
8 "github.com/bnema/dumber/internal/domain/entity"8 "github.com/bnema/dumber/internal/domain/entity"
9- "github.com/bnema/dumber/internal/infrastructure/webkit"
10 "github.com/bnema/dumber/internal/logging"9 "github.com/bnema/dumber/internal/logging"
11 )10 )
12 11
@@ -21,8 +20,8 @@ func NewFolderHandlers(favoritesUC port.HomepageFavorites) *FolderHandlers {
21 }20 }
22 21
23 // HandleList handles folder_list messages.22 // HandleList handles folder_list messages.
24-func (h *FolderHandlers) HandleList() webkit.MessageHandler {23+func (h *FolderHandlers) HandleList() port.WebUIMessageHandler {
25- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {24+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
26 log := logging.FromContext(ctx)25 log := logging.FromContext(ctx)
27 26
28 requestID := ParseRequestID(payload)27 requestID := ParseRequestID(payload)
@@ -48,8 +47,8 @@ type createFolderRequest struct {
48 }47 }
49 48
50 // HandleCreate handles folder_create messages.49 // HandleCreate handles folder_create messages.
51-func (h *FolderHandlers) HandleCreate() webkit.MessageHandler {50+func (h *FolderHandlers) HandleCreate() port.WebUIMessageHandler {
52- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {51+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
53 log := logging.FromContext(ctx)52 log := logging.FromContext(ctx)
54 53
55 var req createFolderRequest54 var req createFolderRequest
@@ -86,8 +85,8 @@ type deleteFolderRequest struct {
86 }85 }
87 86
88 // HandleDelete handles folder_delete messages.87 // HandleDelete handles folder_delete messages.
89-func (h *FolderHandlers) HandleDelete() webkit.MessageHandler {88+func (h *FolderHandlers) HandleDelete() port.WebUIMessageHandler {
90- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {89+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
91 log := logging.FromContext(ctx)90 log := logging.FromContext(ctx)
92 91
93 var req deleteFolderRequest92 var req deleteFolderRequest
@@ -118,8 +117,8 @@ type updateFolderRequest struct {
118 117
119 // HandleUpdate handles folder_update messages.118 // HandleUpdate handles folder_update messages.
120 // It delegates to the port.HomepageFavorites interface's UpdateFolder method.119 // It delegates to the port.HomepageFavorites interface's UpdateFolder method.
121-func (h *FolderHandlers) HandleUpdate() webkit.MessageHandler {120+func (h *FolderHandlers) HandleUpdate() port.WebUIMessageHandler {
122- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {121+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
123 log := logging.FromContext(ctx)122 log := logging.FromContext(ctx)
124 123
125 var req updateFolderRequest124 var req updateFolderRequest
R internal/infrastructure/webkit/handlers/homepage/history.go → internal/infrastructure/handlers/homepage/history.go +16 -17 renamed, 81% similar
@@ -7,7 +7,6 @@ import (
77
88 "github.com/bnema/dumber/internal/application/port"
99 "github.com/bnema/dumber/internal/domain/entity"
10- "github.com/bnema/dumber/internal/infrastructure/webkit"
1110 "github.com/bnema/dumber/internal/logging"
1211 )
1312
@@ -29,8 +28,8 @@ type timelineRequest struct {
2928 }
3029
3130 // HandleTimeline handles history_timeline messages.
32-func (h *HistoryHandlers) HandleTimeline() webkit.MessageHandler {
33- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
31+func (h *HistoryHandlers) HandleTimeline() port.WebUIMessageHandler {
32+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
3433 log := logging.FromContext(ctx)
3534
3635 var req timelineRequest
@@ -61,8 +60,8 @@ type searchRequest struct {
6160 }
6261
6362 // HandleSearchFTS handles history_search_fts messages.
64-func (h *HistoryHandlers) HandleSearchFTS() webkit.MessageHandler {
65- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
63+func (h *HistoryHandlers) HandleSearchFTS() port.WebUIMessageHandler {
64+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
6665 log := logging.FromContext(ctx)
6766
6867 var req searchRequest
@@ -100,8 +99,8 @@ type deleteEntryRequest struct {
10099 }
101100
102101 // HandleDeleteEntry handles history_delete_entry messages.
103-func (h *HistoryHandlers) HandleDeleteEntry() webkit.MessageHandler {
104- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
102+func (h *HistoryHandlers) HandleDeleteEntry() port.WebUIMessageHandler {
103+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
105104 log := logging.FromContext(ctx)
106105
107106 var req deleteEntryRequest
@@ -129,8 +128,8 @@ type deleteRangeRequest struct {
129128 }
130129
131130 // HandleDeleteRange handles history_delete_range messages.
132-func (h *HistoryHandlers) HandleDeleteRange() webkit.MessageHandler {
133- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
131+func (h *HistoryHandlers) HandleDeleteRange() port.WebUIMessageHandler {
132+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
134133 log := logging.FromContext(ctx)
135134
136135 var req deleteRangeRequest
@@ -160,8 +159,8 @@ func (h *HistoryHandlers) HandleDeleteRange() webkit.MessageHandler {
160159 }
161160
162161 // HandleClearAll handles history_clear_all messages.
163-func (h *HistoryHandlers) HandleClearAll() webkit.MessageHandler {
164- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
162+func (h *HistoryHandlers) HandleClearAll() port.WebUIMessageHandler {
163+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
165164 log := logging.FromContext(ctx)
166165
167166 requestID := ParseRequestID(payload)
@@ -199,8 +198,8 @@ func rangeToTime(r string) time.Time {
199198 }
200199
201200 // HandleAnalytics handles history_analytics messages.
202-func (h *HistoryHandlers) HandleAnalytics() webkit.MessageHandler {
203- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
201+func (h *HistoryHandlers) HandleAnalytics() port.WebUIMessageHandler {
202+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
204203 log := logging.FromContext(ctx)
205204
206205 requestID := ParseRequestID(payload)
@@ -225,8 +224,8 @@ type domainStatsRequest struct {
225224 }
226225
227226 // HandleDomainStats handles history_domain_stats messages.
228-func (h *HistoryHandlers) HandleDomainStats() webkit.MessageHandler {
229- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
227+func (h *HistoryHandlers) HandleDomainStats() port.WebUIMessageHandler {
228+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
230229 log := logging.FromContext(ctx)
231230
232231 var req domainStatsRequest
@@ -255,8 +254,8 @@ type deleteDomainRequest struct {
255254 }
256255
257256 // HandleDeleteDomain handles history_delete_domain messages.
258-func (h *HistoryHandlers) HandleDeleteDomain() webkit.MessageHandler {
259- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
257+func (h *HistoryHandlers) HandleDeleteDomain() port.WebUIMessageHandler {
258+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
260259 log := logging.FromContext(ctx)
261260
262261 var req deleteDomainRequest
@@ -7,7 +7,6 @@ import (
7 7
8 "github.com/bnema/dumber/internal/application/port"8 "github.com/bnema/dumber/internal/application/port"
9 "github.com/bnema/dumber/internal/domain/entity"9 "github.com/bnema/dumber/internal/domain/entity"
10- "github.com/bnema/dumber/internal/infrastructure/webkit"
11 "github.com/bnema/dumber/internal/logging"10 "github.com/bnema/dumber/internal/logging"
12 )11 )
13 12
@@ -29,8 +28,8 @@ type timelineRequest struct {
29 }28 }
30 29
31 // HandleTimeline handles history_timeline messages.30 // HandleTimeline handles history_timeline messages.
32-func (h *HistoryHandlers) HandleTimeline() webkit.MessageHandler {31+func (h *HistoryHandlers) HandleTimeline() port.WebUIMessageHandler {
33- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {32+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
34 log := logging.FromContext(ctx)33 log := logging.FromContext(ctx)
35 34
36 var req timelineRequest35 var req timelineRequest
@@ -61,8 +60,8 @@ type searchRequest struct {
61 }60 }
62 61
63 // HandleSearchFTS handles history_search_fts messages.62 // HandleSearchFTS handles history_search_fts messages.
64-func (h *HistoryHandlers) HandleSearchFTS() webkit.MessageHandler {63+func (h *HistoryHandlers) HandleSearchFTS() port.WebUIMessageHandler {
65- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {64+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
66 log := logging.FromContext(ctx)65 log := logging.FromContext(ctx)
67 66
68 var req searchRequest67 var req searchRequest
@@ -100,8 +99,8 @@ type deleteEntryRequest struct {
100 }99 }
101 100
102 // HandleDeleteEntry handles history_delete_entry messages.101 // HandleDeleteEntry handles history_delete_entry messages.
103-func (h *HistoryHandlers) HandleDeleteEntry() webkit.MessageHandler {102+func (h *HistoryHandlers) HandleDeleteEntry() port.WebUIMessageHandler {
104- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {103+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
105 log := logging.FromContext(ctx)104 log := logging.FromContext(ctx)
106 105
107 var req deleteEntryRequest106 var req deleteEntryRequest
@@ -129,8 +128,8 @@ type deleteRangeRequest struct {
129 }128 }
130 129
131 // HandleDeleteRange handles history_delete_range messages.130 // HandleDeleteRange handles history_delete_range messages.
132-func (h *HistoryHandlers) HandleDeleteRange() webkit.MessageHandler {131+func (h *HistoryHandlers) HandleDeleteRange() port.WebUIMessageHandler {
133- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {132+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
134 log := logging.FromContext(ctx)133 log := logging.FromContext(ctx)
135 134
136 var req deleteRangeRequest135 var req deleteRangeRequest
@@ -160,8 +159,8 @@ func (h *HistoryHandlers) HandleDeleteRange() webkit.MessageHandler {
160 }159 }
161 160
162 // HandleClearAll handles history_clear_all messages.161 // HandleClearAll handles history_clear_all messages.
163-func (h *HistoryHandlers) HandleClearAll() webkit.MessageHandler {162+func (h *HistoryHandlers) HandleClearAll() port.WebUIMessageHandler {
164- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {163+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
165 log := logging.FromContext(ctx)164 log := logging.FromContext(ctx)
166 165
167 requestID := ParseRequestID(payload)166 requestID := ParseRequestID(payload)
@@ -199,8 +198,8 @@ func rangeToTime(r string) time.Time {
199 }198 }
200 199
201 // HandleAnalytics handles history_analytics messages.200 // HandleAnalytics handles history_analytics messages.
202-func (h *HistoryHandlers) HandleAnalytics() webkit.MessageHandler {201+func (h *HistoryHandlers) HandleAnalytics() port.WebUIMessageHandler {
203- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {202+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
204 log := logging.FromContext(ctx)203 log := logging.FromContext(ctx)
205 204
206 requestID := ParseRequestID(payload)205 requestID := ParseRequestID(payload)
@@ -225,8 +224,8 @@ type domainStatsRequest struct {
225 }224 }
226 225
227 // HandleDomainStats handles history_domain_stats messages.226 // HandleDomainStats handles history_domain_stats messages.
228-func (h *HistoryHandlers) HandleDomainStats() webkit.MessageHandler {227+func (h *HistoryHandlers) HandleDomainStats() port.WebUIMessageHandler {
229- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {228+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
230 log := logging.FromContext(ctx)229 log := logging.FromContext(ctx)
231 230
232 var req domainStatsRequest231 var req domainStatsRequest
@@ -255,8 +254,8 @@ type deleteDomainRequest struct {
255 }254 }
256 255
257 // HandleDeleteDomain handles history_delete_domain messages.256 // HandleDeleteDomain handles history_delete_domain messages.
258-func (h *HistoryHandlers) HandleDeleteDomain() webkit.MessageHandler {257+func (h *HistoryHandlers) HandleDeleteDomain() port.WebUIMessageHandler {
259- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {258+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
260 log := logging.FromContext(ctx)259 log := logging.FromContext(ctx)
261 260
262 var req deleteDomainRequest261 var req deleteDomainRequest
R internal/infrastructure/webkit/handlers/homepage/registry.go → internal/infrastructure/handlers/homepage/registry.go +2 -3 renamed, 93% similar
@@ -5,7 +5,6 @@ import (
55 "fmt"
66
77 "github.com/bnema/dumber/internal/application/port"
8- "github.com/bnema/dumber/internal/infrastructure/webkit"
98 "github.com/bnema/dumber/internal/logging"
109 )
1110
@@ -16,7 +15,7 @@ type Config struct {
1615 }
1716
1817 // RegisterHandlers registers all homepage message handlers with the router.
19-func RegisterHandlers(ctx context.Context, router *webkit.MessageRouter, cfg Config) error {
18+func RegisterHandlers(ctx context.Context, router port.WebUIHandlerRouter, cfg Config) error {
2019 log := logging.FromContext(ctx)
2120 log.Debug().Msg("registering homepage message handlers")
2221
@@ -25,7 +24,7 @@ func RegisterHandlers(ctx context.Context, router *webkit.MessageRouter, cfg Con
2524 const errorCallback = "__dumber_error"
2625 const worldName = "" // main world
2726
28- handlers := make(map[string]webkit.MessageHandler)
27+ handlers := make(map[string]port.WebUIMessageHandler)
2928
3029 // History handlers
3130 historyHandlers := NewHistoryHandlers(cfg.HistoryUC)
@@ -5,7 +5,6 @@ import (
5 "fmt"5 "fmt"
6 6
7 "github.com/bnema/dumber/internal/application/port"7 "github.com/bnema/dumber/internal/application/port"
8- "github.com/bnema/dumber/internal/infrastructure/webkit"
9 "github.com/bnema/dumber/internal/logging"8 "github.com/bnema/dumber/internal/logging"
10 )9 )
11 10
@@ -16,7 +15,7 @@ type Config struct {
16 }15 }
17 16
18 // RegisterHandlers registers all homepage message handlers with the router.17 // RegisterHandlers registers all homepage message handlers with the router.
19-func RegisterHandlers(ctx context.Context, router *webkit.MessageRouter, cfg Config) error {18+func RegisterHandlers(ctx context.Context, router port.WebUIHandlerRouter, cfg Config) error {
20 log := logging.FromContext(ctx)19 log := logging.FromContext(ctx)
21 log.Debug().Msg("registering homepage message handlers")20 log.Debug().Msg("registering homepage message handlers")
22 21
@@ -25,7 +24,7 @@ func RegisterHandlers(ctx context.Context, router *webkit.MessageRouter, cfg Con
25 const errorCallback = "__dumber_error"24 const errorCallback = "__dumber_error"
26 const worldName = "" // main world25 const worldName = "" // main world
27 26
28- handlers := make(map[string]webkit.MessageHandler)27+ handlers := make(map[string]port.WebUIMessageHandler)
29 28
30 // History handlers29 // History handlers
31 historyHandlers := NewHistoryHandlers(cfg.HistoryUC)30 historyHandlers := NewHistoryHandlers(cfg.HistoryUC)
R internal/infrastructure/webkit/handlers/homepage/response.go → internal/infrastructure/handlers/homepage/response.go +0 -0 renamed, 100% similar

renamed, 100% similar

R internal/infrastructure/webkit/handlers/homepage/tags.go → internal/infrastructure/handlers/homepage/tags.go +12 -13 renamed, 79% similar
@@ -6,7 +6,6 @@ import (
66
77 "github.com/bnema/dumber/internal/application/port"
88 "github.com/bnema/dumber/internal/domain/entity"
9- "github.com/bnema/dumber/internal/infrastructure/webkit"
109 "github.com/bnema/dumber/internal/logging"
1110 )
1211
@@ -21,8 +20,8 @@ func NewTagHandlers(favoritesUC port.HomepageFavorites) *TagHandlers {
2120 }
2221
2322 // HandleList handles tag_list messages.
24-func (h *TagHandlers) HandleList() webkit.MessageHandler {
25- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
23+func (h *TagHandlers) HandleList() port.WebUIMessageHandler {
24+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
2625 log := logging.FromContext(ctx)
2726
2827 requestID := ParseRequestID(payload)
@@ -48,8 +47,8 @@ type createTagRequest struct {
4847 }
4948
5049 // HandleCreate handles tag_create messages.
51-func (h *TagHandlers) HandleCreate() webkit.MessageHandler {
52- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
50+func (h *TagHandlers) HandleCreate() port.WebUIMessageHandler {
51+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
5352 log := logging.FromContext(ctx)
5453
5554 var req createTagRequest
@@ -83,8 +82,8 @@ type deleteTagRequest struct {
8382 }
8483
8584 // HandleDelete handles tag_delete messages.
86-func (h *TagHandlers) HandleDelete() webkit.MessageHandler {
87- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
85+func (h *TagHandlers) HandleDelete() port.WebUIMessageHandler {
86+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
8887 log := logging.FromContext(ctx)
8988
9089 var req deleteTagRequest
@@ -115,8 +114,8 @@ type updateTagRequest struct {
115114
116115 // HandleUpdate handles tag_update messages.
117116 // NOTE: This requires UpdateTag() method to be added to ManageFavoritesUseCase.
118-func (h *TagHandlers) HandleUpdate() webkit.MessageHandler {
119- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
117+func (h *TagHandlers) HandleUpdate() port.WebUIMessageHandler {
118+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
120119 log := logging.FromContext(ctx)
121120
122121 var req updateTagRequest
@@ -154,17 +153,17 @@ type tagAssignRequest struct {
154153 }
155154
156155 // HandleAssign handles tag_assign messages.
157-func (h *TagHandlers) HandleAssign() webkit.MessageHandler {
156+func (h *TagHandlers) HandleAssign() port.WebUIMessageHandler {
158157 return handleTagAssign("tag_assign", h.favoritesUC.TagFavorite)
159158 }
160159
161160 // HandleRemove handles tag_remove messages.
162-func (h *TagHandlers) HandleRemove() webkit.MessageHandler {
161+func (h *TagHandlers) HandleRemove() port.WebUIMessageHandler {
163162 return handleTagAssign("tag_remove", h.favoritesUC.UntagFavorite)
164163 }
165164
166-func handleTagAssign(action string, op func(context.Context, entity.FavoriteID, entity.TagID) error) webkit.MessageHandler {
167- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
165+func handleTagAssign(action string, op func(context.Context, entity.FavoriteID, entity.TagID) error) port.WebUIMessageHandler {
166+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
168167 log := logging.FromContext(ctx)
169168
170169 var req tagAssignRequest
@@ -6,7 +6,6 @@ import (
6 6
7 "github.com/bnema/dumber/internal/application/port"7 "github.com/bnema/dumber/internal/application/port"
8 "github.com/bnema/dumber/internal/domain/entity"8 "github.com/bnema/dumber/internal/domain/entity"
9- "github.com/bnema/dumber/internal/infrastructure/webkit"
10 "github.com/bnema/dumber/internal/logging"9 "github.com/bnema/dumber/internal/logging"
11 )10 )
12 11
@@ -21,8 +20,8 @@ func NewTagHandlers(favoritesUC port.HomepageFavorites) *TagHandlers {
21 }20 }
22 21
23 // HandleList handles tag_list messages.22 // HandleList handles tag_list messages.
24-func (h *TagHandlers) HandleList() webkit.MessageHandler {23+func (h *TagHandlers) HandleList() port.WebUIMessageHandler {
25- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {24+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
26 log := logging.FromContext(ctx)25 log := logging.FromContext(ctx)
27 26
28 requestID := ParseRequestID(payload)27 requestID := ParseRequestID(payload)
@@ -48,8 +47,8 @@ type createTagRequest struct {
48 }47 }
49 48
50 // HandleCreate handles tag_create messages.49 // HandleCreate handles tag_create messages.
51-func (h *TagHandlers) HandleCreate() webkit.MessageHandler {50+func (h *TagHandlers) HandleCreate() port.WebUIMessageHandler {
52- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {51+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
53 log := logging.FromContext(ctx)52 log := logging.FromContext(ctx)
54 53
55 var req createTagRequest54 var req createTagRequest
@@ -83,8 +82,8 @@ type deleteTagRequest struct {
83 }82 }
84 83
85 // HandleDelete handles tag_delete messages.84 // HandleDelete handles tag_delete messages.
86-func (h *TagHandlers) HandleDelete() webkit.MessageHandler {85+func (h *TagHandlers) HandleDelete() port.WebUIMessageHandler {
87- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {86+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
88 log := logging.FromContext(ctx)87 log := logging.FromContext(ctx)
89 88
90 var req deleteTagRequest89 var req deleteTagRequest
@@ -115,8 +114,8 @@ type updateTagRequest struct {
115 114
116 // HandleUpdate handles tag_update messages.115 // HandleUpdate handles tag_update messages.
117 // NOTE: This requires UpdateTag() method to be added to ManageFavoritesUseCase.116 // NOTE: This requires UpdateTag() method to be added to ManageFavoritesUseCase.
118-func (h *TagHandlers) HandleUpdate() webkit.MessageHandler {117+func (h *TagHandlers) HandleUpdate() port.WebUIMessageHandler {
119- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {118+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
120 log := logging.FromContext(ctx)119 log := logging.FromContext(ctx)
121 120
122 var req updateTagRequest121 var req updateTagRequest
@@ -154,17 +153,17 @@ type tagAssignRequest struct {
154 }153 }
155 154
156 // HandleAssign handles tag_assign messages.155 // HandleAssign handles tag_assign messages.
157-func (h *TagHandlers) HandleAssign() webkit.MessageHandler {156+func (h *TagHandlers) HandleAssign() port.WebUIMessageHandler {
158 return handleTagAssign("tag_assign", h.favoritesUC.TagFavorite)157 return handleTagAssign("tag_assign", h.favoritesUC.TagFavorite)
159 }158 }
160 159
161 // HandleRemove handles tag_remove messages.160 // HandleRemove handles tag_remove messages.
162-func (h *TagHandlers) HandleRemove() webkit.MessageHandler {161+func (h *TagHandlers) HandleRemove() port.WebUIMessageHandler {
163 return handleTagAssign("tag_remove", h.favoritesUC.UntagFavorite)162 return handleTagAssign("tag_remove", h.favoritesUC.UntagFavorite)
164 }163 }
165 164
166-func handleTagAssign(action string, op func(context.Context, entity.FavoriteID, entity.TagID) error) webkit.MessageHandler {165+func handleTagAssign(action string, op func(context.Context, entity.FavoriteID, entity.TagID) error) port.WebUIMessageHandler {
167- return webkit.MessageHandlerFunc(func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {166+ return port.WebUIMessageHandlerFunc(func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
168 log := logging.FromContext(ctx)167 log := logging.FromContext(ctx)
169 168
170 var req tagAssignRequest169 var req tagAssignRequest
R internal/infrastructure/webkit/handlers/keybindings.go → internal/infrastructure/handlers/keybindings.go +9 -10 renamed, 84% similar
@@ -6,7 +6,6 @@ import (
66 "fmt"
77
88 "github.com/bnema/dumber/internal/application/port"
9- "github.com/bnema/dumber/internal/infrastructure/webkit"
109 "github.com/bnema/dumber/internal/logging"
1110 )
1211
@@ -34,12 +33,12 @@ func NewKeybindingsHandler(
3433 }
3534
3635 // HandleGetKeybindings returns all keybindings grouped by mode.
37-func (h *KeybindingsHandler) HandleGetKeybindings(ctx context.Context, _ webkit.WebViewID, _ json.RawMessage) (any, error) {
36+func (h *KeybindingsHandler) HandleGetKeybindings(ctx context.Context, _ port.WebViewID, _ json.RawMessage) (any, error) {
3837 return h.getUC.Execute(ctx)
3938 }
4039
4140 // HandleSetKeybinding updates a single keybinding.
42-func (h *KeybindingsHandler) HandleSetKeybinding(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
41+func (h *KeybindingsHandler) HandleSetKeybinding(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
4342 log := logging.FromContext(ctx).With().Str("handler", "keybindings").Logger()
4443 log.Debug().RawJSON("payload", payload).Msg("HandleSetKeybinding called")
4544
@@ -61,7 +60,7 @@ func (h *KeybindingsHandler) HandleSetKeybinding(ctx context.Context, _ webkit.W
6160 }
6261
6362 // HandleResetKeybinding resets a keybinding to default.
64-func (h *KeybindingsHandler) HandleResetKeybinding(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
63+func (h *KeybindingsHandler) HandleResetKeybinding(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
6564 log := logging.FromContext(ctx).With().Str("handler", "keybindings").Logger()
6665
6766 var req port.ResetKeybindingRequest
@@ -79,7 +78,7 @@ func (h *KeybindingsHandler) HandleResetKeybinding(ctx context.Context, _ webkit
7978 }
8079
8180 // HandleResetAllKeybindings resets all keybindings to defaults.
82-func (h *KeybindingsHandler) HandleResetAllKeybindings(ctx context.Context, _ webkit.WebViewID, _ json.RawMessage) (any, error) {
81+func (h *KeybindingsHandler) HandleResetAllKeybindings(ctx context.Context, _ port.WebViewID, _ json.RawMessage) (any, error) {
8382 log := logging.FromContext(ctx).With().Str("handler", "keybindings").Logger()
8483 log.Info().Msg("resetting all keybindings to defaults")
8584
@@ -91,7 +90,7 @@ func (h *KeybindingsHandler) HandleResetAllKeybindings(ctx context.Context, _ we
9190 }
9291
9392 // RegisterKeybindingsHandlers registers keybindings handlers with the router.
94-func RegisterKeybindingsHandlers(ctx context.Context, router *webkit.MessageRouter, handler *KeybindingsHandler) error {
93+func RegisterKeybindingsHandlers(ctx context.Context, router port.WebUIHandlerRouter, handler *KeybindingsHandler) error {
9594 log := logging.FromContext(ctx).With().Str("component", "handlers").Logger()
9695
9796 // Get all keybindings
@@ -100,7 +99,7 @@ func RegisterKeybindingsHandlers(ctx context.Context, router *webkit.MessageRout
10099 "__dumber_keybindings_loaded",
101100 "__dumber_keybindings_error",
102101 "",
103- webkit.MessageHandlerFunc(handler.HandleGetKeybindings),
102+ port.WebUIMessageHandlerFunc(handler.HandleGetKeybindings),
104103 ); err != nil {
105104 return err
106105 }
@@ -111,7 +110,7 @@ func RegisterKeybindingsHandlers(ctx context.Context, router *webkit.MessageRout
111110 "__dumber_keybinding_set",
112111 "__dumber_keybinding_set_error",
113112 "",
114- webkit.MessageHandlerFunc(handler.HandleSetKeybinding),
113+ port.WebUIMessageHandlerFunc(handler.HandleSetKeybinding),
115114 ); err != nil {
116115 return err
117116 }
@@ -122,7 +121,7 @@ func RegisterKeybindingsHandlers(ctx context.Context, router *webkit.MessageRout
122121 "__dumber_keybinding_reset",
123122 "__dumber_keybinding_reset_error",
124123 "",
125- webkit.MessageHandlerFunc(handler.HandleResetKeybinding),
124+ port.WebUIMessageHandlerFunc(handler.HandleResetKeybinding),
126125 ); err != nil {
127126 return err
128127 }
@@ -133,7 +132,7 @@ func RegisterKeybindingsHandlers(ctx context.Context, router *webkit.MessageRout
133132 "__dumber_keybindings_reset_all",
134133 "__dumber_keybindings_reset_all_error",
135134 "",
136- webkit.MessageHandlerFunc(handler.HandleResetAllKeybindings),
135+ port.WebUIMessageHandlerFunc(handler.HandleResetAllKeybindings),
137136 ); err != nil {
138137 return err
139138 }
@@ -6,7 +6,6 @@ import (
6 "fmt"6 "fmt"
7 7
8 "github.com/bnema/dumber/internal/application/port"8 "github.com/bnema/dumber/internal/application/port"
9- "github.com/bnema/dumber/internal/infrastructure/webkit"
10 "github.com/bnema/dumber/internal/logging"9 "github.com/bnema/dumber/internal/logging"
11 )10 )
12 11
@@ -34,12 +33,12 @@ func NewKeybindingsHandler(
34 }33 }
35 34
36 // HandleGetKeybindings returns all keybindings grouped by mode.35 // HandleGetKeybindings returns all keybindings grouped by mode.
37-func (h *KeybindingsHandler) HandleGetKeybindings(ctx context.Context, _ webkit.WebViewID, _ json.RawMessage) (any, error) {36+func (h *KeybindingsHandler) HandleGetKeybindings(ctx context.Context, _ port.WebViewID, _ json.RawMessage) (any, error) {
38 return h.getUC.Execute(ctx)37 return h.getUC.Execute(ctx)
39 }38 }
40 39
41 // HandleSetKeybinding updates a single keybinding.40 // HandleSetKeybinding updates a single keybinding.
42-func (h *KeybindingsHandler) HandleSetKeybinding(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {41+func (h *KeybindingsHandler) HandleSetKeybinding(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
43 log := logging.FromContext(ctx).With().Str("handler", "keybindings").Logger()42 log := logging.FromContext(ctx).With().Str("handler", "keybindings").Logger()
44 log.Debug().RawJSON("payload", payload).Msg("HandleSetKeybinding called")43 log.Debug().RawJSON("payload", payload).Msg("HandleSetKeybinding called")
45 44
@@ -61,7 +60,7 @@ func (h *KeybindingsHandler) HandleSetKeybinding(ctx context.Context, _ webkit.W
61 }60 }
62 61
63 // HandleResetKeybinding resets a keybinding to default.62 // HandleResetKeybinding resets a keybinding to default.
64-func (h *KeybindingsHandler) HandleResetKeybinding(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {63+func (h *KeybindingsHandler) HandleResetKeybinding(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
65 log := logging.FromContext(ctx).With().Str("handler", "keybindings").Logger()64 log := logging.FromContext(ctx).With().Str("handler", "keybindings").Logger()
66 65
67 var req port.ResetKeybindingRequest66 var req port.ResetKeybindingRequest
@@ -79,7 +78,7 @@ func (h *KeybindingsHandler) HandleResetKeybinding(ctx context.Context, _ webkit
79 }78 }
80 79
81 // HandleResetAllKeybindings resets all keybindings to defaults.80 // HandleResetAllKeybindings resets all keybindings to defaults.
82-func (h *KeybindingsHandler) HandleResetAllKeybindings(ctx context.Context, _ webkit.WebViewID, _ json.RawMessage) (any, error) {81+func (h *KeybindingsHandler) HandleResetAllKeybindings(ctx context.Context, _ port.WebViewID, _ json.RawMessage) (any, error) {
83 log := logging.FromContext(ctx).With().Str("handler", "keybindings").Logger()82 log := logging.FromContext(ctx).With().Str("handler", "keybindings").Logger()
84 log.Info().Msg("resetting all keybindings to defaults")83 log.Info().Msg("resetting all keybindings to defaults")
85 84
@@ -91,7 +90,7 @@ func (h *KeybindingsHandler) HandleResetAllKeybindings(ctx context.Context, _ we
91 }90 }
92 91
93 // RegisterKeybindingsHandlers registers keybindings handlers with the router.92 // RegisterKeybindingsHandlers registers keybindings handlers with the router.
94-func RegisterKeybindingsHandlers(ctx context.Context, router *webkit.MessageRouter, handler *KeybindingsHandler) error {93+func RegisterKeybindingsHandlers(ctx context.Context, router port.WebUIHandlerRouter, handler *KeybindingsHandler) error {
95 log := logging.FromContext(ctx).With().Str("component", "handlers").Logger()94 log := logging.FromContext(ctx).With().Str("component", "handlers").Logger()
96 95
97 // Get all keybindings96 // Get all keybindings
@@ -100,7 +99,7 @@ func RegisterKeybindingsHandlers(ctx context.Context, router *webkit.MessageRout
100 "__dumber_keybindings_loaded",99 "__dumber_keybindings_loaded",
101 "__dumber_keybindings_error",100 "__dumber_keybindings_error",
102 "",101 "",
103- webkit.MessageHandlerFunc(handler.HandleGetKeybindings),102+ port.WebUIMessageHandlerFunc(handler.HandleGetKeybindings),
104 ); err != nil {103 ); err != nil {
105 return err104 return err
106 }105 }
@@ -111,7 +110,7 @@ func RegisterKeybindingsHandlers(ctx context.Context, router *webkit.MessageRout
111 "__dumber_keybinding_set",110 "__dumber_keybinding_set",
112 "__dumber_keybinding_set_error",111 "__dumber_keybinding_set_error",
113 "",112 "",
114- webkit.MessageHandlerFunc(handler.HandleSetKeybinding),113+ port.WebUIMessageHandlerFunc(handler.HandleSetKeybinding),
115 ); err != nil {114 ); err != nil {
116 return err115 return err
117 }116 }
@@ -122,7 +121,7 @@ func RegisterKeybindingsHandlers(ctx context.Context, router *webkit.MessageRout
122 "__dumber_keybinding_reset",121 "__dumber_keybinding_reset",
123 "__dumber_keybinding_reset_error",122 "__dumber_keybinding_reset_error",
124 "",123 "",
125- webkit.MessageHandlerFunc(handler.HandleResetKeybinding),124+ port.WebUIMessageHandlerFunc(handler.HandleResetKeybinding),
126 ); err != nil {125 ); err != nil {
127 return err126 return err
128 }127 }
@@ -133,7 +132,7 @@ func RegisterKeybindingsHandlers(ctx context.Context, router *webkit.MessageRout
133 "__dumber_keybindings_reset_all",132 "__dumber_keybindings_reset_all",
134 "__dumber_keybindings_reset_all_error",133 "__dumber_keybindings_reset_all_error",
135 "",134 "",
136- webkit.MessageHandlerFunc(handler.HandleResetAllKeybindings),135+ port.WebUIMessageHandlerFunc(handler.HandleResetAllKeybindings),
137 ); err != nil {136 ); err != nil {
138 return err137 return err
139 }138 }
R internal/infrastructure/webkit/handlers/register.go → internal/infrastructure/handlers/register.go +24 -31 renamed, 50% similar
@@ -7,8 +7,7 @@ import (
77 "unicode/utf8"
88
99 "github.com/bnema/dumber/internal/application/port"
10- "github.com/bnema/dumber/internal/infrastructure/webkit"
11- "github.com/bnema/dumber/internal/infrastructure/webkit/handlers/homepage"
10+ "github.com/bnema/dumber/internal/infrastructure/handlers/homepage"
1211 )
1312
1413 // AccentKeyHandler is implemented by the InsertAccentUseCase to receive
@@ -17,49 +16,43 @@ import (
1716 // Deprecated: use port.AccentKeyHandler instead. This alias is kept for compatibility.
1817 type AccentKeyHandler = port.AccentKeyHandler
1918
20-// Config holds all dependencies for message handlers.
21-type Config struct {
22- HistoryUC port.HomepageHistory
23- FavoritesUC port.HomepageFavorites
24- Clipboard port.Clipboard
25- AutoCopyConfig port.AutoCopyConfig
26- SaveConfig func(context.Context, port.WebUIConfig) error // Pre-built by bootstrap (usecase.SaveWebUIConfigUseCase.Execute)
27- // KeybindingsHandler is required (not optional like other handlers) because the WebUI
28- // always needs keybinding read/write support regardless of configuration.
29- KeybindingsHandler *KeybindingsHandler // Pre-built by bootstrap
30- OnClipboardCopied func(textLen int) // Called when auto-copy completes (for toast notification)
31-}
32-
3319 // RegisterAll registers all message handlers with the router.
34-func RegisterAll(ctx context.Context, router *webkit.MessageRouter, cfg Config) error {
20+// The router can be any engine's message router that implements port.WebUIHandlerRouter.
21+func RegisterAll(ctx context.Context, router port.WebUIHandlerRouter, deps port.HandlerDependencies) error {
3522 // Homepage handlers (history, favorites, folders, tags)
36- if cfg.HistoryUC != nil && cfg.FavoritesUC != nil {
23+ if deps.HistoryUC != nil && deps.FavoritesUC != nil {
3724 if err := homepage.RegisterHandlers(ctx, router, homepage.Config{
38- HistoryUC: cfg.HistoryUC,
39- FavoritesUC: cfg.FavoritesUC,
25+ HistoryUC: deps.HistoryUC,
26+ FavoritesUC: deps.FavoritesUC,
4027 }); err != nil {
4128 return err
4229 }
4330 }
4431
4532 // Configuration handlers
46- if cfg.SaveConfig != nil {
47- if err := RegisterConfigHandlers(ctx, router, cfg.SaveConfig); err != nil {
33+ if deps.SaveConfig != nil {
34+ if err := RegisterConfigHandlers(ctx, router, deps.SaveConfig); err != nil {
4835 return err
4936 }
5037 }
5138
5239 // Keybindings handlers (always available)
53- if cfg.KeybindingsHandler == nil {
54- return fmt.Errorf("KeybindingsHandler is required")
40+ if deps.KeybindingsGetter == nil {
41+ return fmt.Errorf("KeybindingsGetter is required")
5542 }
56- if err := RegisterKeybindingsHandlers(ctx, router, cfg.KeybindingsHandler); err != nil {
43+ kbHandler := NewKeybindingsHandler(
44+ deps.KeybindingsGetter,
45+ deps.KeybindingSetter,
46+ deps.KeybindingResetter,
47+ deps.AllKeybindingsResetter,
48+ )
49+ if err := RegisterKeybindingsHandlers(ctx, router, kbHandler); err != nil {
5750 return err
5851 }
5952
6053 // Clipboard handlers (for auto-copy on selection feature)
61- if cfg.Clipboard != nil && cfg.AutoCopyConfig != nil {
62- if err := RegisterClipboardHandlers(ctx, router, cfg.Clipboard, cfg.AutoCopyConfig, cfg.OnClipboardCopied); err != nil {
54+ if deps.Clipboard != nil && deps.AutoCopyConfig != nil {
55+ if err := RegisterClipboardHandlers(ctx, router, deps.Clipboard, deps.AutoCopyConfig, deps.OnClipboardCopied); err != nil {
6356 return err
6457 }
6558 }
@@ -69,7 +62,7 @@ func RegisterAll(ctx context.Context, router *webkit.MessageRouter, cfg Config)
6962
7063 // RegisterAccentHandlers registers accent key press/release handlers with the router.
7164 // Must be called after the AccentKeyHandler is initialized (i.e., after initAccentPicker).
72-func RegisterAccentHandlers(_ context.Context, router *webkit.MessageRouter, handler AccentKeyHandler) error {
65+func RegisterAccentHandlers(_ context.Context, router port.WebUIHandlerRouter, handler AccentKeyHandler) error {
7366 if router == nil {
7467 return fmt.Errorf("RegisterAccentHandlers: router must not be nil")
7568 }
@@ -77,8 +70,8 @@ func RegisterAccentHandlers(_ context.Context, router *webkit.MessageRouter, han
7770 return fmt.Errorf("RegisterAccentHandlers: handler must not be nil")
7871 }
7972
80- if err := router.RegisterHandler("accent_key_press", webkit.MessageHandlerFunc(
81- func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
73+ if err := router.RegisterHandler("accent_key_press", port.WebUIMessageHandlerFunc(
74+ func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
8275 var p struct {
8376 Char string `json:"char"`
8477 Shift bool `json:"shift"`
@@ -95,8 +88,8 @@ func RegisterAccentHandlers(_ context.Context, router *webkit.MessageRouter, han
9588 return err
9689 }
9790
98- if err := router.RegisterHandler("accent_key_release", webkit.MessageHandlerFunc(
99- func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {
91+ if err := router.RegisterHandler("accent_key_release", port.WebUIMessageHandlerFunc(
92+ func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
10093 var p struct {
10194 Char string `json:"char"`
10295 }
@@ -7,8 +7,7 @@ import (
7 "unicode/utf8"7 "unicode/utf8"
8 8
9 "github.com/bnema/dumber/internal/application/port"9 "github.com/bnema/dumber/internal/application/port"
10- "github.com/bnema/dumber/internal/infrastructure/webkit"10+ "github.com/bnema/dumber/internal/infrastructure/handlers/homepage"
11- "github.com/bnema/dumber/internal/infrastructure/webkit/handlers/homepage"
12 )11 )
13 12
14 // AccentKeyHandler is implemented by the InsertAccentUseCase to receive13 // AccentKeyHandler is implemented by the InsertAccentUseCase to receive
@@ -17,49 +16,43 @@ import (
17 // Deprecated: use port.AccentKeyHandler instead. This alias is kept for compatibility.16 // Deprecated: use port.AccentKeyHandler instead. This alias is kept for compatibility.
18 type AccentKeyHandler = port.AccentKeyHandler17 type AccentKeyHandler = port.AccentKeyHandler
19 18
20-// Config holds all dependencies for message handlers.
21-type Config struct {
22- HistoryUC port.HomepageHistory
23- FavoritesUC port.HomepageFavorites
24- Clipboard port.Clipboard
25- AutoCopyConfig port.AutoCopyConfig
26- SaveConfig func(context.Context, port.WebUIConfig) error // Pre-built by bootstrap (usecase.SaveWebUIConfigUseCase.Execute)
27- // KeybindingsHandler is required (not optional like other handlers) because the WebUI
28- // always needs keybinding read/write support regardless of configuration.
29- KeybindingsHandler *KeybindingsHandler // Pre-built by bootstrap
30- OnClipboardCopied func(textLen int) // Called when auto-copy completes (for toast notification)
31-}
32-
33 // RegisterAll registers all message handlers with the router.19 // RegisterAll registers all message handlers with the router.
34-func RegisterAll(ctx context.Context, router *webkit.MessageRouter, cfg Config) error {20+// The router can be any engine's message router that implements port.WebUIHandlerRouter.
21+func RegisterAll(ctx context.Context, router port.WebUIHandlerRouter, deps port.HandlerDependencies) error {
35 // Homepage handlers (history, favorites, folders, tags)22 // Homepage handlers (history, favorites, folders, tags)
36- if cfg.HistoryUC != nil && cfg.FavoritesUC != nil {23+ if deps.HistoryUC != nil && deps.FavoritesUC != nil {
37 if err := homepage.RegisterHandlers(ctx, router, homepage.Config{24 if err := homepage.RegisterHandlers(ctx, router, homepage.Config{
38- HistoryUC: cfg.HistoryUC,25+ HistoryUC: deps.HistoryUC,
39- FavoritesUC: cfg.FavoritesUC,26+ FavoritesUC: deps.FavoritesUC,
40 }); err != nil {27 }); err != nil {
41 return err28 return err
42 }29 }
43 }30 }
44 31
45 // Configuration handlers32 // Configuration handlers
46- if cfg.SaveConfig != nil {33+ if deps.SaveConfig != nil {
47- if err := RegisterConfigHandlers(ctx, router, cfg.SaveConfig); err != nil {34+ if err := RegisterConfigHandlers(ctx, router, deps.SaveConfig); err != nil {
48 return err35 return err
49 }36 }
50 }37 }
51 38
52 // Keybindings handlers (always available)39 // Keybindings handlers (always available)
53- if cfg.KeybindingsHandler == nil {40+ if deps.KeybindingsGetter == nil {
54- return fmt.Errorf("KeybindingsHandler is required")41+ return fmt.Errorf("KeybindingsGetter is required")
55 }42 }
56- if err := RegisterKeybindingsHandlers(ctx, router, cfg.KeybindingsHandler); err != nil {43+ kbHandler := NewKeybindingsHandler(
44+ deps.KeybindingsGetter,
45+ deps.KeybindingSetter,
46+ deps.KeybindingResetter,
47+ deps.AllKeybindingsResetter,
48+ )
49+ if err := RegisterKeybindingsHandlers(ctx, router, kbHandler); err != nil {
57 return err50 return err
58 }51 }
59 52
60 // Clipboard handlers (for auto-copy on selection feature)53 // Clipboard handlers (for auto-copy on selection feature)
61- if cfg.Clipboard != nil && cfg.AutoCopyConfig != nil {54+ if deps.Clipboard != nil && deps.AutoCopyConfig != nil {
62- if err := RegisterClipboardHandlers(ctx, router, cfg.Clipboard, cfg.AutoCopyConfig, cfg.OnClipboardCopied); err != nil {55+ if err := RegisterClipboardHandlers(ctx, router, deps.Clipboard, deps.AutoCopyConfig, deps.OnClipboardCopied); err != nil {
63 return err56 return err
64 }57 }
65 }58 }
@@ -69,7 +62,7 @@ func RegisterAll(ctx context.Context, router *webkit.MessageRouter, cfg Config)
69 62
70 // RegisterAccentHandlers registers accent key press/release handlers with the router.63 // RegisterAccentHandlers registers accent key press/release handlers with the router.
71 // Must be called after the AccentKeyHandler is initialized (i.e., after initAccentPicker).64 // Must be called after the AccentKeyHandler is initialized (i.e., after initAccentPicker).
72-func RegisterAccentHandlers(_ context.Context, router *webkit.MessageRouter, handler AccentKeyHandler) error {65+func RegisterAccentHandlers(_ context.Context, router port.WebUIHandlerRouter, handler AccentKeyHandler) error {
73 if router == nil {66 if router == nil {
74 return fmt.Errorf("RegisterAccentHandlers: router must not be nil")67 return fmt.Errorf("RegisterAccentHandlers: router must not be nil")
75 }68 }
@@ -77,8 +70,8 @@ func RegisterAccentHandlers(_ context.Context, router *webkit.MessageRouter, han
77 return fmt.Errorf("RegisterAccentHandlers: handler must not be nil")70 return fmt.Errorf("RegisterAccentHandlers: handler must not be nil")
78 }71 }
79 72
80- if err := router.RegisterHandler("accent_key_press", webkit.MessageHandlerFunc(73+ if err := router.RegisterHandler("accent_key_press", port.WebUIMessageHandlerFunc(
81- func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {74+ func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
82 var p struct {75 var p struct {
83 Char string `json:"char"`76 Char string `json:"char"`
84 Shift bool `json:"shift"`77 Shift bool `json:"shift"`
@@ -95,8 +88,8 @@ func RegisterAccentHandlers(_ context.Context, router *webkit.MessageRouter, han
95 return err88 return err
96 }89 }
97 90
98- if err := router.RegisterHandler("accent_key_release", webkit.MessageHandlerFunc(91+ if err := router.RegisterHandler("accent_key_release", port.WebUIMessageHandlerFunc(
99- func(ctx context.Context, _ webkit.WebViewID, payload json.RawMessage) (any, error) {92+ func(ctx context.Context, _ port.WebViewID, payload json.RawMessage) (any, error) {
100 var p struct {93 var p struct {
101 Char string `json:"char"`94 Char string `json:"char"`
102 }95 }
A internal/infrastructure/handlers/register_test.go +86 -0
@@ -0,0 +1,86 @@
1+package handlers
2+
3+import (
4+ "context"
5+ "encoding/json"
6+ "testing"
7+
8+ "github.com/bnema/dumber/internal/application/port"
9+ "github.com/stretchr/testify/assert"
10+ "github.com/stretchr/testify/require"
11+)
12+
13+// stubRouter implements port.WebUIHandlerRouter for testing.
14+type stubRouter struct {
15+ handlers map[string]port.WebUIMessageHandler
16+}
17+
18+func newStubRouter() *stubRouter {
19+ return &stubRouter{handlers: make(map[string]port.WebUIMessageHandler)}
20+}
21+
22+func (r *stubRouter) RegisterHandler(msgType string, handler port.WebUIMessageHandler) error {
23+ r.handlers[msgType] = handler
24+ return nil
25+}
26+
27+func (r *stubRouter) RegisterHandlerWithCallbacks(msgType, _, _, _ string, handler port.WebUIMessageHandler) error {
28+ r.handlers[msgType] = handler
29+ return nil
30+}
31+
32+func TestRegisterAccentHandlers_NilRouter(t *testing.T) {
33+ ctx := context.Background()
34+ handler := &stubAccentHandler{}
35+ err := RegisterAccentHandlers(ctx, nil, handler)
36+ require.Error(t, err)
37+ assert.Contains(t, err.Error(), "router")
38+}
39+
40+func TestRegisterAccentHandlers_NilHandler(t *testing.T) {
41+ ctx := context.Background()
42+ router := newStubRouter()
43+ err := RegisterAccentHandlers(ctx, router, nil)
44+ require.Error(t, err)
45+ assert.Contains(t, err.Error(), "handler")
46+}
47+
48+func TestRegisterAccentHandlers_Success(t *testing.T) {
49+ ctx := context.Background()
50+ router := newStubRouter()
51+ handler := &stubAccentHandler{}
52+ err := RegisterAccentHandlers(ctx, router, handler)
53+ require.NoError(t, err)
54+ assert.Contains(t, router.handlers, "accent_key_press")
55+ assert.Contains(t, router.handlers, "accent_key_release")
56+}
57+
58+func TestRegisterAccentHandlers_KeyPress(t *testing.T) {
59+ ctx := context.Background()
60+ router := newStubRouter()
61+ handler := &stubAccentHandler{}
62+ err := RegisterAccentHandlers(ctx, router, handler)
63+ require.NoError(t, err)
64+
65+ h := router.handlers["accent_key_press"]
66+ require.NotNil(t, h)
67+
68+ payload := json.RawMessage(`{"char":"e","shift":true}`)
69+ _, err = h.Handle(ctx, 0, payload)
70+ require.NoError(t, err)
71+ assert.Equal(t, 'e', handler.lastPressed)
72+ assert.True(t, handler.lastShift)
73+}
74+
75+// stubAccentHandler satisfies port.AccentKeyHandler for tests.
76+type stubAccentHandler struct {
77+ lastPressed rune
78+ lastShift bool
79+}
80+
81+func (h *stubAccentHandler) OnKeyPressed(_ context.Context, r rune, shift bool) bool {
82+ h.lastPressed = r
83+ h.lastShift = shift
84+ return false
85+}
86+func (*stubAccentHandler) OnKeyReleased(_ context.Context, _ rune) {}
@@ -0,0 +1,86 @@
1+package handlers
2+
3+import (
4+ "context"
5+ "encoding/json"
6+ "testing"
7+
8+ "github.com/bnema/dumber/internal/application/port"
9+ "github.com/stretchr/testify/assert"
10+ "github.com/stretchr/testify/require"
11+)
12+
13+// stubRouter implements port.WebUIHandlerRouter for testing.
14+type stubRouter struct {
15+ handlers map[string]port.WebUIMessageHandler
16+}
17+
18+func newStubRouter() *stubRouter {
19+ return &stubRouter{handlers: make(map[string]port.WebUIMessageHandler)}
20+}
21+
22+func (r *stubRouter) RegisterHandler(msgType string, handler port.WebUIMessageHandler) error {
23+ r.handlers[msgType] = handler
24+ return nil
25+}
26+
27+func (r *stubRouter) RegisterHandlerWithCallbacks(msgType, _, _, _ string, handler port.WebUIMessageHandler) error {
28+ r.handlers[msgType] = handler
29+ return nil
30+}
31+
32+func TestRegisterAccentHandlers_NilRouter(t *testing.T) {
33+ ctx := context.Background()
34+ handler := &stubAccentHandler{}
35+ err := RegisterAccentHandlers(ctx, nil, handler)
36+ require.Error(t, err)
37+ assert.Contains(t, err.Error(), "router")
38+}
39+
40+func TestRegisterAccentHandlers_NilHandler(t *testing.T) {
41+ ctx := context.Background()
42+ router := newStubRouter()
43+ err := RegisterAccentHandlers(ctx, router, nil)
44+ require.Error(t, err)
45+ assert.Contains(t, err.Error(), "handler")
46+}
47+
48+func TestRegisterAccentHandlers_Success(t *testing.T) {
49+ ctx := context.Background()
50+ router := newStubRouter()
51+ handler := &stubAccentHandler{}
52+ err := RegisterAccentHandlers(ctx, router, handler)
53+ require.NoError(t, err)
54+ assert.Contains(t, router.handlers, "accent_key_press")
55+ assert.Contains(t, router.handlers, "accent_key_release")
56+}
57+
58+func TestRegisterAccentHandlers_KeyPress(t *testing.T) {
59+ ctx := context.Background()
60+ router := newStubRouter()
61+ handler := &stubAccentHandler{}
62+ err := RegisterAccentHandlers(ctx, router, handler)
63+ require.NoError(t, err)
64+
65+ h := router.handlers["accent_key_press"]
66+ require.NotNil(t, h)
67+
68+ payload := json.RawMessage(`{"char":"e","shift":true}`)
69+ _, err = h.Handle(ctx, 0, payload)
70+ require.NoError(t, err)
71+ assert.Equal(t, 'e', handler.lastPressed)
72+ assert.True(t, handler.lastShift)
73+}
74+
75+// stubAccentHandler satisfies port.AccentKeyHandler for tests.
76+type stubAccentHandler struct {
77+ lastPressed rune
78+ lastShift bool
79+}
80+
81+func (h *stubAccentHandler) OnKeyPressed(_ context.Context, r rune, shift bool) bool {
82+ h.lastPressed = r
83+ h.lastShift = shift
84+ return false
85+}
86+func (*stubAccentHandler) OnKeyReleased(_ context.Context, _ rune) {}
M internal/infrastructure/webkit/engine.go +2 -2
@@ -25,8 +25,8 @@ type Engine struct {
2525 logger zerolog.Logger
2626
2727 // Handler registrars - injected at construction to avoid import cycles.
28- handlerRegistrar func(ctx context.Context, router *MessageRouter, deps port.HandlerDependencies) error
29- accentHandlerRegistrar func(ctx context.Context, router *MessageRouter, handler port.AccentKeyHandler) error
28+ handlerRegistrar func(ctx context.Context, router port.WebUIHandlerRouter, deps port.HandlerDependencies) error
29+ accentHandlerRegistrar func(ctx context.Context, router port.WebUIHandlerRouter, handler port.AccentKeyHandler) error
3030 }
3131
3232 // Compile-time check that Engine implements port.Engine.
@@ -25,8 +25,8 @@ type Engine struct {
25 logger zerolog.Logger25 logger zerolog.Logger
26 26
27 // Handler registrars - injected at construction to avoid import cycles.27 // Handler registrars - injected at construction to avoid import cycles.
28- handlerRegistrar func(ctx context.Context, router *MessageRouter, deps port.HandlerDependencies) error28+ handlerRegistrar func(ctx context.Context, router port.WebUIHandlerRouter, deps port.HandlerDependencies) error
29- accentHandlerRegistrar func(ctx context.Context, router *MessageRouter, handler port.AccentKeyHandler) error29+ accentHandlerRegistrar func(ctx context.Context, router port.WebUIHandlerRouter, handler port.AccentKeyHandler) error
30 }30 }
31 31
32 // Compile-time check that Engine implements port.Engine.32 // Compile-time check that Engine implements port.Engine.
M internal/infrastructure/webkit/engine_init.go +2 -2
@@ -26,8 +26,8 @@ func NewEngine(
2626 themeManager *theme.Manager,
2727 colorResolver port.ColorSchemeResolver,
2828 logger zerolog.Logger,
29- handlerRegistrar func(ctx context.Context, router *MessageRouter, deps port.HandlerDependencies) error,
30- accentHandlerRegistrar func(ctx context.Context, router *MessageRouter, handler port.AccentKeyHandler) error,
29+ handlerRegistrar func(ctx context.Context, router port.WebUIHandlerRouter, deps port.HandlerDependencies) error,
30+ accentHandlerRegistrar func(ctx context.Context, router port.WebUIHandlerRouter, handler port.AccentKeyHandler) error,
3131 ) (*Engine, error) {
3232 // --- Hardware survey and performance profile resolution ---
3333 perfSettings := engineSurveyHardwareAndResolveProfile(ctx, cfg, logger)
@@ -26,8 +26,8 @@ func NewEngine(
26 themeManager *theme.Manager,26 themeManager *theme.Manager,
27 colorResolver port.ColorSchemeResolver,27 colorResolver port.ColorSchemeResolver,
28 logger zerolog.Logger,28 logger zerolog.Logger,
29- handlerRegistrar func(ctx context.Context, router *MessageRouter, deps port.HandlerDependencies) error,29+ handlerRegistrar func(ctx context.Context, router port.WebUIHandlerRouter, deps port.HandlerDependencies) error,
30- accentHandlerRegistrar func(ctx context.Context, router *MessageRouter, handler port.AccentKeyHandler) error,30+ accentHandlerRegistrar func(ctx context.Context, router port.WebUIHandlerRouter, handler port.AccentKeyHandler) error,
31 ) (*Engine, error) {31 ) (*Engine, error) {
32 // --- Hardware survey and performance profile resolution ---32 // --- Hardware survey and performance profile resolution ---
33 perfSettings := engineSurveyHardwareAndResolveProfile(ctx, cfg, logger)33 perfSettings := engineSurveyHardwareAndResolveProfile(ctx, cfg, logger)
D internal/infrastructure/webkit/handlers/register_test.go +0 -40
@@ -1,40 +0,0 @@
1-package handlers
2-
3-import (
4- "context"
5- "testing"
6-
7- "github.com/bnema/dumber/internal/infrastructure/webkit"
8- "github.com/stretchr/testify/assert"
9- "github.com/stretchr/testify/require"
10-)
11-
12-func TestRegisterAccentHandlers_NilRouter(t *testing.T) {
13- ctx := context.Background()
14- handler := &stubAccentHandler{}
15- err := RegisterAccentHandlers(ctx, nil, handler)
16- require.Error(t, err)
17- assert.Contains(t, err.Error(), "router")
18-}
19-
20-func TestRegisterAccentHandlers_NilHandler(t *testing.T) {
21- ctx := context.Background()
22- router := webkit.NewMessageRouter(ctx)
23- err := RegisterAccentHandlers(ctx, router, nil)
24- require.Error(t, err)
25- assert.Contains(t, err.Error(), "handler")
26-}
27-
28-func TestRegisterAccentHandlers_Success(t *testing.T) {
29- ctx := context.Background()
30- router := webkit.NewMessageRouter(ctx)
31- handler := &stubAccentHandler{}
32- err := RegisterAccentHandlers(ctx, router, handler)
33- require.NoError(t, err)
34-}
35-
36-// stubAccentHandler satisfies AccentKeyHandler for tests.
37-type stubAccentHandler struct{}
38-
39-func (*stubAccentHandler) OnKeyPressed(_ context.Context, _ rune, _ bool) bool { return false }
40-func (*stubAccentHandler) OnKeyReleased(_ context.Context, _ rune) {}
@@ -1,40 +0,0 @@
1-package handlers
2-
3-import (
4- "context"
5- "testing"
6-
7- "github.com/bnema/dumber/internal/infrastructure/webkit"
8- "github.com/stretchr/testify/assert"
9- "github.com/stretchr/testify/require"
10-)
11-
12-func TestRegisterAccentHandlers_NilRouter(t *testing.T) {
13- ctx := context.Background()
14- handler := &stubAccentHandler{}
15- err := RegisterAccentHandlers(ctx, nil, handler)
16- require.Error(t, err)
17- assert.Contains(t, err.Error(), "router")
18-}
19-
20-func TestRegisterAccentHandlers_NilHandler(t *testing.T) {
21- ctx := context.Background()
22- router := webkit.NewMessageRouter(ctx)
23- err := RegisterAccentHandlers(ctx, router, nil)
24- require.Error(t, err)
25- assert.Contains(t, err.Error(), "handler")
26-}
27-
28-func TestRegisterAccentHandlers_Success(t *testing.T) {
29- ctx := context.Background()
30- router := webkit.NewMessageRouter(ctx)
31- handler := &stubAccentHandler{}
32- err := RegisterAccentHandlers(ctx, router, handler)
33- require.NoError(t, err)
34-}
35-
36-// stubAccentHandler satisfies AccentKeyHandler for tests.
37-type stubAccentHandler struct{}
38-
39-func (*stubAccentHandler) OnKeyPressed(_ context.Context, _ rune, _ bool) bool { return false }
40-func (*stubAccentHandler) OnKeyReleased(_ context.Context, _ rune) {}
M internal/infrastructure/webkit/messaging.go +10 -11
@@ -7,6 +7,7 @@ import (
77 "fmt"
88 "sync"
99
10+ "github.com/bnema/dumber/internal/application/port"
1011 "github.com/bnema/dumber/internal/logging"
1112 "github.com/bnema/puregotk-webkit/javascriptcore"
1213 "github.com/bnema/puregotk-webkit/webkit"
@@ -20,18 +21,13 @@ type Message struct {
2021 WebViewIDAlt uint64 `json:"webviewId,omitempty"`
2122 }
2223
23-// MessageHandler handles a decoded message payload.
24-type MessageHandler interface {
25- Handle(ctx context.Context, webviewID WebViewID, payload json.RawMessage) (any, error)
26-}
27-
28-// MessageHandlerFunc adapts a function to the MessageHandler interface.
29-type MessageHandlerFunc func(ctx context.Context, webviewID WebViewID, payload json.RawMessage) (any, error)
24+// MessageHandler is an alias for port.WebUIMessageHandler.
25+// Kept for backward compatibility within the webkit package.
26+type MessageHandler = port.WebUIMessageHandler
3027
31-// Handle calls f(ctx, webviewID, payload).
32-func (f MessageHandlerFunc) Handle(ctx context.Context, webviewID WebViewID, payload json.RawMessage) (any, error) {
33- return f(ctx, webviewID, payload)
34-}
28+// MessageHandlerFunc is an alias for port.WebUIMessageHandlerFunc.
29+// Kept for backward compatibility within the webkit package.
30+type MessageHandlerFunc = port.WebUIMessageHandlerFunc
3531
3632 type handlerEntry struct {
3733 handler MessageHandler
@@ -40,6 +36,9 @@ type handlerEntry struct {
4036 world string
4137 }
4238
39+// Compile-time check that MessageRouter implements port.WebUIHandlerRouter.
40+var _ port.WebUIHandlerRouter = (*MessageRouter)(nil)
41+
4342 // MessageRouter dispatches script-message events to registered handlers.
4443 type MessageRouter struct {
4544 handlers map[string]handlerEntry
@@ -7,6 +7,7 @@ import (
7 "fmt"7 "fmt"
8 "sync"8 "sync"
9 9
10+ "github.com/bnema/dumber/internal/application/port"
10 "github.com/bnema/dumber/internal/logging"11 "github.com/bnema/dumber/internal/logging"
11 "github.com/bnema/puregotk-webkit/javascriptcore"12 "github.com/bnema/puregotk-webkit/javascriptcore"
12 "github.com/bnema/puregotk-webkit/webkit"13 "github.com/bnema/puregotk-webkit/webkit"
@@ -20,18 +21,13 @@ type Message struct {
20 WebViewIDAlt uint64 `json:"webviewId,omitempty"`21 WebViewIDAlt uint64 `json:"webviewId,omitempty"`
21 }22 }
22 23
23-// MessageHandler handles a decoded message payload.24+// MessageHandler is an alias for port.WebUIMessageHandler.
24-type MessageHandler interface {25+// Kept for backward compatibility within the webkit package.
25- Handle(ctx context.Context, webviewID WebViewID, payload json.RawMessage) (any, error)26+type MessageHandler = port.WebUIMessageHandler
26-}
27-
28-// MessageHandlerFunc adapts a function to the MessageHandler interface.
29-type MessageHandlerFunc func(ctx context.Context, webviewID WebViewID, payload json.RawMessage) (any, error)
30 27
31-// Handle calls f(ctx, webviewID, payload).28+// MessageHandlerFunc is an alias for port.WebUIMessageHandlerFunc.
32-func (f MessageHandlerFunc) Handle(ctx context.Context, webviewID WebViewID, payload json.RawMessage) (any, error) {29+// Kept for backward compatibility within the webkit package.
33- return f(ctx, webviewID, payload)30+type MessageHandlerFunc = port.WebUIMessageHandlerFunc
34-}
35 31
36 type handlerEntry struct {32 type handlerEntry struct {
37 handler MessageHandler33 handler MessageHandler
@@ -40,6 +36,9 @@ type handlerEntry struct {
40 world string36 world string
41 }37 }
42 38
39+// Compile-time check that MessageRouter implements port.WebUIHandlerRouter.
40+var _ port.WebUIHandlerRouter = (*MessageRouter)(nil)
41+
43 // MessageRouter dispatches script-message events to registered handlers.42 // MessageRouter dispatches script-message events to registered handlers.
44 type MessageRouter struct {43 type MessageRouter struct {
45 handlers map[string]handlerEntry44 handlers map[string]handlerEntry

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