Firefox and Google Chrome are different browsers. WebExtensions is very new for Firefox. Even when it is mature, Firefox and Google Chrome will be different. This may require you to have significantly different sections of code for the various browsers your extension is supposed to run on.
Currently in Firefox, the changeInfo
object that is passed to the listener function for chrome.tabs.onUpdated
can be invalid. It is supposed to have only two possible values: loading
or complete
.
It appears that there is a bug that makes it such that changeInfo
can have the property status
, but the value of that property is undefined
. In these cases, the tabs.Tab
object with is also passed to a tabs.onUpdated
listener, has a property status
with a value that is a string. In most cases, that value is 'completed'
, even when that does not appear to be accurate.
It looks like this may be able to be worked around relatively easily. It depends on what you need.
The following code will override the erroneous undefined
values for changeInfo.status
with the assumption that they are 'loading'
:
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if(changeInfo.hasOwnProperty("status") && typeof changeInfo.status === 'undefined'){
changeInfo.status = 'loading';
}
});
The reality is that you will need to determine for yourself what works for your extension. Firefox and Chrome are going to give somewhat different information to your extension.
For the situation which you described (Google main page to SERP page) the combined webRequest
, webNavigation
, and tabs.onUpdated
events give you the following information:
webRequest: https://www.google.com/images/nav_logo242.png
webRequest: https://www.google.com/complete/search?sclient=psy-ab&site=&source=hp&q=SERP&oq=&gs_l=&pbx=1&bav=on.2,or.&bvm=bv.129759880,d.cGc&fp=1&biw=1256&bih=924&dpr=1&pf=p&gs_rn=64&gs_ri=psy-ab&cp=4&gs_id=kv&xhr=t&tch=1&ech=1&psi=E6u2V_S8BY_gjwPakICACA.1471589139270.1
webRequest: https://www.google.com/gen_204?atyp=i&ct=1&cad=1&rsm=6&ei=E6u2V_S8BY_gjwPakICACA&zx=1471589794481
tabs.updated event: tabId=37:: changeInfo keys:status ::changeInfo.status=undefined (override->loading)
tab.status=complete (override->loading)testTabEvents.js:96:9
tabs.updated event: tabId=37:: changeInfo keys:status,url ::changeInfo.status=complete
tab.status=complete
tab.url=https://www.google.com/?gws_rd=ssl#q=SERPtestTabEvents.js:96:9
webRequest: https://www.google.com/search?sclient=psy-ab&site=&source=hp&q=SERP&oq=SERP&gs_l=hp.3..0i3k1j0l3.655013.655013.0.657681.1.1.0.0.0.0.173.173.0j1.1.0....0...1c.1.64.psy-ab..0.1.163.LqQ90ZRWj7o&pbx=1&bav=on.2,or.&bvm=bv.129759880,d.cGc&fp=1&biw=1256&bih=924&dpr=1&tch=1&ech=1&psi=E6u2V_S8BY_gjwPakICACA.1471589139270.3
webNavigation->ReferenceFragmentUpdated: tadId=37:: url=https://www.google.com/?gws_rd=ssl#q=SERPtestTabEvents.js:182:13
tabs.updated event: tabId=37:: changeInfo keys:status ::changeInfo.status=undefined (override->loading)
tab.status=complete (override->loading)testTabEvents.js:96:9
tabs.updated event: tabId=37:: changeInfo keys:status ::changeInfo.status=undefined (override->loading)
tab.status=complete (override->loading)testTabEvents.js:96:9
webRequest: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAJCAYAAAAGuM1UAAAAaUlEQVR4AY3OxQECQRBE0YdHsyc0G9LihkNqOESA92n9j09LlaCnmEzOFGcMFBCxc+Ra44UjElmSiL0iVxOL+LhjLIj7PWIzNCBd9MAk1iObHKCNfSTcYr2wQ0uWjFKmc0VRJNekXWTjDe6gHTKFP5vkAAAAAElFTkSuQmCC
webRequest: https://id.google.com/verify/NQAAAB8aqx-h_1Es5zxXakqEQ4VnEYZCXpWW_8Rmrl4pN1yV-s-1d_qg6kBSbexs0XcddYBKPk8NAwLOwyJ-W75hWEw
webRequest: https://www.google.com/gen_204?v=3&s=web&atyp=csi&ei=pa22V6CHGoHAjAPhgoPQBg&ei=pa22V6CHGoHAjAPhgoPQBg&cr=r&imp=0&pfa=n.1,ttfc.152,ttlc.0,cbt.96&pfm=n.1,ttfc.152,ttlc.0,cbt.96&pmd=max.17,avg.2,0,1,0,1,0,1,5,0,0,0,0,0,1,1,1,1,1,11,17,1&imn=1&adh=&xjs=dispose.3.11.ifl.1.fpe.1.jsa.1.m.0.lu.0&it=jradf.9&ima=1&rt=ol.553,jsrt.155,prt.557,pprt.557,iml.558,aft.557
webRequest: https://www.google.com/xjs/_/js/k=xjs.s.en_US.tUVHO5ck74k.O/m=aspn,crd,sy7,sy268,sy314,sy3,sy9,sy54,sy315,sy316,sy27,sy317,dvl,sy57,sy58,sy300,em11,vs,sy85,sy86,sy88,sy90,sy81,sy83,sy87,sy91,sy78,sy84,sy89,sy92,sy79,tnv,sy46,atn,sy355,d3l,sy93,sy168,sy169,rqa,me/am=AFCSBBCI-H8ICLcQLEgFGBgE/rt=j/d=0/t=zcms/rs=ACT90oG-vU2X0tyaGFDLQbRJNbKCWyOApg
tabs.updated event: tabId=37:: changeInfo keys:status ::changeInfo.status=undefined (override->loading)
tab.status=complete (override->loading)testTabEvents.js:96:9
webRequest: https://www.google.com/gen_204?atyp=i&ct=slh&cad=&ei=bqW2V8rcMMfkjwOEtKXACQ&s=3&v=2&pv=0.5883361922868646&me=4:1471589138584,e,U&zx=1471589798811
webRequest: https://www.google.com/gen_204?atyp=i&ct=slh&cad=&ei=pa22V6CHGoHAjAPhgoPQBg&t=W&s=1&v=2&pv=0.3475507940470587&me=1:1471589797809,x:4053,e,B&zx=1471589801864
The above event information was obtained from running the extension I put in this answer (for the webRequests) along with the following extension:
testTabEvents.js (hand modified as I put it in this answer, so may have an error or two):
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
let output="";
//We use the properties of "tab" instead of "changeInfo" because in testing it was
// clear that changeInfo was not always properly populated. The key(s) may just
// exist, but not have any value associated with them.
//*
//Testing output showing when the event is fired.
// This is used to determine, by experimentation, what events to ignore and which
// combinations and sequence of events occur during page navigation.
function addPropToOutput(prop){
if(tab.hasOwnProperty(prop)){
output += (changeInfo.hasOwnProperty(prop)) ? '\ntab.' + prop + '=' + tab[prop] : '';
if(prop === 'status'){
output += ((changeInfo.hasOwnProperty("status") && typeof changeInfo.status === 'undefined') ? ' (override->loading)' :'')
}
}else{
output += (changeInfo.hasOwnProperty(prop)) ? '\nchangeInfo.' + prop + '=' + changeInfo[prop] : '';
}
}
//Want status and url always first
changePropertiesOrder.forEach(addPropToOutput);
Object.getOwnPropertyNames(changeInfo).forEach(function(prop){
if(changePropertiesOrder.indexOf(prop) === -1){
//Not in the list
addPropToOutput(prop);
}
});
console.log("tabs.updated event: tabId=" + tabId + ":: changeInfo keys:"
+ Object.keys(changeInfo)
+ (changeInfo.hasOwnProperty("status") ? ' ::changeInfo.status=' + changeInfo.status : '')
+ ((changeInfo.hasOwnProperty("status") && typeof changeInfo.status === 'undefined') ? ' (override->loading)' :'')
+ output
);
if(changeInfo.hasOwnProperty("status") && typeof changeInfo.status === 'undefined'){
changeInfo.status = 'loading';
}
});
var webNavEvents = ['BeforeNavigate',
'Committed',
'Completed',
//'CreatedNavigationTarget', //Not supported by Firefox
'DOMContentLoaded',
'ErrorOccurred',
'HistoryStateUpdated',
'ReferenceFragmentUpdated'
//'TabReplaced' //Not supported by Firefox
];
webNavEvents.forEach(function(navType){
browser.webNavigation['on' + navType].addListener(function(type,details){
console.log('\twebNavigation->' + type
+ ': tadId=' + details.tabId
+ ':: url=' + details.url
+ ((typeof details.transitionType === 'string') ? ':: transitionType=' + details.transitionType : '')
);
}.bind(undefined,navType));
});
manifest.json:
{
"description": "Test tabs.onUpdated and webNavigation events on page load",
"manifest_version": 2,
"name": "onUpdated and webNavigation event testing",
"version": "0.1",
"applications": {
"gecko": {
"id": "onUpdatedWebNavigationEventTesting@testing",
"strict_min_version": "45.0"
}
},
"permissions": [
"webNavigation",
"activeTab",
"tabs"
],
"background": {
"scripts": ["testTabEvents.js"]
}
}
changeInfo.status
transition fromundefined
➞'loading'
➞''complete'' instead ofundefined
➞''complete''. – Android'loading'
to create a load event for that url and once I see a'complete'
I was creating other custom events and close event for that particular url. – Fino