private void VisitRender(HxlRenderWorkElement element) { string parent = stack.Peek(); string slug = GenerateSlug(element); string renderName = NewVariable("_Render" + slug, false, true); string varName = SafeNewVariable(renderName); CurrentOutput.WriteLine("{0} = global::{2}.Create({1});", varName, renderName.TrimStart('_'), typeof(HxlElement).FullName); stack.Push(varName); PushRenderIsland(renderName.TrimStart('_')); element.WritePreLines(CurrentOutput); if (element.ChildNodes.Count > 0) { CurrentOutput.WriteLine(" __self.RenderBody();"); } element.WritePostLines(CurrentOutput); PopRenderIsland(); CurrentOutput.WriteLine("{0}.Append({1});", parent, varName); VisitAll(element.ChildNodes); stack.Pop(); }
static void InlineElement(DomElement e) { StringWriter fore = new StringWriter(); StringWriter aft = new StringWriter(); HxlElementTemplate.RenderElementStart(e, fore); HxlElementTemplate.RenderElementEnd(e, aft); HxlRenderWorkElement frag = (HxlRenderWorkElement)e.ChildNodes[0]; List <string> pre = new List <string>(); List <string> post = new List <string>(); pre.Add(CodeUtility.AppendDomText(fore.ToString())); pre.AddRange(frag.PreLines); post.AddRange(frag.PostLines); post.Add(CodeUtility.AppendDomText(aft.ToString())); var consolidated = new HxlRenderWorkElement(pre, post); frag.RemoveSelf(); foreach (var m in frag.ChildNodes.ToArray()) { consolidated.Append(m); } e.ReplaceWith(consolidated); }
private static void TryConsolidateRenderNodes(HxlRenderWorkElement render) { HxlRenderWorkElement sentinel; if (!IsConsolidatable(render.ChildNodes, out sentinel)) { return; } var consolidated = GetConsolidation(render.ChildNodes, render.PreLines, render.PostLines, sentinel); render.ReplaceWith(consolidated); }
private string GenerateSlug(HxlRenderWorkElement pre) { var line = pre.PreLines.FirstOrDefault(t => !string.IsNullOrEmpty(t)) ?? string.Empty; string result = CodeUtility.Slug("work_" + line.Replace("__self.Write", string.Empty)); if (_slugCache.Add(result)) { return(result); } result += Utility.RandomID(); _slugCache.Add(result); return(result); }
internal override void RewriteIslandChildren(HxlRenderWorkElement result) { int index = 0; int count = result.Elements.Count; foreach (var m in result.Elements) { if (index++ < count - 1) { var child = (HxlRenderWorkElement)m; child.PostLines[child.PostLines.Length - 1] += " else "; } } base.RewriteIslandChildren(result); }
internal static bool IsConsolidatable(DomNodeCollection childNodes, out HxlRenderWorkElement singleton) { singleton = null; if (childNodes.Count == 0) { return(false); } foreach (var node in childNodes) { if (node.NodeType == DomNodeType.Text) { continue; } if (node is HxlTextElement) { continue; } HxlRenderWorkElement render = node as HxlRenderWorkElement; if (render != null) { if (render.ChildNodes.Count == 0) { continue; } if (singleton == null) { singleton = render; continue; } return(false); } return(false); } return(true); }
internal virtual void RewriteIslandChildren(HxlRenderWorkElement result) { }
internal static HxlRenderWorkElement GetConsolidation(IEnumerable <DomNode> nodes, IList <string> front, IList <string> back, HxlRenderWorkElement sentinel) { front = front ?? Empty <string> .List; back = back ?? Empty <string> .List; // <render> // <text /> <text /> <render /> <text/> // </render> // ==> // inline text with Write instructions and push up // nested render nodes List <string> pre = new List <string>(front); List <string> post = new List <string>(); List <string> current = pre; foreach (var m in nodes) { if (m.NodeType == DomNodeType.Text) { string sb = CodeUtility.AppendDomText(m.TextContent); current.Add(sb); } else { var hxlTextElement = m as HxlTextElement; if (hxlTextElement != null) { string sb = CodeUtility.AppendDomText(hxlTextElement.Data); current.Add(sb); } else if (m.NodeType == DomNodeType.Element) { HxlRenderWorkElement mr = (HxlRenderWorkElement)m; current.AddRange(mr.PreLines); // If the element has children, then there can be only // one if (m.ChildNodes.Count > 0) { current = post; } current.AddRange(mr.PostLines); } } } post.AddRange(back); var result = new HxlRenderWorkElement(pre, post); if (sentinel != null) { sentinel.RemoveSelf(); foreach (var m in sentinel.ChildNodes.ToArray()) { result.Append(m); } } return(result); }