Reputation: 31
I'm trying to write my first WebExtension for Firefox 60.0.1 Quantum, and ask for your help.
I'm try to briefly describe my Firefox WebExtension.
Step 1. In the browser panel, press the extention button, - opens my Extension Window.
Step 2. In this Extention Window there is a HTML-Page (file
window.html) with a text field called "Active Tab URL" (id="url").
Step 3. When switching/updating Tabs in main browser window, this
text field should contain URL of the Active/Opened Tab.
My Questions:
I searched the information on the site: https://developer.mozilla.org/en-US/Add-ons/WebExtensions but unfortunately I did not understand how it can be done.
Thank you for your help and ideas!
{
"description": "Adds browser action icon to toolbar to open packaged web page.",
"manifest_version": 2,
"name": "Extension Window",
"version": "1.0",
"permissions": ["tabs", "contextMenus", "clipboardWrite", "clipboardRead"],
"icons": {"48": "icons/icon-48.png"},
"background": {
"scripts": ["background.js"]
},
"browser_action": {
"default_icon": "icons/icon-32.png"
}
}
function openMyWindow() {
var createWindow = {
type: "detached_panel",
url: "window.html",
titlePreface: "Extension Window",
width: 350,
height: 950
};
let windowId;
browser.windows.create(createWindow).then((data) => {
windowId = data.id;});
/*
1. How can I pass a any value to the text field (id="url") of my Extension Window?
2. How can I get the URL of the active Tab, to transfer it to my Extension Window?
*/
}
/*
Add openMyWindow() as a listener to clicks on the browser action.
*/
browser.browserAction.onClicked.addListener(openMyWindow);
<html>
<head>
<title>Extension Window</title>
<meta charset="utf-8">
</head>
<body>
<h1>My Extention Window</h1>
<p>Active Tab URL: <input id="url" type="text"></p>
</body>
</html>
Upvotes: 2
Views: 521
Reputation: 3704
Interesting question, let's get to the solution.
In background.js
, you keep the URL of the current (interesting) tab in memory. Since the extension window is also a tab, we filter that out in setUrlIfDesired. In onCreated we filter about:blank and about:newtab, since those two are used by Firefox to indicate that the tab has not finished loading yet.
As soon as the URL changes to something interesting, we use sendMessageToBrowserPopup
to notify the extension screen that it needs updating.
// Keep URL changes in a variable
let urlOfCurrentTab = null;
// Keep the id of the created window
let windowId = -1;
browser.tabs.onUpdated.addListener((tabId, changeInfo, tabInfo) => {
if(changeInfo.url) {
// Here anything is allowed, even about:blank and about:newtab
setUrlIfDesired("updated", changeInfo.url, tabInfo.active);
}
});
browser.tabs.onCreated.addListener((tabInfo) => {
if(tabInfo.url && tabInfo.active === true){
if(tabInfo.url !== "about:blank" && tabInfo.url !== "about:newtab"){
setUrlIfDesired("created", tabInfo.url, tabInfo.active);
}
}
});
browser.tabs.onActivated.addListener((activeInfo) => {
if(activeInfo.tabId !== -1 && activeInfo.tabId !== null){
browser.tabs.get(activeInfo.tabId).then((tabInfo) => {
setUrlIfDesired("activated", tabInfo.url, tabInfo.active);
});
}
});
function setUrlIfDesired(type, url, active){
console.log(type + ": " + url + " is " + active);
if(url.indexOf("moz-extension") === -1 && url.indexOf("window.html") === -1){
urlOfCurrentTab = url;
console.log("urlOfCurrentTab is now " + urlOfCurrentTab);
sendMessageToBrowserPopup("getCurrentUrlResult", urlOfCurrentTab);
}
}
function openMyWindow(tab) {
browser.windows.create({
type: "detached_panel",
url: "window.html",
titlePreface: "Extension Window",
width: 350,
height: 950
}).then((data) => {
windowId = data.id;
// The window needs time to create, it gets 1000 milliseconds
setTimeout(function(){
setUrlIfDesired("init", tab.url, true); // initialise the current URL
}, 1000);
});
}
// Track whether we need to clear windowId because the window was closed
browser.windows.onRemoved.addListener((removedWindowId) => {
if(removedWindowId === windowId){
windowId = -1;
}
});
/* Add openMyWindow() as a listener to clicks on the browser action. */
browser.browserAction.onClicked.addListener(openMyWindow);
function getCurrentUrl(){
// You would think this would work, but it doesn't. This is because the extension window is the one that is active!
/*browser.tabs.query({active: true, currentWindow: true}).then((tabs) => {
let tab = tabs[0];
sendMessageToBrowserPopup("getCurrentUrlResult", tab.url);
});*/
// So we use the urlOfCurrentTab variable that we kept in memory instead.
sendMessageToBrowserPopup("getCurrentUrlResult", urlOfCurrentTab);
}
// See also https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/Tabs/sendMessage
function sendMessageToBrowserPopup(action, data){
// Only send messages to the window if it exists
if(windowId != -1){
console.log("sending " + data);
browser.runtime.sendMessage({"action": action, "data": data});
}
}
In order for this to work, we need to edit window.html
:
<html>
<head>
<title>Extension Window</title>
<meta charset="utf-8">
</head>
<body>
<h1>My Extension Window</h1>
<p>Active Tab URL: <input id="url" type="text"></p>
<script src="window.js" type="text/javascript"></script>
</body>
</html>
In window.js
(a new file), we subscribe to the event which was emitted by background.js
:
browser.runtime.onMessage.addListener(function(message) {
switch (message.action) {
case "getCurrentUrlResult":
updateTextbox(message.data);
break;
default:
break;
}
});
function updateTextbox(urlOfCurrentTab){
// Update the value in the text box to a new value
document.getElementById("url").value = urlOfCurrentTab;
}
Your manifest.json was good. Don't forget to remove the console.log statements when you understand the code / go to production.
If you have further questions, feel free to ask a new question on StackOverflow.
Upvotes: 1