Skip to content Skip to sidebar Skip to footer

Persistent Unique Id For Chrome Tabs That Lasts Between Browser Sessions

I'm trying to ascertain some way to establish a unique ID for Chrome tabs that meets the following conditions: Uniquely identifies each tab Stays the same for a given tab between

Solution 1:

The question here does most of the discovery work, and the accepted answer basically completes it, but there's a big implementation gap still for people looking to implement something which requires persistent tab IDs. I've attempted to distill this into an actual implementation.

To recap: Tabs can be (almost) uniquely and consistently identified as required by the question by maintaining a register of tabs which stores the following combination of variables in local persistent storage:

  • Tab.id
  • Tab.index
  • A 'fingerprint' of the document open in the tab - [location.href, document.referrer, history.length]

These variables can be tracked and stored in the registry using listeners on a combination of the following events:

  • onUpdated
  • onCreated
  • onMoved
  • onDetached
  • onAttached
  • onRemoved
  • onReplaced

There are still ways to fool this method, but in practice they are probably pretty rare - mostly edge cases.

Since it looks like I'm not the only one who has needed to solve this problem, I built my implementation as a library with the intention that it could be used in any Chrome extension. It's MIT licensed and available on GitHub for forking and pull requests (in fact, any feedback would be welcome - there are definitely possible improvements).

Solution 2:

If I correctly understand your problem, your 5th method should do the trick, but along with these two criteria:

  • chrome.tabs.windowId (The ID of the window the tab is contained within)
  • chrome.tabs.index (The zero-based index of the tab within its window)

All these values need to be stored inside your extension. Besides that, you will also have to hook up your extension to chrome.tabs.onUpdated() and updated accordingly, when tabs are being dragged around, moved across owner windows, etc.

Solution 3:

Put this as a persistent background script in manifest.json:

"background":{"scripts":["background.js"],"persistent":true},

Here is background.js. Hopefully the code is self explanatory.

var tabs_hashes = {};
var tabs_hashes_save_queued = false;

functionStart(){
    chrome.tabs.query({windowType: "normal"}, function(querytabs){
        querytabs.forEach(function(tab){
            tabs_hashes[tab.id] = GetHash(tab.url);
        });

        if (localStorage.getItem("tabs_hashes") !== null){

            var ref_load = JSON.parse(localStorage["tabs_hashes"]);
            var ref_tabId = {};


            querytabs.forEach(function(tab){
                for (var t = 0; t < ref_load.length; t++){
                    if (ref_load[t][1] === tabs_hashes[tab.id]){
                        ref_tabId[ref_load[t][0]] = tab.id;
                        ref_load.splice(t, 1);
                        break;
                    }
                }
            });

            // do what you have to do to convert previous tabId to the new one// just use ref_tabId[your_previous_tabId] to get the current corresponding new tabIdconsole.log(ref_tabId);

        }
    });
}


functionSaveHashes(){
    if (!tabs_hashes_save_queued && Object.keys(tabs_hashes).length > 0){
        tabs_hashes_save_queued = true;
        chrome.tabs.query({windowType: "normal"}, function(querytabs){
            var data = [];
            querytabs.forEach(function(tab){
                if (tabs_hashes[tab.id]){
                    data.push([tab.id, tabs_hashes[tab.id]]);
                } else {
                    data.push([tab.id, GetHash(tab.url)]);
                }
            });
            localStorage["tabs_hashes"] = JSON.stringify(data);
            setTimeout(function(){ tabs_hashes_save_queued = false; }, 1000);
        });
    }
}

functionGetHash(s){
    var hash = 0;
    if (s.length === 0){
        return0;
    }
    for (var i = 0; i < s.length; i++){
        hash = (hash << 5)-hash;
        hash = hash+s.charCodeAt(i);
        hash |= 0;
    }
    returnMath.abs(hash);
}


chrome.tabs.onCreated.addListener(function(tab){
    SaveHashes();
});
chrome.tabs.onAttached.addListener(function(tabId){
    SaveHashes();
});
chrome.tabs.onRemoved.addListener(function(tabId){
    delete tabs_hashes[tabId];
    SaveHashes();
});
chrome.tabs.onDetached.addListener(function(tabId){
    SaveHashes();
});
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo){
    if (changeInfo.pinned != undefined || changeInfo.url != undefined){
        delete tabs_hashes[tabId];
        SaveHashes();
    }
});
chrome.tabs.onMoved.addListener(function(tabId){
    SaveHashes();
});
chrome.tabs.onReplaced.addListener(function(addedTabId, removedTabId){
    delete tabs_hashes[removedTabId];
    SaveHashes();
});


Start();

I use array to save data, because in this way I can preserve tabs order, which is unlikely if data would be saved in the object. When loading data after browser's restart, even if url is not unique, I can trust that it will be under some "close enough" index. I would do it more complex, for example reverse check if tab was not found, but this works ok so far.

Post a Comment for "Persistent Unique Id For Chrome Tabs That Lasts Between Browser Sessions"