Generate initial static html

This commit is contained in:
Frank A. Krueger 2018-02-01 20:18:16 -08:00
parent 0c03a0bf49
commit 4148ea17be
12 changed files with 187 additions and 15 deletions

View File

@ -1,28 +1,30 @@
using System; using System;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace Ooui.AspNetCore namespace Ooui.AspNetCore
{ {
public class ElementResult : ActionResult public class ElementResult : ActionResult
{ {
readonly Element element; readonly Element element;
readonly string title; readonly string title;
public ElementResult (Element element, string title = "") public ElementResult (Element element, string title = "")
{ {
this.element = element; this.element = element;
this.title = title; this.title = title;
} }
public override async Task ExecuteResultAsync (ActionContext context) public override async Task ExecuteResultAsync (ActionContext context)
{ {
var response = context.HttpContext.Response; var response = context.HttpContext.Response;
response.StatusCode = 200; response.StatusCode = 200;
response.ContentType = "text/html; charset=utf-8"; response.ContentType = "text/html; charset=utf-8";
var sessionId = WebSocketHandler.BeginSession (context.HttpContext, element); var sessionId = WebSocketHandler.BeginSession (context.HttpContext, element);
var html = UI.RenderTemplate (WebSocketHandler.WebSocketPath + "?id=" + sessionId, title: title); var initialHtml = element.OuterHtml;
Console.WriteLine(initialHtml);
var html = UI.RenderTemplate (WebSocketHandler.WebSocketPath + "?id=" + sessionId, title: title, initialHtml: initialHtml);
var htmlBytes = Encoding.UTF8.GetBytes (html); var htmlBytes = Encoding.UTF8.GetBytes (html);
response.ContentLength = htmlBytes.Length; response.ContentLength = htmlBytes.Length;
using (var s = response.Body) { using (var s = response.Body) {

View File

@ -21,6 +21,8 @@ namespace Ooui.Forms.Renderers
/// </summary> /// </summary>
protected virtual bool ManageNativeControlLifetime => true; protected virtual bool ManageNativeControlLifetime => true;
protected override bool HtmlNeedsFullEndElement => TagName == "div";
public ViewRenderer (string tagName = "div") public ViewRenderer (string tagName = "div")
: base (tagName) : base (tagName)
{ {

View File

@ -62,6 +62,8 @@ namespace Ooui.Forms
} }
} }
protected override bool HtmlNeedsFullEndElement => TagName == "div";
public VisualElementRenderer (string tagName = "div") : base (tagName) public VisualElementRenderer (string tagName = "div") : base (tagName)
{ {
_propertyChangedHandler = OnElementPropertyChanged; _propertyChangedHandler = OnElementPropertyChanged;

View File

@ -38,6 +38,8 @@ function getSize () {
// Main entrypoint // Main entrypoint
function ooui (rootElementPath) { function ooui (rootElementPath) {
return;
var initialSize = getSize (); var initialSize = getSize ();
var wsArgs = (rootElementPath.indexOf("?") >= 0 ? "&" : "?") + var wsArgs = (rootElementPath.indexOf("?") >= 0 ? "&" : "?") +
"w=" + initialSize.width + "&h=" + initialSize.height; "w=" + initialSize.width + "&h=" + initialSize.height;

View File

@ -5,6 +5,8 @@ namespace Ooui
{ {
public class Div : Element public class Div : Element
{ {
protected override bool HtmlNeedsFullEndElement => true;
public Div () public Div ()
: base ("div") : base ("div")
{ {

View File

@ -243,5 +243,38 @@ namespace Ooui
return base.SaveStateMessageIfNeeded (message); return base.SaveStateMessageIfNeeded (message);
} }
} }
protected virtual bool HtmlNeedsFullEndElement => false;
public override void WriteOuterHtml (System.Xml.XmlWriter w)
{
w.WriteStartElement (TagName);
w.WriteAttributeString ("id", Id);
var style = Style.ToString ();
if (style.Length > 0) {
w.WriteAttributeString ("style", style);
}
lock (attributes) {
foreach (var a in attributes) {
var value = (a.Value == null) ? "null" : Convert.ToString (a.Value, System.Globalization.CultureInfo.InvariantCulture);
w.WriteAttributeString (a.Key, value);
}
}
WriteInnerHtml (w);
if (HtmlNeedsFullEndElement) {
w.WriteFullEndElement ();
}
else {
w.WriteEndElement ();
}
}
public virtual void WriteInnerHtml (System.Xml.XmlWriter w)
{
var children = Children;
foreach (var c in children) {
c.WriteOuterHtml (w);
}
}
} }
} }

View File

@ -180,5 +180,24 @@ namespace Ooui
} }
return false; return false;
} }
public virtual string OuterHtml {
get {
using (var stream = new System.IO.MemoryStream ()) {
var settings = new System.Xml.XmlWriterSettings {
OmitXmlDeclaration = true,
ConformanceLevel = System.Xml.ConformanceLevel.Fragment,
CloseOutput = false,
};
using (var w = System.Xml.XmlWriter.Create (stream, settings)) {
WriteOuterHtml (w);
}
stream.Position = 0;
return new System.IO.StreamReader (stream).ReadToEnd ();
}
}
}
public abstract void WriteOuterHtml (System.Xml.XmlWriter w);
} }
} }

View File

@ -399,7 +399,7 @@ namespace Ooui
o.Append (head); o.Append (head);
o.Append (p.Key); o.Append (p.Key);
o.Append (":"); o.Append (":");
o.Append (String.Format (System.Globalization.CultureInfo.InvariantCulture, "{0}", p.Value)); o.Append (Convert.ToString (p.Value, System.Globalization.CultureInfo.InvariantCulture));
head = ";"; head = ";";
} }
} }

