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

Add Firefox support #1154

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

DaPotatoMan
Copy link

@DaPotatoMan DaPotatoMan commented Mar 23, 2024

resolves #1105
This PR adds support for Firefox.

Userland usage

Background script

import '@inboxsdk/core/background'

Content script

import '@inboxsdk/core/firefox'
import InboxSDK from '@inboxsdk/core'

InboxSDK.load(...);

Additional Notes

import '@inboxsdk/core/firefox'

This additional import is mandatory until firefox fixes MAIN world execution in content scripts (See here).

@wegry

This comment was marked as resolved.

@wegry wegry requested a review from Macil March 25, 2024 14:13
@DaPotatoMan

This comment was marked as resolved.

Copy link
Contributor

@wegry wegry left a comment

Choose a reason for hiding this comment

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

@Macil and I would want any new MV2 specific bits to be dropped prior to accepting this PR.

examples/firefox-mv2/content.js Outdated Show resolved Hide resolved
examples/firefox-mv2/manifest.json Outdated Show resolved Hide resolved
examples/firefox-mv2/monkey.png Outdated Show resolved Hide resolved
src/common/get-extension-id.ts Outdated Show resolved Hide resolved
src/common/load-script.ts Outdated Show resolved Hide resolved
@DaPotatoMan

This comment was marked as resolved.

@DaPotatoMan DaPotatoMan requested a review from wegry March 27, 2024 11:06
Copy link
Contributor

@wegry wegry left a comment

Choose a reason for hiding this comment

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

Thanks for the changes.

@Macil

This comment was marked as resolved.

@wegry

This comment was marked as resolved.

@Macil

This comment was marked as resolved.

@Macil
Copy link
Member

Macil commented Apr 2, 2024

@wegry brought to my intention that the injectScriptImplementation() function inside src/platform-implementation-js/lib/inject-script.ts is set up to avoid including any references to direct script injection so we don't fail some certain Chrome Web Store static analysis of our npm/MV3 build, so we can't put an if-check in there for Firefox to do a direct script injection as I first suggested above. The script injection code needs to not be included in a bundle created by importing our main entry point.

Spelling out my second suggestion a little further: we can add a packages/core/firefox.js file with this content:

import {_setInjectScriptImplementation} from './inboxsdk';
_setInjectScriptImplementation(() => {
  const script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = browser.runtime.getURL('pageWorld.js');
  document.documentElement.appendChild(script);
});
export * from './inboxsdk';

and a packages/core/firefox.d.ts:

export * from './inboxsdk';

and we need to make sure that it's guaranteed that the injectScriptImplementation function is only called asynchronously after the InboxSDK import. I think this may already be the case because of an await import happening on the path to it in src/platform-implementation-js/main.ts, but we can make it explicit by editing src/platform-implementation-js/dom-driver/gmail/make-xhr-interceptor.ts to have

  // Call injectScript asynchronously so InboxSDK alt imports like firefox.js can patch it first
  var pageCommunicatorPromise = Promise.resolve().then(injectScript).then(() => pageCommunicator);

(A cleaner solution that didn't need the asynchronous call to injectScript would be for us to not bundle the InboxSDK in our npm release, and then the firefox.js module could import a module that overrides the inject script function before importing and re-exporting the main InboxSDK entrypoint. But it's not so much cleaner that we need to jump to that now.)

@DaPotatoMan
Copy link
Author

@Macil Taking your suggestion into account, I've removed all setInjectScriptImplementation reliance from the code and added a @inboxsdk/core/firefox import

So userland usage will now work like this (firefox content script):

import InboxSDK from '@inboxsdk/core/firefox'
How it works

Background

In the background.js script the inboxsdk__injectPageWorld event is sent back to the sender tab (content script) if the browser is firefox

browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
const eventKey = 'inboxsdk__injectPageWorld';
if (message.type === eventKey && sender.tab) {
// Relay event to firefox content script handler
if (isFirefox) {
return browser.tabs.sendMessage(sender.tab.id, { type: eventKey });
}

Content script

I've added inboxsdk-FIREFOX.ts file which listens for the event and injects pageWorld.js

import { browser } from '../common/extension-apis';
import InboxSDK from './inboxsdk-NONREMOTE';
browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === 'inboxsdk__injectPageWorld') {
const script = document.createElement('script');
script.type = 'text/javascript';
script.src = browser.runtime.getURL('pageWorld.js');
script.onload = () => console.log('InboxSDK: pageWorld.js has been loaded');
script.onerror = (error) =>
console.error('InboxSDK: pageWorld.js failed to load\n\n', error);
document.head.appendChild(script);
console.log('InboxSDK: pageWorld.js manually injected!');
sendResponse(true);
}
});
export default InboxSDK;

This method eliminates the need for setInjectScriptImplementation usage and further simplifies the implementation.

Additional notes

Build config

I've added the firefox entry to the gulpfile.babel.ts here,
But I'm unsure if I have to add the entry in other places as well.

InboxSDK/gulpfile.babel.ts

Lines 402 to 409 in 21d765d

firefox: {
library: {
export: 'default',
name: 'InboxSDK',
type: OutputLibraryType.UMD,
},
import: './src/inboxsdk-js/inboxsdk-FIREFOX',
},

Please let me know if these changes satisfy your concerns.

@DaPotatoMan DaPotatoMan requested a review from wegry April 5, 2024 07:05
packages/core/background.js Outdated Show resolved Hide resolved
gulpfile.babel.ts Outdated Show resolved Hide resolved
@DaPotatoMan DaPotatoMan requested a review from wegry April 6, 2024 08:59
Copy link
Contributor

@wegry wegry left a comment

Choose a reason for hiding this comment

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

LGTM.

@wegry
Copy link
Contributor

wegry commented Apr 11, 2024

I think what we're waiting for prior to a merge is @Macil will sign off on this as well.

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.

FR: Firefox Support
3 participants