tabs.onUpdated.addListener's changeInfo.status goes from undefined to Complete without ever going to loading
Asked Answered
F

1

1

I see this behavior only when google SERP page is loading (when searched from the search box on google.com/ or box on SERP page it self). I was seeing expected behavior for other pages i.e., I see undifined, loading and finally a complete.

chrome.tabs.onUpdated.addListener( function(tabId, changeInfo, tab){
console.log(changeInfo.status); // prints undefined couple of times and then completed (no sign of loading).
}

I'm working on extension that behaves differently depending on tabs status.

The same code works as expected in chrome.

Also refreshing the SERP page triggers loading and completed status as expected.

Fino answered 18/8, 2016 at 23:16 Comment(4)
This does not contain an actual question. Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. As it is written, all this Question does is inform us of some behavior that is different on Google Chrome and Firefox.Android
If you want help, we are going to need to know how you are using this information and why you have to have changeInfo.status transition from undefined'loading'➞''complete'' instead of undefined➞''complete''.Android
Related: WebExtension: React when a a tab is reloadedAndroid
@Android thanks for replying, I'm trying to make events for urls based of off these status, I was looking for '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
A
2

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"]
    }
}
Android answered 19/8, 2016 at 7:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.