Gears + Firefox + Timer === Dead Browser

0 views
Skip to first unread message

John Leach

unread,
Jun 24, 2008, 7:24:03 PM6/24/08
to frizione
One little showstopper that caused me about three hours debugging is
an interesting combination which kiils Firefox (at least on my Windows
XP SP2 machine):

First the HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Gears - Firefox - Timer Bug</title>
<script src="gears_init.js" type="text/javascript"
charset="utf-8"></script>
<script src="timer.js" type="text/javascript"
charset="utf-8"></script>
</head>
<body onload="runner().run();">
<h1>Gears - Firefox - Timer Bug</h1>
</body>
</html>

Then the JavaScript:

function runner () {
var timer = null;
var localSetTimeout = null;
var localClearTimeout = null;

try {
timer = google.gears.factory.create('beta.timer');
localSetTimeout = timer.setTimeout;
localClearTimeout = timer.clearTimeout;
}
catch (e) {
localSetTimeout = window.setTimeout;
localClearTimeout = window.clearTimeout;
}

var timerId = null;
return {

run: function () {
timerId = localSetTimeout(this.timed, 10000); // boom
},

timed: function () {
// never gets here
localClearTimeout(timerId);
alert("No bug here...");
}
};
}

Now this might be due to my dreadful coding technique, but it works
just fine on IE7. Which I suppose is surprising.

This definitely has to do with the use of the this keyword in the
localSetTimeout call. I never found out why, but the answer is to
either:
1. Remove gears_init.js (not the best choice if you need Gears) or
2. Wrap the timer methods in function calls, thus:

try {
timer = google.gears.factory.create('beta.timer');
localSetTimeout = function (code, millis) {
return timer.setTimeout(code, millis);
};
localClearTimeout = function (timerId) {
timer.clearTimeout(timerId);
};
}
catch (e) {
localSetTimeout = function (code, millis) {
return window.setTimeout(code, millis);
};
localClearTimeout = function (timerId) {
window.clearTimeout(timerId);
};
}

John Leach

unread,
Jun 26, 2008, 7:45:30 AM6/26/08
to Frizione
Definitely a problem 'between the chair and keyboard'. And a this
problem too. Aliasing the function is a bad idea because the
*function* looses it's own this (that is to say the object which
'owns' the function). So that's why the wrapper works - it specifies
the complete function, including the object. I think
window.setTimeout
and setTimeout worked because setTimeout is a global function which
'maps' to window.setTimeout. (Classic two errors compensating).

Not a Gears problem at all. My apologies.

Still, it's interesting that FF2 and FF3 both crash like that. Also,
I
don't think that the this in the object notation of the first example
is causing any grief.

I will write out "Must pay more attention" 100 times on a piece of
paper...

John
Reply all
Reply to author
Forward
0 new messages