public WebViewRenderer(IServiceProvider serviceProvider, ILoggerFactory loggerFactory, XRF.WebView webView) : base(serviceProvider, loggerFactory)
 {
     WebView               = webView;
     jsRuntime             = new WebViewJsRuntime(webView.P);
     DOMBuilder            = new DOMBuilder(serviceProvider.GetService <IWebViewPathResolver>());
     WebView.P.Navigating += (s, e) =>
     {
         if (e.NavigationEvent == WebNavigationEvent.NewPage && e.Url == "file:///xamarinrazor/")
         {
             //renderer.LoadHtml(dom, "file:///xamarinrazor");
             UpdateDOM(true);
             e.Cancel = true;
         }
         else if (e.Url.Contains("__event__"))
         {
             var uri        = new Uri(e.Url);
             var query      = uri.Query;
             var collection = HttpUtility.ParseQueryString(query);
             var eventId    = int.Parse(collection["id"]);
             var eventParam = HttpUtility.UrlDecode(collection["v"]);
             DOMBuilder.DispatchEvent(eventId, eventParam);
             e.Cancel = true;
         }
     };
     WebView.P.Navigated += (s, e) =>
     {
         UpdateDOM();
     };
 }
        public async Task UpdateDOM(bool forceFirstUpdate = false)
        {
            string json;

            if (firstUpdate || forceFirstUpdate)
            {
                json = JsonConvert.SerializeObject(new[] { DOMBuilder.DOM }, new JsonSerializerSettings()
                {
                    ContractResolver = new DefaultContractResolver
                    {
                        NamingStrategy = new CamelCaseNamingStrategy()
                    }
                });
                //json = JsonSerializer.Serialize<object[]>(new[] { DOMBuilder.DOM }, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, IgnoreReadOnlyProperties = false });
                //json = new[] { DOMBuilder.DOM }.Serialize();
                DOMBuilder.GetPatches(); //clear pathches
            }
            else
            {
                var patches = DOMBuilder.GetPatches();
                //json = JsonSerializer.Serialize<object[]>(patches.Select(p=>(object)p).ToArray(), new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, IgnoreReadOnlyProperties = false });
                json = JsonConvert.SerializeObject(patches, new JsonSerializerSettings()
                {
                    ContractResolver = new DefaultContractResolver
                    {
                        NamingStrategy = new CamelCaseNamingStrategy()
                    }
                });
                //json = patches.Serialize();
            }
            //Task.Run(async () =>
            //{
            //if (firstUpdate)
            //{
            //    await Task.Delay(30000);
            //}
            var script = $"window.webView.update({json}, {forceFirstUpdate.ToString().ToLower()})";
            await Device.InvokeOnMainThreadAsync(() => WebView.P.EvaluateJavaScriptAsync(script));

            firstUpdate = false;
            //});
        }
        public async Task <string> AddComponent(Type componentType, Action <object> parameterSetter)
        {
            ComponentRenderer adapter = null;
            await Dispatcher.InvokeAsync(async() =>
            {
                var component   = InstantiateComponent(componentType);
                var componentId = AssignRootComponentId(component);
                parameterSetter?.Invoke(component);

                adapter = new ComponentRenderer(component, this);
                Renderers[componentId] = adapter;
                try
                {
                    await RenderRootComponentAsync(componentId).ConfigureAwait(false);
                }catch (Exception e)
                {
                }
            }).ConfigureAwait(false);

            return(DOMBuilder.ToString());
        }