views:

80

answers:

1

I'm trying to add some jQuery stuff to Gmail using a GreaseMonkey script. Adding jQuery functionality works fine, but the problem is that I can't really detect when Gmail has finished loading.

This is basically what happens:

  1. I refresh Gmail
  2. The loading window starts
  3. The GM script starts 3 times, during the loading window
  4. Something in the loading window changes
  5. The GM script starts one more time
  6. The page changes
  7. The GM script starts for the last time
  8. Gmail view loads and finishes

At this point a bunch of JavaScript has been loaded into the DOM that probably calls on some functions that use AJAX to load the rest of the view.

I'd like for jQuery to do stuff after step 8, when everything has finished loading.

Does anyone know how to do/detect this?

A: 

First, you can yell at Google to fix their gmail-greasemonkey API -- which seems to break more each day. Specifically, registerViewChangeCallback() would facilitate a solution but it seems to have stopped working correctly.

A workaround would be to delay-fire off main document changes. The following code seems to work for me, on Firefox. It might need tweaking for iFrame content.

//
// ==UserScript==
// @name            Fire on page finished (with AJAX mods)
// @namespace       Gmail
// @description     This script shows one way to wait for an AJAX-heavy page to load.
// @include         http://mail.google.com/*
// @include         https://mail.google.com/*
// ==/UserScript==
//

if (window.top != window.self)  //don't run on frames or iframes
    return;


var zGbl_PageChangedByAJAX_Timer = '';


window.addEventListener ("load", LocalMain, false);


function LocalMain ()
{
    if (typeof zGbl_PageChangedByAJAX_Timer == "number")
    {
        clearTimeout (zGbl_PageChangedByAJAX_Timer);
        zGbl_PageChangedByAJAX_Timer  = '';
    }

    document.body.addEventListener ("DOMNodeInserted", PageBitHasLoaded, false);
}


function PageBitHasLoaded (zEvent)
{
    if (typeof zGbl_PageChangedByAJAX_Timer == "number")
    {
        clearTimeout (zGbl_PageChangedByAJAX_Timer);
        zGbl_PageChangedByAJAX_Timer  = '';
    }
    zGbl_PageChangedByAJAX_Timer      = setTimeout (function() {HandlePageChange (); }, 666);
}


function HandlePageChange ()
{
    removeEventListener ("DOMNodeInserted", PageBitHasLoaded, false);

    alert ('Page has finished loading.');
}
Brock Adams
Seems to be working so far! Thanks. And yeah, the API would be a better way. Hopefully they'll resurrect that some day.
Alec