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.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace Ooui.AspNetCore
{
public class ElementResult : ActionResult
{
{
readonly Element element;
readonly string title;
readonly string title;
public ElementResult (Element element, string title = "")
{
{
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;
response.StatusCode = 200;
response.ContentType = "text/html; charset=utf-8";
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);
response.ContentLength = htmlBytes.Length;
using (var s = response.Body) {

View File

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

View File

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

View File

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

View File

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

View File

@ -243,5 +243,38 @@ namespace Ooui
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;
}
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 (p.Key);
o.Append (":");
o.Append (String.Format (System.Globalization.CultureInfo.InvariantCulture, "{0}", p.Value));
o.Append (Convert.ToString (p.Value, System.Globalization.CultureInfo.InvariantCulture));
head = ";";
}
}

View File

@ -31,6 +31,8 @@ namespace Ooui
set => SetAttributeProperty ("cols", value);
}
protected override bool HtmlNeedsFullEndElement => true;
public TextArea ()
: base ("textarea")
{
@ -52,5 +54,10 @@ namespace Ooui
}
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;
}
public override void WriteOuterHtml (System.Xml.XmlWriter w)
{
w.WriteString (text);
}
}
}

View File

@ -44,7 +44,10 @@ namespace Ooui
<style>@Styles</style>
</head>
<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://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

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));
}
}
}