View File

@ -31,6 +31,8 @@ namespace Ooui
set => SetAttributeProperty ("cols", value); set => SetAttributeProperty ("cols", value);
} }
protected override bool HtmlNeedsFullEndElement => true;
public TextArea () public TextArea ()
: base ("textarea") : base ("textarea")
{ {
@ -52,5 +54,10 @@ namespace Ooui
} }
return base.TriggerEventFromMessage (message); return base.TriggerEventFromMessage (message);
} }
public override void WriteInnerHtml (System.Xml.XmlWriter w)
{
w.WriteString (val ?? "");
}
} }
} }

View File

@ -20,5 +20,10 @@ namespace Ooui
{ {
Text = text; Text = text;
} }
public override void WriteOuterHtml (System.Xml.XmlWriter w)
{
w.WriteString (text);
}
} }
} }

View File

@ -44,7 +44,10 @@ namespace Ooui
<style>@Styles</style> <style>@Styles</style>
</head> </head>
<body> <body>
<div id=""ooui-body"" class=""container-fluid""></div>
<div id=""ooui-body"" class=""container-fluid"">
@InitialHtml
</div>
<script type=""text/javascript"" src=""https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js""></script> <script type=""text/javascript"" src=""https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js""></script>
<script type=""text/javascript"" src=""https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js""></script> <script type=""text/javascript"" src=""https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js""></script>
@ -390,9 +393,9 @@ namespace Ooui
} }
} }
public static string RenderTemplate (string webSocketPath, string title = "") public static string RenderTemplate (string webSocketPath, string title = "", string initialHtml = "")
{ {
return Template.Replace ("@WebSocketPath", webSocketPath).Replace ("@Styles", rules.ToString ()).Replace ("@Title", title); return Template.Replace ("@WebSocketPath", webSocketPath).Replace ("@Styles", rules.ToString ()).Replace ("@Title", title).Replace ("@InitialHtml", initialHtml);
} }
class DataHandler : RequestHandler class DataHandler : RequestHandler

95
Tests/WriteHtmlTests.cs Normal file
View File

@ -0,0 +1,95 @@
using System;
#if NUNIT
using NUnit.Framework;
using TestClassAttribute = NUnit.Framework.TestFixtureAttribute;
using TestMethodAttribute = NUnit.Framework.TestCaseAttribute;
#else
using Microsoft.VisualStudio.TestTools.UnitTesting;
#endif
using Ooui;
namespace Tests
{
[TestClass]
public class WriteHtmlTests
{
System.Text.RegularExpressions.Regex idre = new System.Text.RegularExpressions.Regex ("\\sid=\"[^\"]*\"");
string OuterHtmlWithoutIds (Element e)
{
return idre.Replace (e.OuterHtml, "");
}
[TestMethod]
public void TextAreaWithTextStyled ()
{
var e = new TextArea {
Value = "Hello World!",
};
e.Style.BackgroundColor = "#18f";
Assert.AreEqual ("<textarea style=\"background-color:#18f\">Hello World!</textarea>", OuterHtmlWithoutIds (e));
}
[TestMethod]
public void TextAreaEmptyStyled ()
{
var e = new TextArea ();
e.Style.BackgroundColor = "#18f";
Assert.AreEqual ("<textarea style=\"background-color:#18f\"></textarea>", OuterHtmlWithoutIds (e));
}
[TestMethod]
public void Style ()
{
var e = new Div ();
e.Style.BackgroundColor = "#18f";
Assert.AreEqual ("<div style=\"background-color:#18f\"></div>", OuterHtmlWithoutIds (e));
}
[TestMethod]
public void TwoGrandChildren ()
{
var e = new Div (new Div (new Anchor (), new Anchor ()), new Paragraph ());
Assert.AreEqual ("<div><div><a /><a /></div><p /></div>", OuterHtmlWithoutIds (e));
}
[TestMethod]
public void Child ()
{
var e = new Div (new Anchor ());
Assert.AreEqual ("<div><a /></div>", OuterHtmlWithoutIds (e));
}
[TestMethod]
public void TextChild ()
{
var e = new Paragraph ("Hello world!");
Assert.AreEqual ("<p>Hello world!</p>", OuterHtmlWithoutIds (e));
}
[TestMethod]
public void IdIsFirst ()
{
var e = new Anchor ();
Assert.IsTrue (e.OuterHtml.StartsWith ("<a id=\""));
}
[TestMethod]
public void EmptyElement ()
{
var e = new Anchor ();
Assert.AreEqual ("<a />", OuterHtmlWithoutIds (e));
}
[TestMethod]
public void AnchorHRef ()
{
var e = new Anchor {
HRef = "http://google.com"
};
Assert.AreEqual ("<a href=\"http://google.com\" />", OuterHtmlWithoutIds (e));
}
}
}