Skip to content

fix(webview): stop URL bar revert and pubsub handler leak (#1482)#1493

Open
thingnoy wants to merge 1 commit intoresponsively-org:mainfrom
thingnoy:fix/address-bar-url-revert
Open

fix(webview): stop URL bar revert and pubsub handler leak (#1482)#1493
thingnoy wants to merge 1 commit intoresponsively-org:mainfrom
thingnoy:fix/address-bar-url-revert

Conversation

@thingnoy
Copy link
Copy Markdown

✨ Pull Request

📓 Referenced Issue

Fixes: #1482


ℹ️ About the PR

Two related fixes for desktop-app/src/renderer/components/Previewer/Device/index.tsx. They are independent in scope but small enough to review together.

🐛 Bug 1 — Address bar URL revert (the user-visible #1482 symptom)

The webview is bound twice to the Redux address:

  1. JSX: <webview src={address} ... /> — React updates the src attribute whenever Redux changes.
  2. useEffect: ref.current.loadURL(address) — also calls loadURL whenever Redux changes.

After Electron 40 (#1473), these two paths race for primary devices, and for non-primary devices the useEffect was guarded by isPrimary, leaving secondary previews navigating only via src reactivity. The end result on Linux/Windows builds was the webview getting wedged on the first URL — typing a new URL in the address bar dispatches setAddress, but <webview> does not actually navigate.

Fix: Drop reactive src updates and route every navigation through loadURL:

  • Capture the address once on mount as initialAddress and pass that to <webview src>.
  • Remove the isPrimary guard from the loadURL effect so secondary devices stay in sync too. The isNavigatingFromAddressBar flag remains primary-only because only the primary device's webview drives address-bar state.

This matches the approach in #1486; this PR is a clean version that does not also delete release/app/{package.json,package-lock.json,yarn.lock}.

🐛 Bug 2 — PubSub subscriber leak on Back/Forward/Reload/Delete Cache/Cookies/Storage

registerNavigationHandlers calls webViewPubSub.subscribe(...) for RELOAD, BACK, FORWARD, DELETE_STORAGE, DELETE_COOKIES, DELETE_CACHE. It is invoked from a useEffect whose dependency list includes address, so it runs on every navigation. There is no matching unsubscribe in the cleanup, so subscribers accumulate without bound.

After N navigations, a single Back/Forward/Reload click fires N copies of the handler. goBack() / goForward() then jump multiple history entries (or queue rapidly), and Delete Cookies/Cache/Storage make redundant IPC calls.

Fix: Have registerNavigationHandlers return an unsubscribe function that removes every handler it subscribed. The big effect now stores that fn and invokes it from cleanup alongside the existing webview-event removers.


🎯 Result

  • Typing a new URL navigates reliably on Electron 40+, including on a secondary preview that previously only saw src updates.
  • Back / Forward each step exactly one history entry, regardless of how long the session has been running.
  • Delete Cookies/Cache/Storage trigger a single IPC call per click instead of one per accumulated subscription.

🖼️ Testing

  • Loaded multiple sites (google.com, github.com, an internal site that 302-redirects unauthenticated users) and verified the address bar reflects what the user typed and the webview navigates accordingly.
  • Pressed Back/Forward repeatedly across a navigation history of 10+ entries — each click moves exactly one step.
  • Delete Cookies/Cache/Storage invoked once, observed a single IPC call in the main process logs.
  • yarn typecheck passes.

🔍 Files changed

  • desktop-app/src/renderer/components/Previewer/Device/index.tsx only.

…ly-org#1482)

Two related issues in desktop-app/src/renderer/components/Previewer/Device/index.tsx:

1. Address-bar URL revert / "navigation does nothing" (issue responsively-org#1482)

   <webview src={address}> bound to Redux address competed with
   ref.current.loadURL(address) in the [address] effect. After the
   Electron 40 upgrade (responsively-org#1473) this race left the webview wedged on
   the previously loaded URL — typing a new URL and pressing Enter
   updated Redux but did not actually navigate. Secondary devices were
   even worse, since the loadURL effect was guarded by isPrimary and
   they relied solely on src reactivity.

   Fix: capture the address once on mount as initialAddress and pass
   that to <webview src>, then route every navigation through loadURL.
   Removed the isPrimary guard from the loadURL effect so secondary
   devices stay in sync; the isNavigatingFromAddressBar flag remains
   primary-only because only the primary device's webview drives
   address-bar state.

2. PubSub subscriber leak on Back / Forward / Reload / Delete *

   registerNavigationHandlers subscribed to RELOAD/BACK/FORWARD and the
   DELETE_STORAGE/COOKIES/CACHE topics, but it ran from a useEffect
   whose deps included address. Every navigation re-ran the effect
   and added another subscriber without removing the previous one.
   After N navigations a single Back click replayed the handler N
   times, jumping multiple history entries.

   Fix: registerNavigationHandlers now returns an unsubscribe fn that
   removes every handler it subscribed; the big effect stores it and
   invokes it from cleanup alongside the existing webview-event
   removers.

yarn typecheck passes.
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Not changing website when entering new URL

2 participants