Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: upgrade to Manifest V3 #101

Merged
merged 4 commits into from
Jan 19, 2025
Merged

feat: upgrade to Manifest V3 #101

merged 4 commits into from
Jan 19, 2025

Conversation

AprilSylph
Copy link
Owner

@AprilSylph AprilSylph commented Jan 10, 2025

Links

Changelog

  • 2fe52a3 chore(deps): remove webextension-polyfill
    Removed the webextension-polyfill dependency in favour of using the chrome global directly, since this namespace has promises enabled in Manifest V3.
  • 63e9d38 feat: upgrade to Manifest V3
    Upgraded the extension to cross-browser Manifest V3:
    • Changed manifest_version: 23
    • Changed browser_action/browserActionaction
    • Added background.service_worker for Chrome compatibility
    • Removed background.persistent (defaults to false in MV3)
    • Added host_permissions
    • Changed optional_permissionsoptional_host_permissions
    • Updated the minimum browser versions to Chrome 121+ and Firefox 128+ for cross-browser compatibility
  • 659c7e2 fix: use session storage for request ID handling
    As per this comment, removed the handledRequests Map in favour of chrome.storage.session interactions for increased robustness when considering the now non-persistent nature of the background script.

I opted not to implement the host permissions banner since that shouldn't be a problem for the targeted browser versions, although it would be problematic for anyone trying to run this on Safari (which we do not officially support).

Testing steps

Chrome

  • The extension can be installed without any real errors
    (expected: one warning about background.scripts being unsupported)
  • The outbox page can be opened via the toolbar action
  • The outbox page loads saved items, if there are any
  • The outbox page can export saved items to a file
  • The outbox page can import saved items from a file
  • The extension can properly save a non-anonymous ask sent via www.tumblr.com (i.e. it only saves one copy)
  • The extension can properly save an anonymous ask sent via www.tumblr.com
  • The extension can properly save a private answer sent via www.tumblr.com/inbox
  • The extension can properly save an ask sent via *.tumblr.com/ask
  • The extension properly handles errors for asks sent via www.tumblr.com (i.e. the error banner appears on that item in the outbox page)
    (easy repro: open the ask form for a blog you control, disable asks for that blog, then try to send an ask)
  • The extension properly handles errors for asks sent via *.tumblr.com/ask

Firefox

  • The extension can be installed without any real errors
    (expected: one warning about background.service_worker being unrecognised)
  • The outbox page can be opened via the toolbar action
  • The outbox page loads saved items, if there are any
  • The outbox page can export saved items to a file
  • The outbox page can import saved items from a file
  • The extension can properly save a non-anonymous ask sent via www.tumblr.com
  • The extension can properly save an anonymous ask sent via www.tumblr.com
  • The extension can properly save a private answer sent via www.tumblr.com/inbox
  • The extension can properly save an ask sent via *.tumblr.com/ask
  • The extension properly handles errors for asks sent via www.tumblr.com
  • The extension properly handles errors for asks sent via *.tumblr.com/ask

AprilSylph and others added 3 commits January 10, 2025 16:09
Co-authored-by: Marcus <marcustyphoon@gmail.com>
fixes a theoretical bug where request error handling does not work due to the background script/sw being destroyed and recreated between onBeforeRequest firing and onErrorOccurred/onCompleted firing for the same request
@AprilSylph
Copy link
Owner Author

cc @marcustyphoon, forgot you're not a collaborator here yet (sent you an invite now). Consider this a review request 😁

@marcustyphoon marcustyphoon self-requested a review January 10, 2025 22:14
@marcustyphoon
Copy link
Collaborator

I opted not to implement the host permissions banner since that shouldn't be a problem for the targeted browser versions

I... think this is fine. After reading https://bugzilla.mozilla.org/show_bug.cgi?id=1889402 and https://bugzilla.mozilla.org/show_bug.cgi?id=1893232 I believe that it would be an issue if we were to add another host permission in the future, but as-is Firefox users should be prompted on install and can toggle the permission later in the preference pane no matter what they choose.

Chrome users are still, somewhat mysteriously, not given any UI for this, so I guess we're just hoping there's no way to deny the permission during the install flow.

@marcustyphoon
Copy link
Collaborator

marcustyphoon commented Jan 11, 2025

The extension can properly save a non-anonymous ask sent via www.tumblr.com (i.e. it only saves one copy)

The issue of duplicate asks being saved is interesting. I do encounter duplicate asks, but I'm trying to pin down exactly when, and thus whether it's just due to the web-ext run automatic extension reload. (In fairness, if it is, it's possible that that will occur in practice after a Firefox automatic extension update, given that I solved web-ext run issues in order to solve a production Firefox autoupdate issue in XKit Rewritten.)

Ah—nope, I can trigger it with npx web-ext run --no-reload by toggling the extension off and on. Interestingly, it seems to be prevented by this modification:

 chrome.webRequest.onBeforeRequest.addListener(async ({ method, requestBody, requestId, timeStamp, url }) => {
+  await new Promise(resolve => setTimeout(resolve, 2000 * Math.random()));
   const { [requestId]: savedTimeStamp } = await chrome.storage.session.get(requestId);
   if (savedTimeStamp) {

I can't say I fully understand what's happening here, but as you can probably tell from what I tried there, my first thought is that this is a symptom of session storage access being asynchronous. If there can be a time gap between the read of and write to session storage, then another onBeforeRequest handler could do a read during that time gap; I didn't think of an obvious way to prevent this race condition if it exists, but adding a random delay to the handler would make it much less likely that a read would be attempted during a different handler's specific problematic time window. Since that seems to help, I... assume that's what's happening? (Of course one can't actually use this technique without also delaying the onCompleted/onError handlers.)

Edit: One way to solve this is to leave the synchronous deduplication code in place, adding the session storage as a fallback. See the mentioning PR.

@AprilSylph
Copy link
Owner Author

Ping for re-review @marcustyphoon

Copy link
Collaborator

@marcustyphoon marcustyphoon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Smoke tested in Firefox 128 and Chromium 121.

@AprilSylph AprilSylph merged commit c7030e7 into main Jan 19, 2025
1 check passed
@AprilSylph AprilSylph deleted the manifest-v3 branch January 19, 2025 21:52
@AprilSylph AprilSylph linked an issue Jan 19, 2025 that may be closed by this pull request
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.

upgrade to Manifest V3
2 participants