Firefox Extension: Error calling executeScript on file but not code
Asked Answered
S

3

11

I'm trying to execute a script in a new tab when that tab is opened.

In my background script I have:

var listener = function (tab) {
    browser.tabs.executeScript(null, { file: "content_scripts/contentScript.js" });
}

browser.tabs.onCreated.addListener(listener);

In contentScript.js:

function foo() {
    console.log("Executed");
}

foo();

From this I get the following error:

Error: Permission denied to access property "chrome"

If I simply execute code rather than call a js script, ex:

browser.tabs.executeScript(null, { code: "console.log("Executed") });

This does not cause the error. Any idea what is causing this?

Stat answered 24/5, 2016 at 17:2 Comment(3)
I think you have to go to manifest.json and set that file as webaccessible, did you try that?Katusha
The first parameter of executeScript is optional, you can remove the null. About the web_accessible_resources, it is not mentionned on the executeScript page and at least in FF48 it wasn't necessary.Keniakenilworth
Why are you injecting scripts manually in the first place? Just add them as content scripts in the manifest.json and the browser will take care of injecting them at the right time.Divulgate
C
2

It doesn't work properly because apparently this bug has not been fixed and still exists in Firefox 59.

You can work around the issue by letting the tab load for some milliseconds before running executeScript on it.

I have tested this an it works for me:

(Remember that this does not work for new blank tabs as in "about:newtab". These can not be accessed for security reasons.)

background.js

var listener = function (tab) {
    setTimeout(()=>{
        browser.tabs.executeScript(tab.id, {file: "/content_scripts/contentScript.js"}).then(()=>{
            console.log("Executed!")
        }).catch(err=>{
            console.error("Not executed:")
            console.error(err)
        })
    },1000) // Add a delay because of this bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1254003
}

browser.tabs.onCreated.addListener(listener);

content_scripts/contentScript.js

function foo() {
    console.log("Executed");
    alert("Executed!");
}

foo();

manifest.json

{

  "description": "Test executeScript api",
  "manifest_version": 2,
  "name": "ExecuteScript-Test",
  "version": "1.0",

  "permissions": [
    "activeTab",
    "tabs",
    "<all_urls>"
  ],

  "background": {
    "scripts": ["background.js"]
  }

}
Cicero answered 8/5, 2018 at 9:40 Comment(1)
Here is setTimeout wrapped in a Promise to make it easier to delay until some operation is finished (in this case, waiting for the tab to be ready for injection): // Wrap setTimeout in a Promise function delay(msec,value) { return new Promise(function(OKFunction) { setTimeout(OKFunction,msec,value); }); } // delaySterilization
S
0

If FF developers docs it's said:

In Firefox, relative URLs passed into tabs.executeScript() or tabs.insertCSS() are resolved relative to the current page URL. In Chrome, these URLs are resolved relative to the add-on's base URL. To work cross-browser, you can specify the path as an absolute URL, starting at the add-on's root, like this:

/path/to/script.js

so this should do the trick, but in fact FF48 due to unknown reasons both insertCSS() and executeScript() don't want to execute. At the same time I've found if to execute code with these functions calls in debugger in step-by-step mode, they triggered normally. So it looks like FF bug.

Sortie answered 30/8, 2016 at 18:46 Comment(0)
N
0

Can't comment, so sorry this isn't a real answer ...

I'm not seeing the same results. Provided details in case anything jumps out at you as being different from how I ran it and how you are running it.

In background script (located in the extension root directory), on extension startup, both:

var temp = function (tab) {
    browser.tabs.executeScript(null, { file: "src/js/asdf.js" });
};
browser.tabs.onCreated.addListener(temp);

and

browser.tabs.onCreated.addListener(function (tab) {
    browser.tabs.executeScript(null, { file: "src/js/asdf.js" });
});

register correctly (no errors on startup).

The file src/js/asdf.js exists, is the correct relative path from background.js, and contains your foo method and call.

When I create a new blank tab (which by definition cannot have content scripts attached), I see the expected error in the console (albeit from undefined instead from background.js):

Error: Missing host permission for the tab

When I create a new blank tab with content from the beginning (i.e., context click to open a link in a new tab), I see the expected result (Executed in the console log).

When I create a new tab from within the extension, I also see the expected result (Executed in the console log.

Potentially relevant manifest info:

  • asdf.js is not web accessible
  • permissions include tabs and <all_urls>
  • there are no content scripts defined in manifest.json

Running Firefox 59.0.2 (64-bit) on Mac 10.13.4

Nephralgia answered 8/5, 2018 at 15:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.