Example #1
0
        /// <summary>
        /// Evaluate JavaScript in specified window, and with specified scope.
        /// Throws GeckoJavaScriptException on error.
        /// </summary>
        /// <param name="javascript">The javascript to run.</param>
        /// <param name="window">The window to execuate javascript in. (ie. the global object)</param>
        /// <param name="scope">object to use as scope.</param>
        /// <returns>The return value of the script as a JsVal</returns>
        public JsVal EvaluateScript(string javascript, nsISupports window, nsISupports scope)
        {
            string msg            = String.Empty;
            JsVal  exceptionJsVal = default(JsVal);

            using (var globalObject = ConvertCOMObjectToJSObject(window))
                using (new JSAutoCompartment(ContextPointer, globalObject.JSObject))
                {
                    var  retJsVal = new JsVal();
                    bool ret;
                    // If not running in window scope.
                    if (window != scope)
                    {
                        using (var scopeObject = ConvertCOMObjectToJSObject(scope))
                        {
                            var scopeJSVal = JsVal.FromPtr(scopeObject.JSObject);
                            var go         = globalObject.JSObject;
                            if (!SpiderMonkey.JS_SetProperty(ContextPointer, ref go, "__RequestedScope",
                                                             ref scopeJSVal))
                            {
                                throw new GeckoException("Failed to set __RequestedScope Property.");
                            }

                            javascript = InsertReturnStatement(javascript);
                            string s = "(function() { " + javascript + " }).call(this.__RequestedScope)";

                            ret = SpiderMonkey.JS_EvaluateScript(ContextPointer, s, (uint)s.Length, "script", 1,
                                                                 ref retJsVal);
                        }
                    }
                    else
                    {
                        ret = SpiderMonkey.JS_EvaluateScript(ContextPointer, javascript, (uint)javascript.Length,
                                                             "script", 1, ref retJsVal);
                    }

                    if (ret)
                    {
                        return(retJsVal);
                    }

                    var exception = SpiderMonkey.JS_GetPendingException(ContextPointer);
                    if (exception != IntPtr.Zero)
                    {
                        exceptionJsVal = JsVal.FromPtr(exception);
                    }
                    msg += exceptionJsVal.ToString();
                    msg += SpiderMonkey.GetStackTrace(ContextPointer, globalObject.JSObject, exceptionJsVal);
                    throw new GeckoJavaScriptException($"JSError : {msg}");
                }
        }