How to get the active tab in last focused non-extension window? - google-chrome-extension

I am developing an extension which uses a service worker. The service worker opens a popup window using the usual chrome.windows.create().
During development I have 2 chrome windows open, lets call them A & B. A has tabs of various sites. B has tabs for testing my extension.
Now with a tab in focus in B, I click my extension icon on the toolbar which causes my extension to launch its own window, say C, as discussed above. So there are now in total 3 windows open.
In my extension I want to find the tab id of the active tab in B as that's what was I was focused on when I clicked the extension icon. The following however gives me the tab id of the single tab in C which is my extension's popup
async function getTabId() {
let queryOptions = { active: true, lastFocusedWindow: true };
// `tab` will either be a `tabs.Tab` instance or `undefined`.
let [tab] = await chrome.tabs.query(queryOptions);
console.log(tab)
console.log(tab.title);
return tab.id;
}
Which is fine as I passed lastFocusedWindow: true.
So I pass lastFocusedWindow: false , but that gives me the last focused tab in A!
How do I get the last focused tab in B which was the actual non-extension window in focus before my chrome extension launched its popup?

You can get the active tab before opening the new tab and pass the id via URL:
// background script
(async () => {
const [activeTab] = await chrome.tabs.query({active: true, currentWindow: true});
const params = new URLSearchParams({tabId: activeTab?.id});
const newTab = await chrome.tabs.create({url: 'mypage.html?' + params});
})();
// mypage.js
const tabId = +new URLSearchParams(location.search).get('tabId');

Related

Can browser.tabs.query({active: true, currentWindow: true}) ever return more than one tab?

My extension needs to do something with the currently active tab. So I use
browser.tabs.query({active: true, currentWindow: true}).then((tabs) =>
let tab = tabs[0];
if (tab) {
// actual code
} else {
log("no active tab")
}
);
Mostly out of curiosity: are there cases where tabs will have more than one tab?
TLDR: No
For Chrome, Opera and Firefox this is currently impossible, so it's safe to assume that the array will only contain one element.
Opera has multi-select of tabs, but it uses the property highlighted to indicate the multi-select status. active means "visibly selected in window": the contents of the tab are visible in the browser window.
browser.tabs.query returns an array, regardless of the filter you pass to it. It also returns an array when filtering on "index", containing one result if you have one window open.

how to mark pages as visited in chrome extensions?

What I want to do is to execute a script on an active tab only when it's Highlighted and that script wasn't executed before on that page.
The execution is when the tab is highlighted.
The execution must be only once for the page unless if it was refreshed.
If the page was refreshed or the link(location) of the tab was changed then I must execute the script the next time the tab is highlighted.
What I'm basically thinking of doing after surfing the internet is to store a variable in the page window and check it every time.
At first i tried this
chrome.tabs.onHighlighted.addListener(function(){
var query = { active: true, currentWindow: true };
chrome.tabs.query(query, function(tabs) {
chrome.windows.get(tabs[0].windowId, function(window){
if(!window.fbaVisitedPage){
window.fbaVisitedPage=true;
//execute script here only once per page.
}
});
});
});
but it didn't work, so I tried to use the default window variable
chrome.tabs.onHighlighted.addListener(function(){
var query = { active: true, currentWindow: true };
chrome.tabs.query(query, function(tabs) {
chrome.windows.get(tabs[0].windowId, function(win){//change is here
if(!window.fbaVisitedPage){
window.fbaVisitedPage=true;
//execute script here only once per page.
}
});
});
});
The problem in the second code is that the variable window.fbaVisitedPage is still defined even after I refresh the page. I was expecting the variable window.fbaVisitedPage to become undefined after the page is refreshed but that didn't happened.
How can I solve this problem? How can I mark a page as visited and unmark it if the page was reloaded or it's `location' was changed?

How to open a screen as popup from Site Map location

