Retrieve URL

Hello !
How do I retrieve the URL of the tab from which I open a popup window by clicking on the extension button?
I’ve try this, read on this forum, but it don’t work:
console.log((await browser.tabs.query({ active: true, lastFocusedWindow: true }))[0].url)

le manifest:
{

"manifest_version": 2,
"name": "parameters",
"version": "1.0",
"description": "Ajoute des paramètres à la page Web active",

"permissions": [
    "activeTab",
    "tabs"
],

"browser_action": {
    "default_icon": {
        "32": "icons/test.svg"
    },
    "default_title": "parameters",
    "default_popup": "popup/choose_parameters.html"
}
}

Le popup:

<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->

<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->

<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->

<!--[if gt IE 8]>      <html class="no-js"> <!--<![endif]-->

<html>

<head>

    <meta charset="utf-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <title></title>

    <meta name="description" content="">

    <meta name="viewport" content="width=device-width, initial-scale=1">

</head>

<body>

    <form name="formulaire">

        <div class="ppc">

            <div class="did">

                <p>Catégorie</p>

                <select name="category">

                        <option class="opt" value="2">Voiture</option>

                        <option class="opt" value="3">Moto</option>

                    </select>

            </div>

            <div class="did">

                <p>Marque</p>

                <select name="brand">

                        <option class="opt" value="honda">Honda</option>

                        <option class="opt" value="yamaha">Yamaha</option>

                        <option class="opt" value="Citroen">Citroën</option>

                    </select>

                <a href="#" class = "envoi" target="_blank" title="Envoi !"><img src="" class="img-0" alt="envoi"></a>

            </div>

        </div>

    </form>

    <script src="choose_parameters.js"></script>

</body>

</html>

le .js:
console.log((await browser.tabs.query({ active: true, lastFocusedWindow: true }))[0].url)

I dont retrieve the URL in the console.

Who know ?

Right, this gives me the address of the popup, not the source tab:

var tabsProm = browser.tabs.query({
    active: true, 
    lastFocusedWindow: true
});
tabsProm.then((arrTabs) => {
    console.log(arrTabs[0].url);
});

If there isn’t a shortcut, you could switch how you define the default_popup. Remove it from the manifest, and use a background script:

// Listen for the button click and show the popup
browser.browserAction.onClicked.addListener((currTab) => {
	// Record/store currTab details needed in the popup
	  /* You supply this code */
	// Open popup
	browser.browserAction.openPopup();
});

// Define the browser action popup page
browser.browserAction.setPopup({
    popup: browser.extension.getURL('popup/choose_parameters.html')
});

Then your popup can either access storage or message the background script for the information.

Thank you very much.
So, when I set a popup in the manifest, it’s impossible to retrieve the URL of the tab that opens the popup, right?

As I understand it, instead of
/* You supply this code */
I get the URL with

var tabsProm = browser.tabs.query({

    active: true,

    lastFocusedWindow: true

});

and I send a message (which will be retrieved by the content-script injected into the popup) like this:

tabsProm.then((arrTabs) => {

    browser.tabs.sendMessage(content_script.js, {

         command: "my_command",

        key: arrTabs[0].url

    });

});

And in the content-script, I retrieve the message like this:

