feat(application): add port interfaces for WebView, Clipboard, and Notification
- commit
- 25b2387ad9c1dbf939c9685d3ff83d52034179db
- author
- bnema · · 2025-12-09 22:29 UTC
- parent
- 26908df
- signature
- unsigned
3 files · +253 -0
A internal/application/port/clipboard.go +20 -0
| @@ -0,0 +1,20 @@ | |||
| 1 | + | package port | |
| 2 | + | ||
| 3 | + | import "context" | |
| 4 | + | ||
| 5 | + | // Clipboard defines the port interface for clipboard operations. | |
| 6 | + | // This abstracts platform-specific clipboard implementations (GTK, etc.). | |
| 7 | + | type Clipboard interface { | |
| 8 | + | // WriteText copies text to the clipboard. | |
| 9 | + | WriteText(ctx context.Context, text string) error | |
| 10 | + | ||
| 11 | + | // ReadText reads text from the clipboard. | |
| 12 | + | // Returns empty string if clipboard is empty or contains non-text data. | |
| 13 | + | ReadText(ctx context.Context) (string, error) | |
| 14 | + | ||
| 15 | + | // Clear clears the clipboard contents. | |
| 16 | + | Clear(ctx context.Context) error | |
| 17 | + | ||
| 18 | + | // HasText returns true if the clipboard contains text data. | |
| 19 | + | HasText(ctx context.Context) (bool, error) | |
| 20 | + | } | |
| @@ -0,0 +1,20 @@ | |||||
| 1 | + | package port | |||
| 2 | + | ||||
| 3 | + | import "context" | |||
| 4 | + | ||||
| 5 | + | // Clipboard defines the port interface for clipboard operations. | |||
| 6 | + | // This abstracts platform-specific clipboard implementations (GTK, etc.). | |||
| 7 | + | type Clipboard interface { | |||
| 8 | + | // WriteText copies text to the clipboard. | |||
| 9 | + | WriteText(ctx context.Context, text string) error | |||
| 10 | + | ||||
| 11 | + | // ReadText reads text from the clipboard. | |||
| 12 | + | // Returns empty string if clipboard is empty or contains non-text data. | |||
| 13 | + | ReadText(ctx context.Context) (string, error) | |||
| 14 | + | ||||
| 15 | + | // Clear clears the clipboard contents. | |||
| 16 | + | Clear(ctx context.Context) error | |||
| 17 | + | ||||
| 18 | + | // HasText returns true if the clipboard contains text data. | |||
| 19 | + | HasText(ctx context.Context) (bool, error) | |||
| 20 | + | } | |||
A internal/application/port/notification.go +55 -0
| @@ -0,0 +1,55 @@ | |||
| 1 | + | package port | |
| 2 | + | ||
| 3 | + | import "context" | |
| 4 | + | ||
| 5 | + | // NotificationType indicates the visual style of a notification. | |
| 6 | + | type NotificationType int | |
| 7 | + | ||
| 8 | + | const ( | |
| 9 | + | // NotificationInfo is for informational messages. | |
| 10 | + | NotificationInfo NotificationType = iota | |
| 11 | + | // NotificationSuccess is for success confirmations. | |
| 12 | + | NotificationSuccess | |
| 13 | + | // NotificationError is for error messages. | |
| 14 | + | NotificationError | |
| 15 | + | // NotificationWarning is for warning messages. | |
| 16 | + | NotificationWarning | |
| 17 | + | ) | |
| 18 | + | ||
| 19 | + | // String returns a human-readable representation of the notification type. | |
| 20 | + | func (t NotificationType) String() string { | |
| 21 | + | switch t { | |
| 22 | + | case NotificationInfo: | |
| 23 | + | return "info" | |
| 24 | + | case NotificationSuccess: | |
| 25 | + | return "success" | |
| 26 | + | case NotificationError: | |
| 27 | + | return "error" | |
| 28 | + | case NotificationWarning: | |
| 29 | + | return "warning" | |
| 30 | + | default: | |
| 31 | + | return "info" | |
| 32 | + | } | |
| 33 | + | } | |
| 34 | + | ||
| 35 | + | // NotificationID uniquely identifies a displayed notification. | |
| 36 | + | type NotificationID string | |
| 37 | + | ||
| 38 | + | // Notification represents the port interface for user notifications/toasts. | |
| 39 | + | // This abstracts the presentation layer (GTK/libadwaita toasts, frontend overlay, etc.). | |
| 40 | + | type Notification interface { | |
| 41 | + | // Show displays a notification with the given message and type. | |
| 42 | + | // Duration is in milliseconds; pass 0 for default duration. | |
| 43 | + | // Returns an ID that can be used to dismiss the notification. | |
| 44 | + | Show(ctx context.Context, message string, notifType NotificationType, durationMs int) NotificationID | |
| 45 | + | ||
| 46 | + | // ShowZoom displays a special zoom level notification. | |
| 47 | + | // These typically appear in a fixed position and auto-dismiss. | |
| 48 | + | ShowZoom(ctx context.Context, zoomPercent int) NotificationID | |
| 49 | + | ||
| 50 | + | // Dismiss removes a specific notification by ID. | |
| 51 | + | Dismiss(ctx context.Context, id NotificationID) | |
| 52 | + | ||
| 53 | + | // Clear removes all displayed notifications. | |
| 54 | + | Clear(ctx context.Context) | |
| 55 | + | } | |
| @@ -0,0 +1,55 @@ | |||||
| 1 | + | package port | |||
| 2 | + | ||||
| 3 | + | import "context" | |||
| 4 | + | ||||
| 5 | + | // NotificationType indicates the visual style of a notification. | |||
| 6 | + | type NotificationType int | |||
| 7 | + | ||||
| 8 | + | const ( | |||
| 9 | + | // NotificationInfo is for informational messages. | |||
| 10 | + | NotificationInfo NotificationType = iota | |||
| 11 | + | // NotificationSuccess is for success confirmations. | |||
| 12 | + | NotificationSuccess | |||
| 13 | + | // NotificationError is for error messages. | |||
| 14 | + | NotificationError | |||
| 15 | + | // NotificationWarning is for warning messages. | |||
| 16 | + | NotificationWarning | |||
| 17 | + | ) | |||
| 18 | + | ||||
| 19 | + | // String returns a human-readable representation of the notification type. | |||
| 20 | + | func (t NotificationType) String() string { | |||
| 21 | + | switch t { | |||
| 22 | + | case NotificationInfo: | |||
| 23 | + | return "info" | |||
| 24 | + | case NotificationSuccess: | |||
| 25 | + | return "success" | |||
| 26 | + | case NotificationError: | |||
| 27 | + | return "error" | |||
| 28 | + | case NotificationWarning: | |||
| 29 | + | return "warning" | |||
| 30 | + | default: | |||
| 31 | + | return "info" | |||
| 32 | + | } | |||
| 33 | + | } | |||
| 34 | + | ||||
| 35 | + | // NotificationID uniquely identifies a displayed notification. | |||
| 36 | + | type NotificationID string | |||
| 37 | + | ||||
| 38 | + | // Notification represents the port interface for user notifications/toasts. | |||
| 39 | + | // This abstracts the presentation layer (GTK/libadwaita toasts, frontend overlay, etc.). | |||
| 40 | + | type Notification interface { | |||
| 41 | + | // Show displays a notification with the given message and type. | |||
| 42 | + | // Duration is in milliseconds; pass 0 for default duration. | |||
| 43 | + | // Returns an ID that can be used to dismiss the notification. | |||
| 44 | + | Show(ctx context.Context, message string, notifType NotificationType, durationMs int) NotificationID | |||
| 45 | + | ||||
| 46 | + | // ShowZoom displays a special zoom level notification. | |||
| 47 | + | // These typically appear in a fixed position and auto-dismiss. | |||
| 48 | + | ShowZoom(ctx context.Context, zoomPercent int) NotificationID | |||
| 49 | + | ||||
| 50 | + | // Dismiss removes a specific notification by ID. | |||
| 51 | + | Dismiss(ctx context.Context, id NotificationID) | |||
| 52 | + | ||||
| 53 | + | // Clear removes all displayed notifications. | |||
| 54 | + | Clear(ctx context.Context) | |||
| 55 | + | } | |||
A internal/application/port/webview.go +178 -0
| @@ -0,0 +1,178 @@ | |||
| 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.). | |
| 4 | + | package port | |
| 5 | + | ||
| 6 | + | import ( | |
| 7 | + | "context" | |
| 8 | + | ) | |
| 9 | + | ||
| 10 | + | // WebViewID uniquely identifies a WebView instance. | |
| 11 | + | type WebViewID uint64 | |
| 12 | + | ||
| 13 | + | // LoadEvent represents page load state transitions. | |
| 14 | + | type LoadEvent int | |
| 15 | + | ||
| 16 | + | const ( | |
| 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. | |
| 28 | + | func (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. | |
| 45 | + | type 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 | + | // WebViewCallbacks defines callback handlers for WebView events. | |
| 56 | + | // Implementations should invoke these on the main thread/goroutine. | |
| 57 | + | type WebViewCallbacks struct { | |
| 58 | + | // OnLoadChanged is called when load state changes. | |
| 59 | + | OnLoadChanged func(event LoadEvent) | |
| 60 | + | // OnTitleChanged is called when the page title changes. | |
| 61 | + | OnTitleChanged func(title string) | |
| 62 | + | // OnURIChanged is called when the URI changes. | |
| 63 | + | OnURIChanged func(uri string) | |
| 64 | + | // OnProgressChanged is called during page load with progress 0.0-1.0. | |
| 65 | + | OnProgressChanged func(progress float64) | |
| 66 | + | // OnClose is called when the WebView requests to close. | |
| 67 | + | OnClose func() | |
| 68 | + | } | |
| 69 | + | ||
| 70 | + | // WebView defines the port interface for browser view operations. | |
| 71 | + | // This interface abstracts the underlying browser engine (WebKit, etc.) | |
| 72 | + | // and exposes only the navigation and state capabilities needed by | |
| 73 | + | // the application layer. | |
| 74 | + | type WebView interface { | |
| 75 | + | // ID returns the unique identifier for this WebView. | |
| 76 | + | ID() WebViewID | |
| 77 | + | ||
| 78 | + | // --- Navigation --- | |
| 79 | + | ||
| 80 | + | // LoadURI navigates to the specified URI. | |
| 81 | + | LoadURI(ctx context.Context, uri string) error | |
| 82 | + | ||
| 83 | + | // LoadHTML loads HTML content with an optional base URI for relative links. | |
| 84 | + | LoadHTML(ctx context.Context, content, baseURI string) error | |
| 85 | + | ||
| 86 | + | // Reload reloads the current page. | |
| 87 | + | Reload(ctx context.Context) error | |
| 88 | + | ||
| 89 | + | // ReloadBypassCache reloads the current page, bypassing cache. | |
| 90 | + | ReloadBypassCache(ctx context.Context) error | |
| 91 | + | ||
| 92 | + | // Stop stops the current page load. | |
| 93 | + | Stop(ctx context.Context) error | |
| 94 | + | ||
| 95 | + | // GoBack navigates back in history. | |
| 96 | + | // Returns error if back navigation is not possible. | |
| 97 | + | GoBack(ctx context.Context) error | |
| 98 | + | ||
| 99 | + | // GoForward navigates forward in history. | |
| 100 | + | // Returns error if forward navigation is not possible. | |
| 101 | + | GoForward(ctx context.Context) error | |
| 102 | + | ||
| 103 | + | // --- State Queries --- | |
| 104 | + | ||
| 105 | + | // State returns the current WebView state as a snapshot. | |
| 106 | + | State() WebViewState | |
| 107 | + | ||
| 108 | + | // URI returns the current URI. | |
| 109 | + | URI() string | |
| 110 | + | ||
| 111 | + | // Title returns the current page title. | |
| 112 | + | Title() string | |
| 113 | + | ||
| 114 | + | // IsLoading returns true if a page is currently loading. | |
| 115 | + | IsLoading() bool | |
| 116 | + | ||
| 117 | + | // EstimatedProgress returns the load progress (0.0 to 1.0). | |
| 118 | + | EstimatedProgress() float64 | |
| 119 | + | ||
| 120 | + | // CanGoBack returns true if back navigation is available. | |
| 121 | + | CanGoBack() bool | |
| 122 | + | ||
| 123 | + | // CanGoForward returns true if forward navigation is available. | |
| 124 | + | CanGoForward() bool | |
| 125 | + | ||
| 126 | + | // --- Zoom --- | |
| 127 | + | ||
| 128 | + | // SetZoomLevel sets the zoom level (1.0 = 100%). | |
| 129 | + | SetZoomLevel(ctx context.Context, level float64) error | |
| 130 | + | ||
| 131 | + | // GetZoomLevel returns the current zoom level. | |
| 132 | + | GetZoomLevel() float64 | |
| 133 | + | ||
| 134 | + | // --- Callbacks --- | |
| 135 | + | ||
| 136 | + | // SetCallbacks registers callback handlers for WebView events. | |
| 137 | + | // Pass nil to clear all callbacks. | |
| 138 | + | SetCallbacks(callbacks *WebViewCallbacks) | |
| 139 | + | ||
| 140 | + | // --- Lifecycle --- | |
| 141 | + | ||
| 142 | + | // IsDestroyed returns true if the WebView has been destroyed. | |
| 143 | + | IsDestroyed() bool | |
| 144 | + | ||
| 145 | + | // Destroy releases all resources associated with this WebView. | |
| 146 | + | // After calling Destroy, the WebView should not be used. | |
| 147 | + | Destroy() | |
| 148 | + | } | |
| 149 | + | ||
| 150 | + | // WebViewPool defines the port interface for WebView pooling. | |
| 151 | + | // Pools maintain pre-created WebViews for fast tab creation. | |
| 152 | + | type WebViewPool interface { | |
| 153 | + | // Acquire obtains a WebView from the pool or creates a new one. | |
| 154 | + | // The context can be used for cancellation. | |
| 155 | + | Acquire(ctx context.Context) (WebView, error) | |
| 156 | + | ||
| 157 | + | // Release returns a WebView to the pool for reuse. | |
| 158 | + | // The WebView will be reset to a blank state. | |
| 159 | + | // If the pool is full, the WebView will be destroyed. | |
| 160 | + | Release(wv WebView) | |
| 161 | + | ||
| 162 | + | // Prewarm creates WebViews in the background to populate the pool. | |
| 163 | + | // Pass count <= 0 to use the default prewarm count. | |
| 164 | + | Prewarm(count int) | |
| 165 | + | ||
| 166 | + | // Size returns the current number of available WebViews in the pool. | |
| 167 | + | Size() int | |
| 168 | + | ||
| 169 | + | // Close shuts down the pool and destroys all pooled WebViews. | |
| 170 | + | Close() | |
| 171 | + | } | |
| 172 | + | ||
| 173 | + | // WebViewFactory creates new WebView instances. | |
| 174 | + | // This is used when direct WebView creation is needed without pooling. | |
| 175 | + | type WebViewFactory interface { | |
| 176 | + | // Create creates a new WebView instance. | |
| 177 | + | Create(ctx context.Context) (WebView, error) | |
| 178 | + | } | |
| @@ -0,0 +1,178 @@ | |||||
| 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.). | |||
| 4 | + | package port | |||
| 5 | + | ||||
| 6 | + | import ( | |||
| 7 | + | "context" | |||
| 8 | + | ) | |||
| 9 | + | ||||
| 10 | + | // WebViewID uniquely identifies a WebView instance. | |||
| 11 | + | type WebViewID uint64 | |||
| 12 | + | ||||
| 13 | + | // LoadEvent represents page load state transitions. | |||
| 14 | + | type LoadEvent int | |||
| 15 | + | ||||
| 16 | + | const ( | |||
| 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. | |||
| 28 | + | func (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. | |||
| 45 | + | type 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 | + | // WebViewCallbacks defines callback handlers for WebView events. | |||
| 56 | + | // Implementations should invoke these on the main thread/goroutine. | |||
| 57 | + | type WebViewCallbacks struct { | |||
| 58 | + | // OnLoadChanged is called when load state changes. | |||
| 59 | + | OnLoadChanged func(event LoadEvent) | |||
| 60 | + | // OnTitleChanged is called when the page title changes. | |||
| 61 | + | OnTitleChanged func(title string) | |||
| 62 | + | // OnURIChanged is called when the URI changes. | |||
| 63 | + | OnURIChanged func(uri string) | |||
| 64 | + | // OnProgressChanged is called during page load with progress 0.0-1.0. | |||
| 65 | + | OnProgressChanged func(progress float64) | |||
| 66 | + | // OnClose is called when the WebView requests to close. | |||
| 67 | + | OnClose func() | |||
| 68 | + | } | |||
| 69 | + | ||||
| 70 | + | // WebView defines the port interface for browser view operations. | |||
| 71 | + | // This interface abstracts the underlying browser engine (WebKit, etc.) | |||
| 72 | + | // and exposes only the navigation and state capabilities needed by | |||
| 73 | + | // the application layer. | |||
| 74 | + | type WebView interface { | |||
| 75 | + | // ID returns the unique identifier for this WebView. | |||
| 76 | + | ID() WebViewID | |||
| 77 | + | ||||
| 78 | + | // --- Navigation --- | |||
| 79 | + | ||||
| 80 | + | // LoadURI navigates to the specified URI. | |||
| 81 | + | LoadURI(ctx context.Context, uri string) error | |||
| 82 | + | ||||
| 83 | + | // LoadHTML loads HTML content with an optional base URI for relative links. | |||
| 84 | + | LoadHTML(ctx context.Context, content, baseURI string) error | |||
| 85 | + | ||||
| 86 | + | // Reload reloads the current page. | |||
| 87 | + | Reload(ctx context.Context) error | |||
| 88 | + | ||||
| 89 | + | // ReloadBypassCache reloads the current page, bypassing cache. | |||
| 90 | + | ReloadBypassCache(ctx context.Context) error | |||
| 91 | + | ||||
| 92 | + | // Stop stops the current page load. | |||
| 93 | + | Stop(ctx context.Context) error | |||
| 94 | + | ||||
| 95 | + | // GoBack navigates back in history. | |||
| 96 | + | // Returns error if back navigation is not possible. | |||
| 97 | + | GoBack(ctx context.Context) error | |||
| 98 | + | ||||
| 99 | + | // GoForward navigates forward in history. | |||
| 100 | + | // Returns error if forward navigation is not possible. | |||
| 101 | + | GoForward(ctx context.Context) error | |||
| 102 | + | ||||
| 103 | + | // --- State Queries --- | |||
| 104 | + | ||||
| 105 | + | // State returns the current WebView state as a snapshot. | |||
| 106 | + | State() WebViewState | |||
| 107 | + | ||||
| 108 | + | // URI returns the current URI. | |||
| 109 | + | URI() string | |||
| 110 | + | ||||
| 111 | + | // Title returns the current page title. | |||
| 112 | + | Title() string | |||
| 113 | + | ||||
| 114 | + | // IsLoading returns true if a page is currently loading. | |||
| 115 | + | IsLoading() bool | |||
| 116 | + | ||||
| 117 | + | // EstimatedProgress returns the load progress (0.0 to 1.0). | |||
| 118 | + | EstimatedProgress() float64 | |||
| 119 | + | ||||
| 120 | + | // CanGoBack returns true if back navigation is available. | |||
| 121 | + | CanGoBack() bool | |||
| 122 | + | ||||
| 123 | + | // CanGoForward returns true if forward navigation is available. | |||
| 124 | + | CanGoForward() bool | |||
| 125 | + | ||||
| 126 | + | // --- Zoom --- | |||
| 127 | + | ||||
| 128 | + | // SetZoomLevel sets the zoom level (1.0 = 100%). | |||
| 129 | + | SetZoomLevel(ctx context.Context, level float64) error | |||
| 130 | + | ||||
| 131 | + | // GetZoomLevel returns the current zoom level. | |||
| 132 | + | GetZoomLevel() float64 | |||
| 133 | + | ||||
| 134 | + | // --- Callbacks --- | |||
| 135 | + | ||||
| 136 | + | // SetCallbacks registers callback handlers for WebView events. | |||
| 137 | + | // Pass nil to clear all callbacks. | |||
| 138 | + | SetCallbacks(callbacks *WebViewCallbacks) | |||
| 139 | + | ||||
| 140 | + | // --- Lifecycle --- | |||
| 141 | + | ||||
| 142 | + | // IsDestroyed returns true if the WebView has been destroyed. | |||
| 143 | + | IsDestroyed() bool | |||
| 144 | + | ||||
| 145 | + | // Destroy releases all resources associated with this WebView. | |||
| 146 | + | // After calling Destroy, the WebView should not be used. | |||
| 147 | + | Destroy() | |||
| 148 | + | } | |||
| 149 | + | ||||
| 150 | + | // WebViewPool defines the port interface for WebView pooling. | |||
| 151 | + | // Pools maintain pre-created WebViews for fast tab creation. | |||
| 152 | + | type WebViewPool interface { | |||
| 153 | + | // Acquire obtains a WebView from the pool or creates a new one. | |||
| 154 | + | // The context can be used for cancellation. | |||
| 155 | + | Acquire(ctx context.Context) (WebView, error) | |||
| 156 | + | ||||
| 157 | + | // Release returns a WebView to the pool for reuse. | |||
| 158 | + | // The WebView will be reset to a blank state. | |||
| 159 | + | // If the pool is full, the WebView will be destroyed. | |||
| 160 | + | Release(wv WebView) | |||
| 161 | + | ||||
| 162 | + | // Prewarm creates WebViews in the background to populate the pool. | |||
| 163 | + | // Pass count <= 0 to use the default prewarm count. | |||
| 164 | + | Prewarm(count int) | |||
| 165 | + | ||||
| 166 | + | // Size returns the current number of available WebViews in the pool. | |||
| 167 | + | Size() int | |||
| 168 | + | ||||
| 169 | + | // Close shuts down the pool and destroys all pooled WebViews. | |||
| 170 | + | Close() | |||
| 171 | + | } | |||
| 172 | + | ||||
| 173 | + | // WebViewFactory creates new WebView instances. | |||
| 174 | + | // This is used when direct WebView creation is needed without pooling. | |||
| 175 | + | type WebViewFactory interface { | |||
| 176 | + | // Create creates a new WebView instance. | |||
| 177 | + | Create(ctx context.Context) (WebView, error) | |||
| 178 | + | } | |||