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 which 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!

4
  • 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. Commented Dec 23, 2016 at 22:01
  • Hi, thanks for the reply! You are right, I am loading it as a temporary add-on from 'about:debugging'. Commented Dec 23, 2016 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). 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. Commented Dec 23, 2016 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). Commented Dec 24, 2016 at 0:23

1 Answer 1

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.)

Sign up to request clarification or add additional context in comments.

4 Comments

Hey, thanks for the reply, and thank god you've checked that, because apparently
(can't even edit my own comments) ... I was using "all_urls" and not "<all_urls>". 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, Re: alert: not easily. You can create something that is alert-like, but it takes a significant amount of code.
@Makyen, I see, thanks for the reply, guess the "<all_urls>" will have to do for now!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.