0

I am writing a Firefox WebExtension, using chrome.storage.local to save state, which I do when the extension is first selected.

How can I limit the state to a specific tab? I would like each tab to have its own version of the data.

Thanks

Manngo
  • 14,066
  • 10
  • 88
  • 110

1 Answers1

0

As with most storage methodologies, you have to impose a structure upon the data you store so that you can store and retrieve the data as you desire it. In this case, such that you can set() and get() data that is associated with a particular tab. There are a large number of ways to do this. The "best" way to organize the data is something that will depend on, among other things, what data you are storing, how you conceptually organize your data, and what about each tab is unique (from your extension's point of view; i.e. why the data is separated by tab, which might be that it is actually separated by URL, not tab).

There are just too many unspecified parts of what you are trying to do to be able to provide you with good suggestions as to what the "best" way is to do organize your data. However, here is one example of a possible way to do so:

// callback to get and set() just checks for errors
function reportIfStorageError() {
    if (chrome.runtime.lastError) {
        console.log(chrome.runtime.lastError);
    }
}
function getKeyForTab(tab) {
    //Use a key that is a combination of text that for this add-on is
    //  unique to data being stored for a tab, "tabData", plus the tab's ID.
    //  This allows set/get to be just for the data for the tab while
    //  laving all other keys that don't start with "tabData" available
    //  to store any other non-tab related data we desire. In other words,
    //  we don't need to worry about a conflict between some unknown tab ID
    //  and any other key we choose to use.
    return "tabData" + tab.id;
}
function getLocalStorageForTab(tab, theTabsCompleteDataObject) {
    let key = getKeyForTab(tab);
    chrome.storage.local.get({key: theTabsCompleteDataObject}, reportIfStorageError);
    return theTabsCompleteDataObject;
}
function setLocalStorageForTab(tab, theTabsCompleteDataObject) {
    let key = getKeyForTab(tab);
    chrome.storage.local.set({key: theTabsCompleteDataObject}, reportIfStorageError);
}

In the above example, a key is created for the tab which is unique to that tab. To do this we choose a prefix, tabData, which for this add-on we define as what will always start the keys used for tab data. This is done because we have no control over what the ID for the tab will be. If we just used the ID as the key, we would have to allow for the possibility that an ID would match a key we are using to store some other data. This way, we just have to choose keys for other data that don't begin with tabData. The full key for a particular tab is the prefix, tabData concatenated with the tab's ID, tab.id.

The tab provided to both getLocalDataForTab() and setLocalDataForTab() is the tabs.Tab for the tab. The variable theTabsCompleteDataObject is a single object that contains all data associated with the tab.

Makyen
  • 31,849
  • 12
  • 86
  • 121
  • Can I get the tab id _before_ I call `chrome.tabs.query`? I want to save the data at the initialisation stage. – Manngo Jul 15 '16 at 08:22
  • @Manngo, while `browser.tabs.query()` is one method of obtaining a `tabs.Tab` object, it is not the only one (e.g. a `tabs.Tab` object is passed to listeners to `contextMenus.onClicked` events). You have not provided any information as to your code, or its structure. Thus, there is no way for me to answer as to where you might get a reference to the `tabs.Tab` object. I'm also not clear as to why it matters for you to store the data before calling `browser.tabs.query()`. You can certainly make a copy of the data prior to that and store it afterwards. – Makyen Jul 15 '16 at 12:16
  • You’re right, it wasn’t clear what my intention is. I am trying to display a popup with toggled selections specific to each tab. The toggles are calculated and displayed as the popup is opened. Only after that will the action be taken via the `browser.tabs.query`. This is my first WebExtension, so I’m fumbling around here. I ended up doing this: `var tabId; chrome.tabs.query(query,function(t) {tabId=t[0].id/1000; tabId=`tab${tabId.toString().substr(2,3)}`; doInit(); });`. Thanks for your help. – Manngo Jul 15 '16 at 12:21