Editor/Projection/RecordNode.cs
using System;
using System.Collections.Generic;
using Grains.RazorDesigner.Document;
namespace Grains.RazorDesigner.Projection;
public sealed class RecordNode : IReadOnlyNode
{
private readonly ControlRecord _record;
private List<IReadOnlyNode> _children;
private Dictionary<string, IReadOnlyList<IReadOnlyNode>> _slots;
private List<IReadOnlyStateRule> _stateRules;
public RecordNode( ControlRecord record )
{
_record = record ?? throw new ArgumentNullException( nameof( record ) );
}
// Exposed for M2.3 Applier to write LivePanel back without breaking the interface boundary.
internal ControlRecord Backing => _record;
// --- IReadOnlyNode ---
public Guid Id => _record.Id;
public string Kind => _record.Type.ToString();
public string ClassName => _record.ClassName;
public IAppearance Appearance => _record.Appearance;
public IPayload Payload => _record.Payload;
public IReadOnlyList<IReadOnlyNode> Children
{
get
{
if ( _children != null ) return _children;
_children = new List<IReadOnlyNode>();
foreach ( var child in _record.Children )
{
if ( !child.IsSlot )
_children.Add( new RecordNode( child ) );
}
return _children;
}
}
public IReadOnlyDictionary<string, IReadOnlyList<IReadOnlyNode>> Slots
{
get
{
if ( _slots != null ) return _slots;
_slots = new Dictionary<string, IReadOnlyList<IReadOnlyNode>>();
foreach ( var child in _record.Children )
{
if ( child.IsSlot && !string.IsNullOrEmpty( child.SlotName ) )
{
if ( !_slots.TryGetValue( child.SlotName, out var slotList ) )
{
slotList = new List<IReadOnlyNode>();
_slots[child.SlotName] = slotList;
}
foreach ( var slotChild in child.Children )
((List<IReadOnlyNode>)slotList).Add( new RecordNode( slotChild ) );
}
}
return _slots;
}
}
public IReadOnlyList<IReadOnlyStateRule> StateRules
{
get
{
if ( _stateRules != null ) return _stateRules;
_stateRules = _record.StateRules.ConvertAll( r => (IReadOnlyStateRule) new StateRuleView( r ) );
return _stateRules;
}
}
private sealed class StateRuleView : IReadOnlyStateRule
{
private readonly Document.StateRule _r;
public StateRuleView( Document.StateRule r ) { _r = r; }
public Document.PseudoKind State => _r.State;
public Document.NthChildMode NthChildMode => _r.NthChildMode;
public int NthChildArg => _r.NthChildArg;
public IAppearance Delta => _r.Delta; // Appearance : IAppearance — no wrapper needed
}
}