browser.runtime.onMessage.addListener((message) => {

    if (message.command === "my_command") {

        var message_content = message.key;

    }

Is all right?

If you absolutely want use a default_popup instead of jscher2000’s solution:

In the background page, use tabs.onActivated to store the active tab’s ID in a variable.
The popup can then send a message to the background script and receive the tab ID in the reply.

Works for me in 94.0.2 in a test extension with a default_popup, loaded with:
web-ext run

It gives me the URL of the active tab in the active window, at the time when I clicked the browser action.

Please also make sure you’re checking the correct console.

Hi, I can’t make it, I need help.
What I coded isn’t working.
Instead of asking where the error in the code is, I prefer to ask where the error in reasoning is.
I describe below what I want to achieve and how I do it, could you tell me where I am wrong?
It seems strange to me that the backgroud sends a message to a content_script while it is not loaded yet (at the moment of the click)…
But maybe because the backgroud is always running, it stores the message until the content_script is loaded?
Or should I add a “await”?

Objective:
On a website, a click on the extension icon opens a popup.
This popup contains a form that allows you to choose parameters.
Sending the form opens a new tab, with the website URL + popup settings.

Reasoning:
In the manifest:

  • declaration of a background.js script,
  • declaration of an icon associated with a browser_action to react to the click on this icon.

In backgroud.js:

  • addition of an event handler triggered by clicking on the icon that retrieves the website URL.
  • sending a message containing the website URL to a content_script choose_parameters.js
  • declaring an HTML choose_parameters.html popup
  • opening of this popup
    In the choose_parameters.html popup:
  • loading a content_script choose_parameters.js

In the choose_parameters.js:

  • addition of an event handler triggered by clicking on the “submit” button.
    this event handler:
  • retrieves parameters with getElementByName
  • retrieves the URL sent by background.js
  • concatenates URL and parameters
  • opens a new tab with the new URL

If this reasoning is wrong, it is normal that my code does not work…
Would you help me please ?
With my thanks.

I was using the Web Console in my popup after it loaded. Maybe the execution is different in that context.

I think it’s better to let your popup script request the information from the background script. Here’s an example modified from some actual code, but I haven’t tested this:

/*** for background ***/

// Listen for the button click and show the popup
let tabUrlText;
browser.browserAction.onClicked.addListener((currTab) => {
	// Record/store currTab details needed in the popup
	tabUrlText = currTab.url;
	// Open popup
	browser.browserAction.openPopup();
});

// Define the browser action popup page
browser.browserAction.setPopup({
    popup: browser.extension.getURL('popup/choose_parameters.html')
});

// Handle request from popup
function handleMessage(request, sender, sendResponse) {
	if ("want" in request) {
		if (request.want == "tabUrl") {
			sendResponse({
				tabUrl: tabUrlText
			});
			return true;
		}
	}
}
browser.runtime.onMessage.addListener(handleMessage);

/*** for popup ***/

browser.runtime.sendMessage({
	want: "tabUrl"
}).then((oResponse) => {
	console.log(oResponse.tabUrl);
}).catch((err) => {
	console.log('Problem getting tabUrl: '+err.message);
});

Thank you jsher,

Thus, it is not the browser that sends a message and the content_script that is listening but the opposite.
This principle seems more consistent to me.
I’ll try that and I’ll let you know.

Hello, how do you display the code in color and without empty lines?

Use the </> button or three backticks to wrap code into markdown code blocks. To give a syntax highlighting hint, you can specify the language immediately after the three starting backticks, similar to github for example.

Hello, thank you freaktechnik.
here is the same message, more readable:

I tried the following, it doesn’t work.

/*** From background ***/

js

// Listen for the button click and show the popup
let tabUrlText;
browser.browserAction.onClicked.addListener((currTab) => {
    // Record/store currTab details needed in the popup
    tabUrlText = currTab.url;
    // Open popup
    browser.browserAction.openPopup();
});
// Define the browser action popup page
browser.browserAction.setPopup({
    popup: browser.extension.getURL('../popup/choose_parameters.html')
});
// Handle request from popup
function handleMessage(request, sender, sendResponse) {
    if ("want" in request) {
        if (request.want == "tabUrl") {
            sendResponse({
                tabUrl: tabUrlText
            });
            return true;
        }
        }
}
    browser.runtime.onMessage.addListener(handleMessage);

/*** From popup/choose_parameters.html ***/
The same code as mentioned above

/*** Frome popup/choose_parameters.js ***/

js
let CurrentURL;
let categorie;
let selectdestinationElmt;
let marque;
/**
 * S'il y a une erreur d'execution du script,
 * Affiche le message d'erreur du popup, et cache le reste du popup.
 */
function reportExecuteScriptError(error) {
    document.querySelector("#popup-content").classList.add("hidden");
    document.querySelector("#error-content").classList.remove("hidden");
}
/**
 * Ecoute les clics sur les boutons et envoie le message correspondant au
 * content script dans la page.
 */
function listenForClicks() {
    document.addEventListener("click", (e) => {
        /**
         * Récupère les informations du popup,
         * puis envoie le message au script d'arrière plan.
         */
        if (e.target.classList.contains("envoi")) {
            // Récupérer la catégorie
            var selectsourceElmt = document.getElementByName("category");
            categorie = selectsourceElmt.options[selectsourceElmt.selectedIndex].value;
            // Récupérer la marque
            var selectdestinationElmt = document.getElementByName("brand");
            marque = selectdestinationElmt.options[selectdestinationElmt.selectedIndex].value;
            // concaténer
            if (categorie == 2) {
                var newURL = CurrentURL + '/recherche?category=' + categorie + '&brand=' + marque;
            } else {
                var newURL = CurrentURL + '/recherche?category=' + categorie + '&moto_brand=' + marque;
            }
            // Ouvrir un nouvel onglet avec l'URL requête
            browser.tabs.create({
                url: newURL
            });
        }
    });
}
/** Au chargement de la page,
 *  envoie une requête au background script
 *  qui retourne l'URL de l'onglet actif au moment de l'appui sur le bouton
 */
browser.runtime.sendMessage({
    want: "tabUrl"
}).then((oResponse) => {
    CurrentURL = oResponse.tabUrl;
    listenForClicks();
    console.log(oResponse.tabUrl);
}).catch((err) => {
    reportExecuteScriptError(err);
    console.log('Problem getting tabUrl: ' + err.message);
});

/*** Errors in the console ***/


Does anyone see what’s wrong?

The line 12 error says we need to change

popup: browser.extension.getURL('../popup/choose_parameters.html')`

to

popup: browser.runtime.getURL('../popup/choose_parameters.html')

Does that help?

Hello,
thank you jscher2000,
it’s done, I’ve changed “extension” by “runtime”, but it doesnt work.
Ther is the errors now :


I dont understand what mean “Receiving end does not exist”.

This occurs when you open the popup? It could indicate that the last line of the background script (browser.runtime.onMessage.addListener(handleMessage);) never ran due to an error earlier in the script.

Hello jsher2000, thanks for your answers.
This error message appears even before I click the button to open the popup.
This is what is displayed when, just after installing the extension, I click on the deboggage button.
Then, when I click on the extension button, the popup opens correctly and I can select the items from the choice lists.
But when I click on the “send” button, it produces the same effect as pressing the extension button: it is again the popup that opens with the choice lists…