public void Bind(CefV8Value obj)
        {
            if (this.obj != null) throw new InvalidOperationException();

            this.obj = obj;
            BindCore();
        }
 public void Dispose(bool disposing)
 {
     if (this.obj != null)
     {
         this.obj.Dispose();
         this.obj = null;
     }
 }
Exemple #3
0
 private CefV8_JavascriptObject UpdateObject(CefV8Value res, ObjectObservability?objectObservability = null)
 {
     BasicUpdateObject(res, objectObservability);
     return(new CefV8_JavascriptObject(res));
 }
Exemple #4
0
        public IJavascriptObject CreateArray(int size)
        {
            var res = CefV8Value.CreateArray(size);

            return(UpdateObject(res));
        }
Exemple #5
0
 public IJavascriptObject CreateDateTime(DateTime value)
 {
     return(new CefV8_JavascriptObject(CefV8Value.CreateDate(value)));
 }
Exemple #6
0
 protected internal unsafe override bool SetByIndex(int index, CefV8Value @object, CefV8Value value, ref string exception)
 {
     return(_implementation.SetByIndex(index, @object, value, ref exception));
 }
Exemple #7
0
 protected internal unsafe override bool GetByIndex(int index, CefV8Value @object, ref CefV8Value retval, ref string exception)
 {
     return(_implementation.GetByIndex(index, @object, ref retval, ref exception));
 }
Exemple #8
0
 public IJavascriptObject CreateString(string value)
 {
     return(new CefV8_JavascriptObject(CefV8Value.CreateString(value)));
 }
 public CefV8Value CreateObject()
 {
     Handler = CefV8Value.CreateObject();
     Handler.SetValue("log", CefV8Value.CreateFunction("log", this), CefV8PropertyAttribute.None);
     return(Handler);
 }
 protected override bool Execute(string name, CefV8Value obj, CefV8Value[] arguments, out CefV8Value returnValue, out string exception)
 {
     returnValue = CefV8Value.CreateNull();
     exception   = null;
     return(true);
 }
Exemple #11
0
 public object Bind(CefV8Value obj)
 {
     // TODO: bind proxy to v8 value, it will be inspect obj and cache v8 functions to access them
     // TODO: also proxy object must reference FrameContext, 'cause it require to know a v8context
     return(Activator.CreateInstance(proxyType, null));
 }
