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.
}
Related
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?
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'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)
I am building an extension where I want to be able to add a signifier to the extension button when the extension in the code has been activated. I was hoping I could add text to the extension button (top right)
Here is a simple scenario. Let's say my extension monitors browsing and gets the tab url, in my extension I have a list of domains to watch for.
Watch for these domains
www.website1.com
www.website2.com
If a user visits a domain in the watched list I want to indicate this somehow, by adding some text somewhere - I was hoping in the top right of the browser where the extensions buttons are. I don't really want to use a notification window as I want something unobtrusive. The text that I want to display would just be a few letters but different for different urls.
Does anyone have any inspiration?
Thanks
You may change the extension icon like this:
chrome.browserAction.setIcon({path: icon});
There is also a 'badge' - small box over the extension icon that shows ie. number of unread messages in gmail extension. You can manipulate it like this:
chrome.browserAction.setBadgeBackgroundColor({color:[190, 190, 190, 230]});
chrome.browserAction.setBadgeText({text:"?"});
It is also possible to generate icon dynamically on a canvas element and then display it like this:
chrome.browserAction.setIcon({imageData:canvasContext.getImageData(0, 0, canvas.width,canvas.height)});
Note that you must call this from your background script, since the content script will not have permission!
tl;dr: Call it from background.js
I googled around this comment because I was trying to call a chrome.browserActions function from my content script
It's only accessible to scripts that are running as part of a chrome extension, since content_scripts are the same as client scripts you'd have to access them through the chrome.* api's
and to fix some addition headaches I had the call for setBadge text needs to look like:
chrome.browserAction.setBadgeText({text: 'ASDF'});
You can put as many characters as you want, but only 4 or so will appear. I got hung up on what the object property needed to be.
You can also set a timeout to check changes on the system every x minutes, and then update de badge.
On my extension, I have an task counter called inside a notification function. Something like :
$.getJSON(
"http://mydomain/notifications?ajax=1&callback=?",
function(data){
var result = data.retorno;
if(result.length > 0){
var totalItens = result[0].total
} else {
var totalItens = 0;
}
chrome.browserAction.setIcon({path: '19.png'});
chrome.browserAction.setBadgeText({text:''+totalItens+''});
for(var i=0; i<result.length; i++){
var imagem = 'http://mydomain/myimage';
var titulo = 'mytitle';
var desciption = 'mydescription';
var urlNot = 'http://mydomain/mypageOnclick';
var not = new Notifier(urlNot);
not.Notify(
imagem, // The image.
titulo, // The title.
desciption // The body.
);
}
}
);
You have to change in 3 files.
manifest.json
Check this code added
"background": { "scripts": ["background.js"], "persistent": false }
script.js
Add the following code:
const msg = 'updateIcon'
chrome.runtime.sendMessage({ message: msg }, function(response) {
});
background.js
Add the following code:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
console.log(request);
// Callback for that request
chrome.browserAction.setIcon({path: "/assets/icon.png"});
});
In my Chrome extension, I want to listen for changes to one particular tab only. Using the chrome.tabs.onUpdated.addListener method, my observation is that this runs on ALL tabs. I have implemented a way to capture the id of the tab that I'm interested in and then check that first, like so:
var extTabId = 10; // captured when this tab is created
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (tabId !== extTabId) {
return false;
}
// do whatever else I need this specific tab in question to do
});
Is there an easier way do this so that I only add a listener for extTabId?
There is no simpler solution, your approach is the way to go.