Beispiel #1
0
        public Task <JavaScriptExecutionResult> ExecuteFunctionAsync(CefFrame frame, JavaScriptValue[] arguments = null)
        {
            CheckIsRendererFunction();

            var tsc = new TaskCompletionSource <JavaScriptExecutionResult>();

            if (JavaScriptObjectRepository.JavaScriptExecutionTasks.TryAdd(new Tuple <int, long>(tsc.GetHashCode(), frame.Identifier), tsc))
            {
                var jsvalue = arguments == null?JavaScriptValue.CreateArray() : arguments.ToJSValue();

                var message = BridgeMessage.Create(JavaScriptCommunicationBridge.EVALUATE_JS_CALLBACK);

                message.Arguments.Add(MessageValue.CreateInt(tsc.GetHashCode()));

                message.Arguments.Add(MessageValue.CreateInt(JSFunctionDescriber.Id));

                message.Arguments.Add(MessageValue.CreateString(jsvalue.ToDefinition()));

                JavaScriptCommunicationBridge.SendProcessMessage(CefProcessId.Renderer, frame, message);

                return(tsc.Task);
            }


            throw new InvalidOperationException("Same function already exists.");
        }
        //public static JSValue FromJson(this JSValue @this, string json)
        //{

        //}

        public static JavaScriptValue ToJSValue(this JavaScriptValue[] source)
        {
            var target = JavaScriptValue.CreateArray();

            for (int i = 0; i < source.Length; i++)
            {
                target.SetValue(i, source[i]);
            }

            return(target);
        }
        public void Success(params JavaScriptValue[] retvals)
        {
            if (_isCalled)
            {
                throw new InvalidOperationException();
            }

            var retval = retvals?.ToJSValue() ?? JavaScriptValue.CreateArray();

            var arguments = new MessageArrayValue();

            arguments.Add(MessageValue.CreateBool(true));
            arguments.Add(MessageValue.CreateString(retval.ToDefinition()));
            arguments.Add(MessageValue.CreateString($"{_uuid}"));


            CefRuntime.PostTask(CefThreadId.Renderer, new JavaScriptCommunicationBridge.RenderSideJavaScriptExecutionCallbackTask(_jsBridge, _frame, arguments));

            _isCalled = true;
        }
        public void Success(params JavaScriptValue[] retvals)
        {
            if (_isCalled)
            {
                throw new InvalidOperationException();
            }


            var message = BridgeMessage.Create(JavaScriptCommunicationBridge.EXECUTE_JAVASCRIPT_FUNCTION);

            message.Arguments.Add(MessageValue.CreateBool(true));

            var retval = retvals?.ToJSValue() ?? JavaScriptValue.CreateArray();

            message.Arguments.Add(MessageValue.CreateString(retval.ToDefinition()));
            message.Arguments.Add(MessageValue.CreateString($"{_uuid}"));


            _jsBridge.SendProcessMessage(_frame, message);

            _isCalled = true;
        }
        protected override bool Execute(string name, CefV8Value obj, CefV8Value[] arguments, out CefV8Value returnValue, out string exception)
        {
            if (name == _name)
            {
                var bid = _context.GetBrowser()?.Identifier ?? 0;
                var fid = _context.GetFrame()?.Identifier ?? 0;

                var request = MessageBridgeRequest.Create(JavaScriptCommunicationBridge.EXECUTE_JAVASCRIPT_FUNCTION, bid, fid, _context.GetHashCode());

                request.Arguments.Add(MessageValue.CreateString(_parentKey));
                request.Arguments.Add(MessageValue.CreateString(_name));

                var args = JavaScriptValue.CreateArray();

                var index = 0;

                foreach (var arg in arguments)
                {
                    var value = arg.ToJSValue();

                    if (value != null)
                    {
                        args.SetValue(index++, value);
                    }
                }

                request.Arguments.Add(MessageValue.CreateString(args.ToDefinition()));

                var guid = Guid.NewGuid();

                request.Arguments.Add(MessageValue.CreateString($"{guid}"));

                var response = _bridge.SendExecutionRequest(request);

                if (response.IsSuccess)
                {
                    if (_functionInfo.IsAsync)
                    {
                        var callback = CefV8Value.CreateObject();

                        var successFunc = CefV8Value.CreateFunction("success", new JavaScriptBridgeFunctionCallbackHandler(/*_parentKey, _name,*/ guid, _context));

                        var errorFunc = CefV8Value.CreateFunction("error", new JavaScriptBridgeFunctionCallbackHandler(/*_parentKey, _name,*/ guid, _context));

                        callback.SetValue("success", successFunc);
                        callback.SetValue("error", errorFunc);

                        returnValue = callback;
                        exception   = null;
                    }
                    else
                    {
                        var retval = JavaScriptValue.FromJson(response.Arguments[0].GetString())?.ToCefV8Value();

                        exception = null;

                        if (retval != null)
                        {
                            returnValue = retval;
                        }
                        else
                        {
                            returnValue = CefV8Value.CreateUndefined();
                        }
                    }
                }
                else
                {
                    exception   = response.ExceptionMessage;
                    returnValue = null;
                }

                return(true);
            }

            returnValue = null;
            exception   = $"{name} is not defined.";

            return(true);
        }
        public static JavaScriptValue ToJSValue(this CefV8Value source)
        {
            if (source == null || !source.IsValid)
            {
                throw new ArgumentNullException();
            }

            JavaScriptValue target;

            if (source.IsFunction)
            {
                var context = CefV8Context.GetEnteredContext();

                var info = new JavaScriptRenderSideFunction(context, source);

                JavaScriptObjectRepository.RenderSideFunctions.Add(info);

                target = JavaScriptValue.CreateFunction(info);
            }
            else if (source.IsArray)
            {
                target = JavaScriptValue.CreateArray();
                for (int i = 0; i < source.GetArrayLength(); i++)
                {
                    var item = source.GetValue(i);
                    if (item != null && item.IsValid)
                    {
                        target.AddArrayValue(item.ToJSValue());
                    }
                }
            }
            else if (source.IsObject)
            {
                target = JavaScriptValue.CreateObject();
                foreach (var key in source.GetKeys())
                {
                    var item = source.GetValue(key);
                    if (item != null && item.IsValid)
                    {
                        target.SetValue(key, item.ToJSValue());
                    }
                }
            }
            else if (source.IsBool)
            {
                target = JavaScriptValue.CreateBool(source.GetBoolValue());
            }
            else if (source.IsDate)
            {
                target = JavaScriptValue.CreateDateTime(source.GetDateValue());
            }
            else if (source.IsDouble)
            {
                target = JavaScriptValue.CreateNumber(source.GetDoubleValue());
            }
            else if (source.IsInt)
            {
                target = JavaScriptValue.CreateNumber(source.GetIntValue());
            }
            else if (source.IsUInt)
            {
                target = JavaScriptValue.CreateNumber(source.GetUIntValue());
            }
            else if (source.IsString)
            {
                target = JavaScriptValue.CreateString(source.GetStringValue());
            }
            else
            {
                target = JavaScriptValue.CreateNull();
            }


            return(target);
        }
        protected override bool Execute(string name, CefV8Value obj, CefV8Value[] arguments, out CefV8Value returnValue, out string exception)
        {
            var context = CefV8Context.GetCurrentContext();

            var browser = context.GetBrowser();

            var frame = browser.GetMainFrame();

            var function = Extension.FunctionHandlers.SingleOrDefault(x => x.FuntionName.Equals(name));

            //WinFormium.GetLogger().Debug($"{name}");

            if (function == null)
            {
                exception   = $"[NanUI]:{name} is not defined.";
                returnValue = null;


                return(true);
            }



            var args = JavaScriptValue.CreateArray();

            var index = 0;

            foreach (var arg in arguments)
            {
                var value = arg.ToJSValue();

                if (value != null)
                {
                    args.SetValue(index++, value);
                }
            }


            exception = null;

            var uuid = Guid.NewGuid();



            if (function.FunctionType == JavaScriptExtensionFunctionHandlerType.RendererSideFunction || function.FunctionType == JavaScriptExtensionFunctionHandlerType.RendererSideAsyncFunction)
            {
                if (function.FunctionType == JavaScriptExtensionFunctionHandlerType.RendererSideFunction)
                {
                    var retval = function.RendererSideFunction.Invoke(args.ToArray());
                    returnValue = retval?.ToCefV8Value() ?? CefV8Value.CreateUndefined();
                }
                else
                {
                    function.RendererSideAsyncFunction.Invoke(args.ToArray(), new JavaScriptRendererSideAsyncFunctionCallback(frame, uuid, JSBridge));

                    var callback    = CefV8Value.CreateObject();
                    var successFunc = CefV8Value.CreateFunction("success", new JavaScriptBridgeFunctionCallbackHandler(uuid, context));

                    var errorFunc = CefV8Value.CreateFunction("error", new JavaScriptBridgeFunctionCallbackHandler(uuid, context));


                    callback.SetValue("success", successFunc);
                    callback.SetValue("error", errorFunc);

                    returnValue = callback;
                }

                return(true);
            }
            else
            {
                var request = MessageBridgeRequest.Create(JavaScriptCommunicationBridge.EXECUTE_EXT_JAVASCRIPT_FUNCION, browser.Identifier, frame.Identifier, context.GetHashCode());


                request.Arguments.Add(MessageValue.CreateString(Extension.Name));

                request.Arguments.Add(MessageValue.CreateString(name));

                request.Arguments.Add(MessageValue.CreateString(args.ToDefinition()));

                request.Arguments.Add(MessageValue.CreateString($"{uuid}"));


                var response = JSBridge.SendExecutionRequest(request);



                if (response.IsSuccess)
                {
                    if (function.FunctionType == JavaScriptExtensionFunctionHandlerType.BrowserSideFunction)
                    {
                        if (response.Arguments != null && response.Arguments.Count > 0)
                        {
                            var retval = JavaScriptValue.FromJson(response.Arguments[0].GetString())?.ToCefV8Value();


                            if (retval != null)
                            {
                                returnValue = retval;
                                return(true);
                            }
                        }
                    }
                    else
                    {
                        var callback    = CefV8Value.CreateObject();
                        var successFunc = CefV8Value.CreateFunction("success", new JavaScriptBridgeFunctionCallbackHandler(uuid, context));

                        var errorFunc = CefV8Value.CreateFunction("error", new JavaScriptBridgeFunctionCallbackHandler(uuid, context));

                        callback.SetValue("success", successFunc);
                        callback.SetValue("error", errorFunc);

                        returnValue = callback;

                        return(true);
                    }

                    returnValue = CefV8Value.CreateUndefined();
                }
                else
                {
                    returnValue = null;
                    exception   = response.ExceptionMessage;
                }
            }

            return(true);
        }