admin管理员组

文章数量:1401628

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?

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?

Share Improve this question edited Dec 28, 2020 at 11:55 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked May 29, 2017 at 7:07 Dev herculeDev hercule 1171 silver badge14 bronze badges 7
  • As you can see in the documentation, there's no such event. You'll have to experiment with other events to find a bination of checks. – woxxom Commented May 29, 2017 at 8:41
  • Thank you for your reply, can you exlain me more what do you mean by "You'll have to experiment with other events to find a bination of checks" have you any examples? – Dev hercule Commented May 29, 2017 at 8:45
  • Experiment means just that: declare and attach listeners with console.log inside for all chrome.tabs events and see what happens on tab duplication that differentiates it. And no, I don't have any examples. – woxxom Commented May 29, 2017 at 8:48
  • I've already done that, but no solution – Dev hercule Commented May 29, 2017 at 9:08
  • Seriously? It doesn't seem you've really tried. The duplicated tab should have the same URL as the tab preceding it (the tab .index property) so it should be possible to use that and something else to differentiate. – woxxom Commented May 29, 2017 at 9:12
 |  Show 2 more ments

2 Answers 2

Reset to default 3

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 pleteness
chrome.tabs.onUpdated.addListener((tabId, changes, tab) => {
    if(newTabsId.has(tabId) && changes.status === 'plete') { 
        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 pare 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

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
  }
});

本文标签: javascriptDetect Tab duplication eventsStack Overflow