Is there a way to retrieve all the tabs open and sort them in to an array in Chrome? So if Gmail and YouTube were open, there would be two entries in the array entitled "gmail.com" and "youtube.com".
Yes, here is how you can do this:
Note: this requires permission "tabs" to be specified in your manifest file.
chrome.windows.getAll({populate:true}, getAllOpenWindows);
function getAllOpenWindows(winData) {
var tabs = [];
for (var i in winData) {
if (winData[i].focused === true) {
var winTabs = winData[i].tabs;
var totTabs = winTabs.length;
for (var j=0; j<totTabs;j++) {
tabs.push(winTabs[j].url);
}
}
}
console.log(tabs);
}
In this example I am just adding tab url as you asked in an array but each "tab" object contains a lot more information. Url will be the full URL you can apply some regular expression to extract the domain names from the URL.
Unless you are building a plugin, there isn't a way that I know of to retrieve all of the names of the open tabs, especially if the tabs contain content from separate domains. If you were able to do such a thing, it could be quite a security issue!
You can check the Chrome documentation here: http://developer.chrome.com/extensions/devguide.html
Related
Hi I am making a chrome extension for some practice that is a simple website blocker. I have two different JS files that are needing to share the same array that contains URLs to be blocked.
background.js handles the webRequests and blocking websites
options.html is the options page where users can edit URLs to be blocked, it calls storeURL.js so that it can store all the elements in the list on the html page into a js array. No problem so far.
However I cannot access the array inside of storeURL.js from background.js. It seems as if they are being called in two separate instances. If I try to include both storeURL.js and background.js inside of my background.html, that results in two totally separate storeURL.js scripts running.
How should I go about doing this? Should I store the array contents from storeURL.js into a file?
Some examples:
background.js
chrome.webRequest.onBeforeRequest.addListener(
blocking,["blocking"]);
{ urls: blockedURLS, types: [] }, ["blocking"]);
storeURL.js populates the array based on the list in options.html
var blockedURLS = [];
$('li').each(function(i, elem) {
blockedURLS.push($(elem).text());
});
blockedURLS in my background.js appears as undefined. I have also tried to point my options.html file to background.js and just include all of the js in one file with the following:
<script type="text/javascript" src="background.js"></script>
However when I do this it seems that a second background.js is called rather than just pointing to the one already running.
Feels like I've reached a dead end with possibly a simple solution that is available to fix my problem. I'm fairly new to JS/chrome extensions as well.
Thanks for taking the time to read this!
EDIT:
After some more fiddling I am able to access my blockedURL array in my background.js. However it is never updated.
var blockedURLS = ["hi"] ;
var list = document.getElementById('list');
$("#saveList").click(function(e) {
e.preventDefault();
localStorage.setItem('todoList', list.innerHTML);
alertify.success("You have saved your list.");
//Pushes each element in the list from options.html into the urls array
blockedURLS = [];
$('li').each(function(i, elem) {
blockedURLS.push($(elem).text());
});
alert("Currently blocked:\n" + blockedURLS);
});
$("#reset").click(function(e) {
e.preventDefault();
localStorage.clear();
location.reload();
});
loadToDo();
function loadToDo() {
if (localStorage.getItem('todoList')){
list.innerHTML = localStorage.getItem('todoList');
}
}
What should be happening is that after I go into my options.html and save the list, "hi" should be replaced with all the different URLs I have in my list. However it is not. The blockedURL array is printed correctly in that alert though.
I haved to work with that kind of thing recently. I have never find a really good way to do... So I have used the Storage api of Chrome Extension API. But it's not really funny to use because all methods are asynchronus so you can't simply do
myValue = chrome.storage.local.get("MyValue")
If you want I have made an object that store data automatically in the chrome storage but allows simple and synchronus calls like myValue = storage.myValue or storage.myValue = "something"
Here the github link
It was written in CoffeeScript so you can find javascript file in bin folder. The generated javascript is not very easy to read/modified but you can understand the idea simply by reading the CoffeeScript code I guess.
I can explain more how it works if you want. Tell me in comment and I will update my response.
And pay attention that it's a code I have written for my use so it's not the cleaner and bugless code that I have ever made :-) but it works fine.
EDIT : I have forget to says that you need to include this tow files in all pages / Content Script where you need to use it, of course.
Ho and sorry for my poor english... it's not actually my principal language ;-)
I had to use the following command:
var bg = chrome.extension.getBackgroundPage();
then I could access the blockedURLS array by:
alert(bg.blockedURLS);
and also edit the array by
chrome.extension.getBackgroundPage().blockedURLS = [];
which would set it to an empty array.
Thanks guys for the help, it helped me in thinking of different possibilities on approaching this problem.
Client has two websites: desktop and mobile (don't ask why desktop isn't responsive).
Desktop site has many pages that are actually just anchors within a page. E.g. aboutus.html#team that now has to redirect to team.html when someone is viewing on a small mobile device. And all mobile pages have different names than desktop pages (aboutus.html = about-us.html).
Rather than put code on every single page to redirect that individual page (which leaves no way to redirect the anchored URLs) it's been suggested to use an array for the desktopURLs and a related array for the mobileURLs.
So (note I omitted the // after http: so they don't show up as links since I don't have enough points to post links):
var desktopURL = ['http:domain.com/aboutus.html','http:domain.com/aboutus.html#/team','http:domain.com/contactus.html']
var mobileURL = ['http:m.domain.com/about-us.html','http:m.domain.com/team.html','http:m.domain.com/contact-us.html']
Once I have that set up, where desktopURL index 1 = mobileURL index 1.
I need to basically say this in code:
Get the window.location.href and look it up in desktopURL and return the index value.
Once you have the index value of desktopURL for the current window, update window.location.href with the object of the matching index number from the mobileURL array.
So that, when I'm a person on a phone and I go to domain.com/aboutus.html I am automatically redirected to m.domain.com/about-us.html
Note that I cannot change the names of any of the pages on the mobile site (making them match the original site would have made this easy). So I need to figure out a code way to do this and I have researched extensively but am just not sure how to achieve this simple task.
Here is the JS:
var desktopURL = ['aboutus.html','aboutus.html#team','contactus.html']
var mobileURL = ['about-us.html','team.html','contact-us.html']
//Get the name of current page
var currPage=(window.location.href).split("/")[(window.location.href).split("/").length-1];
console.log(currPage);
var index=desktopURL.indexOf(currPage);
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
window.location.href=mobileURL[index];
}
Check redirecttest[dot]webuda[dot]com
What you are looking to accomplish is better handled with an object lookup. Managing two arrays, as you have suggested, is very fragile solution (no real relationship exists there, which will make it difficult to scale/maintain).
var MOBILE_ROOT = 'm.domain.com';
var LOOKUP = {
'/aboutus.html': '/about-us.html',
'/aboutus.html#/team': '/team.html',
'/contactus.html': '/contact-us.html'
};
function redirect () {
var path = window.location.pathname;
var hash = window.location.hash;
window.location.href = MOBILE_ROOT + LOOKUP[ path + hash ];
}
...
if ( //user agent lookup goes here ) {
redirect();
}
im currently developing an extension, but im kind of lost by the moment.
Basically, what i want it to do, its kind of what "OneTab" extension does.
So my first question is, after adding the listener to the extension button, and executing the function, i want to get all the url's of the current window, and store them in an array and the show them in the html file.
So im using this:
chrome.tabs.getSelected(null,function(tab) {
var tablink = tab.url;
console.log(tablink);
});
but its not working and im not sure how it will check all the tabs one by one.
Thanks in advance.
chrome.tabs.getSelected() will only get you the current tab.
In order to get the list of all the tabs in the current window, you need to use the chrome.windows API. This API will return an object of the current window which will have the list of tab objects.
Here is the sample code:
chrome.windows.getCurrent({"populate":true}, function(currentWindow) {
var tabURLs = [];
var tabs = currentWindow.tabs;
for (var i=0; i<tabs.length; i++) {
tabURLs.push(tabs[i].url);
}
console.log(tabURLs);
});
For details check:
http://developer.chrome.com/extensions/windows.html#method-getCurrent
I am trying to write a Chrome extension that keeps track of how many times one visits a given news site and directs the user to other sites when they've been reading the same one too often. is there a way to do this by looking at the URL on each page load? The pseudocode would be, taking the NY Times as an example:
var nytimesCount = 0;
if (URL includes "nytimes.com")
{
nytimesCount++;
}
Pretty simple. Is there a way to do this? Would using cookies (as per this question: Counting page visits with javascript and cookies), or some other method altogether, be easier?
You can get the URL origin with javascript using window.location.origin, and store your data in an array with the indices being the name of the origin, such as:
if (typeof visitedSites[window.location.origin] !== 'undefined') {
visitedSites[window.location.origin] += 1;
} else {
visitedSites[window.location.origin] = 1;
}
In terms of saving the data, I would look into using HTML5 local storage, which will work great in Chrome. http://diveintohtml5.info/storage.html
I am having some issues with an extension that i am trying to make. The extension's job is to check URLs before making the request and block the ones that are available in the list provided. The manifest.json file loads flagged.js which declares and initializes the array. Then, it loads the file that has the function to check URLs:
// To detected and filter globally flagged websites
chrome.webRequest.onBeforeRequest.addListener(
// What to do if detected a website
function(info) {
return {redirectUrl: 'chrome-extension://' + chrome.i18n.getMessage('##extension_id') +
'/blocked.html?flag_type=globally&url=' + escape(info.url)};
},
// Website to watchout for
{
urls: flagged,
types: []
},
// Action to be performed?
["blocking"]);
My issue starts with the part urls: flagged, it seems the list must be hardwired in order to be accepted. What i mean to say, is that i must specify the list items as such:
var flagged = [
"*://*.domain_1.com/*",
"*://*.domain_2.com/*",
"*://*.domain_3.com/*",
"*://*.domain_4.com/*",
];
If i attempt to go to any of the above specified domains, the extension will redirect them to the block.html page no problems. However, i want that list to be automatically or periodically updated, so i introduced this part:
// Get list from the text file we have stored
function getFlagged(url) {
var list = [];
var file = new XMLHttpRequest();
file.open("GET", url, true);
file.onreadystatechange = function() {
if (file.readyState === 4) {
if (file.status === 200) {
allText = file.responseText;
list = file.responseText.split('|');
for( var i=0; i<list.length; i++ )
flagged.push(list[i]);
}
}
}
file.send(null);
}
I have tried to change and add things that may not make sense or could be done differently, i was just desperate. The list will be populated with the new items, say *domain_5* and *domain_6* for example. This operation will occur first thing when the extension is being loaded, or so i think. However, when i try to access *domain_5* and *domain_6*, the extension does NOT block them despite the fact that they are in the list flagged.
Any help with this issue would be very appreciated!
Thank you
EDIT: I am not an expert on JS or Chrome.APIs, this is my first attempt at chrome extensions.
Yeah, Your Listener is registering before the XMLHttpRequest is finished.
Call the listener in your onreadystatechange function and you'll get it to work.