I've embedded gecko into my application, I use a function to display
an XUL dialog to the user (below).  The function sets up the window,
and then sets some java script properties and defines a function in
the windows context in order to pass a return value back out of the
window, as well as pass some arguments into the javascript within the
XUL window.

All was fine and good in the 1.8 branch we were using previously.
However, it would be rather silly to continue using the 1.8 branch on
a project which hasn't been released yet, so I've been updating the
embedding code to use the 1.9 branch (HEAD).  Minor changes were
needed to get the code to compile and work, had to remove
NS_STATIC_CAST as this seems to have went away, and update the
references for the ASCII to UTF8/16 string conversion functions.
Simple enough.

The JavaScript portion seems to be a problem however.  In the code
below, everything looks and works find up until the JS_SetProperty
call is made (if the JS_SetProperty call and related error checking is
commented out, the same problem occurs at the JS_DefineFunction line
following after it).

When JS_SetProperty is called, if I step into the function in the
debugger, I see that on line 3531 of jsapi.c there is a call to
CHECK_REQUEST(cx) which expands to (note cx is jscx from my function
at the end of this message when JS_SetProperty is called):

#define
CHECK_REQUEST(cx)                                                   \
    JS_ASSERT((cx)->requestDepth || (cx)->thread == (cx)->runtime-
>gcThread)

At the time of failure, the variables are:
cx->requestDepth = 0
cx->thread = (pointer value which appears to be valid by visual
inspection)
cx->runtime->gcThread = 0x0

In every other call to JS_SetProperty I see from the debugger, cx-
>requestDepth seems to be 3.

While this is bad, it does not suprise me.  I always had the feeling
when this code was writen that it wasn't being done the right way.
I've googled and looked for changes in 1.9 that would indicate this
sort of breakage and have found nothing, which leads me to believe
that no one does it that way I am, likely because its not the right
way to go about it.

So if anyone has an idea about how to make the code below actually
work correctly, what what the correct way to get variables into the
javascript context of a xul window before the scripts in it are run,
as well as get a 'return' value out of it afterwords, I'd love to hear
it.



---------------------------------------------------------------------------------
int Gecko_OpenDialog(void *nativeParentWindow, const wchar_t *url, int
width, int height, BOOL isModal, unsigned int argc, ...)
{
        va_list arg_list;
        nsresult rv;
        JSContext *jscx = 0;

        nsCOMPtr<nsIWebBrowserChrome> chrome;

        rv = OpenWindow(nsnull, nsIWebBrowserChrome::CHROME_OPENAS_CHROME|
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG|
nsIWebBrowserChrome::CHROME_TITLEBAR|( isModal!=FALSE ?
nsIWebBrowserChrome::CHROME_MODAL : 0), url, getter_AddRefs(chrome),
nativeParentWindow);
        if(!NS_SUCCEEDED(rv)) {
                return(-2);
        }

        nsCOMPtr<nsIWebBrowser> webBrowser;
        rv = chrome->GetWebBrowser(getter_AddRefs(webBrowser));
        if(!NS_SUCCEEDED(rv)) {
                return(-3);
        }

        nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(webBrowser));
        if(webNav==NULL) {
                return(-4);
        }

        nsCOMPtr<nsIDOMWindow> dwindow;
        rv = webBrowser->GetContentDOMWindow(getter_AddRefs(dwindow));
        if(!NS_SUCCEEDED(rv)) {
                return(-5);
        }

        int retVal = -1;        // the default value is 'canceled'

// BEGIN JAVASCRIPT SETUP
        nsCOMPtr<nsIScriptGlobalObject> scriptGlobalObj =
do_QueryInterface(dwindow);
        if(scriptGlobalObj) {
                nsCOMPtr<nsIScriptContext> scriptcx;
                scriptcx = scriptGlobalObj->GetContext();
                if(scriptcx) {
                        jscx = (JSContext *)scriptcx->GetNativeContext();
                } else {
                        return(-6);
                }
        } else {
                return(-7);
        }

        // if everything went as planned...
        JSBool w;
        jsval val;
        JSFunction *jfunc;
        if(jscx) {
                JSObject *jswindow = scriptGlobalObj->GetGlobalJSObject();
                int i = (int)&retVal;
                val = INT_TO_JSVAL(i);
                w = JS_SetProperty(jscx, jswindow, "retValPtr", &val);
                if(w==JS_FALSE) {
                        return(-8);
                }
                jfunc = JS_DefineFunction(jscx, jswindow, 
"setDialogReturnValue",
jsSetDialogReturnValue, 1, 0);
                if(jfunc==NULL) {
                        return(-9);
                }

                // Add the arguments
                va_start(arg_list, argc);
                char *nameStr;
                char *argStr;
                JSString *str;
                while(argc>1) {
                        nameStr = va_arg(arg_list, char *);
                        argc--;
                        argStr = va_arg(arg_list, char *);
                        argc--;
                        str = JS_NewStringCopyN(jscx, argStr, strlen(argStr));
                        val = STRING_TO_JSVAL(str);
                        w = JS_SetProperty(jscx, jswindow, nameStr, &val);
                }
                va_end(arg_list);
        } else {
                return(-10);
        }
// END JAVASCRIPT SETUP

        if((width>0)&&(height>0)) {
                chrome->SizeBrowserTo(width, height);
                // since we set the size manually, we have to force visibility
                nsCOMPtr<nsIEmbeddingSiteWindow> embeddedWindow =
do_QueryInterface(chrome);
                embeddedWindow->SetVisibility(PR_TRUE);
        }
        chrome->ShowAsModal();
        return(retVal);
}


_______________________________________________
dev-embedding mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-embedding

Reply via email to