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)
9
10// WebViewID uniquely identifies a WebView instance.
11type WebViewID uint64
12
13// LoadEvent represents page load state transitions.
14type LoadEvent int
15
16const (
17 // LoadStarted indicates navigation has begun.
18 LoadStarted LoadEvent = iota
19 // LoadRedirected indicates a redirect occurred.
20 LoadRedirected
21 // LoadCommitted indicates content is being received.
22 LoadCommitted
23 // LoadFinished indicates the page has fully loaded.
24 LoadFinished
25)
26
27// String returns a human-readable representation of the load event.
28func (e LoadEvent) String() string {
29 switch e {
30 case LoadStarted:
31 return "started"
32 case LoadRedirected:
33 return "redirected"
34 case LoadCommitted:
35 return "committed"
36 case LoadFinished:
37 return "finished"
38 default:
39 return "unknown"
40 }
41}
42
43// WebViewState represents a snapshot of the current WebView state.
44// This is an immutable struct that can be safely passed between components.
45type WebViewState struct {
46 URI string
47 Title string
48 IsLoading bool
49 Progress float64 // 0.0 to 1.0
50 CanGoBack bool
51 CanGoFwd bool
52 ZoomLevel float64
53}
54
55// WebProcessTerminationReason describes why the web process terminated.
56type WebProcessTerminationReason int
57
58const (
59 WebProcessTerminationUnknown WebProcessTerminationReason = iota
60 WebProcessTerminationCrashed
61 WebProcessTerminationExceededMemory
62 WebProcessTerminationByAPI
63)
64
65// PopupRequest contains metadata about a popup window request.
66type PopupRequest struct {
67 TargetURI string
68 FrameName string // e.g., "_blank", custom name, or empty
69 IsUserGesture bool
70 ParentViewID WebViewID
71}
72
73// Texture represents a graphics texture (abstraction over gdk.Texture).
74// This interface allows the port layer to work with textures without
75// importing GTK/GDK packages directly.
76type Texture interface {
77 // GoPointer returns the underlying C pointer for GTK interop.
78 GoPointer() uintptr
79}
80
81// WebViewCallbacks defines callback handlers for WebView events.
82// Implementations should invoke these on the main thread/goroutine.
83type WebViewCallbacks struct {
84 // OnLoadChanged is called when load state changes.
85 OnLoadChanged func(event LoadEvent)
86 // OnTitleChanged is called when the page title changes.
87 OnTitleChanged func(title string)
88 // OnURIChanged is called when the URI changes.
89 OnURIChanged func(uri string)
90 // OnProgressChanged is called during page load with progress 0.0-1.0.
91 OnProgressChanged func(progress float64)
92 // OnFaviconChanged is called when the page favicon changes.
93 // The parameter is a *gdk.Texture (passed as Texture interface to avoid GTK import in port layer).
94 OnFaviconChanged func(favicon Texture)
95 // OnClose is called when the WebView requests to close.
96 OnClose func()
97 // OnCreate is called when a popup window is requested.
98 // Return a WebView to allow the popup, or nil to block it.
99 OnCreate func(request PopupRequest) WebView
100 // OnReadyToShow is called when a popup WebView is ready to display.
101 OnReadyToShow func()
102 // OnLinkHover is called when hovering over a link, image, or media element.
103 // The uri parameter contains the target URL, or empty string when leaving.
104 OnLinkHover func(uri string)
105 // OnWebProcessTerminated is called when the web process exits unexpectedly.
106 OnWebProcessTerminated func(reason WebProcessTerminationReason, reasonLabel string, uri string)
107
108 // OnPermissionRequest is called when a site requests permission (mic, camera, screen sharing).
109 // Return true to indicate the request was handled. Call allow()/deny() to respond.
110 // The permission types are passed as strings ("microphone", "camera", "display", etc.).
111 OnPermissionRequest func(origin string, permTypes []string, allow, deny func()) bool
112}
113
114// FindOptions configures search behavior.
115type FindOptions struct {
116 CaseInsensitive bool
117 AtWordStarts bool
118 WrapAround bool
119}
120
121// FindController abstracts WebKit's FindController for clean architecture.
122type FindController interface {
123 Search(text string, options FindOptions, maxMatches uint)
124 CountMatches(text string, options FindOptions, maxMatches uint)
125 SearchNext()
126 SearchPrevious()
127 SearchFinish()
128 GetSearchText() string
129
130 // Signal connections
131 OnFoundText(callback func(matchCount uint)) uint
132 OnFailedToFindText(callback func()) uint
133 OnCountedMatches(callback func(matchCount uint)) uint
134 DisconnectSignal(id uint)
135}
136
137// WebView defines the port interface for browser view operations.
138// This interface abstracts the underlying browser engine (WebKit, etc.)
139// and exposes only the navigation and state capabilities needed by
140// the application layer.
141type WebView interface {
142 // ID returns the unique identifier for this WebView.
143 ID() WebViewID
144
145 // --- Navigation ---
146
147 // LoadURI navigates to the specified URI.
148 LoadURI(ctx context.Context, uri string) error
149
150 // LoadHTML loads HTML content with an optional base URI for relative links.
151 LoadHTML(ctx context.Context, content, baseURI string) error
152
153 // Reload reloads the current page.
154 Reload(ctx context.Context) error
155
156 // ReloadBypassCache reloads the current page, bypassing cache.
157 ReloadBypassCache(ctx context.Context) error
158
159 // Stop stops the current page load.
160 Stop(ctx context.Context) error
161
162 // GoBack navigates back in history.
163 // Uses WebKit native navigation if available, falls back to JavaScript history.back() for SPA compatibility.
164 GoBack(ctx context.Context) error
165
166 // GoForward navigates forward in history.
167 // Uses WebKit native navigation if available, falls back to JavaScript history.forward() for SPA compatibility.
168 GoForward(ctx context.Context) error
169
170 // --- State Queries ---
171
172 // State returns the current WebView state as a snapshot.
173 State() WebViewState
174
175 // URI returns the current URI.
176 URI() string
177
178 // Title returns the current page title.
179 Title() string
180
181 // IsLoading returns true if a page is currently loading.
182 IsLoading() bool
183
184 // EstimatedProgress returns the load progress (0.0 to 1.0).
185 EstimatedProgress() float64
186
187 // CanGoBack returns true if back navigation is available.
188 CanGoBack() bool
189
190 // CanGoForward returns true if forward navigation is available.
191 CanGoForward() bool
192
193 // --- Zoom ---
194
195 // SetZoomLevel sets the zoom level (1.0 = 100%).
196 SetZoomLevel(ctx context.Context, level float64) error
197
198 // GetZoomLevel returns the current zoom level.
199 GetZoomLevel() float64
200
201 // --- Find ---
202
203 // GetFindController returns the find controller for text search.
204 // Returns nil if find is not supported.
205 GetFindController() FindController
206
207 // --- Callbacks ---
208
209 // SetCallbacks registers callback handlers for WebView events.
210 // Pass nil to clear all callbacks.
211 SetCallbacks(callbacks *WebViewCallbacks)
212
213 // --- Media/Fullscreen State ---
214
215 // IsFullscreen returns true if the WebView is currently in fullscreen mode.
216 IsFullscreen() bool
217
218 // IsPlayingAudio returns true if the WebView is currently playing audio.
219 IsPlayingAudio() bool
220
221 // --- Lifecycle ---
222
223 // IsDestroyed returns true if the WebView has been destroyed.
224 IsDestroyed() bool
225
226 // Destroy releases all resources associated with this WebView.
227 // After calling Destroy, the WebView should not be used.
228 Destroy()
229}
230
231// WebViewPool defines the port interface for WebView pooling.
232// Pools maintain pre-created WebViews for fast tab creation.
233type WebViewPool interface {
234 // Acquire obtains a WebView from the pool or creates a new one.
235 // The context can be used for cancellation.
236 Acquire(ctx context.Context) (WebView, error)
237
238 // Release returns a WebView to the pool for reuse.
239 // The WebView will be reset to a blank state.
240 // If the pool is full, the WebView will be destroyed.
241 Release(wv WebView)
242
243 // Prewarm creates WebViews in the background to populate the pool.
244 // Pass count <= 0 to use the default prewarm count.
245 Prewarm(count int)
246
247 // Size returns the current number of available WebViews in the pool.
248 Size() int
249
250 // Close shuts down the pool and destroys all pooled WebViews.
251 Close()
252}
253
254// WebViewFactory creates new WebView instances.
255// This is used when direct WebView creation is needed without pooling.
256type WebViewFactory interface {
257 // Create creates a new WebView instance.
258 Create(ctx context.Context) (WebView, error)
259
260 // CreateRelated creates a WebView that shares session/cookies with parent.
261 // This is required for popup windows to maintain authentication state.
262 // Popup WebViews bypass the pool since they must be related to a specific parent.
263 CreateRelated(ctx context.Context, parentID WebViewID) (WebView, error)
264}