Exemple #12
0
 internal V8Array(CefV8Value val)
 {
     _value = val;
 }
            protected override bool Execute(string name, CefV8Value obj, CefV8Value[] arguments, out CefV8Value returnValue, out string exception)
            {
                if (name == _config.JSQueryFunction)
                {
                    if (arguments.Length != 1 || !arguments[0].IsObject)
                    {
                        returnValue = null;
                        exception = "Invalid arguments; expecting a single object";
                        return true;
                    }

                    var arg = arguments[0];

                    var requestVal = arg.GetValue(CefMessageRouter.MemberRequest);
                    if (requestVal == null || !requestVal.IsString)
                    {
                        returnValue = null;
                        exception = "Invalid arguments; object member '" +
                                    CefMessageRouter.MemberRequest + "' is required and must " +
                                    "have type string";
                        return true;
                    }

                    CefV8Value successVal = null;
                    if (arg.HasValue(CefMessageRouter.MemberOnSuccess))
                    {
                        successVal = arg.GetValue(CefMessageRouter.MemberOnSuccess);
                        if (!successVal.IsFunction)
                        {
                            returnValue = null;
                            exception = "Invalid arguments; object member '" +
                                        CefMessageRouter.MemberOnSuccess + "' must have type " +
                                        "function";
                            return true;
                        }
                    }

                    CefV8Value failureVal = null;
                    if (arg.HasValue(CefMessageRouter.MemberOnFailure))
                    {
                        failureVal = arg.GetValue(CefMessageRouter.MemberOnFailure);
                        if (!failureVal.IsFunction)
                        {
                            returnValue = null;
                            exception = "Invalid arguments; object member '" +
                                        CefMessageRouter.MemberOnFailure + "' must have type " +
                                        "function";
                            return true;
                        }
                    }

                    CefV8Value persistentVal = null;
                    if (arg.HasValue(CefMessageRouter.MemberPersistent))
                    {
                        persistentVal = arg.GetValue(CefMessageRouter.MemberPersistent);
                        if (!persistentVal.IsBool)
                        {
                            returnValue = null;
                            exception = "Invalid arguments; object member '" +
                                        CefMessageRouter.MemberPersistent + "' must have type " +
                                        "boolean";
                            return true;
                        }
                    }

                    var context = CefV8Context.GetCurrentContext();
                    var contextId = GetIDForContext(context);
                    var frameId = context.GetFrame().Identifier;
                    var persistent = (persistentVal != null && persistentVal.GetBoolValue());

                    var requestId = _router.SendQuery(context.GetBrowser(), frameId, contextId,
                        requestVal.GetStringValue(), persistent, successVal, failureVal);
                    returnValue = CefV8Value.CreateInt(requestId);
                    exception = null;
                    return true;
                }
                else if (name == _config.JSCancelFunction)
                {
                    if (arguments.Length != 1 || !arguments[0].IsInt)
                    {
                        returnValue = null;
                        exception = "Invalid arguments; expecting a single integer";
                        return true;
                    }

                    var result = false;
                    var requestId = arguments[0].GetIntValue();
                    if (requestId != CefMessageRouter.ReservedId)
                    {
                        CefV8Context context = CefV8Context.GetCurrentContext();
                        var contextId = GetIDForContext(context);
                        var frameId = context.GetFrame().Identifier;

                        result = _router.SendCancel(context.GetBrowser(), frameId, contextId, requestId);
                    }
                    returnValue = CefV8Value.CreateBool(result);
                    exception = null;
                    return true;
                }

                returnValue = null;
                exception = null;
                return false;
            }
        // Returns the new request ID.
        private int SendQuery(CefBrowser browser, long frameId, int contextId, string request, bool persistent, CefV8Value successCallback, CefV8Value failureCallback)
        {
            Helpers.RequireRendererThread();

            var requestId = _requestIdGenerator.GetNextId();

            var info = new RequestInfo
            {
                Persistent = persistent,
                SuccessCallback = successCallback,
                FailureCallback = failureCallback,
            };
            _browserRequestInfoMap.Add(browser.Identifier, new KeyValuePair<int, int>(contextId, requestId), info);

            var message = CefProcessMessage.Create(_queryMessageName);
            var args = message.Arguments;
            args.SetInt(0, Helpers.Int64GetLow(frameId));
            args.SetInt(1, Helpers.Int64GetHigh(frameId));
            args.SetInt(2, contextId);
            args.SetInt(3, requestId);
            args.SetString(4, request);
            args.SetBool(5, persistent);

            browser.SendProcessMessage(CefProcessId.Browser, message);

            args.Dispose();
            message.Dispose();

            return requestId;
        }
Exemple #15
0
 public IJavascriptObject CreateUndefined()
 {
     return(new CefV8_JavascriptObject(CefV8Value.CreateUndefined()));
 }
        protected override bool Execute(string name, CefV8Value obj, CefV8Value[] arguments, out CefV8Value returnValue, out string exception)
        {
            returnValue = CefV8Value.CreateNull();
            exception   = null;

            try
            {
                var context = CefV8Context.GetCurrentContext();
                var browser = context.GetBrowser();
                var frame   = browser.GetMainFrame();

                if (name == "log" && arguments.Length > 0)
                {
                    var message = arguments[0].GetStringValue();
                    if (!string.IsNullOrEmpty(message))
                    {
                        Log.Trace(message.ToString(), true);
                    }
                }
                return(true);
            }
            catch (Exception ex)
            {
                returnValue = CefV8Value.CreateNull();
                exception   = ex.Message;
                return(true);
            }
        }
Exemple #17
0
 public IJavascriptObject CreateObject(ObjectObservability objectObservability)
 {
     return(UpdateObject(CefV8Value.CreateObject(null), objectObservability));
 }
        protected override bool Execute(string name, CefV8Value obj, CefV8Value[] arguments, out CefV8Value returnValue, out string exception)
        {
            exception   = null;
            returnValue = null;

            switch (name)
            {
            case "sendMessage":
                string inputArg_Name  = arguments[0].GetStringValue();
                string inputArg_Value = arguments[1].GetStringValue();

                if (inputArg_Name == "Send Message To Browser")
                {
                    CefProcessMessage processMessage = CefProcessMessage.Create(inputArg_Name);
                    CefListValue      listValue      = processMessage.Arguments;
                    listValue.SetString(0, inputArg_Name);

                    CefV8Context.GetCurrentContext().GetBrowser().SendProcessMessage(CefProcessId.Browser, processMessage);
                }

                break;

            default:
                returnValue = null;
                break;
            }

            return(true);
        }
