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

Evaluating JavaScript from C++

34 views
Skip to first unread message

Martin Enlund

unread,
Aug 28, 2000, 3:00:00 AM8/28/00
to
Hello.

I'm wondering if anyone has any pointers to how I evaluate JavaScript
code from C++ in my XPCOM Component. The problem is with the context
(or the globalobject?), as I can evaluate strings like "3 + 3" and get
the results just fine.

My wish is to evaluate things in a given context (like the JS Context
of the mozilla chrome window. (So I can alter javascript variables in
that context).


I guess this is possible somehow, and if it isn't, it should be :)

(I've tried using "nsIJSContextStack" and similar components I figured
could be useful, but to no avail (as usual :)


--
Martin Enlund - ma...@lysator.liu.se


Robert Ginda

unread,
Aug 28, 2000, 3:00:00 AM8/28/00
to

Why would you need to directly alter JS variables from an XPCOM
component? Have you considered passing the values back via out
parameters instead? Modifying global variables from within a method
call sounds fairly dubious to me. Also, you can't be guaranteed that
your component is being called from a chrome window, it may be called
from a JS Component, trusted web content, or from within xpcshell.

But, pardon my rant. You can get at the calling JS context with
nsIXPCNativeCallContext:

NS_WITH_SERVICE(nsIXPConnect, xpc, nsIXPConnect::GetCID(), &rv);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;

nsCOMPtr<nsIXPCNativeCallContext> cc;
rv = xpc->GetCurrentNativeCallContext(getter_AddRefs(cc));
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;

JSContext *cx;
rv = cc->GetJSContext (&cx);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;

From there it's all JS API calls.

Rob.

Martin Enlund

unread,
Aug 29, 2000, 3:00:00 AM8/29/00
to
Robert Ginda <rgi...@netscape.com> writes:

> Why would you need to directly alter JS variables from an XPCOM
> component? Have you considered passing the values back via out
> parameters instead? Modifying global variables from within a method
> call sounds fairly dubious to me. Also, you can't be guaranteed that
> your component is being called from a chrome window, it may be called
> from a JS Component, trusted web content, or from within xpcshell.

In my Very Special Environment(tm) I can be sure that there's only one
chrome window running. In this VSE I'm trying to replace the
commonDialogs component, with my own popup(createPopup)-based
alternative (mainly for speed reasons). I have my own JS statemachine
running, handling all user input and feedback. I'm aware of other ways
to accomplish this (or something similar) but then I get stuck when
trying to catch and parse keyboard-events in my c++ component.

Basically what I want to do is to tell my statemachine (in the chrome
js context) to change state, and when the dialog finishes, switch to
the previous state. (The statemachine then handles all necessary event
handling).

I tried out your code, and it doesn't quite solve what I want to
do. Apparently, when the CD component gets called there is no "callers
js context" at all (afaik).

So if you know of any other ways to get the context of a certain XUL
window, I'd be glad to know. (I got the nsIDOMWindow * for it).


Now, back to hacking.

// Martin

--
ma...@lysator.liu.se

Martin Enlund

unread,
Aug 29, 2000, 3:00:00 AM8/29/00
to
Martin Enlund <ma...@lysator.liu.se> writes:

> Robert Ginda <rgi...@netscape.com> writes:
>
> > Why would you need to directly alter JS variables from an XPCOM
> > component? Have you considered passing the values back via out
> > parameters instead? Modifying global variables from within a method
> > call sounds fairly dubious to me. Also, you can't be guaranteed that
> > your component is being called from a chrome window, it may be called
> > from a JS Component, trusted web content, or from within xpcshell.

This is what I've tried to do now:

NS_WITH_SERVICE(nsIXPConnect, xpc, nsIXPConnect::GetCID(), &rv);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;

nsCOMPtr<nsIXPCNativeCallContext> cc;
rv = xpc->GetCurrentNativeCallContext(getter_AddRefs(cc));
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;

JSContext *cx;
rv = cc->GetJSContext (&cx);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;

JSObject *globalObj;
globalObj = JS_GetGlobalObject(cx);

static const char source[] = "9 * 23";
PRBool ok = JS_EvaluateScript(cx, globalObj, source, strlen(source), "builtin", 1, &result);

Strings like "9 * 23" and other simple expressions work fine, but when
I try something like "var lajbans=9;" or "dump('js eval');" I get
errors.

(I guess the context is the right one when I call this component,
since I do it straight from the chrome))

If I've missed some obvious place to look for JS documentation, please
help me out.


Regards // Martin Enlund

Martin Enlund

unread,
Aug 30, 2000, 3:00:00 AM8/30/00
to
Martin Enlund <ma...@lysator.liu.se> writes:

> Strings like "9 * 23" and other simple expressions work fine, but when
> I try something like "var lajbans=9;" or "dump('js eval');" I get
> errors.

I finally managed to eval functions by using JS_CallFunctionName. But
I still think that evaluating a script with JS_EvaluateScript should
work when doing this. :)

One question still remains though. Is it possible to get the current
js context or a list of js contexts from a nsIDOMWindow or something
similar? (GetCurrentNativeCallContext) doesn't solve this.


Regards, Martin Enlund

Martin Enlund

unread,
Aug 30, 2000, 3:00:00 AM8/30/00
to
0 new messages