/// <summary> /// Adds a parameter. /// </summary> /// <param name="name">The name of the parameter.</param> /// <param name="value">The value of the parameter.</param> public void Add(string name, object?value) { var nextIndex = _frames[0].ElementSubtreeLengthField++; _frames[nextIndex] = RenderTreeFrame.Attribute(0, name, value); }
/// <summary> /// Handles click events by invoking <paramref name="handler"/>. /// </summary> /// <param name="handler">The handler to be invoked when the event occurs.</param> /// <returns>A <see cref="RenderTreeFrame"/> that represents the event handler.</returns> protected RenderTreeFrame onclick(Action handler) // Note that the 'sequence' value is updated later when inserted into the tree => RenderTreeFrame.Attribute(0, "onclick", _ => handler());
public static void Component <T>(RenderTreeFrame frame, int?subtreeLength = null, int?sequence = null) where T : IComponent { Component(frame, typeof(T).FullName, subtreeLength, sequence); }
public static void ComponentWithInstance <T>(RenderTreeFrame frame, int componentId, int?subtreeLength = null, int?sequence = null) where T : IComponent { AssertFrame.Component <T>(frame, subtreeLength, sequence); Assert.IsType <T>(frame.Component); Assert.Equal(componentId, frame.ComponentId); }
private void Test(/*MM*/ RenderTreeFrame frame) { }
public static void Attribute(RenderTreeFrame frame, string attributeName, Action <object> attributeValidator, int?sequence = null) { AssertFrame.Attribute(frame, attributeName, sequence); attributeValidator(frame.AttributeValue); }
private bool TryApplySpecialProperty(RenderBatch batch, ElementNode element, string attributeName, RenderTreeFrame attributeFrame) { switch (attributeName) { case "value": return(TryApplyValueProperty(element, attributeFrame)); case "checked": return(TryApplyCheckedProperty(element, attributeFrame)); default: return(false); } }
public static void ComponentReferenceCapture(RenderTreeFrame frame, Action <object> action, int?sequence = null) { Assert.Equal(RenderTreeFrameType.ComponentReferenceCapture, frame.FrameType); Assert.Same(action, frame.ComponentReferenceCaptureAction); AssertFrame.Sequence(frame, sequence); }
private int InsertFrame(RenderBatch batch, ContainerNode parent, int childIndex, ArraySegment <RenderTreeFrame> frames, RenderTreeFrame frame, int frameIndex) { switch (frame.FrameType) { case RenderTreeFrameType.Element: { InsertElement(batch, parent, childIndex, frames, frame, frameIndex); return(1); } case RenderTreeFrameType.Text: { InsertText(parent, childIndex, frame); return(1); } case RenderTreeFrameType.Attribute: { throw new Exception("Attribute frames should only be present as leading children of element frames."); } case RenderTreeFrameType.Component: { InsertComponent(parent, childIndex, frame); return(1); } case RenderTreeFrameType.Region: { return(InsertFrameRange(batch, parent, childIndex, frames, frameIndex + 1, frameIndex + frame.RegionSubtreeLength)); } case RenderTreeFrameType.ElementReferenceCapture: { if (parent is ElementNode) { return(0); // A "capture" is a child in the diff, but has no node in the DOM } else { throw new Exception("Reference capture frames can only be children of element frames."); } } case RenderTreeFrameType.Markup: { InsertMarkup(parent, childIndex, frame); return(1); } } throw new Exception($"Unknown frame type: {frame.FrameType}"); }
private void InsertElement(RenderBatch batch, ContainerNode parent, int childIndex, ArraySegment <RenderTreeFrame> frames, RenderTreeFrame frame, int frameIndex) { // Note: we don't handle SVG here var newElement = new ElementNode(frame.ElementName); var inserted = false; // Apply attributes for (var i = frameIndex + 1; i < frameIndex + frame.ElementSubtreeLength; i++) { var descendantFrame = batch.ReferenceFrames.Array[i]; if (descendantFrame.FrameType == RenderTreeFrameType.Attribute) { ApplyAttribute(batch, newElement, descendantFrame); } else { parent.InsertLogicalChild(newElement, childIndex); inserted = true; // As soon as we see a non-attribute child, all the subsequent child frames are // not attributes, so bail out and insert the remnants recursively InsertFrameRange(batch, newElement, 0, frames, i, frameIndex + frame.ElementSubtreeLength); break; } } // this element did not have any children, so it's not inserted yet. if (!inserted) { parent.InsertLogicalChild(newElement, childIndex); } }
public static void Attribute(RenderTreeFrame frame, string attributeName, Type valueType, int?sequence = null) { AssertFrame.Attribute(frame, attributeName, sequence); Assert.IsType(valueType, frame.AttributeValue); }
public static void Attribute(RenderTreeFrame frame, string attributeName, Action <UIEventArgs> attributeEventHandlerValue, int?sequence = null) { AssertFrame.Attribute(frame, attributeName, sequence); Assert.Equal(attributeEventHandlerValue, frame.AttributeValue); }
private int InsertFrame(RenderBatch batch, ContainerNode parent, int childIndex, ArraySegment <RenderTreeFrame> frames, RenderTreeFrame frame, int frameIndex) { switch (frame.FrameType) { case RenderTreeFrameType.Element: { InsertElement(batch, parent, childIndex, frames, frame, frameIndex); return(1); } case RenderTreeFrameType.Text: { InsertText(parent, childIndex, frame); return(1); } case RenderTreeFrameType.Attribute: { throw new Exception("Attribute frames should only be present as leading children of element frames."); } case RenderTreeFrameType.Component: { InsertComponent(parent, childIndex, frame); return(1); } case RenderTreeFrameType.Region: { return(InsertFrameRange(batch, parent, childIndex, frames, frameIndex + 1, frameIndex + CountDescendantFrames(frame))); } case RenderTreeFrameType.ElementReferenceCapture: { // No action for reference captures. break; } case RenderTreeFrameType.Markup: { InsertMarkup(parent, childIndex, frame); return(1); } } throw new Exception($"Unknown frame type: {frame.FrameType}"); }
public static void Region(RenderTreeFrame frame, int subtreeLength, int?sequence = null) { Assert.Equal(RenderTreeFrameType.Region, frame.FrameType); Assert.Equal(subtreeLength, frame.RegionSubtreeLength); AssertFrame.Sequence(frame, sequence); }
public static void Attribute(RenderTreeFrame frame, string attributeName, int?sequence = null) { Assert.AreEqual(RenderTreeFrameType.Attribute, frame.FrameType); Assert.AreEqual(attributeName, frame.AttributeName); AssertFrame.Sequence(frame, sequence); }
public static void TextWhitespace(RenderTreeFrame frame, int?sequence = null) { Assert.Equal(RenderTreeFrameType.Text, frame.FrameType); AssertFrame.Sequence(frame, sequence); Assert.True(string.IsNullOrWhiteSpace(frame.TextContent)); }
private static ArrayRange <RenderTreeFrame> ReadReferenceFrames(ReadOnlySpan <byte> data, string[] strings) { var result = new RenderTreeFrame[data.Length / 16]; for (var i = 0; i < data.Length; i += 16) { var frameData = data.Slice(i, 16); var type = (RenderTreeFrameType)BitConverter.ToInt32(frameData.Slice(0, 4)); // We want each frame to take up the same number of bytes, so that the // recipient can index into the array directly instead of having to // walk through it. // Since we can fit every frame type into 3 ints, use that as the // common size. For smaller frames, we add padding to expand it to // 12 bytes (i.e., 3 x 4-byte ints). // The total size then for each frame is 16 bytes (frame type, then // 3 other ints). switch (type) { case RenderTreeFrameType.Attribute: var attributeName = ReadString(frameData.Slice(4, 4), strings); var attributeValue = ReadString(frameData.Slice(8, 4), strings); var attributeEventHandlerId = BitConverter.ToInt32(frameData.Slice(12, 4)); result[i / 16] = RenderTreeFrame.Attribute(0, attributeName, attributeValue).WithAttributeEventHandlerId(attributeEventHandlerId); break; case RenderTreeFrameType.Component: var componentSubtreeLength = BitConverter.ToInt32(frameData.Slice(4, 4)); var componentId = BitConverter.ToInt32(frameData.Slice(8, 4)); // Nowhere to put this without creating a ComponentState result[i / 16] = RenderTreeFrame.ChildComponent(0, componentType: null) .WithComponentSubtreeLength(componentSubtreeLength) .WithComponent(new ComponentState(Renderer, componentId, new FakeComponent(), null)); break; case RenderTreeFrameType.ComponentReferenceCapture: // Client doesn't process these, skip. result[i / 16] = RenderTreeFrame.ComponentReferenceCapture(0, null, 0); break; case RenderTreeFrameType.Element: var elementSubtreeLength = BitConverter.ToInt32(frameData.Slice(4, 4)); var elementName = ReadString(frameData.Slice(8, 4), strings); result[i / 16] = RenderTreeFrame.Element(0, elementName).WithElementSubtreeLength(elementSubtreeLength); break; case RenderTreeFrameType.ElementReferenceCapture: var referenceCaptureId = ReadString(frameData.Slice(4, 4), strings); result[i / 16] = RenderTreeFrame.ElementReferenceCapture(0, null) .WithElementReferenceCaptureId(referenceCaptureId); break; case RenderTreeFrameType.Region: var regionSubtreeLength = BitConverter.ToInt32(frameData.Slice(4, 4)); result[i / 16] = RenderTreeFrame.Region(0).WithRegionSubtreeLength(regionSubtreeLength); break; case RenderTreeFrameType.Text: var text = ReadString(frameData.Slice(4, 4), strings); result[i / 16] = RenderTreeFrame.Text(0, text); break; case RenderTreeFrameType.Markup: var markup = ReadString(frameData.Slice(4, 4), strings); result[i / 16] = RenderTreeFrame.Markup(0, markup); break; default: throw new ArgumentException($"Unsupported frame type: {type}"); } } return(new ArrayRange <RenderTreeFrame>(result, result.Length)); }
public static void Attribute(RenderTreeFrame frame, string attributeName, string attributeValue, int?sequence = null) { AssertFrame.Attribute(frame, attributeName, sequence); Assert.Equal(attributeValue, frame.AttributeValue); }
/// <summary> /// Handles change events by invoking <paramref name="handler"/>. /// </summary> /// <param name="handler">The handler to be invoked when the event occurs. The handler will receive the new value as a parameter.</param> /// <returns>A <see cref="RenderTreeFrame"/> that represents the event handler.</returns> protected RenderTreeFrame onchange(Action <object> handler) // Note that the 'sequence' value is updated later when inserted into the tree => RenderTreeFrame.Attribute(0, "onchange", args => handler(((UIChangeEventArgs)args).Value));