Exemple #19
0
 public static IJavascriptObject Convert(this CefV8Value value)
 {
     return(new CefV8_JavascriptObject(value));
 }
        /// <summary>
        /// The on context created.
        /// </summary>
        /// <param name="browser">
        /// The browser.
        /// </param>
        /// <param name="frame">
        /// The frame.
        /// </param>
        /// <param name="context">
        /// The context.
        /// </param>
        protected override void OnContextCreated(CefBrowser browser, CefFrame frame, CefV8Context context)
        {
            #region Initialize
            var global = context.GetGlobal();
            #endregion

            #region Exposed
            CefV8Value exposed = CefV8Value.CreateObject();
            global.SetValue("exposed", exposed, CefV8PropertyAttribute.None);
            #endregion

            #region Cef Assembly
            var extension = new CefAssembly(browser, frame, context);
            extension.CreateObject(global, new List <string>()
            {
                "mscorlib", "System", "System.Core"
            });
            //extension.CreateObject(global, AppDomain.CurrentDomain.GetAssemblies().Where(s =>
            //{
            //    if (s.GetName().Name.StartsWith("blis")) return true;
            //    return false;
            //})
            //.Select(s => s.GetName().Name).ToList());
            #endregion

            #region Custom XHR
            var xhr = new xhrObject(browser, frame, context);
            global.SetValue("xHttpRequest", xhr.CreateObject(), CefV8PropertyAttribute.None);
            #endregion

            #region V8 Engine API
            var v8Engine = new V8EngineObject(browser, frame, context);
            global.SetValue("V8Engine", v8Engine.CreateObject(), CefV8PropertyAttribute.None);
            #endregion

            #region Database API
            var database = new DatabaseObject(browser, frame, context);
            global.SetValue("DB", database.CreateObject(), CefV8PropertyAttribute.None);
            #endregion

            #region Console API
            var console = new ConsoleObject(browser, frame, context);
            global.SetValue("Console", database.CreateObject(), CefV8PropertyAttribute.None);
            #endregion

            #region Window API
            var window = new WindowObject(browser, frame, context);
            global.SetValue("Window", window.CreateObject(), CefV8PropertyAttribute.None);
            #endregion

            #region Server API
            var server = new ServerObject(browser, frame, context, this);
            global.SetValue("Server", server.CreateObject(), CefV8PropertyAttribute.None);
            #endregion

            #region ChromeDevToosProtocol Object
            var chromeDevToolsProtocol = new ChromeDevToolsProtocol(browser, frame, context);
            global.SetValue("DevTools", chromeDevToolsProtocol.CreateObject(), CefV8PropertyAttribute.None);
            #endregion

            #region V8 Object
            //var v8object = new V8Object(browser, frame, context);
            global.SetValue("V8Object", v8Engine.v8object.CreateObject(), CefV8PropertyAttribute.None);
            #endregion

            #region OnContextCreated
            MessageRouter.OnContextCreated(browser, frame, context);
            context.Dispose();
            #endregion
        }
        private void WriteV8Value(CefV8Value value, StringBuilder result, int indent = 0)
        {
            /*
            var isUndefined = value.IsUndefined;
            var isNull = value.IsNull;
            var isBool = value.IsBool;
            var isInt = value.IsInt;
            var isDouble = value.IsDouble;
            var isDate = value.IsDate;
            var isString = value.IsString;
            var isArray = value.IsArray;
            var isObject = value.IsObject;
            var isFunction = value.IsFunction;

            result.Append("[");
            if (isUndefined) result.Append("undefined ");
            if (isNull) result.Append("null ");
            if (isBool) result.Append("bool ");
            if (isInt) result.Append("int ");
            if (isDouble) result.Append("double ");
            if (isDate) result.Append("date ");
            if (isString) result.Append("string ");
            if (isArray) result.Append("array ");
            if (isObject) result.Append("object ");
            if (isFunction) result.Append("function");
            result.Append("]");
            */

            if (value.IsUndefined)
            {
                result.Append("(undefined)");
            }
            else if (value.IsNull)
            {
                result.Append("(null)");
            }
            else if (value.IsBool)
            {
                result.AppendFormat("(bool) {0}", value.GetBoolValue() ? "true" : "false");
            }
            else if (value.IsInt)
            {
                result.AppendFormat("(int) {0}", value.GetIntValue());
            }
            else if (value.IsDouble)
            {
                result.AppendFormat("(double) {0}", value.GetDoubleValue().ToString(CultureInfo.InvariantCulture.NumberFormat));
            }
            else if (value.IsDate)
            {
                result.AppendFormat("(date) {0}", value.GetDateValue().ToString("s"));
            }
            else if (value.IsString)
            {
                result.AppendFormat("(string) {0}", value.GetStringValue());
            }
            else if (value.IsArray) // for array IsObject also is true
            {
                var indentString = string.Empty.PadLeft((indent + 1) * 4, ' ');
                result.Append("(array) [");
                var length = value.GetArrayLength();
                for (var i = 0; i < length; i++)
                {
                    result.AppendFormat("\n{0}{1} = ", indentString, i);
                    WriteV8Value(value.GetValue(i), result, indent + 1);
                }
                if (length != 0)
                {
                    result.Append('\n');
                    result.Append(indentString);
                }
                result.Append(']');
            }
            else if (value.IsFunction) // for function IsObject also is true
            {
                var name = value.GetFunctionName();
                var handler = value.GetFunctionHandler();
                var declaration = value.GetStringValue();

                result.Append("(function) ");
                result.Append(!string.IsNullOrEmpty(name) ? name : "(anonymous)");
                if (handler != null)
                {
                    result.Append(" (handler: ");
                    result.Append(handler.ToString());
                    result.Append(")");
                }
                if (!string.IsNullOrEmpty(declaration))
                {
                    result.Append(" = ");
                    result.Append(declaration);
                }
            }
            else if (value.IsObject)
            {
                var indentString = string.Empty.PadLeft((indent + 1) * 4, ' ');
                result.Append("(object) {");
                var keys = value.GetKeys().AsEnumerable();
                foreach (var key in keys)
                {
                    result.AppendFormat("\n{0}{1} = ", indentString, key);
                    WriteV8Value(value.GetValue(key), result, indent + 1);
                }
                if (keys.Any())
                {
                    result.Append('\n');
                    result.Append(indentString);
                }
                result.Append('}');
            }
            //else result.Append("(unknown)");
        }
