fix(webkit): add cookie persistence and title change notifications
- commit
- cb46c3d6a58a1b3a84103ef8fd01287912c359ab
- author
- brice · · 2025-12-15 20:04 UTC
- committer
- brice · · 2025-12-15 20:15 UTC
- parent
- 08a887b
- signature
- unsigned
1 file · +20 -6
M internal/infrastructure/webkit/webview.go +20 -6
| @@ -10,6 +10,8 @@ import ( | |||
| 10 | 10 | "github.com/bnema/dumber/internal/logging" | |
| 11 | 11 | "github.com/bnema/puregotk-webkit/webkit" | |
| 12 | 12 | "github.com/jwijenbergh/puregotk/v4/gio" | |
| 13 | + | "github.com/jwijenbergh/puregotk/v4/glib" | |
| 14 | + | "github.com/jwijenbergh/puregotk/v4/gobject" | |
| 13 | 15 | "github.com/jwijenbergh/puregotk/v4/gtk" | |
| 14 | 16 | "github.com/rs/zerolog" | |
| 15 | 17 | ) | |
| @@ -113,6 +115,7 @@ type WebView struct { | |||
| 113 | 115 | } | |
| 114 | 116 | ||
| 115 | 117 | // NewWebView creates a new WebView with the given context and settings. | |
| 118 | + | // Uses the persistent NetworkSession from wkCtx for cookie/data persistence. | |
| 116 | 119 | func NewWebView(ctx context.Context, wkCtx *WebKitContext, settings *SettingsManager) (*WebView, error) { | |
| 117 | 120 | log := logging.FromContext(ctx) | |
| 118 | 121 | ||
| @@ -120,9 +123,10 @@ func NewWebView(ctx context.Context, wkCtx *WebKitContext, settings *SettingsMan | |||
| 120 | 123 | return nil, fmt.Errorf("webkit context not initialized") | |
| 121 | 124 | } | |
| 122 | 125 | ||
| 123 | - | inner := webkit.NewWebView() | |
| 126 | + | // Use NetworkSession-aware constructor for persistent cookie storage | |
| 127 | + | inner := webkit.NewWebViewWithNetworkSession(wkCtx.NetworkSession()) | |
| 124 | 128 | if inner == nil { | |
| 125 | - | return nil, fmt.Errorf("failed to create webkit webview") | |
| 129 | + | return nil, fmt.Errorf("failed to create webkit webview with network session") | |
| 126 | 130 | } | |
| 127 | 131 | ||
| 128 | 132 | wv := &WebView{ | |
| @@ -275,10 +279,20 @@ func (wv *WebView) connectSignals() { | |||
| 275 | 279 | sigID = wv.inner.ConnectReadyToShow(&readyToShowCb) | |
| 276 | 280 | wv.signalIDs = append(wv.signalIDs, sigID) | |
| 277 | 281 | ||
| 278 | - | // Note: notify::title, notify::uri, notify::estimated-load-progress | |
| 279 | - | // would need GObject property change notifications which may require | |
| 280 | - | // different API patterns in puregotk. For now, we update these in | |
| 281 | - | // load-changed which covers most cases. | |
| 282 | + | // notify::title signal for title changes | |
| 283 | + | // This fires when the page title changes (e.g., after page load, SPA navigation) | |
| 284 | + | titleCb := func() { | |
| 285 | + | title := wv.inner.GetTitle() | |
| 286 | + | wv.mu.Lock() | |
| 287 | + | wv.title = title | |
| 288 | + | wv.mu.Unlock() | |
| 289 | + | ||
| 290 | + | if wv.OnTitleChanged != nil { | |
| 291 | + | wv.OnTitleChanged(title) | |
| 292 | + | } | |
| 293 | + | } | |
| 294 | + | sigID = gobject.SignalConnect(wv.inner.GoPointer(), "notify::title", glib.NewCallback(&titleCb)) | |
| 295 | + | wv.signalIDs = append(wv.signalIDs, sigID) | |
| 282 | 296 | } | |
| 283 | 297 | ||
| 284 | 298 | // ID returns the unique identifier for this WebView. | |
| @@ -10,6 +10,8 @@ import ( | |||||
| 10 | "github.com/bnema/dumber/internal/logging" | 10 | "github.com/bnema/dumber/internal/logging" | ||
| 11 | "github.com/bnema/puregotk-webkit/webkit" | 11 | "github.com/bnema/puregotk-webkit/webkit" | ||
| 12 | "github.com/jwijenbergh/puregotk/v4/gio" | 12 | "github.com/jwijenbergh/puregotk/v4/gio" | ||
| 13 | + | "github.com/jwijenbergh/puregotk/v4/glib" | |||
| 14 | + | "github.com/jwijenbergh/puregotk/v4/gobject" | |||
| 13 | "github.com/jwijenbergh/puregotk/v4/gtk" | 15 | "github.com/jwijenbergh/puregotk/v4/gtk" | ||
| 14 | "github.com/rs/zerolog" | 16 | "github.com/rs/zerolog" | ||
| 15 | ) | 17 | ) | ||
| @@ -113,6 +115,7 @@ type WebView struct { | |||||
| 113 | } | 115 | } | ||
| 114 | 116 | ||||
| 115 | // NewWebView creates a new WebView with the given context and settings. | 117 | // NewWebView creates a new WebView with the given context and settings. | ||
| 118 | + | // Uses the persistent NetworkSession from wkCtx for cookie/data persistence. | |||
| 116 | func NewWebView(ctx context.Context, wkCtx *WebKitContext, settings *SettingsManager) (*WebView, error) { | 119 | func NewWebView(ctx context.Context, wkCtx *WebKitContext, settings *SettingsManager) (*WebView, error) { | ||
| 117 | log := logging.FromContext(ctx) | 120 | log := logging.FromContext(ctx) | ||
| 118 | 121 | ||||
| @@ -120,9 +123,10 @@ func NewWebView(ctx context.Context, wkCtx *WebKitContext, settings *SettingsMan | |||||
| 120 | return nil, fmt.Errorf("webkit context not initialized") | 123 | return nil, fmt.Errorf("webkit context not initialized") | ||
| 121 | } | 124 | } | ||
| 122 | 125 | ||||
| 123 | - | inner := webkit.NewWebView() | 126 | + | // Use NetworkSession-aware constructor for persistent cookie storage |
| 127 | + | inner := webkit.NewWebViewWithNetworkSession(wkCtx.NetworkSession()) | |||
| 124 | if inner == nil { | 128 | if inner == nil { | ||
| 125 | - | return nil, fmt.Errorf("failed to create webkit webview") | 129 | + | return nil, fmt.Errorf("failed to create webkit webview with network session") |
| 126 | } | 130 | } | ||
| 127 | 131 | ||||
| 128 | wv := &WebView{ | 132 | wv := &WebView{ | ||
| @@ -275,10 +279,20 @@ func (wv *WebView) connectSignals() { | |||||
| 275 | sigID = wv.inner.ConnectReadyToShow(&readyToShowCb) | 279 | sigID = wv.inner.ConnectReadyToShow(&readyToShowCb) | ||
| 276 | wv.signalIDs = append(wv.signalIDs, sigID) | 280 | wv.signalIDs = append(wv.signalIDs, sigID) | ||
| 277 | 281 | ||||
| 278 | - | // Note: notify::title, notify::uri, notify::estimated-load-progress | 282 | + | // notify::title signal for title changes |
| 279 | - | // would need GObject property change notifications which may require | 283 | + | // This fires when the page title changes (e.g., after page load, SPA navigation) |
| 280 | - | // different API patterns in puregotk. For now, we update these in | 284 | + | titleCb := func() { |
| 281 | - | // load-changed which covers most cases. | 285 | + | title := wv.inner.GetTitle() |
| 286 | + | wv.mu.Lock() | |||
| 287 | + | wv.title = title | |||
| 288 | + | wv.mu.Unlock() | |||
| 289 | + | ||||
| 290 | + | if wv.OnTitleChanged != nil { | |||
| 291 | + | wv.OnTitleChanged(title) | |||
| 292 | + | } | |||
| 293 | + | } | |||
| 294 | + | sigID = gobject.SignalConnect(wv.inner.GoPointer(), "notify::title", glib.NewCallback(&titleCb)) | |||
| 295 | + | wv.signalIDs = append(wv.signalIDs, sigID) | |||
| 282 | } | 296 | } | ||
| 283 | 297 | ||||
| 284 | // ID returns the unique identifier for this WebView. | 298 | // ID returns the unique identifier for this WebView. | ||