Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect Tab duplication events

I'm developing a Chrome extension;

I need to detect when a tab is duplicated, I'm looking for a tab detection event like onduplicate.addListener()?

Is that possible with the Chrome extension API?

like image 705
Dev hercule Avatar asked May 29 '17 07:05

Dev hercule


2 Answers

This is the closest implementation:

const newTabsId = new Set();

// Observe all new tabs with opener ID
chrome.tabs.onCreated.addListener(tab => {
    if(tab.openerTabId) {
        newTabsId.add(tab.id);
    }
});

// Waiting for a new tab completeness
chrome.tabs.onUpdated.addListener((tabId, changes, tab) => {
    if(newTabsId.has(tabId) && changes.status === 'complete') { 
        if(!tab.openerTabId) {
            return;
        }
        // Retrieve opener (original) tab
        getTabById(tab.openerTabId)
            .then(originalTab => {
                if(
                    originalTab.url === tab.url &&          // original and new tab should have same URL
                    originalTab.index + 1 === tab.index &&  // new tab should have next index
                    tab.active && tab.selected              // new tab should be active and selected
                                                            // also we may compare scroll from top, but for that we need to use content-script
                ) {
                    console.log('Duplicate:', tab);
                }
            });
        // Remove this tab from observable list
        newTabsId.delete(tabId);
    }
});

// Syntax sugar
function getTabById(id) {
    return new Promise((resolve, reject) => {
        chrome.tabs.get(id, resolve);
    });
}

// Cleanup memory: remove from observables if tab has been closed
chrome.tabs.onRemoved.addListener(tabId => {
    newTabsId.delete(tabId);
});

EDIT 1: But yeah, there is no clear solution now to detect real duplicate

like image 179
Denis L Avatar answered Sep 17 '22 18:09

Denis L


Tab duplication preserves sessionStorage of the page so simply store some unique variable in your content script in each page and check if it's present in the beginning of your content script.

manifest:

"content_scripts": [{
  "matches": ["<all_urls>"],
  "run_at": "document_start",
  "js": ["content.js"]
}],

content script:

if (sessionStorage[chrome.runtime.id]) {
  chrome.runtime.sendMessage({
    action: 'checkDup',
    tabId: Number(sessionStorage[chrome.runtime.id]),
  }, isDupe => {
    console.log(isDupe);
  });
} else {
  chrome.runtime.sendMessage({
    action: 'getTabId'
  }, tabId => {
    sessionStorage[chrome.runtime.id] = tabId;
  });
}

background/event script:

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  switch (msg.action) {
    case 'getTabId':
      sendResponse(sender.tab.id);
      return;
    case 'checkDup':
      chrome.tabs.get(msg.tabId, tab => {
        if (tab 
        && tab.index == sender.tab.index - 1 
        && tab.url == sender.tab.url) {
          sendResponse(true);
          console.log('Tab duplicated: ', tab, '->', sender.tab);
        }
      });
      return true; // keep the message channel open
  }
});
like image 23
wOxxOm Avatar answered Sep 20 '22 18:09

wOxxOm