Exemple #22
0
 public IJavascriptObject CreateObject(bool readOnly)
 {
     return(UpdateObject(CefV8Value.CreateObject(null), readOnly));
 }
Exemple #23
0
 protected internal unsafe override bool SetByName(string name, CefV8Value @object, CefV8Value value, ref string exception)
 {
     return(_implementation.SetByName(name, @object, value, ref exception));
 }
Exemple #24
0
 private CefV8_JavascriptObject UpdateObject(CefV8Value res, bool?readOnly = null)
 {
     BasicUpdateObject(res, readOnly);
     return(new CefV8_JavascriptObject(res));
 }
Exemple #25
0
 public IJavascriptObject CreateBool(bool value)
 {
     return(new CefV8_JavascriptObject(CefV8Value.CreateBool(value)));
 }
 public WebCallback(CefV8Context context, CefTaskRunner runner, CefV8Value callback)
 {
     this.Context  = context;
     this.Runner   = runner;
     this.Callback = callback;
 }
Exemple #27
0
 public IJavascriptObject CreateDouble(double value)
 {
     return(new CefV8_JavascriptObject(CefV8Value.CreateDouble(value)));
 }
Exemple #28
0
                protected override bool Execute(string name, CefV8Value obj, CefV8Value[] arguments, out CefV8Value returnValue, out string exception)
                {
                    var message = default(CefProcessMessage);

                    try
                    {
                        CefListValue args;
                        switch (name)
                        {
                        case ReportDocumentSize:
                            message = CefProcessMessage.Create("document-size-response");
                            using (args = message.Arguments)
                            {
                                args.SetInt(0, arguments[0].GetIntValue());
                                args.SetInt(1, arguments[1].GetIntValue());
                                Frame.SendProcessMessage(CefProcessId.Browser, message);
                            }
                            returnValue = null;
                            exception   = null;
                            return(true);

                        default:
                            returnValue = null;
                            exception   = null;
                            return(false);
                        }
                    }
                    finally
                    {
                        message?.Dispose();
                    }
                }
