0

I've trying to run execute script from my background script using keyboard shortcuts, it doesn't work and returns:

Error: No window matching {"matchesHost":[]}

But if I just open the popup page, close it, and do the same, everything works.

I've recreated the problem in using the Beastify example with minimal changes. Here's the code:

manifest.json

{
    ... (not interesting part, same as in beastify)

    "permissions": [
    "activeTab"
    ],  

    "browser_action": {
        "default_icon": "icons/beasts-32.png",
        "default_title": "Beastify",
        "default_popup": "popup/choose_beast.html"
    },

    "web_accessible_resources": [
        "beasts/frog.jpg",
        "beasts/turtle.jpg",
        "beasts/snake.jpg"
    ],

My additions start here:

    "background": {
        "scripts": ["background_scripts/background_script.js"]
    },

    "commands": {
        "run_content_test": {
            "suggested_key": {
                "default": "Alt+Shift+W"
            }
        }
    }
}

popup/choose_beast.js (same as in original)

/*
Given the name of a beast, get the URL to the corresponding image.
*/
function beastNameToURL(beastName) {
  switch (beastName) {
    case "Frog":
      return browser.extension.getURL("beasts/frog.jpg");
    case "Snake":
      return browser.extension.getURL("beasts/snake.jpg");
    case "Turtle":
      return browser.extension.getURL("beasts/turtle.jpg");
  }
}

/*
Listen for clicks in the popup.

If the click is on one of the beasts:
  Inject the "beastify.js" content script in the active tab.

  Then get the active tab and send "beastify.js" a message
  containing the URL to the chosen beast's image.

If it's on a button wich contains class "clear":
  Reload the page.
  Close the popup. This is needed, as the content script malfunctions after page reloads.
*/
document.addEventListener("click", (e) => {
  if (e.target.classList.contains("beast")) {
    var chosenBeast = e.target.textContent;
    var chosenBeastURL = beastNameToURL(chosenBeast);

    browser.tabs.executeScript(null, {
      file: "/content_scripts/beastify.js"
    });

    var gettingActiveTab = browser.tabs.query({active: true, currentWindow: true});
    gettingActiveTab.then((tabs) => {
      browser.tabs.sendMessage(tabs[0].id, {beastURL: chosenBeastURL});
    });
  }
  else if (e.target.classList.contains("clear")) {
    browser.tabs.reload();
    window.close();

    return;
  }
});

background_scripts/background_script.js (added by me)

browser.commands.onCommand.addListener(function(command) {
    var executing = browser.tabs.executeScript(
            null, 
            {file: "/content_scripts/content_test.js"});

    executing.then(
            function (res){
                console.log("started content_test.js: " + res);
            }, 
            function (err){
                console.log("haven't started, error: " + err);
            });
});

content_scripts/content_test.js (added by me)

alert("0");

I'm skipping the whole content_scripts/beastify.js cause it has nothing to do with it (IMO), but it can be found here.

Now, I know that the background script runs and receives the messages even when the popup page hasn't been opened before, because I see it failing executing the script. I have no idea what causes this behavior and if there's a way to fix it.

Note: I tried adding permissions such as "tabs" and even "all_urls", but it didn't change anything.

Note 2: I'm running the add-on as a temporary add-on from the about:debugging page, but I'm trying to execute the script on a normal non-restricted page (on this page for example I can recreate the problem).

Thanks a lot guys!

  • Please describe the *exact* user interaction which you do starting from, I assume, loading the extension as a Temporary Add-on from `about:debugging`. I'm trying to determine what about anything you are doing is causing opening the popup to resolve the error. The error you are getting, `Error: No window matching {"matchesHost":[]}` is expected in some circumstances (when you try to inject into a tab containing a URL for which you don't have permission to inject). It is something you should handle gracefully in the catch portion of your handling the Promise. – Makyen Dec 23 '16 at 22:01
  • Hi, thanks for the reply! You are right, I am loading it as a temporary add-on from 'about:debugging'. – SunlessVoid Dec 23 '16 at 22:10
  • That does not tell me if you are attempting to execute it when the URL for the active tab in the current window is `about:debugging`. Nor does it hint at explaining why popup open/close "fixes" the error. You are not permitted to inject scripts into most `about:*` pages, including `about:debugging` (and [some other pages](http://stackoverflow.com/q/40798543/3773011)). Attempting to inject scripts using `tabs.executeScript()` into such pages will result in the error you are getting. There are solutions to this, but I'm still trying to find out why opening & closing the popup stops the error. – Makyen Dec 23 '16 at 23:11
  • Hey, sorry for the misinformation. I was not talking about the about:debugging page. I am aware that for the most part I can't inject into those, I was talking about a normal page (a stackoverflow page for example). – SunlessVoid Dec 24 '16 at 00:23

1 Answers1

3
// in manifest.json

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

DOES work for me (Firefox 50, Mac OS X 10.11.6).

I had gotten the exact same error message you described when I had used the original

    "permissions": [
       "activeTab"
    ],

So the addition of "<all_urls>" seems to fix the problem. However, you said that you were still experiencing the issue when you included "all_urls" in your permissions, so I am not sure whether the way I did it fixes the issue in your own setup.

edit: Whether giving any webextension such broad permissions would be wise in terms of the security risks it might pose is a separate, important consideration, I would imagine.

(I would have posted this as a comment, but I don't have enough reputation yet to be able to add comments.)

Cam U
  • 340
  • 3
  • 10
  • Hey, thanks for the reply, and thank god you've checked that, because apparently – SunlessVoid Dec 24 '16 at 09:28
  • (can't even edit my own comments) ... I was using "all_urls" and not "". On a side note, is there a way to create an alert from the background script without executeScript? Feels weird giving my add-on that privilege. – SunlessVoid Dec 24 '16 at 09:31
  • @SunlessVoid, Re: alert: not easily. You can create something that is alert-like, but it takes a significant amount of code. – Makyen Dec 24 '16 at 18:34
  • @Makyen, I see, thanks for the reply, guess the "" will have to do for now! – SunlessVoid Dec 24 '16 at 18:56