v0.27.2 5960dd8

webview.go RawHistoryFolder

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}

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