0
votes

In my Firefox web extension I am adding a new button to the browser toolbar which opens a small popup. Inside this popup a button is displayed which should create a new browser window, open a couple of URLs in new tabs and finally execute different content scripts on those pages.

My code looks like this

manifest.json

{
  "manifest_version": 2,
  "name": "Auto URL Opener",
  "version": "0.0.1",

  "description": "Auto URL Opener",
  "icons": { "48": "icon48.png" },

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

  "browser_action": {
    "default_icon": { "48": "icon48.png" },
    "default_title": "Auto URL Opener",
    "default_popup": "popup.html"
  }
}

popup.html

<!DOCTYPE html>
<html>
    <head>
         <meta charset="utf-8">
    </head>
    <body>
         <button id="openUrlsButton">Open URLs</button>
         <script src="popup.js"></script>
    </body>
</html>

popup.js

document.getElementById('openUrlsButton').addEventListener("click", function(e) {
    console.log('### create new window and open tabs');

    browser.windows.create({
        incognito: false,
        url: 'about:blank'
    }).then((window) => {
        console.log('### window created', window.id);

        browser.tabs.create({
            url: 'http://www.xkcd.com/',
            windowId: window.id
        }).then((tab) => {
            console.log('### tab1 created', tab.id);

            browser.tabs.executeScript(tab.id, {
                code: 'document.body.style.border = "5px solid green"'
            }).then(() => {
                console.log('### executed content script in tab1');  
            });
        });

        browser.tabs.create({
            url: 'http://www.google.com/',
            windowId: window.id
        }).then((tab) => {
            console.log('### tab2 created', tab.id);

            browser.tabs.executeScript(tab.id, {
                code: 'document.body.style.border = "5px solid blue"'
            });
        }).then(() => {
            console.log('### executed content script in tab2');  
        });
    });
}

My desired behavior is

  • a new browser window is opened
  • in the new browser window three tabs are opened
    • one with "about:blank" page
    • one with the xkcd website
    • one with the google website
  • content script in tab with xkcd website is executed
  • content script in tab with google website is executed
  • the browser console shows 6 log messages
    • ### create new window and open tabs
    • ### window created <window id>
    • ### tab1 created <tab id>
    • ### executed content script in tab1
    • ### tab2 created <tab id>
    • ### executed content script in tab2

Actual behavior is

  • a new browser window is opened
  • in the new browser window three tabs are opened
    • one with "about:blank" page
    • one with the xkcd website
    • one with the google website
  • content scripts are not executed
  • the browser console shows 2 of 6 log messages
    • ### create new window and open tabs
    • ### window created <window id>

It feels like the execution of the code is interrupted when the new browser window is opened and the web extension popup is automatically closed.

When I re-factor my code the following way

manifest.json

{
  "manifest_version": 2,
  "name": "Auto URL Opener",
  "version": "0.0.1",

  "description": "Auto URL Opener",
  "icons": { "48": "icon48.png" },

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

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

  "browser_action": {
    "default_icon": { "48": "icon48.png" },
    "default_title": "Auto URL Opener",
    "default_popup": "popup.html"
  }
}

popup.html

<!DOCTYPE html>
<html>
    <head>
         <meta charset="utf-8">
    </head>
    <body>
         <button id="openUrlsButton">Open URLs</button>
         <script src="popup.js"></script>
    </body>
</html>

popup.js

document.getElementById('openUrlsButton').addEventListener("click", function(e) {
    browser.runtime.sendMessage({
        task: "open urls"
    });
}

background.js

function openUrls() {
    console.log('### create new window and open tabs');

    browser.windows.create({
        incognito: false,
        url: 'about:blank'
    }).then((window) => {
        console.log('### window created', window.id);

        browser.tabs.create({
            url: 'http://www.xkcd.com/',
            windowId: window.id
        }).then((tab) => {
            console.log('### tab1 created', tab.id);

            browser.tabs.executeScript(tab.id, {
                code: 'document.body.style.border = "5px solid green"'
            }).then(() => {
                console.log('### executed content script in tab1');  
            });
        });

        browser.tabs.create({
            url: 'http://www.google.com/',
            windowId: window.id
        }).then((tab) => {
            console.log('### tab2 created', tab.id);

            browser.tabs.executeScript(tab.id, {
                code: 'document.body.style.border = "5px solid blue"'
            });
        }).then(() => {
            console.log('### executed content script in tab2');  
        });
    });
}

browser.runtime.onMessage.addListener(openUrls);

I get the desired behavior but I am not sure if this is a good solution.

1
Please edit the question to be on-topic: include a minimal reproducible example that duplicates the problem. For Chrome extensions or Firefox WebExtensions this almost always means including your manifest.json and some of the background, content, and/or popup scripts/HTML. Questions seeking debugging help ("why isn't this code working the way I want?") must include: (1) the desired behavior, (2) a specific problem or error and (3) the shortest code necessary to reproduce it in the question itself. Please also see: What topics can I ask about here?, and How to Ask. - Makyen
What, exactly, was shown in the Browser Console (Ctrl-Shift-J, or Cmd-Shift-J on OSX) when you tried to install and use the extension? - Makyen
@Makyen Thank you for the feedback. I have updated my question with full working code, more detailed description and desired/actual behavior. - Stig P.
@StigP.: I provided the solution, if it solves your problem, please accept the answer - Sudarshan
@Sudarshan, IMO, it is inappropriate to be asking for acceptance less than a minute after posting an answer. In general, it is reasonable for OPs to wait a while before accepting an answer to see if other, potentially better, answers will be posted. Once an answer is accepted, it is much less likely that another answer will be posted. In this case, the edit that the OP made to the question to add complete code effectively makes it a brand new question (and now answerable). - Makyen

1 Answers

0
votes

Script 1

code is placed in popup.js fileweb extension popup is open and active

Script 2

code is placed in background.js fileextension is open and active

Script 2 approach is the correct method of solving the problem