Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get tab URL from page action (WebExtensions, Android)

I would like to get the URL of the current tab within a page action popup.
At first it seems obvious: Just use the tabs API. But that doesn't seem to be available on Android if I deciphering the docs correctly. So I kept looking for something else and found the onClicked event of the pageAction API.

The pageAction API seems to be listed as compatible with Android and the onClicked event is marked as supported. So that implies that it would actually return a tabs.Tab object. But does it really? Has anyone tried it?

What is the best way to retrieve the URL? I know I could just use a content script and let that run in every single tab and create a long lived messaging connection to send the URL to the page action popup whenever it is requested. But that would be very inefficient and make the code insanely complicated compared to how easy it would be using the tabs API.

Is there anything else I could do?

like image 471
Forivin Avatar asked Jan 30 '17 16:01

Forivin


People also ask

How do I show page actions for a tab?

While browser actions are displayed by default, page actions are hidden by default. They can be shown for a particular tab by calling pageAction.show () , passing in the tab's id. You can also change this default behavior using the show_matches property.

Which URLs show the page action by default?

This shows the page action by default for all HTTPS URLs under the "mozilla.org" domain, except for pages under "developer.mozilla.org". Show the page action by default for pages whose URLs match any of the given patterns.

Which tab is the active tab in Firefox for Android?

The active tab is usually the selected one. However, on Firefox for Android, extension popups open in a new tab. When this popup tab is selected, the active tab will instead be the one in which the popup opened. boolean.

What is pagepage_action?

page_action A page action is an icon that your extension adds inside the browser's URL bar. Your extension may optionally also supply an associated popup whose content is specified using HTML, CSS, and JavaScript.


1 Answers

Current (Firefox 54 and later)

As of Firefox 54, the tabs API is available in Firefox for Android. This means you can use the normal methods available to desktop Firefox. Specifically, chrome.tabs.query() or browser.tabs.query(). However, you will need the activeTab and/or tabs permissions in your manifest.json.

chrome.tabs.query:

chrome.tabs.query({active:true,currentWindow:true},function(tabs){
    //'tabs' will be an array with only one element: an Object describing the active tab
    //  in the current window.
    var currentTabUrl = tabs[0].url;
});

browser.tabs.query:

browser.tabs.query({active:true,currentWindow:true}).then(function(tabs){
    //'tabs' will be an array with only one element: an Object describing the active tab
    //  in the current window.
    var currentTabUrl = tabs[0].url;
});

Prior to Firefox 54

If you have defined a page/browser action popup

If you have defined a popup for your page/browser action, then the onClicked event does not fire. Your popup is not passed any information when it is created/shown. Thus, you will not receive a tabs.Tab object. The normal way to obtain tab information is from tabs.query, which, as you have already determined, is not (yet) available in Firefox for Android.

The APIs available to Firefox on Android are quite limited. For what you are wanting to do, using webNavigation events to keep a record of each tab's frame 0 URL would be more efficient than a content script in every page. You could use the webNavigation.onCommitted or webNavigation.onCompleted events depending on your needs. You will need to assume that the active tab of the current window is the one which most recently had a webNavigation event, or perhaps you could also monitor webRequest events. However, any way that you do it, which tab you assume to be the current tab will just be an assumption, and will be inaccurate under some circumstances.

A more accurate URL (and active tab determination) requires using a content script

If the page that is being visited changes the tab's URL through some method that does not trigger navigation, using webNavigation events will not give you the updated URL. As you have identified, without the tabs API, the only way to be certain you have the actual current URL for the tab, when you define an actual page/browser action popup (and thus don't get a tabs.Tab object), is to inject a content script into every page. You will either need the content scripts to continuously update the URLs, or be listening with storage.onChanged for a request for that information from your background/popup script. Communication from the background/popup scripts to content scripts must be accomplished through the storage API due to not having the tabs API (i.e. no tabs.sendMessage).

Using page/browser action onClicked

An alternative, which I have not tried on Firefox on Android, would be to not define an actual page/browser action popup. If you don't define an actual popup, you receive the onClicked event (getting the tabs.Tab Object with both the active tab's ID and the URL) and then can open a pseudo-popup1.


1. The implementation of opening a a pseudo-popup in my linked answer uses the tabs and windows APIs which are both currently unavailable for Firefox for Android. It could be re-written to use the above mentioned webNavigation listener to track tab URLs and window.open() to open the window used for the pseudo-popup. Again, I have not tested this with Firefox on Android to determine that it actually works.

like image 90
Makyen Avatar answered Oct 07 '22 00:10

Makyen