public ComponentRenderer(IComponent component, WebViewRenderer webViewRenderer, ComponentRenderer parent = null) { Component = component; WebViewRenderer = webViewRenderer; Parent = parent; InitialNode = parent?.CurrentNode ?? -1; if (parent != null) { parent.Children.Add(this); //foreach(var sequence in parent.Sequences.Reverse()) //{ // Sequences.Push(sequence); //} } }
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()); }
void ProcessTree(RenderTreeEdit edit, RenderBatch batch, int startIndex, int subLength) { for (int i = 0; i < subLength; i++) { int currentIndex = startIndex + i; var frame = batch.ReferenceFrames.Array[currentIndex]; switch (edit.Type) { case RenderTreeEditType.PrependFrame: { switch (frame.FrameType) { case RenderTreeFrameType.Component: { CurrentNode = WebViewRenderer.DOMBuilder.CreateMarkerElement(CurrentNode, frame.Sequence, frame.Component.GetType().Name); //Sequences.Push(frame.Sequence); var childRenderer = new ComponentRenderer(frame.Component, WebViewRenderer, this); WebViewRenderer.Renderers[frame.ComponentId] = childRenderer; //we dont need to process the subtree of components as the Renderer will process it again //ProcessTree(edit, batch, currentIndex + 1, frame.ElementSubtreeLength - 1); i += frame.ComponentSubtreeLength - 1; //Sequences.Pop(); CurrentNode = WebViewRenderer.DOMBuilder.Parent(CurrentNode); } break; case RenderTreeFrameType.Element: { CurrentNode = WebViewRenderer.DOMBuilder.CreateElement(CurrentNode, frame.Sequence, frame.ElementName); //Sequences.Push(frame.Sequence); ProcessTree(edit, batch, currentIndex + 1, frame.ElementSubtreeLength - 1); i += frame.ElementSubtreeLength - 1; //Sequences.Pop(); CurrentNode = WebViewRenderer.DOMBuilder.Parent(CurrentNode); } break; case RenderTreeFrameType.Attribute: { if (frame.AttributeValue is EventCallback callback) { WebViewRenderer.DOMBuilder.SetEvent(CurrentNode, frame.Sequence, frame.AttributeName, callback, frame.AttributeEventUpdatesAttributeName); } else { WebViewRenderer.DOMBuilder.SetAttribute(CurrentNode, frame.Sequence, frame.AttributeName, frame.AttributeValue); } } break; case RenderTreeFrameType.Text: WebViewRenderer.DOMBuilder.InsertText(CurrentNode, frame.Sequence, frame.TextContent); break; case RenderTreeFrameType.Markup: { WebViewRenderer.DOMBuilder.InsertMarkup(CurrentNode, frame.Sequence, frame.MarkupContent); } break; case RenderTreeFrameType.Region: { CurrentNode = WebViewRenderer.DOMBuilder.CreateMarkerElement(CurrentNode, frame.Sequence, frame.AttributeName); //Sequences.Push(frame.Sequence); ProcessTree(edit, batch, currentIndex + 1, frame.RegionSubtreeLength - 1); i += frame.RegionSubtreeLength - 1; //Sequences.Pop(); CurrentNode = WebViewRenderer.DOMBuilder.Parent(CurrentNode); } break; case RenderTreeFrameType.ElementReferenceCapture: ElementReference reference = new ElementReference(CurrentNode.ToString()); //WebViewRenderer.DOMBuilder.Reference(); frame.ElementReferenceCaptureAction(reference); break; case RenderTreeFrameType.None: break; default: throw new NotImplementedException($"Invalid Frame type: {frame.FrameType}"); } } break; case RenderTreeEditType.UpdateText: { WebViewRenderer.DOMBuilder.UpdateText(CurrentNode, frame.Sequence, frame.TextContent); } break; case RenderTreeEditType.RemoveFrame: { WebViewRenderer.DOMBuilder.RemoveAt(CurrentNode, edit.SiblingIndex); } break; case RenderTreeEditType.UpdateMarkup: { WebViewRenderer.DOMBuilder.UpdateMarkup(CurrentNode, frame.Sequence, frame.TextContent); } break; case RenderTreeEditType.SetAttribute: { var node = WebViewRenderer.DOMBuilder.Child(CurrentNode, edit.SiblingIndex); if (frame.AttributeValue is EventCallback callback) { WebViewRenderer.DOMBuilder.SetEvent(node, frame.Sequence, frame.AttributeName, callback, frame.AttributeEventUpdatesAttributeName); } else { WebViewRenderer.DOMBuilder.SetAttribute(node, frame.Sequence, frame.AttributeName, frame.AttributeValue); } //WebViewRenderer.DOMManager.SetAttribute(CurrentNode, frame.Sequence, frame.AttributeName, frame.AttributeValue); } break; case RenderTreeEditType.RemoveAttribute: { WebViewRenderer.DOMBuilder.RemoveAttribute(CurrentNode, frame.Sequence, frame.AttributeName); } break; case RenderTreeEditType.StepIn: CurrentNode = WebViewRenderer.DOMBuilder.Child(CurrentNode, edit.SiblingIndex); break; case RenderTreeEditType.StepOut: CurrentNode = WebViewRenderer.DOMBuilder.Parent(CurrentNode); break; case RenderTreeEditType.PermutationListEntry: case RenderTreeEditType.PermutationListEnd: default: throw new NotImplementedException($"Invalid edit type: {edit.Type}"); } } }