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?
Related
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.
I am developing an extension which shows some values in popup. The values are fetched in event page script periodically.
function load() {
var value = fetch();
// I would like to set this value to popup content.
}
chrome.alarms.onAlarm.addListener(function(alarm) {
if (alarm.name === "refresh") {
load();
}
});
chrome.alarms.create("refresh", {"periodInMinutes": 10});
I tried to get the popup window to change its content using chrome.extension.getViews({ViewType: "popup"}) in event page script but it returned an empty array.
I know I can do it using storage but it seems to me overkill.
So how can I use the value in popup?
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
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.
}
I'd like to add a custom style sheet in a page without a content script. My CSS is OK, but the code below, using the onUpdated and onCreated event listeners do not work.
Part of manifest.json:
"permissions": [
"http://www.site_domain.com/*",
"tabs"],
background.html:
chrome.tabs.onUpdated.addListener(function (tab) {
var tabUrl = tab.url;
if (tabUrl.indexOf("site_domain") != -1) {
changeBgkColor();
}
});
chrome.tabs.onCreated.addListener(function (tab) {
var tabUrl = tab.url;
if (tabUrl.indexOf("site_domain") != -1) {
changeBgkColor();
}
});
function changeBgkColor(){
chrome.tabs.insertCSS(null, {file:"css/styles.css"})
};
chrome.tabs.onCreate has to be replaced with chrome.tabs.onCreated (with a d!).
After fixing this, you'd better pass a tabId to the chrome.tabs.insertCSS method. Also, reduce the code repetition by merging the event listeners:
chrome.tabs.onCreated.addListener(do_something);
chrome.tabs.onUpdated.addListener(function(tabId, info, tab) {
if (info.status == 'complete') do_something(tab);
});
function do_something(tab) {
var tabUrl = tab.url;
if (tabUrl && tabUrl.indexOf("site_domain") != -1) {
// changeBgkColour() here:
chrome.tabs.insertCSS(tab.id, {
file: "css/styles.css"
});
}
}
Since these events are called right after the creation of the tabs. each rule might have to be sufficed with !important, to prevent the rules from being overwritten by style sheets on the page.
According to the documentation of onCreated, the url property may not be set when the event is fired, so add tabUrl && in the condition, to prevent possible errors.
Also, your domain check is insufficient. .indexOf('google.com') would also match http://stackoverflow.com/q/x/what-is-google.com?.
I'm pretty much doing the same with Chrome 23 (late 2012) and to me it seems that
onCreate is not needed anymore (onUpdated will be fired perfectly even with a cold start and a tab not selected)
changeInfo status "loading" injects the script pretty fast, but it may end up injected twice, even worse, way too early (it shows up in the inspector, but most rules will be overwritten by the page's rules; importants are mandatory)
with changeInfo status "complete" the script is inserted much later (sometimes with bigger load times this can be quite annoying), but it's more stable and for some reason it's not shown in the inspector.
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
if (changeInfo.status === "complete") {
chrome.tabs.insertCSS(tabId, {code: "body{border:1px solid red}"});
}
})
(I'm not really sure if it is an answer per se, unfortunately this post is too long to be a comment - for the url checking I myself use regexp of course, but this has already been noted above)