Is there any way to open a custom screen, as placed in the Acumatica menu in the Site map, as a popup (not a new tab) so that it doesn't occupy the existing browser?
I've tried using this, which works ok:
var url = "http://localhost/AcumaticaDB2562/?ScreenId=AC302000&&OpenSourceName=Bills+and+Adjustments&DataID=" + apinvoice.RefNbr;
throw new PXRedirectToUrlException(url, "Open Source")
{
Mode = PXBaseRedirectException.WindowMode.NewWindow
};
The problem is, I don't want the lefthand menu to show up. I just want the screen without any navigation. Is this possible?
I like to use PXRedirectHelper.TryRedirect for calling other graphs. The WindowMode tells the framework how to open the graph. For your question, you will want to use WindowMode.NewWindow as shown in the example below:
var graph = PXGraph.CreateInstance<MyGraph>();
PXRedirectHelper.TryRedirect(graph, PXRedirectHelper.WindowMode.NewWindow);
The enum values for WindowMode are: InLineWindow, New, NewWindow, PopUp, Same.
Alternatively you could do something like this...
throw new PXRedirectRequiredException(graph, true, string.Empty) { Mode = PXBaseRedirectException.WindowMode.NewWindow };

Need to modify browser action popup contents upon tab change

I need to modify the contents of browser Action popup on tab change.
I am detecting change of tab in background.js script
var tabHandler={
processChange:function(tab){
var parser = document.createElement('a');//To extract the hostname, we create dom element
parser.href = tab.url;
var regex=/^(www\.)?([^\.]+)/
var matches=regex.exec(parser.hostname)//This gives us the hostname, we extract the website name
var website=matches[2];
function getWebsiteCoupons(site){
var coupons=cache.pull(site)
if(!coupons){
couponfetcher(site)
coupons=cache.pull(site);
}
return coupons;
}
var coupons=getWebsiteCoupons(website);
//NEED TO UPDATE THE POPUP HERE
chrome.browserAction.setBadgeText({text:coupons.coupons.length+coupons.deals.length+""})
},
onTabUpdate:function(tabId, changeInfo, dtab){
chrome.tabs.get(tabId,tabHandler.processChange);
},
tabChanged:function(activeInfo) {
console.log(this) ;
chrome.tabs.get(activeInfo.tabId,tabHandler.processChange);
},
init:function(){
chrome.tabs.onActivated.addListener(this.tabChanged);
}
}
tabHandler.init();
So I tried to detect a click action on the browser action, but this doesn't work when I have a popup already defined.
function BrowserActionClicked(tab){
alert("hello");
}
chrome.browserAction.onClicked.addListener(BrowserActionClicked)
If I remove the popup from manifest, the script works. But I don't know how to get instance of the manifest's contents
I also tried getting the views. The view however is an empty view, doesn't contain the contents of the popup.
var view=chrome.extension.getViews();
$(view.document).append("Hello");
this didn't work either. How do I update the contents of the browser popup from background script?
I am in a bit of a fix here, to be honest

wrong current url in google chrome extension

I have a google chrome extension that is shown onclick in a popup. There is a context menu with some options that need the current / active tab url. The extension has a problem described below.
Old code:
function menuCallback(info, tab) {
var currentUrl = tab.url;
With old code: If you right-click inside the popup, the current url returned is "chrome-extension..." and so on.
New Code: (i tried to fix the issue with)
chrome.tabs.query({'active': true, 'windowId': chrome.windows.WINDOW_ID_CURRENT},
function(tabs){
currentUrl = tabs[0].url;
}
);
This works, as it returns the tab url even if the click comes from inside the popup. But if i have like 10 open tabs and switch between two, always the old one is returned. For example i'm at google.de first, url returned is google.de. Now i switch to an already open tab like "heise.de" and right-click, it's still google.de. Next attempt / try the url is correct.
You probably want to use the onUpdated listener.
chrome.tabs.onUpdated.addListener(doSomething);
Which gives you the tabId, changeInfo and tab metadata. You then can do as you please:
var doSomething = function (tabId, changeInfo, tab) {
var match = /http:\/\/www.google.com/.exec(tab.url);
if(match && changeInfo.status == 'complete') {
... do something ...
}
}
EDIT: After reading again your question, what you probably want is the onHighlighted event listener. It returns an object with an array of tabsIds and the window as soon as you select a tab.
chrome.tabs.onHighlighted.addListener(function(o) { tabId = o.tabIds[0]; })
You can then use get in order to obtain more information about that specific tab.
chrome.tabs.get(tabId, function(tab) { ... })
I'm leaving the onUpdated code in case anyone wants the tab information whenever a page changes.
Using the query parameters the simplest solution to finding the URL of the active tab in the currently focused window would be the following.
chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
currentUrl = tabs[0].url;
});
chrome.tabs.getSelected(null, function(tab) {
var currentURL= tab.url;
alert(currentURL); // this should give you current url.
}

Resources