Rename UITree -> RenderTree, UIEventInfo -> UIEventArgs
This commit is contained in:
parent
5793bf700a
commit
674024ed61
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
using Microsoft.Blazor.Browser;
|
||||
using Microsoft.Blazor.Components;
|
||||
using Microsoft.Blazor.UITree;
|
||||
using Microsoft.Blazor.RenderTree;
|
||||
|
||||
namespace HostedInAspNet.Client
|
||||
{
|
||||
|
|
@ -19,10 +19,10 @@ namespace HostedInAspNet.Client
|
|||
|
||||
internal class MyComponent : IComponent
|
||||
{
|
||||
public void BuildUITree(UITreeBuilder builder)
|
||||
public void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
builder.OpenElement("h1");
|
||||
builder.AddText("Hello from UITree");
|
||||
builder.AddText("Hello from RenderTree");
|
||||
builder.CloseElement();
|
||||
|
||||
builder.OpenElement("ul");
|
||||
|
|
|
|||
|
|
@ -1,27 +1,27 @@
|
|||
import { System_String, System_Array, Pointer } from '../Platform/Platform';
|
||||
import { platform } from '../Environment';
|
||||
const uiTreeNodeStructLength = 32;
|
||||
const renderTreeNodeStructLength = 32;
|
||||
|
||||
// To minimise GC pressure, instead of instantiating a JS object to represent each tree node,
|
||||
// we work in terms of pointers to the structs on the .NET heap, and use static functions that
|
||||
// know how to read property values from those structs.
|
||||
|
||||
export function getTreeNodePtr(uiTreeEntries: System_Array, index: number): UITreeNodePointer {
|
||||
return platform.getArrayEntryPtr(uiTreeEntries, index, uiTreeNodeStructLength) as UITreeNodePointer;
|
||||
export function getTreeNodePtr(renderTreeEntries: System_Array, index: number): RenderTreeNodePointer {
|
||||
return platform.getArrayEntryPtr(renderTreeEntries, index, renderTreeNodeStructLength) as RenderTreeNodePointer;
|
||||
}
|
||||
|
||||
export const uiTreeNode = {
|
||||
// The properties and memory layout must be kept in sync with the .NET equivalent in UITreeNode.cs
|
||||
nodeType: (node: UITreeNodePointer) => _readInt32Property(node, 0) as NodeType,
|
||||
elementName: (node: UITreeNodePointer) => _readStringProperty(node, 4),
|
||||
descendantsEndIndex: (node: UITreeNodePointer) => _readInt32Property(node, 8) as NodeType,
|
||||
textContent: (node: UITreeNodePointer) => _readStringProperty(node, 12),
|
||||
attributeName: (node: UITreeNodePointer) => _readStringProperty(node, 16),
|
||||
attributeValue: (node: UITreeNodePointer) => _readStringProperty(node, 20),
|
||||
export const renderTreeNode = {
|
||||
// The properties and memory layout must be kept in sync with the .NET equivalent in RenderTreeNode.cs
|
||||
nodeType: (node: RenderTreeNodePointer) => _readInt32Property(node, 0) as NodeType,
|
||||
elementName: (node: RenderTreeNodePointer) => _readStringProperty(node, 4),
|
||||
descendantsEndIndex: (node: RenderTreeNodePointer) => _readInt32Property(node, 8) as NodeType,
|
||||
textContent: (node: RenderTreeNodePointer) => _readStringProperty(node, 12),
|
||||
attributeName: (node: RenderTreeNodePointer) => _readStringProperty(node, 16),
|
||||
attributeValue: (node: RenderTreeNodePointer) => _readStringProperty(node, 20),
|
||||
};
|
||||
|
||||
export enum NodeType {
|
||||
// The values must be kept in sync with the .NET equivalent in UITreeNodeType.cs
|
||||
// The values must be kept in sync with the .NET equivalent in RenderTreeNodeType.cs
|
||||
element = 1,
|
||||
text = 2,
|
||||
attribute = 3,
|
||||
|
|
@ -37,6 +37,6 @@ function _readStringProperty(baseAddress: Pointer, offsetBytes: number) {
|
|||
return platform.toJavaScriptString(managedString);
|
||||
}
|
||||
|
||||
// Nominal type to ensure only valid pointers are passed to the uiTreeNode functions.
|
||||
// Nominal type to ensure only valid pointers are passed to the renderTreeNode functions.
|
||||
// At runtime the values are just numbers.
|
||||
export interface UITreeNodePointer extends Pointer { UITreeNodePointer__DO_NOT_IMPLEMENT: any }
|
||||
export interface RenderTreeNodePointer extends Pointer { RenderTreeNodePointer__DO_NOT_IMPLEMENT: any }
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { registerFunction } from '../RegisteredFunction';
|
||||
import { System_Object, System_String, System_Array, MethodHandle } from '../Platform/Platform';
|
||||
import { platform } from '../Environment';
|
||||
import { getTreeNodePtr, uiTreeNode, NodeType, UITreeNodePointer } from './UITreeNode';
|
||||
import { getTreeNodePtr, renderTreeNode, NodeType, RenderTreeNodePointer } from './RenderTreeNode';
|
||||
let raiseEventMethod: MethodHandle;
|
||||
let getComponentRenderInfoMethod: MethodHandle;
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ let getComponentRenderInfoMethod: MethodHandle;
|
|||
const componentIdToParentElement: { [componentId: string]: Element } = {};
|
||||
|
||||
registerFunction('_blazorAttachComponentToElement', attachComponentToElement);
|
||||
registerFunction('_blazorRender', renderUITree);
|
||||
registerFunction('_blazorRender', renderRenderTree);
|
||||
|
||||
function attachComponentToElement(elementSelector: System_String, componentId: System_String) {
|
||||
const elementSelectorJs = platform.toJavaScriptString(elementSelector);
|
||||
|
|
@ -26,7 +26,7 @@ function attachComponentToElement(elementSelector: System_String, componentId: S
|
|||
componentIdToParentElement[componentIdJs] = element;
|
||||
}
|
||||
|
||||
function renderUITree(componentId: System_String, tree: System_Array, treeLength: number) {
|
||||
function renderRenderTree(componentId: System_String, tree: System_Array, treeLength: number) {
|
||||
const componentIdJs = platform.toJavaScriptString(componentId);
|
||||
const element = componentIdToParentElement[componentIdJs];
|
||||
if (!element) {
|
||||
|
|
@ -43,15 +43,15 @@ function insertNodeRange(componentId: string, intoDomElement: Element, tree: Sys
|
|||
insertNode(componentId, intoDomElement, tree, node, index);
|
||||
|
||||
// Skip over any descendants, since they are already dealt with recursively
|
||||
const descendantsEndIndex = uiTreeNode.descendantsEndIndex(node);
|
||||
const descendantsEndIndex = renderTreeNode.descendantsEndIndex(node);
|
||||
if (descendantsEndIndex > 0) {
|
||||
index = descendantsEndIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function insertNode(componentId: string, intoDomElement: Element, tree: System_Array, node: UITreeNodePointer, nodeIndex: number) {
|
||||
const nodeType = uiTreeNode.nodeType(node);
|
||||
function insertNode(componentId: string, intoDomElement: Element, tree: System_Array, node: RenderTreeNodePointer, nodeIndex: number) {
|
||||
const nodeType = renderTreeNode.nodeType(node);
|
||||
switch (nodeType) {
|
||||
case NodeType.element:
|
||||
insertElement(componentId, intoDomElement, tree, node, nodeIndex);
|
||||
|
|
@ -94,16 +94,16 @@ function insertComponent(intoDomElement: Element, parentComponentId: string, com
|
|||
insertNodeRange(componentId, containerElement, componentTree, 0, componentTreeLength - 1);
|
||||
}
|
||||
|
||||
function insertElement(componentId: string, intoDomElement: Element, tree: System_Array, elementNode: UITreeNodePointer, elementNodeIndex: number) {
|
||||
const tagName = uiTreeNode.elementName(elementNode);
|
||||
function insertElement(componentId: string, intoDomElement: Element, tree: System_Array, elementNode: RenderTreeNodePointer, elementNodeIndex: number) {
|
||||
const tagName = renderTreeNode.elementName(elementNode);
|
||||
const newDomElement = document.createElement(tagName);
|
||||
intoDomElement.appendChild(newDomElement);
|
||||
|
||||
// Apply attributes
|
||||
const descendantsEndIndex = uiTreeNode.descendantsEndIndex(elementNode);
|
||||
const descendantsEndIndex = renderTreeNode.descendantsEndIndex(elementNode);
|
||||
for (let descendantIndex = elementNodeIndex + 1; descendantIndex <= descendantsEndIndex; descendantIndex++) {
|
||||
const descendantNode = getTreeNodePtr(tree, descendantIndex);
|
||||
if (uiTreeNode.nodeType(descendantNode) === NodeType.attribute) {
|
||||
if (renderTreeNode.nodeType(descendantNode) === NodeType.attribute) {
|
||||
applyAttribute(componentId, newDomElement, descendantNode, descendantIndex);
|
||||
} else {
|
||||
// As soon as we see a non-attribute child, all the subsequent child nodes are
|
||||
|
|
@ -114,8 +114,8 @@ function insertElement(componentId: string, intoDomElement: Element, tree: Syste
|
|||
}
|
||||
}
|
||||
|
||||
function applyAttribute(componentId: string, toDomElement: Element, attributeNode: UITreeNodePointer, attributeNodeIndex: number) {
|
||||
const attributeName = uiTreeNode.attributeName(attributeNode);
|
||||
function applyAttribute(componentId: string, toDomElement: Element, attributeNode: RenderTreeNodePointer, attributeNodeIndex: number) {
|
||||
const attributeName = renderTreeNode.attributeName(attributeNode);
|
||||
|
||||
switch (attributeName) {
|
||||
case 'onclick':
|
||||
|
|
@ -134,31 +134,31 @@ function applyAttribute(componentId: string, toDomElement: Element, attributeNod
|
|||
// Treat as a regular string-valued attribute
|
||||
toDomElement.setAttribute(
|
||||
attributeName,
|
||||
uiTreeNode.attributeValue(attributeNode)
|
||||
renderTreeNode.attributeValue(attributeNode)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function raiseEvent(componentId: string, uiTreeNodeIndex: number, eventInfoType: EventInfoType, eventInfo: any) {
|
||||
function raiseEvent(componentId: string, renderTreeNodeIndex: number, eventInfoType: EventInfoType, eventInfo: any) {
|
||||
if (!raiseEventMethod) {
|
||||
raiseEventMethod = platform.findMethod(
|
||||
'Microsoft.Blazor.Browser', 'Microsoft.Blazor.Browser', 'Events', 'RaiseEvent'
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: Find a way of passing the uiTreeNodeIndex as a System.Int32, possibly boxing
|
||||
// TODO: Find a way of passing the renderTreeNodeIndex as a System.Int32, possibly boxing
|
||||
// it first if necessary. Until then we have to send it as a string.
|
||||
platform.callMethod(raiseEventMethod, null, [
|
||||
platform.toDotNetString(componentId),
|
||||
platform.toDotNetString(uiTreeNodeIndex.toString()),
|
||||
platform.toDotNetString(renderTreeNodeIndex.toString()),
|
||||
platform.toDotNetString(eventInfoType),
|
||||
platform.toDotNetString(JSON.stringify(eventInfo))
|
||||
]);
|
||||
}
|
||||
|
||||
function insertText(intoDomElement: Element, textNode: UITreeNodePointer) {
|
||||
const textContent = uiTreeNode.textContent(textNode);
|
||||
function insertText(intoDomElement: Element, textNode: RenderTreeNodePointer) {
|
||||
const textContent = renderTreeNode.textContent(textNode);
|
||||
const newDomTextNode = document.createTextNode(textContent);
|
||||
intoDomElement.appendChild(newDomTextNode);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
using Microsoft.Blazor.Browser.Interop;
|
||||
using Microsoft.Blazor.Components;
|
||||
using Microsoft.Blazor.UITree;
|
||||
using Microsoft.Blazor.RenderTree;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.Blazor.Browser
|
|||
= new WeakValueDictionary<string, DOMComponentRenderState>();
|
||||
private static long _nextDOMComponentId = 0;
|
||||
|
||||
private readonly UITreeBuilder _uITreeBuilder; // TODO: Maintain two, so we can diff successive renders
|
||||
private readonly RenderTreeBuilder _uITreeBuilder; // TODO: Maintain two, so we can diff successive renders
|
||||
|
||||
public string DOMComponentId { get; }
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ namespace Microsoft.Blazor.Browser
|
|||
{
|
||||
DOMComponentId = componentId;
|
||||
Component = component;
|
||||
_uITreeBuilder = new UITreeBuilder();
|
||||
_uITreeBuilder = new RenderTreeBuilder();
|
||||
}
|
||||
|
||||
public static DOMComponentRenderState GetOrCreate(IComponent component)
|
||||
|
|
@ -64,22 +64,22 @@ namespace Microsoft.Blazor.Browser
|
|||
? result
|
||||
: throw new ArgumentException($"No component was found with ID {id}");
|
||||
|
||||
private ArraySegment<UITreeNode> UpdateRender()
|
||||
private ArraySegment<RenderTreeNode> UpdateRender()
|
||||
{
|
||||
_uITreeBuilder.Clear();
|
||||
Component.BuildUITree(_uITreeBuilder);
|
||||
Component.BuildRenderTree(_uITreeBuilder);
|
||||
|
||||
// TODO: Change this to return a diff between the previous render result and this new one
|
||||
return _uITreeBuilder.GetNodes();
|
||||
}
|
||||
|
||||
public void RaiseEvent(int uiTreeNodeIndex, UIEventInfo eventInfo)
|
||||
public void RaiseEvent(int uiTreeNodeIndex, UIEventArgs eventInfo)
|
||||
{
|
||||
var nodes = _uITreeBuilder.GetNodes();
|
||||
var eventHandler = nodes.Array[nodes.Offset + uiTreeNodeIndex].AttributeEventHandlerValue;
|
||||
if (eventHandler == null)
|
||||
{
|
||||
throw new ArgumentException($"Cannot raise event because the specified {nameof(UITreeNode)} at index {uiTreeNodeIndex} does not have any {nameof(UITreeNode.AttributeEventHandlerValue)}.");
|
||||
throw new ArgumentException($"Cannot raise event because the specified {nameof(RenderTreeNode)} at index {uiTreeNodeIndex} does not have any {nameof(RenderTreeNode.AttributeEventHandlerValue)}.");
|
||||
}
|
||||
|
||||
eventHandler.Invoke(eventInfo);
|
||||
|
|
@ -89,7 +89,7 @@ namespace Microsoft.Blazor.Browser
|
|||
public void RenderToDOM()
|
||||
{
|
||||
var tree = UpdateRender();
|
||||
RegisteredFunction.InvokeUnmarshalled<string, UITreeNode[], int, object>(
|
||||
RegisteredFunction.InvokeUnmarshalled<string, RenderTreeNode[], int, object>(
|
||||
"_blazorRender",
|
||||
DOMComponentId,
|
||||
tree.Array,
|
||||
|
|
@ -116,16 +116,16 @@ namespace Microsoft.Blazor.Browser
|
|||
return new ComponentRenderInfo
|
||||
{
|
||||
ComponentId = componentRenderState.DOMComponentId,
|
||||
UITree = componentNodes.Array,
|
||||
UITreeLength = componentNodes.Count
|
||||
RenderTree = componentNodes.Array,
|
||||
RenderTreeLength = componentNodes.Count
|
||||
};
|
||||
}
|
||||
|
||||
public struct ComponentRenderInfo
|
||||
{
|
||||
public string ComponentId;
|
||||
public UITreeNode[] UITree;
|
||||
public int UITreeLength;
|
||||
public RenderTreeNode[] RenderTree;
|
||||
public int RenderTreeLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Blazor.Browser.Interop;
|
||||
using Microsoft.Blazor.UITree;
|
||||
using Microsoft.Blazor.RenderTree;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.Blazor.Browser
|
||||
|
|
@ -20,14 +20,14 @@ namespace Microsoft.Blazor.Browser
|
|||
renderState.RaiseEvent(int.Parse(uiTreeNodeIndex), eventInfo);
|
||||
}
|
||||
|
||||
private static UIEventInfo ParseEventInfo(string eventInfoType, string eventInfoJson)
|
||||
private static UIEventArgs ParseEventInfo(string eventInfoType, string eventInfoJson)
|
||||
{
|
||||
switch (eventInfoType)
|
||||
{
|
||||
case "mouse":
|
||||
return Json.Deserialize<UIMouseEventInfo>(eventInfoJson);
|
||||
return Json.Deserialize<UIMouseEventArgs>(eventInfoJson);
|
||||
case "keyboard":
|
||||
return Json.Deserialize<UIKeyboardEventInfo>(eventInfoJson);
|
||||
return Json.Deserialize<UIKeyboardEventArgs>(eventInfoJson);
|
||||
default:
|
||||
throw new ArgumentException($"Unsupported value '{eventInfoType}'.", nameof(eventInfoType));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Blazor.UITree;
|
||||
using Microsoft.Blazor.RenderTree;
|
||||
|
||||
namespace Microsoft.Blazor.Components
|
||||
{
|
||||
|
|
@ -11,9 +11,9 @@ namespace Microsoft.Blazor.Components
|
|||
public interface IComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Builds a <see cref="UITree"/> representing the current state of the component.
|
||||
/// Builds a <see cref="RenderTree"/> representing the current state of the component.
|
||||
/// </summary>
|
||||
/// <param name="builder">A <see cref="UITreeBuilder"/> to which the rendered nodes should be appended.</param>
|
||||
void BuildUITree(UITreeBuilder builder);
|
||||
/// <param name="builder">A <see cref="RenderTreeBuilder"/> to which the rendered nodes should be appended.</param>
|
||||
void BuildRenderTree(RenderTreeBuilder builder);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,22 +5,22 @@ using Microsoft.Blazor.Components;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Blazor.UITree
|
||||
namespace Microsoft.Blazor.RenderTree
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides methods for building a collection of <see cref="UITreeNode"/> entries.
|
||||
/// Provides methods for building a collection of <see cref="RenderTreeNode"/> entries.
|
||||
/// </summary>
|
||||
public class UITreeBuilder
|
||||
public class RenderTreeBuilder
|
||||
{
|
||||
private const int MinBufferLength = 10;
|
||||
private UITreeNode[] _entries = new UITreeNode[100];
|
||||
private RenderTreeNode[] _entries = new RenderTreeNode[100];
|
||||
private int _entriesInUse = 0;
|
||||
private Stack<int> _openElementIndices = new Stack<int>();
|
||||
private UITreeNodeType? _lastNonAttributeNodeType;
|
||||
private RenderTreeNodeType? _lastNonAttributeNodeType;
|
||||
|
||||
/// <summary>
|
||||
/// Appends a node representing an element, i.e., a container for other nodes.
|
||||
/// In order for the <see cref="UITreeBuilder"/> state to be valid, you must
|
||||
/// In order for the <see cref="RenderTreeBuilder"/> state to be valid, you must
|
||||
/// also call <see cref="CloseElement"/> immediately after appending the
|
||||
/// new element's child nodes.
|
||||
/// </summary>
|
||||
|
|
@ -28,7 +28,7 @@ namespace Microsoft.Blazor.UITree
|
|||
public void OpenElement(string elementName)
|
||||
{
|
||||
_openElementIndices.Push(_entriesInUse);
|
||||
Append(UITreeNode.Element(elementName));
|
||||
Append(RenderTreeNode.Element(elementName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -46,7 +46,7 @@ namespace Microsoft.Blazor.UITree
|
|||
/// </summary>
|
||||
/// <param name="textContent">Content for the new text node.</param>
|
||||
public void AddText(string textContent)
|
||||
=> Append(UITreeNode.Text(textContent));
|
||||
=> Append(RenderTreeNode.Text(textContent));
|
||||
|
||||
/// <summary>
|
||||
/// Appends a node representing a string-valued attribute.
|
||||
|
|
@ -57,11 +57,11 @@ namespace Microsoft.Blazor.UITree
|
|||
public void AddAttribute(string name, string value)
|
||||
{
|
||||
AssertCanAddAttribute();
|
||||
Append(UITreeNode.Attribute(name, value));
|
||||
Append(RenderTreeNode.Attribute(name, value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends a node representing an <see cref="UIEventHandler"/>-valued attribute.
|
||||
/// Appends a node representing an <see cref="UIEventArgs"/>-valued attribute.
|
||||
/// The attribute is associated with the most recently added element.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the attribute.</param>
|
||||
|
|
@ -69,7 +69,7 @@ namespace Microsoft.Blazor.UITree
|
|||
public void AddAttribute(string name, UIEventHandler value)
|
||||
{
|
||||
AssertCanAddAttribute();
|
||||
Append(UITreeNode.Attribute(name, value));
|
||||
Append(RenderTreeNode.Attribute(name, value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -84,15 +84,15 @@ namespace Microsoft.Blazor.UITree
|
|||
// previous tree, we'll either instantiate a new component or reuse the
|
||||
// existing instance (and notify it about changes to parameters).
|
||||
var instance = Activator.CreateInstance<TComponent>();
|
||||
Append(UITreeNode.ChildComponent(instance));
|
||||
Append(RenderTreeNode.ChildComponent(instance));
|
||||
}
|
||||
|
||||
private void AssertCanAddAttribute()
|
||||
{
|
||||
if (_lastNonAttributeNodeType != UITreeNodeType.Element
|
||||
&& _lastNonAttributeNodeType != UITreeNodeType.Component)
|
||||
if (_lastNonAttributeNodeType != RenderTreeNodeType.Element
|
||||
&& _lastNonAttributeNodeType != RenderTreeNodeType.Component)
|
||||
{
|
||||
throw new InvalidOperationException($"Attributes may only be added immediately after nodes of type {UITreeNodeType.Element} or {UITreeNodeType.Component}");
|
||||
throw new InvalidOperationException($"Attributes may only be added immediately after nodes of type {RenderTreeNodeType.Element} or {RenderTreeNodeType.Component}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -115,14 +115,14 @@ namespace Microsoft.Blazor.UITree
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="UITreeNode"/> values that have been appended.
|
||||
/// Returns the <see cref="RenderTreeNode"/> values that have been appended.
|
||||
/// The return value's <see cref="ArraySegment{T}.Offset"/> is always zero.
|
||||
/// </summary>
|
||||
/// <returns>An array segment of <see cref="UITreeNode"/> values.</returns>
|
||||
public ArraySegment<UITreeNode> GetNodes() =>
|
||||
new ArraySegment<UITreeNode>(_entries, 0, _entriesInUse);
|
||||
/// <returns>An array segment of <see cref="RenderTreeNode"/> values.</returns>
|
||||
public ArraySegment<RenderTreeNode> GetNodes() =>
|
||||
new ArraySegment<RenderTreeNode>(_entries, 0, _entriesInUse);
|
||||
|
||||
private void Append(UITreeNode node)
|
||||
private void Append(RenderTreeNode node)
|
||||
{
|
||||
if (_entriesInUse == _entries.Length)
|
||||
{
|
||||
|
|
@ -132,7 +132,7 @@ namespace Microsoft.Blazor.UITree
|
|||
_entries[_entriesInUse++] = node;
|
||||
|
||||
var nodeType = node.NodeType;
|
||||
if (nodeType != UITreeNodeType.Attribute)
|
||||
if (nodeType != RenderTreeNodeType.Attribute)
|
||||
{
|
||||
_lastNonAttributeNodeType = node.NodeType;
|
||||
}
|
||||
|
|
@ -2,9 +2,8 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Blazor.Components;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.Blazor.UITree
|
||||
namespace Microsoft.Blazor.RenderTree
|
||||
{
|
||||
// TODO: Consider coalescing properties of compatible types that don't need to be
|
||||
// used simultaneously. For example, 'ElementName' and 'AttributeName' could be replaced
|
||||
|
|
@ -13,85 +12,85 @@ namespace Microsoft.Blazor.UITree
|
|||
/// <summary>
|
||||
/// Represents an entry in a tree of user interface (UI) items.
|
||||
/// </summary>
|
||||
public struct UITreeNode
|
||||
public struct RenderTreeNode
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the type of this node.
|
||||
/// </summary>
|
||||
public UITreeNodeType NodeType { get; private set; }
|
||||
public RenderTreeNodeType NodeType { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="NodeType"/> property equals <see cref="UITreeNodeType.Element"/>,
|
||||
/// If the <see cref="NodeType"/> property equals <see cref="RenderTreeNodeType.Element"/>,
|
||||
/// gets a name representing the type of the element. Otherwise, the value is <see langword="null"/>.
|
||||
/// </summary>
|
||||
public string ElementName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="NodeType"/> property equals <see cref="UITreeNodeType.Element"/>,
|
||||
/// If the <see cref="NodeType"/> property equals <see cref="RenderTreeNodeType.Element"/>,
|
||||
/// gets the index of the final descendant node in the tree. The value is
|
||||
/// zero if the node is of a different type, or if it has not yet been closed.
|
||||
/// </summary>
|
||||
public int ElementDescendantsEndIndex { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="NodeType"/> property equals <see cref="UITreeNodeType.Text"/>,
|
||||
/// If the <see cref="NodeType"/> property equals <see cref="RenderTreeNodeType.Text"/>,
|
||||
/// gets the content of the text node. Otherwise, the value is <see langword="null"/>.
|
||||
/// </summary>
|
||||
public string TextContent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="NodeType"/> property equals <see cref="UITreeNodeType.Attribute"/>,
|
||||
/// If the <see cref="NodeType"/> property equals <see cref="RenderTreeNodeType.Attribute"/>,
|
||||
/// gets the attribute name. Otherwise, the value is <see langword="null"/>.
|
||||
/// </summary>
|
||||
public string AttributeName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="NodeType"/> property equals <see cref="UITreeNodeType.Attribute"/>,
|
||||
/// If the <see cref="NodeType"/> property equals <see cref="RenderTreeNodeType.Attribute"/>,
|
||||
/// gets the attribute value. Otherwise, the value is <see langword="null"/>.
|
||||
/// </summary>
|
||||
public string AttributeValue { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="NodeType"/> property equals <see cref="UITreeNodeType.Attribute"/>,
|
||||
/// If the <see cref="NodeType"/> property equals <see cref="RenderTreeNodeType.Attribute"/>,
|
||||
/// gets the attribute's event handle, if any. Otherwise, the value is <see langword="null"/>.
|
||||
/// </summary>
|
||||
public UIEventHandler AttributeEventHandlerValue { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the <see cref="NodeType"/> property equals <see cref="UITreeNodeType.Component"/>,
|
||||
/// If the <see cref="NodeType"/> property equals <see cref="RenderTreeNodeType.Component"/>,
|
||||
/// gets the child component instance. Otherwise, the value is <see langword="null"/>.
|
||||
/// </summary>
|
||||
public IComponent Component { get; private set; }
|
||||
|
||||
internal static UITreeNode Element(string elementName) => new UITreeNode
|
||||
internal static RenderTreeNode Element(string elementName) => new RenderTreeNode
|
||||
{
|
||||
NodeType = UITreeNodeType.Element,
|
||||
NodeType = RenderTreeNodeType.Element,
|
||||
ElementName = elementName,
|
||||
};
|
||||
|
||||
internal static UITreeNode Text(string textContent) => new UITreeNode
|
||||
internal static RenderTreeNode Text(string textContent) => new RenderTreeNode
|
||||
{
|
||||
NodeType = UITreeNodeType.Text,
|
||||
NodeType = RenderTreeNodeType.Text,
|
||||
TextContent = textContent,
|
||||
};
|
||||
|
||||
internal static UITreeNode Attribute(string name, string value) => new UITreeNode
|
||||
internal static RenderTreeNode Attribute(string name, string value) => new RenderTreeNode
|
||||
{
|
||||
NodeType = UITreeNodeType.Attribute,
|
||||
NodeType = RenderTreeNodeType.Attribute,
|
||||
AttributeName = name,
|
||||
AttributeValue = value
|
||||
};
|
||||
|
||||
internal static UITreeNode Attribute(string name, UIEventHandler value) => new UITreeNode
|
||||
internal static RenderTreeNode Attribute(string name, UIEventHandler value) => new RenderTreeNode
|
||||
{
|
||||
NodeType = UITreeNodeType.Attribute,
|
||||
NodeType = RenderTreeNodeType.Attribute,
|
||||
AttributeName = name,
|
||||
AttributeEventHandlerValue = value
|
||||
};
|
||||
|
||||
internal static UITreeNode ChildComponent(IComponent component) => new UITreeNode
|
||||
internal static RenderTreeNode ChildComponent(IComponent component) => new RenderTreeNode
|
||||
{
|
||||
NodeType = UITreeNodeType.Component,
|
||||
NodeType = RenderTreeNodeType.Component,
|
||||
Component = component
|
||||
};
|
||||
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.Blazor.UITree
|
||||
namespace Microsoft.Blazor.RenderTree
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the type of a <see cref="UITreeNode"/>.
|
||||
/// Describes the type of a <see cref="RenderTreeNode"/>.
|
||||
/// </summary>
|
||||
public enum UITreeNodeType: int
|
||||
public enum RenderTreeNodeType: int
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a container for other nodes.
|
||||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.Blazor.UITree
|
|||
Text = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Represents a key-value pair associated with another <see cref="UITreeNode"/>.
|
||||
/// Represents a key-value pair associated with another <see cref="RenderTreeNode"/>.
|
||||
/// </summary>
|
||||
Attribute = 3,
|
||||
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.Blazor.UITree
|
||||
namespace Microsoft.Blazor.RenderTree
|
||||
{
|
||||
/// <summary>
|
||||
/// Supplies information about an event that is being raised.
|
||||
/// </summary>
|
||||
public class UIEventInfo
|
||||
public class UIEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the event.
|
||||
|
|
@ -17,14 +17,14 @@ namespace Microsoft.Blazor.UITree
|
|||
/// <summary>
|
||||
/// Supplies information about a mouse event that is being raised.
|
||||
/// </summary>
|
||||
public class UIMouseEventInfo : UIEventInfo
|
||||
public class UIMouseEventArgs : UIEventArgs
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Supplies information about a keyboard event that is being raised.
|
||||
/// </summary>
|
||||
public class UIKeyboardEventInfo : UIEventInfo
|
||||
public class UIKeyboardEventArgs : UIEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// If applicable, gets or sets the key that produced the event.
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.Blazor.UITree
|
||||
namespace Microsoft.Blazor.RenderTree
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles an event raised for a <see cref="UITreeNode"/>.
|
||||
/// Handles an event raised for a <see cref="RenderTreeNode"/>.
|
||||
/// </summary>
|
||||
public delegate void UIEventHandler(UIEventInfo eventInfo);
|
||||
public delegate void UIEventHandler(UIEventArgs eventInfo);
|
||||
}
|
||||
|
|
@ -2,20 +2,20 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Blazor.Components;
|
||||
using Microsoft.Blazor.UITree;
|
||||
using Microsoft.Blazor.RenderTree;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Blazor.Test
|
||||
{
|
||||
public class UITreeBuilderTest
|
||||
public class RenderTreeBuilderTest
|
||||
{
|
||||
[Fact]
|
||||
public void StartsEmpty()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new UITreeBuilder();
|
||||
var builder = new RenderTreeBuilder();
|
||||
|
||||
// Assert
|
||||
var nodes = builder.GetNodes();
|
||||
|
|
@ -28,7 +28,7 @@ namespace Microsoft.Blazor.Test
|
|||
public void CanAddText()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new UITreeBuilder();
|
||||
var builder = new RenderTreeBuilder();
|
||||
|
||||
// Act
|
||||
builder.AddText("First item");
|
||||
|
|
@ -46,7 +46,7 @@ namespace Microsoft.Blazor.Test
|
|||
public void UnclosedElementsHaveNoEndDescendantIndex()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new UITreeBuilder();
|
||||
var builder = new RenderTreeBuilder();
|
||||
|
||||
// Act
|
||||
builder.OpenElement("my element");
|
||||
|
|
@ -60,7 +60,7 @@ namespace Microsoft.Blazor.Test
|
|||
public void ClosedEmptyElementsHaveSelfAsEndDescendantIndex()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new UITreeBuilder();
|
||||
var builder = new RenderTreeBuilder();
|
||||
|
||||
// Act
|
||||
builder.AddText("some node so that the element isn't at position zero");
|
||||
|
|
@ -77,7 +77,7 @@ namespace Microsoft.Blazor.Test
|
|||
public void ClosedElementsHaveCorrectEndDescendantIndex()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new UITreeBuilder();
|
||||
var builder = new RenderTreeBuilder();
|
||||
|
||||
// Act
|
||||
builder.OpenElement("my element");
|
||||
|
|
@ -96,7 +96,7 @@ namespace Microsoft.Blazor.Test
|
|||
public void CanNestElements()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new UITreeBuilder();
|
||||
var builder = new RenderTreeBuilder();
|
||||
|
||||
// Act
|
||||
builder.AddText("standalone text 1"); // 0: standalone text 1
|
||||
|
|
@ -136,7 +136,7 @@ namespace Microsoft.Blazor.Test
|
|||
public void CanAddAttributes()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new UITreeBuilder();
|
||||
var builder = new RenderTreeBuilder();
|
||||
UIEventHandler eventHandler = eventInfo => { };
|
||||
|
||||
// Act
|
||||
|
|
@ -163,7 +163,7 @@ namespace Microsoft.Blazor.Test
|
|||
public void CannotAddAttributeAtRoot()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new UITreeBuilder();
|
||||
var builder = new RenderTreeBuilder();
|
||||
|
||||
// Act/Assert
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
|
|
@ -176,7 +176,7 @@ namespace Microsoft.Blazor.Test
|
|||
public void CannotAddEventHandlerAttributeAtRoot()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new UITreeBuilder();
|
||||
var builder = new RenderTreeBuilder();
|
||||
|
||||
// Act/Assert
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
|
|
@ -189,7 +189,7 @@ namespace Microsoft.Blazor.Test
|
|||
public void CannotAddAttributeToText()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new UITreeBuilder();
|
||||
var builder = new RenderTreeBuilder();
|
||||
|
||||
// Act/Assert
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
|
|
@ -204,7 +204,7 @@ namespace Microsoft.Blazor.Test
|
|||
public void CannotAddEventHandlerAttributeToText()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new UITreeBuilder();
|
||||
var builder = new RenderTreeBuilder();
|
||||
|
||||
// Act/Assert
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
|
|
@ -219,7 +219,7 @@ namespace Microsoft.Blazor.Test
|
|||
public void CanAddChildComponents()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new UITreeBuilder();
|
||||
var builder = new RenderTreeBuilder();
|
||||
|
||||
// Act
|
||||
builder.OpenElement("parent"); // 0: <parent>
|
||||
|
|
@ -244,7 +244,7 @@ namespace Microsoft.Blazor.Test
|
|||
public void CanClear()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new UITreeBuilder();
|
||||
var builder = new RenderTreeBuilder();
|
||||
|
||||
// Act
|
||||
builder.AddText("some text");
|
||||
|
|
@ -257,41 +257,41 @@ namespace Microsoft.Blazor.Test
|
|||
Assert.Empty(builder.GetNodes());
|
||||
}
|
||||
|
||||
void AssertText(UITreeNode node, string textContent)
|
||||
void AssertText(RenderTreeNode node, string textContent)
|
||||
{
|
||||
Assert.Equal(UITreeNodeType.Text, node.NodeType);
|
||||
Assert.Equal(RenderTreeNodeType.Text, node.NodeType);
|
||||
Assert.Equal(textContent, node.TextContent);
|
||||
Assert.Equal(0, node.ElementDescendantsEndIndex);
|
||||
}
|
||||
|
||||
void AssertElement(UITreeNode node, string elementName, int descendantsEndIndex)
|
||||
void AssertElement(RenderTreeNode node, string elementName, int descendantsEndIndex)
|
||||
{
|
||||
Assert.Equal(UITreeNodeType.Element, node.NodeType);
|
||||
Assert.Equal(RenderTreeNodeType.Element, node.NodeType);
|
||||
Assert.Equal(elementName, node.ElementName);
|
||||
Assert.Equal(descendantsEndIndex, node.ElementDescendantsEndIndex);
|
||||
}
|
||||
|
||||
void AssertAttribute(UITreeNode node, string attributeName)
|
||||
void AssertAttribute(RenderTreeNode node, string attributeName)
|
||||
{
|
||||
Assert.Equal(UITreeNodeType.Attribute, node.NodeType);
|
||||
Assert.Equal(RenderTreeNodeType.Attribute, node.NodeType);
|
||||
Assert.Equal(attributeName, node.AttributeName);
|
||||
}
|
||||
|
||||
void AssertAttribute(UITreeNode node, string attributeName, string attributeValue)
|
||||
void AssertAttribute(RenderTreeNode node, string attributeName, string attributeValue)
|
||||
{
|
||||
AssertAttribute(node, attributeName);
|
||||
Assert.Equal(attributeValue, node.AttributeValue);
|
||||
}
|
||||
|
||||
void AssertAttribute(UITreeNode node, string attributeName, UIEventHandler attributeEventHandlerValue)
|
||||
void AssertAttribute(RenderTreeNode node, string attributeName, UIEventHandler attributeEventHandlerValue)
|
||||
{
|
||||
AssertAttribute(node, attributeName);
|
||||
Assert.Equal(attributeEventHandlerValue, node.AttributeEventHandlerValue);
|
||||
}
|
||||
|
||||
private void AssertComponent<T>(UITreeNode node) where T: IComponent
|
||||
private void AssertComponent<T>(RenderTreeNode node) where T: IComponent
|
||||
{
|
||||
Assert.Equal(UITreeNodeType.Component, node.NodeType);
|
||||
Assert.Equal(RenderTreeNodeType.Component, node.NodeType);
|
||||
|
||||
// Currently, we instantiate child components during the tree building phase.
|
||||
// Later this will change so it happens during the tree diffing phase, so this
|
||||
|
|
@ -303,7 +303,7 @@ namespace Microsoft.Blazor.Test
|
|||
|
||||
private class TestComponent : IComponent
|
||||
{
|
||||
public void BuildUITree(UITreeBuilder builder)
|
||||
public void BuildRenderTree(RenderTreeBuilder builder)
|
||||
=> throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ActiveDebugProfile>BasicTestApp</ActiveDebugProfile>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Blazor.Components;
|
||||
using Microsoft.Blazor.UITree;
|
||||
using Microsoft.Blazor.RenderTree;
|
||||
|
||||
namespace BasicTestApp
|
||||
{
|
||||
|
|
@ -10,7 +10,7 @@ namespace BasicTestApp
|
|||
{
|
||||
private int currentCount = 0;
|
||||
|
||||
public void BuildUITree(UITreeBuilder builder)
|
||||
public void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
builder.OpenElement("h1");
|
||||
builder.AddText("Counter");
|
||||
|
|
@ -27,7 +27,7 @@ namespace BasicTestApp
|
|||
builder.CloseElement();
|
||||
}
|
||||
|
||||
private void OnButtonClicked(UIEventInfo eventInfo)
|
||||
private void OnButtonClicked(UIEventArgs eventInfo)
|
||||
{
|
||||
currentCount++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Blazor.Components;
|
||||
using Microsoft.Blazor.UITree;
|
||||
using Microsoft.Blazor.RenderTree;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BasicTestApp
|
||||
|
|
@ -11,7 +11,7 @@ namespace BasicTestApp
|
|||
{
|
||||
private List<string> keysPressed = new List<string>();
|
||||
|
||||
public void BuildUITree(UITreeBuilder builder)
|
||||
public void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
builder.AddText("Type here:");
|
||||
builder.OpenElement("input");
|
||||
|
|
@ -28,9 +28,9 @@ namespace BasicTestApp
|
|||
builder.CloseElement();
|
||||
}
|
||||
|
||||
private void OnKeyPressed(UIEventInfo eventInfo)
|
||||
private void OnKeyPressed(UIEventArgs eventInfo)
|
||||
{
|
||||
keysPressed.Add(((UIKeyboardEventInfo)eventInfo).Key);
|
||||
keysPressed.Add(((UIKeyboardEventArgs)eventInfo).Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Blazor.Components;
|
||||
using Microsoft.Blazor.UITree;
|
||||
using Microsoft.Blazor.RenderTree;
|
||||
|
||||
namespace BasicTestApp
|
||||
{
|
||||
public class ParentChildComponent : IComponent
|
||||
{
|
||||
public void BuildUITree(UITreeBuilder builder)
|
||||
public void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
builder.OpenElement("fieldset");
|
||||
builder.OpenElement("legend");
|
||||
|
|
@ -20,7 +20,7 @@ namespace BasicTestApp
|
|||
|
||||
private class ChildComponent : IComponent
|
||||
{
|
||||
public void BuildUITree(UITreeBuilder builder)
|
||||
public void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
builder.AddText("Child component");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Blazor.Components;
|
||||
using Microsoft.Blazor.UITree;
|
||||
using Microsoft.Blazor.RenderTree;
|
||||
|
||||
namespace BasicTestApp
|
||||
{
|
||||
public class RedTextComponent : IComponent
|
||||
{
|
||||
public void BuildUITree(UITreeBuilder builder)
|
||||
public void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
builder.OpenElement("h1");
|
||||
builder.AddAttribute("style", "color: red;");
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Blazor.Components;
|
||||
using Microsoft.Blazor.UITree;
|
||||
using Microsoft.Blazor.RenderTree;
|
||||
|
||||
namespace BasicTestApp
|
||||
{
|
||||
public class TextOnlyComponent : IComponent
|
||||
{
|
||||
public void BuildUITree(UITreeBuilder builder)
|
||||
public void BuildRenderTree(RenderTreeBuilder builder)
|
||||
{
|
||||
builder.AddText($"Hello from {nameof(TextOnlyComponent)}");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue