Reputation: 883
I'm trying to write an extension to Chrome that keeps close track of the various tabs open. It seems that new tabs keep appearing out of thin air, though. What's going on here?
Here is a very simple background page that illustrates what I'm talking about:
(function () {
'use strict';
var tabKeeper = {};
function logError(tabId) {
if (!tabKeeper[tabId]) {
console.log('Tab ' + tabId + ' not found!');
console.log(JSON.stringify(tabKeeper));
tabKeeper[tabId] = true;
}
}
chrome.tabs.onCreated.addListener((tab) => {
console.log('Tab created: ' + tab.id);
tabKeeper[tab.id] = true;
});
chrome.webNavigation.onCompleted.addListener((details) => {
console.log('Navigation complete: ' + details.tabId);
logError(details.tabId);
});
chrome.tabs.query({}, (tabs) => {
if (!tabs) { return; }
tabs.forEach((tab) => {
console.log('Tab found at startup: ' + tab.id);
tabKeeper[tab.id] = true;
});
});
})();
Steps to reproduce behavior (Chrome 47.0.2526.73):
Here is what I see in the console log:
Tab found at startup: 2
Navigation complete: 2
Tab created: 4
Navigation complete: 4
Navigation complete: 4
Navigation complete: 6
Tab 6 not found!
{"2":true,"4":true}
This seems to be very repeatable. What is tab 6? Where did it come from? Why don't I get an event when it is created?
Upvotes: 1
Views: 377
Reputation: 941
This is due to the Chrome Prerendering
feature. When you enter an address to the address bar, before you actually get the tabs opened up, it is rendered as a hidden tab which gets visible when you press enter. The content scripts and your chrome extension are active for these hidden tabs also. It basically speeds up the process for better user experience by keeping the content ready before any user actually access it.
More details here.
Also knowing about how the visibility state change for any page would be very helpful to understand why these events are invoked.
This is the basic cause of why the events are triggered but the tabs are yet not open and visible to you. Also in case of prerendering
i.e when the visibility state changes, the chrome.tabs.onCreated.addListener()
is not invoked but another listener called chrome.tabs.onReplaced()
is called. More details on page visibility state here.
Upvotes: 5
Reputation: 73526
This is a hidden prerendered tab created automatically when an omnibox search is performed.
Its tab.index
property is -1
(the zero-based index of the tab within its window).
If the search is cancelled or changed the tab is destroyed.
If the search is confirmed this tab becomes visible.
The behavior is controlled by Prefetch resources to load pages more quickly
option in Chrome settings.
Upvotes: 1