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.