1// Package port defines application-layer interfaces for external capabilities.
2// Ports abstract infrastructure concerns, allowing the application layer to
3// remain independent of specific implementations (WebKit, GTK, etc.).
4package port
5
6import (
7 "context"
8 "encoding/json"
9
10 "github.com/bnema/dumber/internal/domain/entity"
11)
12
13// CookiePolicy controls cookie acceptance behavior for the engine's network session.
14type CookiePolicy string
15
16const (
17 // CookiePolicyAlways accepts all cookies.
18 CookiePolicyAlways CookiePolicy = "always"
19 // CookiePolicyNoThirdParty rejects third-party cookies.
20 CookiePolicyNoThirdParty CookiePolicy = "no_third_party"
21 // CookiePolicyNever rejects all cookies.
22 CookiePolicyNever CookiePolicy = "never"
23)
24
25// MemoryPressureConfig holds memory pressure settings for an engine process.
26// This is a value type (no infrastructure dependencies) co-located with the
27// interfaces that use it (MemoryPressureApplier, EngineOptions).
28// Zero values mean "use engine defaults".
29type MemoryPressureConfig struct {
30 // MemoryLimitMB sets the memory limit in megabytes.
31 // 0 means unset (uses engine default).
32 MemoryLimitMB int
33
34 // PollIntervalSec sets the interval for memory usage checks.
35 // 0 means unset (uses engine default: 30 seconds).
36 PollIntervalSec float64
37
38 // ConservativeThreshold sets threshold for conservative memory release.
39 // Must be in (0, 1). 0 means unset (uses engine default: 0.33).
40 ConservativeThreshold float64
41
42 // StrictThreshold sets threshold for strict memory release.
43 // Must be in (0, 1). 0 means unset (uses engine default: 0.5).
44 StrictThreshold float64
45}
46
47// IsConfigured returns true if any memory pressure setting is configured.
48func (c *MemoryPressureConfig) IsConfigured() bool {
49 if c == nil {
50 return false
51 }
52 return c.MemoryLimitMB > 0 ||
53 c.PollIntervalSec > 0 ||
54 c.ConservativeThreshold > 0 ||
55 c.StrictThreshold > 0
56}
57
58// MemoryPressureApplier applies memory pressure settings to engine processes.
59// This interface abstracts engine-specific memory pressure configuration
60// to allow testing without engine dependencies.
61type MemoryPressureApplier interface {
62 // ApplyNetworkProcessSettings applies memory pressure settings to the network process.
63 // Must be called BEFORE creating any NetworkSession.
64 ApplyNetworkProcessSettings(ctx context.Context, cfg *MemoryPressureConfig) error
65
66 // ApplyWebProcessSettings applies memory pressure settings to web processes.
67 // Returns an opaque settings object that should be passed to context creation.
68 // Returns nil if no settings are configured.
69 ApplyWebProcessSettings(ctx context.Context, cfg *MemoryPressureConfig) (any, error)
70}
71
72// EngineOptions configures engine initialization.
73type EngineOptions struct {
74 // DataDir is the directory for persistent data (cookies, storage, etc.).
75 DataDir string
76
77 // CacheDir is the directory for cache data.
78 CacheDir string
79
80 // CookiePolicy controls cookie acceptance behavior.
81 // Empty value means runtime defaults are used.
82 CookiePolicy CookiePolicy
83
84 // WebProcessMemory configures memory pressure for web processes.
85 // nil means use engine defaults.
86 WebProcessMemory *MemoryPressureConfig
87
88 // NetworkProcessMemory configures memory pressure for the network process.
89 // nil means use engine defaults.
90 NetworkProcessMemory *MemoryPressureConfig
91}
92
93// Engine is the top-level interface for a browser engine implementation.
94// It provides access to all engine subsystems and manages the lifecycle
95// of the underlying browser context.
96//
97// Engines are fully initialized by their constructor (e.g., webkit.NewEngine).
98// There is no separate Init step.
99type Engine interface {
100 // Factory returns the WebViewFactory for creating new WebView instances.
101 Factory() WebViewFactory
102
103 // Pool returns the WebViewPool for acquiring pre-warmed WebView instances.
104 Pool() WebViewPool
105
106 // ContentInjector returns the ContentInjector for injecting scripts and styles.
107 ContentInjector() ContentInjector
108
109 // SettingsApplier returns the SettingsApplier for applying browser settings.
110 SettingsApplier() SettingsApplier
111
112 // FilterApplier returns the FilterApplier for applying content filters.
113 // Returns nil if content filtering is not supported by this engine.
114 FilterApplier() FilterApplier
115
116 // FaviconDatabase returns the FaviconDatabase for async favicon lookups.
117 FaviconDatabase() FaviconDatabase
118
119 // InternalSchemePath returns the URI scheme used for internal app resources.
120 InternalSchemePath() string
121
122 // Close releases all resources held by the engine.
123 Close() error
124
125 // RegisterHandlers registers all WebUI message bridge handlers.
126 RegisterHandlers(ctx context.Context, deps HandlerDependencies) error
127
128 // RegisterAccentHandlers registers accent/dead-key input handlers.
129 RegisterAccentHandlers(ctx context.Context, handler AccentKeyHandler) error
130
131 // ConfigureDownloads sets up download handling for this engine.
132 ConfigureDownloads(ctx context.Context, downloadPath string, eventHandler DownloadEventHandler, preparer DownloadPreparer) error
133
134 // OnToolkitReady is called after the UI toolkit has initialized.
135 OnToolkitReady(ctx context.Context) error
136
137 // UpdateAppearance updates default background color for new WebViews.
138 UpdateAppearance(ctx context.Context, r, g, b, alpha float64) error
139
140 // UpdateSettings applies runtime config changes to engine internals.
141 UpdateSettings(ctx context.Context, update entity.EngineSettingsUpdate) error
142
143 // SetHandlerContext sets the base context for message handler dispatch.
144 SetHandlerContext(ctx context.Context)
145}
146
147// WebUIMessageHandler handles a decoded message payload from the JS bridge.
148// Used by both WebKit and CEF message routers via the shared handlers package.
149type WebUIMessageHandler interface {
150 Handle(ctx context.Context, webviewID WebViewID, payload json.RawMessage) (any, error)
151}
152
153// WebUIMessageHandlerFunc adapts a function to the WebUIMessageHandler interface.
154type WebUIMessageHandlerFunc func(ctx context.Context, webviewID WebViewID, payload json.RawMessage) (any, error)
155
156// Handle calls f(ctx, webviewID, payload).
157func (f WebUIMessageHandlerFunc) Handle(ctx context.Context, webviewID WebViewID, payload json.RawMessage) (any, error) {
158 return f(ctx, webviewID, payload)
159}
160
161// WebUIHandlerRouter registers message handlers for the JS↔Go bridge.
162// Both WebKit's MessageRouter and CEF's MessageRouter implement this interface,
163// allowing shared handler registration code.
164type WebUIHandlerRouter interface {
165 RegisterHandler(msgType string, handler WebUIMessageHandler) error
166 RegisterHandlerWithCallbacks(msgType, callback, errorCallback, worldName string, handler WebUIMessageHandler) error
167}
168
169// WebUIMessage represents a JS -> Go message envelope.
170// Used by both WebKit (postMessage) and CEF (fetch to /api/message).
171type WebUIMessage struct {
172 Type string `json:"type"`
173 Payload json.RawMessage `json:"payload"`
174 WebViewID uint64 `json:"webview_id,omitempty"`
175 WebViewIDAlt uint64 `json:"webviewId,omitempty"`
176}
177
178// HandlerDependencies holds use cases needed by WebUI message handlers.
179type HandlerDependencies struct {
180 HistoryUC HomepageHistory
181 FavoritesUC HomepageFavorites
182 Clipboard Clipboard
183 AutoCopyConfig AutoCopyConfig
184 ClipboardTextOrchestrator ClipboardTextOrchestrator
185 OnClipboardCopied func(textLen int)
186 HandlerDeps
187}
188
189// SchemeHandler defines the port interface for registering custom URI schemes.
190// Implementations intercept navigation to registered schemes and serve content
191// from application code.
192type SchemeHandler interface {
193 // RegisterScheme registers a handler for the given URI scheme.
194 // The handler receives the full URI and returns the response body,
195 // MIME type, and any error.
196 RegisterScheme(scheme string, handler func(uri string) ([]byte, string, error))
197}
198
199// SettingsApplier defines the port interface for applying browser settings to WebViews.
200// Implementations apply engine-specific settings (security, features, etc.) uniformly
201// across a set of WebView instances.
202type SettingsApplier interface {
203 // ApplyToAll applies settings to all provided WebView instances.
204 ApplyToAll(ctx context.Context, webviews []WebView)
205}
206
207// FilterApplier defines the port interface for applying content filters to WebViews.
208// Implementations configure content blocking rules on a set of WebView instances.
209// This interface is optional; Engine.FilterApplier() returns nil if not supported.
210type FilterApplier interface {
211 // ApplyToAll applies content filters to all provided WebView instances.
212 ApplyToAll(ctx context.Context, webviews []WebView)
213}
214
215// FaviconDatabase defines the port interface for async favicon lookups.
216// Implementations retrieve favicons from an engine-managed database and
217// deliver them via callback on the main thread.
218type FaviconDatabase interface {
219 // GetFaviconAsync retrieves the favicon for the given page URL asynchronously.
220 // The callback is invoked with the favicon Texture when available.
221 GetFaviconAsync(pageURL string, callback func(Texture))
222}
223
224// ScriptRefresher defines the port interface for refreshing injected scripts
225// across multiple WebView instances (e.g., after a settings change).
226type ScriptRefresher interface {
227 // RefreshAll re-injects scripts into all provided WebView instances.
228 RefreshAll(ctx context.Context, webviews []WebView)
229}
230
231// FilterManagerProvider is an optional capability interface for engines that
232// support content filter management (e.g. ad blocking). Callers should type-assert
233// the Engine to FilterManagerProvider rather than a concrete engine type.
234type FilterManagerProvider interface {
235 InternalFilterManager() FilterManager
236}
237
238// NativeWidgetProvider is an optional capability for WebViews that can provide
239// a native widget pointer for embedding into the host toolkit's layout system.
240// For GTK-based engines this returns a *gtk.Widget pointer; other engines
241// provide their equivalent embedding handle.
242type NativeWidgetProvider interface {
243 NativeWidget() uintptr
244}