Timtest Timtest - 1 month ago 14
Javascript Question

Session for each tab - Google Chrome Extension

In a Google Chrome Extension, is there a way to have different "sessions" for each tab?

For exemple, Adblock does that: it shows the number of blocked ads for the current page, and this number changes for each tab (and if you have 2 windows open, a different number for each window...)

For exemple, if I use the Chrome demo to change the icon on click :

manifest.json

{
"name": "A browser action which changes its icon when clicked",
"description": "Change browser action color when its icon is clicked",
"version": "1.2",
"background": { "scripts": ["background.js"] },
"browser_action": {
"name": "Click to change the icon's color"
},
"manifest_version": 2
}


background.js

var min = 1;
var max = 5;
var current = min;

function updateIcon() {
chrome.browserAction.setIcon({path:"icon" + current + ".png"});
current++;

if (current > max)
current = min;
}

chrome.browserAction.onClicked.addListener(updateIcon);
updateIcon();


Is there a way to add some code to have a different "scope" on each tab? For exemple, if I click 3 times on the first tab, it would show icon3, and if I open a new tab, it would show icon1 for this tab (but still icon3 for the first tab)

Thanks

Xan Xan
Answer

chrome.browserAction API takes tabs into account by providing, and taking, tabId as a parameter.

For example, here's the expected signature of an onClicked listener:

The callback parameter should be a function that looks like this:

function( tabs.Tab tab) {...};

tabs.Tab tab

So, in your updateIcon function, you can get the ID of the tab:

function updateIcon(tab) {
  // Can use tab.id here
  /* ... */
  chrome.browserAction.setIcon({
    path:"icon" + current + ".png",
    tabId: tab.id // Limit change to tab
  });
}

Of course, this means you have to store your data per-tab. Simplest way is to make current an Object (or Array, but it'll be sparse) with tabIds acting like keys.

var min = 1;
var max = 5;
var current = {};

function updateIcon(tab) {
  if (!current[tab.id]) { // Not yet defined
    current[tab.id] = min;
  }

  chrome.browserAction.setIcon({
    path: "icon" + current[tab.id] + ".png",
    tabId: tab.id
  });

  if (current[tab.id] === max) {
    current[tab.id] = min;
  } else {
    current[tab.id]++;
  }
}

If you're wary of the tab data growing over time, you can listen to chrome.tabs.onRemoved to clear the data out.

You may also want to pay attention to chrome.tabs.onReplaced (which replaces the content within a tab, changing the ID).