Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

setTimeout not defined in XPCOM?

177 views
Skip to first unread message

Sebastian Lisken

unread,
Sep 18, 2008, 10:02:34 PM9/18/08
to
Hi,

I'm writing a Firefox extension. I have some code that works if I put it
into a .js file within chrome/content that is referenced via XUL
overlays. The problem with this is that the code runs for every new
window that's opened, and most of what it does should not be per window
but per Firefox session. So I'm trying to move that code to a JavaScript
component (a singleton, or service, starting with a template generated
by http://ted.mielczarek.org/code/mozilla/jscomponentwiz/), and most of
it is still working after some minor adjustments. However, as soon as I
come across any of a few lines that use setTimeout, I get an entry in
the Error Console (I set javascript.options.showInConsole and
javascript.options.strict in prefs.js) saying either "setTimeout is not
defined" or "setTimeout is not a function". Are these functions not
available in the XPCOM environment? In that case, how can I get the same
functionality? If not, how do I access setTimeout? (If you need to know,
this is under Firefox 2.0.0.16.)

Thanks for any replies.

Sebastian Lisken

white...@fastmail.us

unread,
Sep 18, 2008, 10:13:25 PM9/18/08
to
I think I recall noticing the same thing when I did the same thing for
the same reasons. I think I managed to get what I wanted done using the
nsITimer interface.

Mikeal Rogers

unread,
Sep 18, 2008, 10:24:22 PM9/18/08
to dev-ext...@lists.mozilla.org
setTimeout and setInterval are window methods, you can get at them
from anywhere if you pull the hiddenDomWindow.

var hwindow = Components.classes["@mozilla.org/appshell/
appShellService;1"]
.getService(Components.interfaces.nsIAppShellService)
.hiddenDOMWindow;

hwindow.setInterval
hwindow.setTimeout

-Mikeal

On Sep 18, 2008, at September 18, 20087:13 PM, white...@fastmail.us
wrote:

> _______________________________________________
> dev-extensions mailing list
> dev-ext...@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-extensions

Lance Duivenbode

unread,
Sep 18, 2008, 10:15:49 PM9/18/08
to dev-ext...@lists.mozilla.org
Hi Sebastian,

If you're writing a component you can't access standard window
properties/methods since your code is not actually attached to a window
context.

However, XPCOM does have an nsITimer component that will either execute a
callback function or notify an observer after a delay. Check out the link
below for more details:

http://developer.mozilla.org/en/NsITimer

Cheers,
Lance

Sebastian Lisken

unread,
Sep 19, 2008, 6:53:52 AM9/19/08
to
Thanks a lot for these very helpful replies. I have now got both methods
to work. The one I'm sticking with is nsITimer, because in that one I
can also automate passing on the value of "this", something I previously
had to do with each individual invocation of setTimeout. I also enjoy
the fact that this solution includes the phrases "that: this" and
"this.that". :-) For anyone else finding this thread, here is my code:

In my components' prototype, I have these functions:

setTimeout: function (func, delay)
{
var timer =
Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
var callback = { that: this, notify: function () {
func.call(this.that); } };
timer.initWithCallback(callback, delay,
Components.interfaces.nsITimer.TYPE_ONE_SHOT);
},
clearTimeout: function (timer)
{
timer.cancel();
},

And I use it with something like

var timer = this.setTimeout(function () { /* do something possibly
involving "this" */ }, delay);
/* ... */
this.clearTimeout(timer);

, so simply the old JavaScript syntax with an extra "this", but simpler
because here is what I had used before:

var that = this;
var timer = setTimeout(function () { /* do something using "that"
whenever I mean "this" */ }, delay);
/* ... */
clearTimeout(timer);

Sebastian

Sebastian Lisken

unread,
Sep 19, 2008, 7:19:07 AM9/19/08
to
On reflection, of course I could have done my this/that trick anyway,
whether I'm using nsITimer or hiddenDOMWindow - but to do in the
nsITimer approach was more natural because I needed to create a callback
object there anyway.

Sebastian

Sebastian Lisken

unread,
Sep 19, 2008, 8:06:14 AM9/19/08
to
On further reflection, I forgot to return the timer in setTimeout, which
makes my "clearTimeout" function practically useless. :-) Here is my
corrected "setTimeout":

setTimeout: function (func, delay)
{
var timer =
Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
var callback = { that: this, notify: function () {
func.call(this.that); } };
timer.initWithCallback(callback, delay,
Components.interfaces.nsITimer.TYPE_ONE_SHOT);

return timer;
},

Sebastian

Neil

unread,
Sep 19, 2008, 9:28:38 AM9/19/08
to
Sebastian Lisken wrote:

>On reflection, of course I could have done my this/that trick anyway, whether I'm using nsITimer or hiddenDOMWindow - but to do in the nsITimer approach was more natural because I needed to create a callback object there anyway.
>
>

Actually these days you can write a callback function instead, something
along these lines (warning: untested):
var that = this;
function callback() {
func.call(that);
}

Or the other approach is to make this your callback, but that only works
if you have one function to call.

--
Warning: May contain traces of nuts.

0 new messages