ln.templates/ln.templates/html/TemplateElement.cs

141 lines
5.3 KiB
C#

// /**
// * File: TemplateElement.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.Collections;
using System.Collections.Generic;
using ln.templates.script;
namespace ln.templates.html
{
public class TemplateElement : Element
{
Dictionary<string, NewExpression> expressions = new Dictionary<string, NewExpression>();
Dictionary<string, NewExpression> loops = new Dictionary<string, NewExpression>();
List<NewExpression> conditions = new List<NewExpression>();
NewExpression includeExpression;
bool hideTag;
public TemplateElement(string tagName)
:base(tagName)
{
hideTag = "template".Equals(tagName.ToLower());
}
public override void SetAttribute(string attributeName, string attributeValue)
{
if (attributeName.StartsWith("v-for:", StringComparison.InvariantCultureIgnoreCase))
loops.Add(attributeName.Substring(6), new NewExpression(attributeValue));
else if (attributeName.Equals("v-if", StringComparison.InvariantCultureIgnoreCase))
conditions.Add(new NewExpression(attributeValue));
else if (attributeName.Equals("v-include", StringComparison.InvariantCultureIgnoreCase))
includeExpression = new NewExpression(attributeValue);
else if (attributeName[0] == ':')
expressions.Add(attributeName.Substring(1), new NewExpression(attributeValue));
else
base.SetAttribute(attributeName, attributeValue);
}
public virtual void RenderTemplate(RenderContext renderContext)
{
if (loops.Count == 0)
{
RenderElement(renderContext);
} else
{
Stack<KeyValuePair<string, NewExpression>> loopStack = new Stack<KeyValuePair<string, NewExpression>>(loops);
DoLoop(renderContext, loopStack);
}
}
void DoLoop(RenderContext renderContext, Stack<KeyValuePair<string, NewExpression>> loopStack)
{
if (loopStack.Count == 0)
{
RenderElement(renderContext);
} else
{
KeyValuePair<string, NewExpression> loop = loopStack.Pop();
IEnumerable enumerable = (IEnumerable)loop.Value.Resolve(renderContext);
foreach (object o in enumerable)
{
renderContext.SetScriptObject(loop.Key, o);
DoLoop(renderContext, loopStack);
}
loopStack.Push(loop);
}
}
void RenderElement(RenderContext renderContext)
{
if (checkConditions(renderContext))
{
if (includeExpression != null)
{
object includeValue = includeExpression.Resolve(renderContext);
if (!(includeValue is TemplateDocument includeTemplate))
{
includeTemplate = renderContext.TemplateSource.GetTemplateByPath((string)includeValue);
}
includeTemplate.RenderTemplate(renderContext, true);
}
else
{
if (!hideTag)
{
renderContext.ContentWriter.Write("<{0}", Name);
foreach (KeyValuePair<String, String> attributePair in Attributes)
renderContext.ContentWriter.Write(" {0}=\"{1}\"", attributePair.Key, attributePair.Value);
foreach (KeyValuePair<string,NewExpression> keyValuePair in expressions)
{
object value = keyValuePair.Value.Resolve(renderContext);
if (value != null)
{
renderContext.ContentWriter.Write(" {0}=\"{1}\"", keyValuePair.Key, value);
}
}
renderContext.ContentWriter.Write(">");
}
if (!IsVoid)
{
foreach (Element element in Children)
{
if (element is TemplateElement templateElement)
{
templateElement.RenderTemplate(renderContext);
}
else
{
renderContext.ContentWriter.Write(element.ToString());
}
}
if (!hideTag)
renderContext.ContentWriter.Write("</{0}>", Name);
}
}
}
}
bool checkConditions(RenderContext renderContext)
{
foreach (NewExpression condition in conditions)
if (!condition.IsTrue(renderContext))
return false;
return true;
}
}
}