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

Improve browser detection fix #68 #86

Closed
wants to merge 1 commit into from

Conversation

HaNdTriX
Copy link

By checking window.browser the webpack.ProvidePlugin won’t be confused.

By checking window.browser the webpack.ProvidePlugin won’t be confused.
@HaNdTriX
Copy link
Author

HaNdTriX commented Mar 21, 2018

@rpl is there anything I can help you with to get the PR merged?
What are the cons of using window.browser?

@HaNdTriX
Copy link
Author

HaNdTriX commented Mar 28, 2018

Just in case anyone is interested in a way to temporarily solve this issue without forking this package.
You can use the string-replace-loader module to monkey patch webextension-polyfill on the fly.

Just add the following loader to your webpack config:

@@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";

if (typeof browser === "undefined") {
if (typeof window.browser === "undefined") {
Copy link
Contributor

@ExE-Boss ExE-Boss May 12, 2018

Choose a reason for hiding this comment

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

Quoting myself from #68 (comment):

I personally prefer using:

if (!("browser" in window)) {
    // [...]
}

because using window.browser directly when testing if it exists tends to print dereferencing an undefined reference warnings in the console.

Edit: Turns out that that causes the tests to fail because of jsdom/jsdom#1622:

// Set (or reset) the browser property.
if (browserObject) {
window.browser = browserObject;
} else {
// TODO: change into `delete window.browser` once tmpvar/jsdom#1622 has been fixed.
window.browser = undefined;
}

But using this function works:

const isDefined = (obj, key) => {
  if (typeof obj !== "object" || obj === null) {
    return false;
  }
  return key in obj && typeof obj[key] !== "undefined";
};

Edit 2: Turns out that that doesn’t work either because of #114 (comment) and #115 (comment)

@Rob--W
Copy link
Member

Rob--W commented Jul 5, 2018

The polyfill is supposed to be a no-op (not doing anything) in Firefox. In a content script, window.browser is undefined in Firefox, so this PR would incorrectly cause the global browser object to be replaced in Firefox.

Would #86 (comment), using this.browser instead of window.browser work? So that the output becomes something like this:

if (this.browser === undefined && window.browser === undefined) {
}

I'm closing the issue anyway, since there is a merge conflict and we intend to change the detection logic for Edge support (#3).

@Rob--W Rob--W closed this Jul 5, 2018
@vitalets
Copy link

So what is the suggested solution for using with webpack.ProvidePlugin?
The following does not work for me:

 plugins: [
    new webpack.ProvidePlugin({
      browser: ['webextension-polyfill'],
    }),
 ]

@HaNdTriX
Copy link
Author

HaNdTriX commented Aug 15, 2018

We are using the polyfill with webpack in the following way:
https://github.com/webextension-toolbox/webextension-toolbox/blob/master/src/webpack-config.js#L116-L134

@HaNdTriX HaNdTriX deleted the webpack branch August 15, 2018 08:54
@ExE-Boss
Copy link
Contributor

ExE-Boss commented Aug 15, 2018

@HaNdTriX

We are using the polyfill with webpack in the following way: https://github.com/webextension-toolbox/webextension-toolbox/blob/master/src/webpack-config.js#L116-L134

// The webextension-polyill doesn't work well with webpacks ProvidePlugin.
// So we need to monkey patch it on the fly
// More info: https://github.com/mozilla/webextension-polyfill/pull/86
config.module.rules.push({
  test: /webextension-polyfill[\\/]+dist[\\/]+browser-polyfill\.js$/,
  loader: require.resolve('string-replace-loader'),
  query: {
    search: 'typeof browser === "undefined"',
    replace: 'typeof window.browser === "undefined"'
  }
});

That won’t work on Firefox in content scripts, as in content scripts on Firefox, this !== window, it’s why #114 took me so long to get right.

See also b3609f7.

@Rob--W
Copy link
Member

Rob--W commented Aug 15, 2018

Just comparing with undefined is not solid. See #153 .

@vitalets
Copy link

@HaNdTriX Thanks for solution.

@Rob--W What about adding a short note about incompatibility with webpack.ProvidePlugin to the readme? It's not obvious and may take a long time to discover why it's not working. As from webpack docs Provide plugin is equivalent to require / import.

@Rob--W
Copy link
Member

Rob--W commented Aug 15, 2018

@vitalets The solution from @HaNdTriX should not be used, because 1) it causes the polyfill to load unconditionally in Firefox, and 2) it causes the polyfill to break in web pages that trigger registration of the "browser" global (see #153).

I don't have a solution ready yet, but for the time being I have opened #156 to track documentation of this feature.

@HaNdTriX
Copy link
Author

HaNdTriX commented Aug 15, 2018

@Rob--W Thanks for letting me know. Nevertheless we check inside webpack and exclude the polyfill for firefox anyway.

Here is our current workaround. Please keep in mind that on firefox these lines will be omitted.

@NN---
Copy link

NN--- commented Nov 3, 2018

@HaNdTriX

@rpl is there anything I can help you with to get the PR merged?
What are the cons of using window.browser?

In Firefox window.browser is undefined as opposed to browser.
https://bugzilla.mozilla.org/show_bug.cgi?id=1208775

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.

None yet

5 participants