Exemple #29
0
 private static void SetAttribute(CefV8Value value, string name, CefV8Value propertyValue)
 {
     value.SetValue(name, propertyValue, CefV8PropertyAttribute.ReadOnly | CefV8PropertyAttribute.DontEnum | CefV8PropertyAttribute.DontDelete);
 }
Exemple #30
0
                protected override bool Execute(string name, CefV8Value obj, CefV8Value[] arguments, out CefV8Value returnValue, out string exception)
                {
                    try
                    {
                        returnValue = handler(name, obj, arguments);
                        exception   = null;
                    }
                    catch (Exception e)
                    {
                        returnValue = null;
                        exception   = e.ToString();
                    }

                    return(true);
                }
Exemple #31
0
 public IJavascriptObject CreateNull()
 {
     return(new CefV8_JavascriptObject(CefV8Value.CreateNull()));
 }
Exemple #32
0
            protected override void OnContextCreated(CefBrowser browser, CefFrame frame, CefV8Context context)
            {
                if (frame.IsMain)
                {
                    // Retrieve the context's window object and install the "vvvvReportDocumentSize" function
                    // used to tell the node about the document size as well as the "vvvvSend" function
                    // used to tell the node about variables computed inside the frame.
                    using (var window = context.GetGlobal())
                    {
                        var handler = new CustomCallbackHandler(browser, frame);
                        var reportDocumentSizeFunc = CefV8Value.CreateFunction(CustomCallbackHandler.ReportDocumentSize, handler);
                        window.SetValue(CustomCallbackHandler.ReportDocumentSize, reportDocumentSizeFunc);


                        window.SetValue("vvvvQuery", CefV8Value.CreateFunction("vvvvQuery", new DelegatingHandler((name, obj, args) =>
                        {
                            const string argForm = "{ request: 'NAME', arguments: {}, onSuccess: function(response) {}, onError: function(error_message) {} }";
                            string invalidArg    = $"vvvvQuery expects one argument of the form {argForm}";

                            if (args.Length != 1)
                            {
                                throw new Exception($"vvvvQuery expects one argument");
                            }

                            var x = args[0];
                            if (x is null || !x.IsObject)
                            {
                                throw new Exception($"The argument must be of the form {argForm}");
                            }

                            var requestValue = x.GetValue("request");
                            if (requestValue.IsUndefined)
                            {
                                throw new Exception($"The request entry is missing");
                            }
                            if (!requestValue.IsString)
                            {
                                throw new Exception($"The request must be a string");
                            }

                            var onSuccessValue = x.GetValue("onSuccess");
                            if (!onSuccessValue.IsUndefined && !onSuccessValue.IsFunction)
                            {
                                throw new Exception($"The onSuccess entry must be a function");
                            }

                            var onErrorValue = x.GetValue("onError");
                            if (!onErrorValue.IsUndefined && !onErrorValue.IsFunction)
                            {
                                throw new Exception($"The onError entry must be a function");
                            }

                            var request = requestValue.GetStringValue();
                            var id      = queryCount++;

                            if (queries.TryAdd((request, id), (context, onSuccessValue, onErrorValue)))
                            {
                                using var message = CefProcessMessage.Create("query-request");
                                message.Arguments.SetString(0, request);
                                message.Arguments.SetInt(1, id);
                                message.Arguments.SetValue(2, ToValue(x.GetValue("arguments")));
                                frame.SendProcessMessage(CefProcessId.Browser, message);
                            }

                            return(default);
Exemple #33
0
 public IJavascriptObject CreateObject()
 {
     return(UpdateObject(CefV8Value.CreateObject(null)));
 }
 public object Bind(CefV8Value obj)
 {
     // TODO: bind proxy to v8 value, it will be inspect obj and cache v8 functions to access them
     // TODO: also proxy object must reference FrameContext, 'cause it require to know a v8context
     return Activator.CreateInstance(proxyType, null);
 }
Exemple #35
0
 public IJavascriptObject CreateUint(uint value)
 {
     return(new CefV8_JavascriptObject(CefV8Value.CreateUInt(value)));
 }
        private string Dump(CefV8Value[] arguments)
        {
            var result = new StringBuilder();

            var argCount = arguments != null ? arguments.Length : 0;
            for (var i = 0; i < argCount; i++)
            {
                result.AppendFormat("arg[{0}] = ", i);
                WriteV8Value(arguments[i], result);
                result.Append('\n');
            }

            return result.ToString();
        }
        protected override bool Execute(string name, CefV8Value obj, CefV8Value[] arguments, out CefV8Value returnValue, out string exception)
        {
            returnValue = CefV8Value.CreateNull();
            exception   = null;

            try
            {
                var context = CefV8Context.GetCurrentContext();
                var browser = context.GetBrowser();
                var frame   = browser.GetMainFrame();

                if (name == "Create")
                {
                    var Handler = CefV8Value.CreateObject();
                    Handler.SetValue("open", CefV8Value.CreateFunction("open", this), CefV8PropertyAttribute.None);
                    Handler.SetValue("send", CefV8Value.CreateFunction("send", this), CefV8PropertyAttribute.None);
                    Handler.SetValue("onreadystatechange", CefV8Value.CreateFunction("onreadystatechange", this), CefV8PropertyAttribute.None);
                    Handler.SetValue("setRequestHeader", CefV8Value.CreateFunction("setRequestHeader", this), CefV8PropertyAttribute.None);
                    Handler.SetValue("getResponseHeader", CefV8Value.CreateFunction("getResponseHeader", this), CefV8PropertyAttribute.None);
                    returnValue = Handler;
                }
                else if (name == "open")
                {
                    if (arguments.Length >= 2)
                    {
                        var method = arguments[0].GetStringValue();
                        var url    = arguments[1].GetStringValue();

                        _req        = (HttpWebRequest)WebRequest.Create(arguments[1].GetStringValue());
                        _req.Method = method;
                    }
                }
                else if (name == "send")
                {
                    string data = null;

                    try
                    {
                        if (_req.Method == "POST" && arguments.Length == 1)
                        {
                            if (arguments[0].IsString)
                            {
                                var pd = Encoding.UTF8.GetBytes(arguments[0].GetStringValue());
                                _req.GetRequestStream().Write(pd, 0, pd.Length);
                            }
                            else if (arguments[0].IsArray)
                            {
                                var result = arguments[0];
                                var values = new List <char>();
                                for (int i = 0; i < result.GetArrayLength(); i++)
                                {
                                    var value = result.GetValue(i);
                                    values.Add(Extension.ConvertToV8Value(value));
                                }

                                var pd = values.Select(c => (byte)c).ToArray();
                                _req.GetRequestStream().Write(pd, 0, pd.Length);
                            }
                        }

                        _rsp = (HttpWebResponse)_req.GetResponse();
                        if (_rsp.StatusCode == HttpStatusCode.OK)
                        {
                            var d = new StreamReader(_rsp.GetResponseStream()).ReadToEnd();
                            if (!string.IsNullOrEmpty(d))
                            {
                                data = d;
                            }
                        }
                    }
                    catch {}

                    if (data != null)
                    {
                        returnValue = CefV8Value.CreateString(data);
                    }
                }
                else if (name == "setRequestHeader")
                {
                    if (arguments.Length == 2)
                    {
                        if (_req != null)
                        {
                            var _name = arguments[0].GetStringValue();
                            var val   = arguments[1].GetStringValue();

                            if (!string.IsNullOrEmpty(_name) && !string.IsNullOrEmpty(val))
                            {
                                if (_name.ToLower() == "user-agent")
                                {
                                    _req.UserAgent = val;
                                }
                                else if (_name.ToLower() == "connection")
                                {
                                    _req.KeepAlive = val.ToLower() == "keep-alive";
                                }
                                else
                                {
                                    _req.Headers.Add(_name, val);
                                }
                            }
                        }
                    }
                }
                else if (name == "getResponseHeader")
                {
                    string val = null;
                    if (arguments.Length == 1 && _rsp != null)
                    {
                        val = _rsp.Headers[arguments[0].GetStringValue()];
                    }

                    if (val != null)
                    {
                        returnValue = CefV8Value.CreateString(val);
                    }
                }
                return(true);
            }
            catch (Exception ex)
            {
                returnValue = CefV8Value.CreateNull();
                exception   = ex.Message;
                return(true);
            }
        }
        protected override bool Execute(string name, CefV8Value obj, CefV8Value[] arguments, out CefV8Value returnValue, out string exception)
        {
            try
            {
                if (name == "Log")
                {
                    var message = arguments[0].GetStringValue();
                    #if DIAGNOSTICS
                    Cef.Logger.Info(LogTarget.Default, message);
                    #endif
                    returnValue = null;
                }
                else if (name == "ReturnVoid")
                {
                    returnValue = null;
                }
                else if (name == "ReturnVoidAndDisposeThis")
                {
                    returnValue = null;

                    if (obj != null) { obj.Dispose(); obj = null; }
                }
                else if (name == "ReturnUndefined")
                {
                    returnValue = CefV8Value.CreateUndefined();
                }
                else if (name == "ReturnNull")
                {
                    returnValue = CefV8Value.CreateNull();
                }
                else if (name == "ReturnBool")
                {
                    returnValue = CefV8Value.CreateBool(true);
                }
                else if (name == "ReturnInt")
                {
                    returnValue = CefV8Value.CreateInt(12345678);
                }
                else if (name == "ReturnDouble")
                {
                    returnValue = CefV8Value.CreateDouble(1234.5678);
                }
                else if (name == "ReturnDate")
                {
                    returnValue = CefV8Value.CreateDate(DateTime.UtcNow);
                }
                else if (name == "ReturnString")
                {
                    returnValue = CefV8Value.CreateString("Some string, passed to CEF!");
                }
                else if (name == "ReturnArray")
                {
                    var array = CefV8Value.CreateArray(3);
                    array.SetValue(0, CefV8Value.CreateInt(123));
                    array.SetValue(1, CefV8Value.CreateString("hello!"));
                    array.SetValue(2, CefV8Value.CreateBool(false));

                    returnValue = array;
                }
                else if (name == "ReturnObject")
                {
                    var obj1 = CefV8Value.CreateObject();
                    obj1.SetValue("index", CefV8Value.CreateInt(123));
                    obj1.SetValue("reply", CefV8Value.CreateString("hello!"));
                    obj1.SetValue("success", CefV8Value.CreateBool(false));

                    returnValue = obj1;
                }
                else if (name == "ReturnComplexArray")
                {
                    var obj1 = CefV8Value.CreateObject();
                    obj1.SetValue("index", CefV8Value.CreateInt(123));
                    obj1.SetValue("reply", CefV8Value.CreateString("hello!"));
                    obj1.SetValue("success", CefV8Value.CreateBool(false));

                    var array = CefV8Value.CreateArray(5);
                    array.SetValue(0, CefV8Value.CreateInt(123));
                    array.SetValue(1, CefV8Value.CreateString("hello!"));
                    array.SetValue(2, CefV8Value.CreateBool(false));
                    array.SetValue(3, obj1);
                    array.SetValue(4, CefV8Value.CreateString("hello2!"));

                    obj1 = CefV8Value.CreateObject();
                    obj1.SetValue("index", CefV8Value.CreateInt(123));
                    obj1.SetValue("reply", CefV8Value.CreateString("hello!"));
                    obj1.SetValue("success", CefV8Value.CreateBool(false));

                    var obj2 = CefV8Value.CreateObject();
                    obj2.SetValue("i'm still", CefV8Value.CreateString("alive"));

                    obj1.SetValue("inner", obj2);

                    array.SetValue(5, obj1);

                    returnValue = array;
                }
                else if (name == "ReturnComplexObject")
                {
                    var obj1 = CefV8Value.CreateObject();
                    obj1.SetValue("index", CefV8Value.CreateInt(123));
                    obj1.SetValue("reply", CefV8Value.CreateString("hello!"));
                    obj1.SetValue("success", CefV8Value.CreateBool(false));

                    var obj2 = CefV8Value.CreateObject();
                    obj2.SetValue("i'm still", CefV8Value.CreateString("alive"));

                    obj1.SetValue("inner", obj2);

                    obj2.Dispose(); // force to dispose object wrapper and underlying v8 persistent handle.
                    // note, that obj2 will passed in obj before, but it anyway safe to destroy obj2 handle,
                    // 'cause v8 api internally always open handles.

                    returnValue = obj1;
                }
                else if (name == "SubtractIntImplicit")
                {
                    var a = arguments[0].GetIntValue();
                    var b = arguments[1].GetIntValue();

                    returnValue = CefV8Value.CreateInt(a - b);
                }
                else if (name == "SubtractIntExplicit")
                {
                    if (!arguments[0].IsInt) throw new ArgumentException("arg0");
                    var a = arguments[0].GetIntValue();

                    if (!arguments[1].IsInt) throw new ArgumentException("arg1");
                    var b = arguments[1].GetIntValue();

                    returnValue = CefV8Value.CreateInt(a - b);
                }
                else if (name == "Dump")
                {
                    returnValue = CefV8Value.CreateString(Dump(arguments));
                }
                else if (name == "get_PrivateWorkingSet")
                {
                    var result = Process.GetCurrentProcess().PrivateMemorySize64 / (1024.0 * 1024.0);
                    returnValue = CefV8Value.CreateDouble(result);
                }
                else if (name == "leakTestV8Func")
                {
                    var handler = new TestV8Handler();
                    for (var i = 0; i < 100000; i++)
                    {
                        var x = CefV8Value.CreateFunction("LeakTest", handler);
                        x.Dispose();
                    }
                    returnValue = CefV8Value.CreateBool(true);
                }
                else
                {
                    returnValue = null;
                    exception = null;
                    return false;
                }

                exception = null;
                return true;
            }
            catch (Exception ex)
            {
                returnValue = null;
                exception = ex.ToString();
                return true;
            }
        }
        private static object InvokeScript(CefV8Context context, string memberName, params object[] args)
        {
            if (context == null) throw new ArgumentNullException("context");

            if (!context.Enter()) throw new CefException("Failed to enter V8 context.");
            try
            {
                // TODO: this list can be private list of context, 'cause we can invoke only one function at one time
                List<CefV8Value> proxies = new List<CefV8Value>(16);

                // javascript 'this' object
                CefV8Value obj = null;

                CefV8Value target = context.GetGlobal();
                proxies.Add(target);
                if (!memberName.Contains('.'))
                {
                    obj = target;
                    target = obj.GetValue(memberName);
                    proxies.Add(target);
                }
                else
                {
                    foreach (var member in memberName.Split('.'))
                    {
                        obj = target;
                        target = obj.GetValue(member); // TODO: do analysis of target - if it is not an object - throw
                        if (!target.IsObject) throw new CefException("Argument 'memberName' must be member access expression to a function. Invalid object in path.");
                        proxies.Add(target);
                    }
                }
                if (!target.IsFunction) throw new ArgumentException("Argument 'memberName' must be member access expression to a function.");

                CefV8Value[] v8Args;

                if (args.Length == 0) v8Args = null;
                else
                {
                    v8Args = new CefV8Value[args.Length]; // TODO: InvokeScript core can be optimized by prevent recreating arrays
                    for (var i = 0; i < args.Length; i++)
                    {
                        var value = CefConvert.ToV8Value(args[i]);
                        v8Args[i] = value;
                    }
                }

                var v8RetVal = target.ExecuteFunctionWithContext(context, obj, v8Args);

                // force destroing of proxies, to avoid unneccessary GC load (CLR and V8)
                foreach (var proxy in proxies)
                    proxy.Dispose();

                proxies.Clear();

                // FIXME: not sure if exception CAN be null, this need to be checked
                if (v8RetVal.HasException)
                {
                    var exception = v8RetVal.GetException();
                    throw new JavaScriptException(exception.GetMessage());
                }

                //if (!string.IsNullOrEmpty(exception))

                var result = CefConvert.ToObject(v8RetVal);
                v8RetVal.Dispose();
                return result;
            }
            finally
            {
                if (!context.Exit()) throw new CefException("Failed to exit V8 context.");
            }
        }
 protected override bool Set(string name, CefV8Value obj, CefV8Value value, out string exception)
 {
     throw new NotSupportedException();
 }